Re: "only" vs "[]"

2022-08-08 Thread vit via Digitalmars-d-learn

On Monday, 8 August 2022 at 11:35:48 UTC, pascal111 wrote:
The output of next code is the same to extent that we feel that 
there's no difference between "only" and "[]", so what "only" 
added here?:


'''D
[1,2,3].writeln;
only(1,2,3).writeln;
'''

output:

[1, 2, 3]
[1, 2, 3]



`only(1,2,3)` doesn't use GC. `[1,2,3]` allocate GC array.


Inferred attributes errors in template function.

2022-05-27 Thread vit via Digitalmars-d-learn

Hello, I have this problem:

```d
static int i;

void bar(T)(){
static if(is(T == int))
(()@system => 1)();
static if(is(T == float))
i = 42;

}
void foo(T)(){
bar!T();
}

void main()@safe pure{
foo!long();
	foo!float();	//Error: `pure` function `D main` cannot call 
impure function `onlineapp.foo!float.foo`
	foo!int();		//Error: `@safe` function `D main` cannot call 
`@system` function `onlineapp.foo!int.foo`

}
```

When template function foo is called and its inferred attributes 
are not compatible with attributes of main, errors are not really 
useful. Compiler print that foo!float is not pure or foo!int is 
not @safe but doesn't tell why. Is in dmd some flag that print 
errors similarly to this?:


```d
void main()@safe pure{
foo!long();
foo!float();
	//Error: `pure` function `D main` cannot call impure 
function `onlineapp.foo!float.foo`
	//Error: potentially `pure` function 
`onlineapp.foo!float.foo` cannot call impure function 
`onlineapp.bar!float.bar`
	//Error: potentially `pure` function 
`onlineapp.bar!float.bar` cannot access mutable static data `i`

foo!int();  
	//Error: `@safe` function `D main` cannot call `@system` 
function `onlineapp.foo!int.foo`
	//Error: potentially `@safe` function 
`onlineapp.foo!int.foo` cannot call `@system` function 
`onlineapp.bar!int.bar`
 	//Error: potentially `@safe` function 
`onlineapp.bar!int.bar` cannot call `@system` delegate 
`onlineapp.bar!int.bar.__lambda1`

}
```


Re: mixin template

2022-05-23 Thread vit via Digitalmars-d-learn

On Monday, 23 May 2022 at 15:14:53 UTC, Vindex wrote:

I have this code:

```
import std.array, std.exception, std.stdio;

mixin template RealizeException() {
this(string msg, string file = __FILE__, size_t line = 
__LINE__) {

super(msg, file, line);
}
}

class WrongUsage : Exception {
mixin RealizeException;

this(string[] messages, string file = __FILE__, size_t line 
= __LINE__) {

auto msg = std.array.join(messages, "\n");
super(msg, file, line);
}
}

void main() {
throw new WrongUsage("Error message.");
}
```

... and this error:

```
mixin_exception.d(19): Error: constructor 
`mixin_exception.WrongUsage.this(string[] messages, string file 
= __FILE__, ulong line = cast(ulong)__LINE__)` is not callable 
using argument types `(string)`
mixin_exception.d(19):cannot pass argument `"Error 
message."` of type `string` to parameter `string[] messages`
Failed: ["/usr/bin/dmd", "-v", "-o-", "mixin_exception.d", 
"-I."]


```

Why? Why can't I have two constructors when I use mixin?

If I replace mixin to real code, I have no problem:

```
class WrongUsage : Exception {
this(string msg, string file = __FILE__, size_t line = 
__LINE__) {

super(msg, file, line);
}

this(string[] messages, string file = __FILE__, size_t line 
= __LINE__) {

auto msg = std.array.join(messages, "\n");
super(msg, file, line);
}
}
```


mixin template create scope, for example if it was normal 
function (no ctor), you can do this:

```d

mixin template RealizeException() {
static void foo(string){}
}

class WrongUsage{
mixin RealizeException x;

alias foo = x.foo;

static void foo(string[]){}

}

void main() {
WrongUsage.foo("Error message.");
}
```

But for ctor this doesn't work...


Re: Odd construct idea. Splitting arguments inside a parameter list.

2022-05-23 Thread vit via Digitalmars-d-learn

On Monday, 23 May 2022 at 08:34:21 UTC, Chris Katko wrote:

D
struct pair
{
float x,y;
}

[...]


This work too:
```d
myFunction(taco, p.tupleof, burrito);
```


Re: decimal type in d

2022-05-17 Thread vit via Digitalmars-d-learn

On Monday, 16 May 2022 at 09:59:41 UTC, bauss wrote:

On Monday, 16 May 2022 at 09:46:57 UTC, IGotD- wrote:

On Sunday, 15 May 2022 at 13:26:30 UTC, vit wrote:

[...]


This also something I wondered, it should be standard in the D 
library. Implementing it can be done straight forward with 
existing D language primitives, essentially a struct.


For those who don't know, decimal in C# is like a floating 
point value but the exponent is a power of 10 (internally 
total 16 bytes). This means that for "simple" mathematics 
rational decimal values remains rational decimals values and 
not some rounded value that would happen if you would use 
normal floating point values. The decimal type is essential 
for financial calculations.


I think D can more or less copy the C# solution.


Here's the implementation if anyone needs it:

https://referencesource.microsoft.com/#mscorlib/system/decimal.cs,1b2858baf311cbf9

Should be fairly straightforward to implement.


Thanks, but it is not full implementation of decimal, arithmetic 
operator are missing.




On Monday, 16 May 2022 at 16:41:33 UTC, Steven Schveighoffer 
wrote:

On 5/15/22 9:26 AM, vit wrote:
Hello, I want read decimal type from sql db, do some 
arithmetic operations inside D program and write it back to 
DB. Result need to be close to result as if this operations 
was performed in sql DB. Something like C# decimal.
Exists this kind of library ind D? (ideally `pure @safe @nogc 
nothrow`).


https://code.dlang.org/search?q=decimal

-Steve


Thanks, most of the packages are incomplete or too old (doesn't 
compile), but this one https://code.dlang.org/packages/decimal 
can by modified to work for my use.





decimal type in d

2022-05-15 Thread vit via Digitalmars-d-learn
Hello, I want read decimal type from sql db, do some arithmetic 
operations inside D program and write it back to DB. Result need 
to be close to result as if this operations was performed in sql 
DB. Something like C# decimal.
Exists this kind of library ind D? (ideally `pure @safe @nogc 
nothrow`).


Re: Template shenannigans with multiple datatypes

2022-05-13 Thread vit via Digitalmars-d-learn

On Friday, 13 May 2022 at 11:58:15 UTC, zjh wrote:

On Friday, 13 May 2022 at 08:28:56 UTC, vit wrote:


...



```d
...
this(DataSources dataSources){
this.dataSources = dataSources;
}
...
return new MultiGraph!(staticMap!(PointerTarget, Ts))(ts);//ts
```

How is `ts` convert to `DataSources`?


`ts` have same type like `DataSources`:

```d

import std.meta : staticMap, allSatisfy;
import std.traits : PointerTarget, isPointer;
import std.conv : to;

alias Pointer(T) = T*;

class MultiGraph(Ts...){// Ts == (float, double, int)
alias DataSources = staticMap!(Pointer, Ts);	// (float, 
double, int) -> (float*, double*, int*)


DataSources dataSources;// -> (float*, double*, int*)
float[][DataSources.length] buffers;// -> float[][3]

this(DataSources dataSources){	// dataSources == (float*, 
double*, int*)

this.dataSources = dataSources;
}

void onTick() {
//grab datasource data and do something.
foreach(enum i, alias d; dataSources)
buffers[i] ~= to!float(*d); //or whatever
}
}

auto multiGraph(Ts...)(Ts ts)   // Ts == (float*, double*, int*)
if(allSatisfy!(isPointer, Ts)){ //all types in Ts are pointers
alias DataSources = staticMap!(PointerTarget, Ts);	// 
(float*, double*, int*) -> (float, double, int)

return new MultiGraph!(DataSources)(ts);
}


void main(){
float myFloat;
double myDouble;
int myInteger;
auto g = multiGraph(, , );

}

```


Re: Template shenannigans with multiple datatypes

2022-05-13 Thread vit via Digitalmars-d-learn

On Friday, 13 May 2022 at 07:32:16 UTC, Chris Katko wrote:

On Friday, 13 May 2022 at 07:05:36 UTC, vit wrote:

On Friday, 13 May 2022 at 06:43:39 UTC, Chris Katko wrote:
I have an intrinsicGraph(T) class that is given a pointer to 
a T dataSource and automatically polls that variable every 
frame to add it to the graph, whether it's a float, double, 
integer, and maybe bool.


[...]


I dont understand first qestion but second question has a 
solution:


```d
intrinsic_graph!T make_graph(T, Args...)(auto ref T val, auto 
ref Args args){

return new intrinsic_graph!T(val, args);
}


instrinsicGraph!float testGraph;
instrinsicGraph!ulong testGraph2;
// later
testGraph = make_graph(units[0].x, 100, 300, COLOR(1,0,0,1));
testGraph2 = make_graph(g.stats.fps, 100, 500, COLOR(1,0,0,1));


```


Okay, to clarify just in case I'm very confusing because I'm up 
late.


If I wanted a "multipleGraph". A graph that takes multiple 
values and plots them on the same graph. I need to store a 
buffer for each dataSource. Luckily, because I'm painting them 
to the screen, the buffers only really need to be float even if 
they started as a boolean, int, or double. However, if I'm 
keeping a list of pointers to things I want to snoop when I 
call onTick(), I can't think of a way to support multiple types:


```D
class intrinsicGraph(T)
   {
   T* dataSource;
   float[] buffer;

   void onTick()
 {
 //grab datasource data and do something.
 buffer ~= to!float(*datasource);
 }
   }

auto g = intrinsicGraph!float();
```

But what if there's multiple types?

```D
class multiGraph(???)
   {
   ???[] dataSources;
   float[] buffers;

   void onTick()
 {
 //grab datasource data and do something.
 foreach(d, i; dataSources)
buffers[i] ~= to!float(*d); //or whatever
 }
   }

auto g = multiGraph!???(, , );

```

This is a kinda "dynamic language" feature but it feels like 
this information is theoretically, knowable at static, 
compile-time. I know what the variable types will be at 
compile-time, but I don't know how to put them all in one class 
and reference them automatically.


Try variadic templates:

```d
import std.meta : staticMap, allSatisfy;
import std.traits : PointerTarget, isPointer;
import std.conv : to;

alias Pointer(T) = T*;

class MultiGraph(Ts...){
alias DataSources = staticMap!(Pointer, Ts);

DataSources dataSources;
float[][DataSources.length] buffers;

this(DataSources dataSources){
this.dataSources = dataSources;
}

void onTick() {
//grab datasource data and do something.
foreach(enum i, ref d; dataSources)
buffers[i] ~= to!float(*d); //or whatever
}
}

auto multiGraph(Ts...)(Ts ts)
if(allSatisfy!(isPointer, Ts)){
return new MultiGraph!(staticMap!(PointerTarget, Ts))(ts);
}


void main(){
float myFloat;
double myDouble;
int myInteger;
auto g = multiGraph(, , );

}
```


Re: Template shenannigans with multiple datatypes

2022-05-13 Thread vit via Digitalmars-d-learn

On Friday, 13 May 2022 at 06:43:39 UTC, Chris Katko wrote:
I have an intrinsicGraph(T) class that is given a pointer to a 
T dataSource and automatically polls that variable every frame 
to add it to the graph, whether it's a float, double, integer, 
and maybe bool.


[...]


I dont understand first qestion but second question has a 
solution:


```d
intrinsic_graph!T make_graph(T, Args...)(auto ref T val, auto ref 
Args args){

return new intrinsic_graph!T(val, args);
}


instrinsicGraph!float testGraph;
instrinsicGraph!ulong testGraph2;
// later
testGraph = make_graph(units[0].x, 100, 300, COLOR(1,0,0,1));
testGraph2 = make_graph(g.stats.fps, 100, 500, COLOR(1,0,0,1));


```


Re: Virtual methods on stack objects

2022-05-12 Thread vit via Digitalmars-d-learn

On Wednesday, 11 May 2022 at 20:53:21 UTC, Marvin Hannott wrote:

On Wednesday, 11 May 2022 at 20:23:07 UTC, Ali Çehreli wrote:

On 5/11/22 13:06, Marvin Hannott wrote:

> I appreciate the answer, don't much like the "solutions".

Me neither. :)

> It's not so much about copying

Great!

> scoped class objects should have value semantics.

std.typecons.scoped does exactly that:

  https://dlang.org/phobos/std_typecons.html#scoped

import std.stdio;
import std.typecons;

interface Animal {
  string sing();
}

class Cat : Animal {
  this() {
writeln("Hi!");
  }

  ~this() {
writeln("Bye!");
  }

  string sing() {
return "mew";
  }
}

void foo(Animal animal) {
  writeln(animal.sing());
}

void bar() {
  auto cat = scoped!Cat();
  foo(cat);
}

void main() {
  bar();
}

The output:

Hi!
mew
Bye!

Ali


Yeah, but you can't return `Cat` . And the documentation for 
`scoped` says:
It's illegal to move a class instance even if you are sure 
there are no pointers to it. As such, it is illegal to move a 
scoped object.


That's kinda very limiting.

Anyway, I cooked up another idea based on your first 
suggestions.

```D
struct S
{
static private interface I
{
int f(int i);
}

static private final class A : I
{
int f(int i) {return i;}
}

static private final class B : I
{
int f(int i) {return i+ 1;}
}

private I i;
private int d;

this(int d)
{
this.d = d;
if(d < 10)
{
i = scoped!A();
}else {
i = scoped!B();
}
}

int f() { return i.f(d);}
}
```
I mean, this is a super dumb example, but it kinda works. And I 
think it could be made a lot less tedious with some mixin magic.


`scoped` is not necesary, try this:

```d
import std.typecons;

struct S{
static private interface I{
int f(int i)const;
}

static private final class A : I{
static immutable typeof(this) instance = new 
immutable typeof(this)();


int f(int i)const {return i;}
}

static private final class B : I{
static immutable typeof(this) instance = new 
immutable typeof(this)();


int f(int i)const {return i+ 1;}
}

private immutable I i;
private int d;

this(int d){
this.d = d;

if(d < 10) i = A.instance;
else i = B.instance;

}

int f() { return i.f(d);}
}

void main(){
import std.stdio;
S(1).f().writeln();  /// 1
S(100).f().writeln(); /// 101

}
```


Re: dip1000 return scope dmd v 2.100

2022-05-07 Thread vit via Digitalmars-d-learn

On Friday, 6 May 2022 at 17:17:01 UTC, Dennis wrote:

On Friday, 6 May 2022 at 09:24:06 UTC, vit wrote:

[...]


They were recently updated to match the implementation in 2.100.


[...]


`return scope` means pointer members (such `this.ptr`, `C.ptr`) 
may not escape the function, unless they are returned. If you 
call `test()` on a `scope` variable, the return value will be a 
scope pointer.


[...]


Thanks


dip1000 return scope dmd v 2.100

2022-05-06 Thread vit via Digitalmars-d-learn

Hello, new dmd (2.100) has return/scope changes.
It look like examples at page 
https://dlang.org/spec/function.html#ref-return-scope-parameters 
are no longer relevant.


What difference are between `return scope`, `scope return` and 
`return`?

Why `void* ptr` in struct change effect of `scope return` ?


```d
@safe:

struct A{
int  val;
//void* ptr;

int* test() scope return{
return// OK
}
}

struct B{
int  val;
void* ptr;

int* test() return{
return  // OK
}
}

struct C{
int  val;
void* ptr;

int* test() scope return{
		return  // Error: returning `` escapes a 
reference to parameter `this`

}
}


void main(){}
```


Re: How to unpack template parameters,Or how to forward parameters?

2022-05-05 Thread vit via Digitalmars-d-learn

On Friday, 6 May 2022 at 00:41:18 UTC, zjh wrote:

Hello everyone,I have following function:
```d
import core.stdc.stdio;
void f(int i,int j){
printf("%i,%i",i,j);
}
```
I want to forward `int[N]` to `(int i,int j)` etc. How can I 
write a forwarding function?

```d
void ff(alias g,int...I)(int[2]k){
g(k[I]);
}//How to unpack template variable parameters?

void f(int[2]k){
ff!(f,0,1)(k);//how to forward?
}

```

main function:
```d
extern(C):void main()
{
int[2] a=[2,4];
f(a);//calling like this
}
```


Try this:

```d
import core.stdc.stdio;

void f(int i,int j){
printf("%i,%i",i,j);
}


import std.range :  iota;
import std.traits :  isStaticArray;
import std.meta :  AliasSeq;


template expand(alias arr)
if(isStaticArray!(typeof(arr))){
auto get(size_t I)(){
return arr[I];
}

alias Result = AliasSeq!();

static foreach(I; iota(0, arr.length))
Result = AliasSeq!(Result, get!I);

alias expand = Result;
}


extern(C):void main(){
int[2] a=[2,4];
f(expand!a);
}
```


Re: Why isn't my dynamic array method doesn't work for this type?

2022-05-05 Thread vit via Digitalmars-d-learn

On Thursday, 5 May 2022 at 11:49:29 UTC, vit wrote:

On Thursday, 5 May 2022 at 10:40:44 UTC, rempas wrote:
I have created a structure that is a actually an array that 
allocates memory and growths. It is a template and it has 
worked with a couple of types that I have tried with. It 
doesn't work with one tho and I cannot understand why. I will 
list the smallest possible code I could. Keep in mind that it 
is a couple of code. For anyone that wants to read it, keep in 
mind that I have to make this code work with LDC and using 
"-betterC".


[...]


```d
  this.capacity += DEF_VEC_REALLOC_SIZE;
  //realloc(this.ptr, T.sizeof * DEF_VEC_REALLOC_SIZE);
  this.ptr = realloc(this.ptr, T.sizeof * this.capacity); 
//<<--

```


```d
void add(T element) {
if (this.capacity == this.length) {
this.capacity += DEF_VEC_REALLOC_SIZE;
this.ptr = realloc(this.ptr, T.sizeof * this.capacity);
if (!this.ptr) { // Re-allocation error check
			fprintf(stderr, "Error: Could not allocate more memory for 
the *%s object! Exiting...",

  cast(char*)(T).stringof);
exit_prog(1);
}
}


this.ptr[this.length++] = element;

}
```


Re: Why isn't my dynamic array method doesn't work for this type?

2022-05-05 Thread vit via Digitalmars-d-learn

On Thursday, 5 May 2022 at 10:40:44 UTC, rempas wrote:
I have created a structure that is a actually an array that 
allocates memory and growths. It is a template and it has 
worked with a couple of types that I have tried with. It 
doesn't work with one tho and I cannot understand why. I will 
list the smallest possible code I could. Keep in mind that it 
is a couple of code. For anyone that wants to read it, keep in 
mind that I have to make this code work with LDC and using 
"-betterC".


[...]


```d
  this.capacity += DEF_VEC_REALLOC_SIZE;
  //realloc(this.ptr, T.sizeof * DEF_VEC_REALLOC_SIZE);
  this.ptr = realloc(this.ptr, T.sizeof * this.capacity); 
//<<--

```


Re: Help with DynamicArray of Emsi Containers

2022-05-01 Thread vit via Digitalmars-d-learn
On Saturday, 30 April 2022 at 20:22:43 UTC, Christian Köstlin 
wrote:
I am struggling with initializing an Emsi Containers 
DynamicArray in a nice way. Some background information of my 
usecase:


I experimenting in porting some old 3d engine code of mine from 
c++ to dlang. In the engine I want to exactly control when 
resources are freed and not rely on the garbage collector. For 
that I am using reference counters courtesy of autoptr.


e.g.

```d

alias Texture = IntrusivePtr!TextureData; // dub package autoptr
class TextureData
{
  IFImage image; // dub package imagefmt
}

```


another class of mine now is supposed to hold several of those 
textures for multitexturing and should be initialized in its 
constructor:


```d
class Appearance
{
  Texture[] textures;
  this(Texture[] textures)
  {
this.textures = textures;
  }
}
```
Unfortunately this does not work properly together with 
autoptr's (see 
https://github.com/submada/autoptr/issues/5#issuecomment-997683868).


Because of that I am using now DynamicArrays from Emsi 
Containers, but I am having trouble initializing them:


```d
class Apperance
{
  DynamicArray!Texture textures;
  this(DynamicArray!Texture textures)
  {
this.textures = textures;
  }
}
```
does not compile.

What would be the best way to initialize the variable?

Kind regards,
Christian


DynamicArray has disabled postblit (is not copyable).


Package autoptr is deprecated (internaly redirected to 
btl:atuoptr), all functionality is moved to package 
[BTL](https://code.dlang.org/packages/btl) (subpackage 
btl:autoptr). This library contains subpackage btl:vector with 
functionality like DynamicArray with support for copying. I use 
IntrusivePtr inside Vector/SmallVector and i have no problems.





Re: generic function instance without call

2022-04-27 Thread vit via Digitalmars-d-learn

On Wednesday, 27 April 2022 at 16:03:32 UTC, user1234 wrote:

On Wednesday, 27 April 2022 at 15:23:26 UTC, vit wrote:
Hi, is it possible to get address of generic function instance 
for specified arguments without calling the function?


Example:


```d

auto foo(alias fn, Args...)(auto ref Args args){
///return function/delegate type of `fn` for arguments 
`args`

}

void main(){

long x;

auto fn = foo!((a, b) => true)(new int(42), x);

static assert(is(typeof(fn) == bool function(int*, scope 
ref long)@safe pure nothrow @nogc ));

}

```


yeah sure; declare an alias that (fully) specialize the generic 
func and take the address using the alias Identifier.


This work for types but not for attributes like `scope`, `return` 
and `auto ref`.





Re: generic function instance without call

2022-04-27 Thread vit via Digitalmars-d-learn

Fix:
```d
auto fn = foo!((a, ref b) => true)(new int(42), x);
```



generic function instance without call

2022-04-27 Thread vit via Digitalmars-d-learn
Hi, is it possible to get address of generic function instance 
for specified arguments without calling the function?


Example:


```d

auto foo(alias fn, Args...)(auto ref Args args){
///return function/delegate type of `fn` for arguments `args`
}

void main(){

long x;

auto fn = foo!((a, b) => true)(new int(42), x);

static assert(is(typeof(fn) == bool function(int*, scope ref 
long)@safe pure nothrow @nogc ));

}

```


Re: Reference counting example

2022-04-27 Thread vit via Digitalmars-d-learn

On Tuesday, 26 April 2022 at 23:33:28 UTC, cc wrote:

On Tuesday, 26 April 2022 at 22:16:01 UTC, cc wrote:

Test application:


I should point out that all this stuff with saving refcounted 
things to arrays and so on is extremely untested and 
experimental


One problem I'm seeing is the inability for a refcounted class 
to pass itself to another function, since the class internals 
don't see the struct wrapper.. you can pass the naked object 
reference itself, and hope the reference doesn't get saved 
otherwise there's your dangling pointer, but then you also have 
the problem of inconsistent method declarations, with some 
things taking Foo and others taking RefCounted!Foo etc...


Every night I pray for a `refcounted` keyword.  Wouldn't 
something like `auto foo = new refcount Foo();` be nice?  Then 
every class that deals with the objects could continue to be 
allocator-agnostic... definitely not a trivial change though.


Yor code has antoher big problem. Class Animal has 
@safe/pure/nothrow/@nogc destruction but class Cow has @system 
destructor. When you assign RC!Cow to RC!Animal you can have 
@safe @nogc ... function call @system destructor of Cow.



I have library with check this kind of error for you 
(https://code.dlang.org/packages/btl).


If you need aliasing (your case) or weak pointers then try it.

```d

import std.stdio;
import core.memory;
import core.lifetime;

import btl.autoptr;
import btl.vector;

alias ARRAY = Vector;
alias RC = RcPtr;

class Animal {
void speak() {
writeln("Animal: ???");
}

~this()@system{}   //without this code doesnt compile
}
class Cow : Animal {
ARRAY!(RC!Animal) friends; // Amazingly, this works, as 
long as the array elem type is NOT the same as RC!(this class)
// otherwise we get a 
forwarding error

int x;
this() { writefln("[Cow]"); }
this(int x) { this.x = x; writefln("[Cow %s]", x); }
~this() { writefln("[/Cow %s]", x); }
override void speak() {
writefln("Cow#%s: Moo.", x);
}
}

class Farm {
ARRAY!(RC!Cow) animals;
//this() {}
this(int) { writeln("[Farm]"); }
~this() {
writeln("[~Farm]");
animals.clear();
writeln("[/Farm]");
}

void pet(RC!Animal animal) {
writefln("Farm: The %s says...", animal);
animal.get.speak;
}

}

void main() {
auto used = GC.stats.usedSize;
scope(exit) assert(GC.stats.usedSize == used); // GC is 
not touched!

{
assert(RC!Cow.make().get.x == 0);
assert(RC!Cow.make(99).get.x == 99);
}

RC!Animal other;

auto farm = RC!Farm.make(1);
{
auto cow = RC!Cow.make(1);
farm.get.animals ~= cow;
farm.get.animals ~= RC!Cow.make(2);
other = farm.get.animals[1];
auto cowGoesOutOfScope = RC!Cow.make(70);
}
writeln("out, should have seen Cow#70's dtor");

farm.get.animals[0] = farm.get.animals[1];
writeln("animals[0] (Cow#1) just got overwritten so we 
should have seen its dtor");


farm.get.animals ~= RC!Cow.make(3);

farm.get.pet(other);
other = null;

farm = null;

writeln("done");
}
```


Re: Create an associative array with function pointers as the value

2022-04-20 Thread vit via Digitalmars-d-learn

On Wednesday, 20 April 2022 at 10:42:59 UTC, rempas wrote:
I'm trying to create an associative array where the keys will 
be a "string" type and the values will be function pointers. 
I'm using a custom type is called "file_struct" and for anyone 
that wants to try specifically with this type, the definition 
is the following:


[...]


You need shared static this for initializing immutable AA:

```d
immutable void function(ref file_struct)[string] 
common_identifiers;


shared static this(){
common_identifiers = [
  "let" : _let,
  // "macro"   : _macro,
];
}
```


scope variable `b` assigned to `a` with longer lifetime (-dip1000)

2022-04-09 Thread vit via Digitalmars-d-learn

Hello,
Why doesn't this code compile?


```d

static struct Foo{
void *ptr;

void proxySwap1(scope ref typeof(this) rhs)scope pure nothrow 
@trusted @nogc{

auto tmp = this.ptr;
this.ptr = rhs.ptr;
rhs.ptr = tmp;
}
void proxySwap2()(scope ref typeof(this) rhs)scope pure 
nothrow @trusted @nogc{

this.proxySwap1(rhs);
}
void proxySwap3()(scope ref typeof(this) rhs)scope pure 
nothrow @trusted @nogc{

auto tmp = this.ptr;
this.ptr = rhs.ptr;
rhs.ptr = tmp;
}
}

void main()@safe{

scope Foo a;
scope Foo b;

a.proxySwap1(b);//OK
a.proxySwap2(b);//OK
a.proxySwap3(b);	//Error: scope variable `b` assigned to `a` 
with longer lifetime

}
```



Re: Can std.variant be used with std.container.rbtree?

2022-04-02 Thread vit via Digitalmars-d-learn

On Saturday, 2 April 2022 at 14:49:15 UTC, Vijay Nayar wrote:

On Saturday, 2 April 2022 at 14:35:10 UTC, Vijay Nayar wrote:
The `tryMatch` method fails to compile, and instead I get the 
following error:

```d
/dlang/dmd/linux/bin64/../../src/phobos/std/sumtype.d(2004): 
Error: static assert:  "`handlers[0]` of type `int 
function(ref ubyte[] _1, ref ubyte[] _2) pure nothrow @nogc 
@safe` never matches"

```


Through sheer trial and error, I discovered that changing the 
handler arguments from `ref ubyte[]` to `const ref ubyte[]` the 
error goes away. However, I did not find any information in the 
documentation or code that made this requirement clear. It was 
basically a guess based on the fact that `string` has no 
trouble but `ubyte[]` did, and string is basically just 
`immutable(char[])`.


So far, I'm finding that learning to use `SumType` is 
significantly more cryptic than `Variant`, by a large margin. 
I'll still give it a shot of course, because I want to get past 
this problem.


Try this:

```d
import std.sumtype;
import std.algorithm : cmp;

alias VarType = SumType!(double, ubyte[]);


int opCmp(const ref VarType v1, const ref VarType v2) {
//you need all combinations of types:
static int impl(A, B)(auto ref A a, auto ref B b){
// (double, ubyte[]) or  (ubyte[], double):
static if(!is(immutable A == immutable B))
assert(0, "type missmatch");
// (ubyte[], ubyte[]):
else static if(is(immutable A == immutable ubyte[]))
return cmp(a, b);
// (double, double):
else
return (a < b) ? (-1) : (a < b ? 1 : 0);
}
return tryMatch!impl(v1, v2);
}

void main(){
VarType b1 = cast(ubyte[]) [0x01, 0x02, 0x03];
VarType b2 = cast(ubyte[]) [0x01, 0x02, 0x04];
	assert(opCmp(b1, b2) == -1);	//operator overloading work only if 
opCmp is method.

}
```


Re: Can std.variant be used with std.container.rbtree?

2022-04-02 Thread vit via Digitalmars-d-learn

On Friday, 1 April 2022 at 22:22:21 UTC, Vijay Nayar wrote:

Consider the following program:
```d
void main()
{   
  import std.stdio;
  import std.container.rbtree;
  import std.variant;

[...]


Variant can contain any type => variant cannot assume attributes 
like pure nothrow @safe @nogc on its methods. RedBlackTree has 
nothrow dtor => Element type must have nothrow dtor => Variand 
need nothrow dtor... Similar for other methods.


Try use ```std.sumtype```.


Re: How to create delegates with an independent scope?

2022-03-30 Thread vit via Digitalmars-d-learn

On Wednesday, 30 March 2022 at 12:56:39 UTC, Vijay Nayar wrote:

On Wednesday, 30 March 2022 at 12:53:10 UTC, vit wrote:

use two delegates :)

```d
(){
// Deliberately create a copy to keep in delegate scope.
string myStr = i.dup;
			// The delegate will hopefully carry this copy around in 
its own scope.

funcs ~= (() => myStr ~ " sandwich");
}();
```


Very interesting. Both this and creating a "function creator 
function" work, and it seems clear that functions create their 
own scopes. However, it seems that loops do not, is that 
correct?  Maybe I was thrown off by the surrounding `{ }`, but 
I had assumed that loops created their own scopes.


It is bug: https://issues.dlang.org/show_bug.cgi?id=21929



Re: How to create delegates with an independent scope?

2022-03-30 Thread vit via Digitalmars-d-learn

On Wednesday, 30 March 2022 at 12:46:07 UTC, Vijay Nayar wrote:

Consider the following code example:

```d
import std.stdio;

void main()
{
  alias DelegateT = string delegate();

  // An array of delegates, each has their own scope.
  DelegateT[] funcs;
  foreach (i; ["ham", "cheese"]) {
// Deliberately create a copy to keep in delegate scope.
string myStr = i.dup;
// The delegate will hopefully carry this copy around in 
its own scope.

funcs ~= (() => myStr ~ " sandwich");
  }

  foreach (f; funcs) {
writeln(f());
  }
}
```

The expected output is: "ham sandwich" and then "cheese 
sandwich".


The actual output is: "cheese sandwich" and then "cheese 
sandwich".


It seems that the variable `myStr` is in a sort of shared scope 
for both functions in the array, and the last value written to 
it dominates.


How do I create a delegate that acts like a 
[closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), that is, it carries with it the environment in which it was created?


use two delegates :)

```d
import std;

void main(){
alias DelegateT = string delegate();

// An array of delegates, each has their own scope.
DelegateT[] funcs;
foreach (i; ["ham", "cheese"]) {
(){
// Deliberately create a copy to keep in delegate scope.
string myStr = i.dup;
			// The delegate will hopefully carry this copy around in its 
own scope.

funcs ~= (() => myStr ~ " sandwich");
}();
}

foreach (f; funcs) {
writeln(f());
}
}
```



Re: How to make a generic function to take a class or struct by reference?

2022-03-27 Thread vit via Digitalmars-d-learn

On Sunday, 27 March 2022 at 16:27:44 UTC, JN wrote:
I would like to have only one definition of getX if possible, 
because they both are doing the same thing. I can't remove the 
ref one, because without a ref it will pass the struct as a 
temporary and compiler won't like that.


```d
import std.stdio;

struct Foo
{
int x;

void doStuff()
{
*getX(this) = 5;
}
}

class Bar
{
int x;

void doStuff()
{
*getX(this) = 5;
}
}

int* getX(T)(ref T t)
{
return 
}

int* getX(T)(T t)
{
return 
}

void main()
{
Foo foo;
Bar bar = new Bar();

foo.doStuff();
bar.doStuff();

assert(foo.x == 5);
assert(bar.x == 5);
}
```


Try this:
```d

int* getX(T)(return auto ref T t){
static if(is(T == class))
return 
else static if(is(T == struct) && __traits(isRef, t))
return 
else
static assert(0, "no impl " ~ T.stringof);
}
```
or:

```d

int* getX(T)(return auto ref T t)
if(is(T == class) || (is(T == struct) && __traits(isRef, t))){
return 
}
```


error forward references if scope

2022-03-12 Thread vit via Digitalmars-d-learn

Hello,
why this code compile without problems:

```d

struct Query{
public const SharedPtr!Builder builder;
}

interface Builder{
void build(ref Query query);
}

struct SharedPtr(T){
enum touch_T = __traits(hasMember, T, "touch");
//...
}


void main(){

}

```

but if `ref Query query` is scope then there is error?

```d

struct Query{
public const SharedPtr!Builder builder;
}

interface Builder{
void build(scope ref Query query); //SCOPE
}

struct SharedPtr(T){
enum touch_T = __traits(hasMember, T, "touch");
//...
}



void main(){

}
```

```
src/app.d(3,1): Error: no size because of forward references
src/app.d(4,18): Error: template instance 
`app.SharedPtr!(Builder)` error instantiating


```


Re: Cannot Call Super-Class Overloaded Function If Class has Function Override?

2022-03-01 Thread vit via Digitalmars-d-learn

On Tuesday, 1 March 2022 at 08:40:12 UTC, Vijay Nayar wrote:
I've randomly encountered a strange error, and I cannot find 
any explanation for it in the official documentation of syntax.


[...]


Here is more info (3.): 
https://docarchives.dlang.io/v2.078.0/spec/function.html#function-inheritance




Re: Cannot Call Super-Class Overloaded Function If Class has Function Override?

2022-03-01 Thread vit via Digitalmars-d-learn

On Tuesday, 1 March 2022 at 08:40:12 UTC, Vijay Nayar wrote:
I've randomly encountered a strange error, and I cannot find 
any explanation for it in the official documentation of syntax.


Essentially, a class cannot call function overload in a 
super-class if the class itself contains an override. Is this a 
bug? Is this on purpose? Take a look at `B.otherThing()` below.


``` d
void main()
{
  abstract class A {
// An abstract method for sub-classes
abstract void doThing(string a, size_t b);
// A convenience helper.
void doThing(string a) {
  doThing(a, a.length);
}
  }

  class B : A {
// If this overload exists, something strange happens...
override
void doThing(string a, size_t b) {
}

void otherThing() {
  // Error: `B.doThing(string a, ulong b)`
  // is not callable using argument
  // types `(string)`
  doThing("hello");

  super.doThing("hello");  // OK
}
  }
}
```


```d
void main()
{
  abstract class A {
// An abstract method for sub-classes
abstract void doThing(string a, size_t b);
// A convenience helper.
void doThing(string a) {
  doThing(a, a.length);
}
  }

  class B : A {
// If this overload exists, something strange happens...
override
void doThing(string a, size_t b) {
}

alias doThing = typeof(super).doThing;	//add super.doThing to 
overload set.


void otherThing() {
  // Error: `B.doThing(string a, ulong b)`
  // is not callable using argument
  // types `(string)`
  doThing("hello");

  super.doThing("hello");  // OK
}
  }
}
```


Re: opCast in class prevents destroy

2022-03-01 Thread vit via Digitalmars-d-learn

On Tuesday, 1 March 2022 at 08:16:13 UTC, Mike Parker wrote:

On Tuesday, 1 March 2022 at 07:16:11 UTC, bauss wrote:

Right now if you want to add an additional cast then you have 
to implement ALL the default behaviors and then add your 
custom cast.


It's two template functions like the OP used: one for T to 
catch everything, and one specialization.




That doesn't seem correct to me at least.


Depends on your perspective I guess. For the inverse, when you 
want to allow only one kind of cast and prevent everything 
else, you only have to implement one template right now. If 
that were not the case, then you'd have to implement an 
additional catch-all template that bombs out with a static 
assert.


So either way makes sense, IMO. Though I totally understand how 
the current behavior can be a surprise when people expect it to 
behave like, e.g., C++.


But D is not C++. So is `opCast` intended to expand the list of 
target types (like C++), or is it intended to define it? The 
spec says, "To define how one type can be cast to another", 
which doesn't really answer the question.


Now is possible this:

```d
import std.stdio;

struct Foo{
int i;

this(int i)@safe{
this.i = i;
writeln("ctor(", i, "): ", cast(void*));
}

Foo opCast(T, this This)()@safe
if(is(immutable T == immutable This)){
return Foo(2);
}

~this()@safe{
writeln("dtor(", i, "): ", cast(void*));
}
}

struct Bar{
const Foo foo;

this(int i)@safe{
this.foo = Foo(i);
}
}

void main()@safe{
Bar bar =  Bar(1);
}
```

Result:
```d
ctor(1): 7FFE0D5A94A8  //dtor for Foo(1) is never called.
ctor(2): 7FFE0D5A9410
dtor(2): 7FFE0D5A9470
dtor(2): 7FFE0D5A9470  //dtor for Foo(2) is called twice.
```


Re: passing a variadic parameter to randomSample

2022-01-25 Thread vit via Digitalmars-d-learn

On Tuesday, 25 January 2022 at 09:48:25 UTC, forkit wrote:
so I'm trying to write (or rather learn how to write) a 
'variadic template function', that returns just one of its 
variadic parameter, randomly chosen.


But can't get my head around the problem here :-(

.. Error: template `std.random.randomSample` cannot deduce 
function from argument types `


// --

module test;
import std;

string RandomChoice(R...)(R r)
{
auto rnd = MinstdRand0(42);
return r.randomSample(1, rnd).to!string;
}

void main()
{
writeln( RandomChoice("typeA", "typeB", "typeC") );
}

// --


`r` is not input range, try this:

```d
module test;
import std;


string RandomChoice1(R...)(R r)
{
auto rnd = MinstdRand0(unpredictableSeed);
return only(r).randomSample(1, rnd).front;
}

string RandomChoice2(R...)(R r)@nogc
{
auto rnd = MinstdRand0(unpredictableSeed);

switch(rnd.front % R.length){
static foreach(enum I, alias arg; r){
case I:
return arg;
}

default:
assert(0, "no impl");
}
}

void main()
{
writeln( RandomChoice1("typeA", "typeB", "typeC") );
writeln( RandomChoice2("typeA", "typeB", "typeC") );
}
```



Re: forward tuple arg to local variable + dtor

2022-01-22 Thread vit via Digitalmars-d-learn
On Saturday, 22 January 2022 at 19:01:09 UTC, Stanislav Blinov 
wrote:

On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote:


[...]


Take by value and make a copy without forwarding:

```d
import std.typecons : Tuple;
import std.meta : allSatisfy;

[...]


Thanks, second options is what I need. (In my case forwarding is 
more complex because weak ptrs need lock()).





Re: forward tuple arg to local variable + dtor

2022-01-22 Thread vit via Digitalmars-d-learn

On Saturday, 22 January 2022 at 17:23:12 UTC, Ali Çehreli wrote:

On 1/22/22 07:17, vit wrote:

> Why local variable of type tuple call destructors immediately
after
> initialization?

I don't even understand where the local variable comes from. If 
you want a pair of Foo objects, I would use std.typeconst.Tuple.


Otherwise I would use AliasSeq as I understand it like the 
following:


alias tup = AliasSeq!(Foo, Foo);

static foreach(Type; tup) {{
  Type x;
  writeln("check(", x.i, "): ", cast(void*));
}}

So, to me, AliasSeq!(Foo, Foo) is just a pair of types. I 
instantiate an object for each type individually and use it 
inside.


Ali


I want implement something like this:

```d
import std.stdio : writeln;
import std.meta : AliasSeq, staticMap;
import core.memory : pureMalloc, pureFree;
import core.lifetime : emplace, forward;


void main()@safe{
auto rc1 = RcPtr!int.make(1);   //ref counted pointer

long result = 0;

//apply can be @safe
apply!((ref int a, ref long b){
rc1 = null;	//apply has copy of rc1, a is not 
dangling reference

result = a + b;

})(rc1, RcPtr!long.make(2));

assert(result == 3);
}

//@safe access to data of multiple ref counted objects:
public auto apply(alias fn, Args...)(scope auto ref Args 
args){
	Args params = forward!args;	//copy lvalue and move rvalue 
args


@property auto ref elm(alias param)()@trusted{
return param.get();
}

return fn(staticMap!(elm, params));

}

//simple implementation of ref counted pointer
struct RcPtr(T){

private Payload* payload;

private this(Payload* payload)@safe{
this.payload = payload;
}

//copy ctor
public this(ref typeof(this) rhs){
this.payload = rhs.payload;
if(payload)
payload.count += 1;
}

//make data
public static auto make(Args...)(auto ref Args args){
Payload* payload = ()@trusted{
return cast(Payload*)pureMalloc(Payload.sizeof);
}();
emplace(payload, forward!args);
return RcPtr(payload);  
}

public ~this(){
this.opAssign(null);
}

//release payload
void opAssign(typeof(null) nil){
if(payload){
payload.count -= 1;
if(payload.count == 0){
destroy(*payload);
()@trusted{
pureFree(payload);
}();
payload = null;
}
}
}

//
ref T get()@system{
assert(payload);
return payload.data;
}

private struct Payload{
int count = 1;
T data;

this(Args...)(auto ref Args args){
data = T(forward!args);
}
}
}



```


Re: forward tuple arg to local variable + dtor

2022-01-22 Thread vit via Digitalmars-d-learn

On Saturday, 22 January 2022 at 14:23:32 UTC, Adam Ruppe wrote:
You can't forward to a local variable. Local variables will be 
a copy of the tuple. forward only actually works if sent 
*directly* to another function call.


There's a bunch of things in D that only work in function 
parameter lists and not local variables. This is one of them.


Thanks,
Why local variable of type tuple call destructors immediately 
after initialization?


```d
import std.stdio : writeln;
import std.meta : AliasSeq;

struct Foo{
int i;

this(int i){
this.i = i;
writeln("ctor(", i, "): ", cast(void*));
}

~this(){
writeln("dtor(", i, "): ", cast(void*));
i *= -1;
}
}


void main(){
{
AliasSeq!(Foo, Foo) tup;

static foreach(alias x; tup)
writeln("check(", x.i, "): ", cast(void*));	//x is 
destructed

}
}

```

Print:
```
dtor(0): 7FFF30D76868
dtor(0): 7FFF30D76858
check(0): 7FFF30D76858 //dangling?
check(0): 7FFF30D76868 //dangling?
```



forward tuple arg to local variable + dtor

2022-01-22 Thread vit via Digitalmars-d-learn

Hello,

Why is tuple variable `params` immediately destructed after its 
construction?

Why is `check(-2)` after `dtor(2)`?

Code:
```d
import std.stdio : writeln;
import core.lifetime : forward, move;

struct Foo{
int i;

this(int i){
this.i = i;
writeln("ctor(", i, "): ", cast(void*));
}

~this(){
writeln("dtor(", i, "): ", cast(void*));
i *= -1;
}
}

void seq(Args...)(auto ref Args args){
Args params = forward!args;
writeln("params initialized");

alias foo = params[0];
writeln("check(", foo.i, "): ", cast(void*));

}

void main(){
writeln("Foo(1):");
{
auto foo = Foo(1);
writeln("check(", foo.i, "): ", cast(void*));
}

writeln("\nFoo(2):");
seq(Foo(2));
}


```

Output:
```
Foo(1):
ctor(1): 7FFEBCAF0538
check(1): 7FFEBCAF0538
dtor(1): 7FFEBCAF0538

Foo(2):
ctor(2): 7FFEBCAF0548
dtor(2): 7FFEBCAF04F0
params initialized
check(-2): 7FFEBCAF04F0
dtor(0): 7FFEBCAF0558
```




Re: Function prototype overloading does not work ?

2022-01-19 Thread vit via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 08:47:27 UTC, Enjoys Math wrote:

```
module expr;

import dots;
import operator;
import equation;
import var;
import var_expr;
import zz_const;

class Expr
{
public:
   void opBinary(string op)(string s) const
   {
  static if (op == "+")
  {
 Expr right = null;

 if (s == ".." || s == "..." || s == "")
 {
right = new Dots();
 }

 if (right !is null)
return new Op("+", [this, right]);
  }
   }

   override string toString() const
   {
  assert(0);
   }

   Expr sub(Expr x, Expr y)
   {
  if (this == x)
 return y;
  return this;
   }

   Expr sub(Expr x, ref Var y)
   {
  return sub(x, new VarExpr(y));
   }

   Expr sub(ref Var x, Expr y)
   {
  return sub(new VarExpr(x), y);
   }

   Expr sub(int x, Expr y)
   {
  return sub(ZZ(x), y);
   }

   Expr sub(Expr x, int y)
   {
  return sub(x, ZZ(y));
   }

   Expr sub(ref Var x, ref Var y)
   {
  return sub(new VarExpr(x), new VarExpr(y));
   }

   Expr sub(ref Var x, int y)
   {
  return sub(new VarExpr(x), ZZ(y));
   }

   Expr sub(int x, ref Var y)
   {
  return sub(ZZ(x), new VarExpr(y));
   }

   override bool opEquals(Object o) {
  return this is o;
   }
}
```
See all the overloads I had to make to sub in order to bypass 
identity assignment for classes.  I.e. Var can't be of type 
Expr.  Anyway, this approach is not working because code 
calling `Expr.sub(int, Var)` is not seeing the definitions.  It 
says no function matching those args, but clearly there are!


Try replacing methods sub with template:
```d
module expr;

import dots;
import operator;
import equation;
import var;
import var_expr;
import zz_const;

class Expr
{
public:
   void opBinary(string op)(string s) const;

   override string toString() const;

   Expr sub(Expr x, Expr y)
   {
  if (this == x)
 return y;
  return this;
   }

//template sub:
Expr sub(T, U)(auto ref T x, auto ref U y){

//transform parameter to Expr:
static Expr expr(E)(auto ref E e){
static if(is(E : Expr))
return e;
else static if(is(E : int))
return ZZ(e);
else static if(is(E : Var))
return new VarExpr(e);
else
static assert(0, "no impl " ~ E.stringof);
}

//call sub(Expr, Expr)
this.sub(expr(x), expr(y));

}

   override bool opEquals(Object o) ;
}
```


Re: alias and __VERSION__ condition doesn't play well

2022-01-18 Thread vit via Digitalmars-d-learn
On Wednesday, 19 January 2022 at 04:15:54 UTC, Steven 
Schveighoffer wrote:

On 1/18/22 7:19 AM, vit wrote:

On Tuesday, 18 January 2022 at 12:05:38 UTC, Paul Backus wrote:

On Tuesday, 18 January 2022 at 04:42:45 UTC, frame wrote:

At the very top of my module I have this declaration:

```d
static if (__VERSION__ >= 2098)
{
    alias Foo = TypeA;
}
else
{
    alias Foo = TypeB;
}
```

No problem inside the module itself but this doesn't work 
when imported from another module:

Error: undefined identifier `Foo`


Works for me: https://run.dlang.io/is/XZlvQ8


It works until you have cyclic dependencies:

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


Has nothing to do with `__VERSION__`:

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

That does seem like a bug. And it's LDC specific, dmd seems to 
work fine.


-Steve


In dmd is order of module compilation different.
Same problem:

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

This is not only problem with imports:

```d
class Foo{
Bar.B b;

static if(true)
alias F = int;

}

class Bar{
Foo.F f; //Error: no property `F` for type `onlineapp.Foo`

static if(true)
alias B = int;

}

void main(){}
```




Re: alias and __VERSION__ condition doesn't play well

2022-01-18 Thread vit via Digitalmars-d-learn

On Tuesday, 18 January 2022 at 12:05:38 UTC, Paul Backus wrote:

On Tuesday, 18 January 2022 at 04:42:45 UTC, frame wrote:

At the very top of my module I have this declaration:

```d
static if (__VERSION__ >= 2098)
{
alias Foo = TypeA;
}
else
{
alias Foo = TypeB;
}
```

No problem inside the module itself but this doesn't work when 
imported from another module:

Error: undefined identifier `Foo`


Works for me: https://run.dlang.io/is/XZlvQ8


It works until you have cyclic dependencies:

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


Re: alias and __VERSION__ condition doesn't play well

2022-01-17 Thread vit via Digitalmars-d-learn

On Tuesday, 18 January 2022 at 04:42:45 UTC, frame wrote:

At the very top of my module I have this declaration:

```d
static if (__VERSION__ >= 2098)
{
alias Foo = TypeA;
}
else
{
alias Foo = TypeB;
}
```

No problem inside the module itself but this doesn't work when 
imported from another module:

Error: undefined identifier `Foo`

While this workaround works:

```d
template getAlias()
{
static if (__VERSION__ >= 2098)
{
alias getAlias = TypeA;
}
else
{
alias getAlias = TypeB;
}
}
alias Foo = getAlias!();
```

Is there a reason for that?


static ifs and mixins need semantic analysis to expand, but when 
you import module, the semantic analysis doesn't run yet (depends 
on order).


Beter workaround is:
```d
import std.traits : Select;

alias Foo  = Select!(__VERSION__ >= 2098, TypeA, TypeB);
```


Re: error: rvalue constructor and a copy constructor

2022-01-12 Thread vit via Digitalmars-d-learn

On Wednesday, 12 January 2022 at 08:04:19 UTC, vit wrote:

Hello, I have this code:

```d

[...]


run.dlang.io has old version of dmd-beta/dmd-nightly with bug


error: rvalue constructor and a copy constructor

2022-01-12 Thread vit via Digitalmars-d-learn

Hello, I have this code:

```d

import core.lifetime : move, forward;
import std.stdio : writeln;

struct Foo{
int i;

static auto make(int i){
Foo tmp;
tmp.i = i;
return move(tmp);
}

this(scope const ref typeof(this) rhs){
this.i = rhs.i;
writeln("copy");
}

this(T)(scope const T rhs)
if(is(immutable T == immutable typeof(this))){
this.i = rhs.i;
writeln("move");
}

}

auto foo(T)(auto ref T x){
return Foo(forward!x);
}

void main(){
Foo x = foo(Foo.make(1));
writeln("end");
}
```

When is this code compiled with 2.098.1 then it print:

```
Error: Cannot define both an rvalue constructor and a copy 
constructor for `struct Foo`
   Template instance `__ctor!(Foo)` creates a rvalue 
constructor for `struct Foo`
Error: template instance `onlineapp.Foo.__ctor!(Foo)` error 
instantiating

   instantiated from here: `foo!(Foo)`
```

When is compiled by dmd-beta/dmd-nightly then it works fine.

Is dmd-beta/dmd-nightly with bug or is this new valid behaviour?


Re: A slice consisting of non-consecutive elements of an array?

2022-01-11 Thread vit via Digitalmars-d-learn

On Wednesday, 12 January 2022 at 06:58:47 UTC, vit wrote:

On Wednesday, 12 January 2022 at 06:43:40 UTC, forkit wrote:

On Wednesday, 12 January 2022 at 06:16:49 UTC, vit wrote:


Yes std.algorithm : filter.

```d
import std.stdio : writeln;
import std.algorithm : filter;

void main()@safe{
auto a = ["one", "one", "two", "one", "two", "one", 
"one", "two"];


writeln(a);
writeln(a.filter!(x => x == "one"));
}
```


Interesting. I looked it up.. it says "returns a new range..."

Does that mean what I think it means (i.e. a new allocation 
takes place) ?


No, it is only view to old slice:
```d
void main()@safe{
auto a = ["one", "one", "two", "one", "two", "one", "one", 
"two"];


auto b = (()@nogc => a.filter!(x => x == "one"))();
writeln(a);
writeln(b);
}
```


filter is implemented like this (but more generic):
```d
import std.stdio : writeln;


auto filter(alias fn, T)(T[] slice){

//InputRange:
static struct Filter{
T[] slice;
bool empty()const{return slice.length == 0;}
T front(){return slice[0];}
void popFront(){
do{
slice = slice[1 .. $];
}while(slice.length && !fn(slice[0]));
}
}

return Filter(slice);
}

void main()@safe{
auto a = ["one", "one", "two", "one", "two", "one", "one", 
"two"];


writeln(a);
writeln(a.filter!(x => x == "one"));
}
```


Re: A slice consisting of non-consecutive elements of an array?

2022-01-11 Thread vit via Digitalmars-d-learn

On Wednesday, 12 January 2022 at 06:43:40 UTC, forkit wrote:

On Wednesday, 12 January 2022 at 06:16:49 UTC, vit wrote:


Yes std.algorithm : filter.

```d
import std.stdio : writeln;
import std.algorithm : filter;

void main()@safe{
auto a = ["one", "one", "two", "one", "two", "one", 
"one", "two"];


writeln(a);
writeln(a.filter!(x => x == "one"));
}
```


Interesting. I looked it up.. it says "returns a new range..."

Does that mean what I think it means (i.e. a new allocation 
takes place) ?


No, it is only view to old slice:
```d
void main()@safe{
auto a = ["one", "one", "two", "one", "two", "one", "one", 
"two"];


auto b = (()@nogc => a.filter!(x => x == "one"))();
writeln(a);
writeln(b);
}
```


Re: A slice consisting of non-consecutive elements of an array?

2022-01-11 Thread vit via Digitalmars-d-learn

On Wednesday, 12 January 2022 at 05:27:08 UTC, forkit wrote:

I am familiar with the concept of a slice in D.

However, a slice is a consecutive slice, is in not? (e.g) 
[4..$-1]


I would like a slice (or a view, or whatever name you wanna 
call it), of particular elements within an array that may not 
be consecutive. e.g. [4-7,8,10,13-16]


Consider below:

I want a slice/view on this array that only contains elements 
with the string "one".


["one", "one", "two", "one", "two", "one", "one", "two]

Most importantly, I do NOT want to allocate - so the slice/view 
needs to be 'referencing'  existing data (not copying it).


Yes, I can hard code it, C style. I already know this.

Does phobos offer something like this?


Yes std.algorithm : filter.

```d
import std.stdio : writeln;
import std.algorithm : filter;

void main()@safe{
auto a = ["one", "one", "two", "one", "two", "one", 
"one", "two"];


writeln(a);
writeln(a.filter!(x => x == "one"));
}
```


Re: fixedstring: a @safe, @nogc string type

2022-01-11 Thread vit via Digitalmars-d-announce

On Tuesday, 11 January 2022 at 11:16:13 UTC, Moth wrote:

On Tuesday, 11 January 2022 at 03:20:22 UTC, Salih Dincer wrote:

[snip]


glad to hear you're finding it useful! =]

... i know there's currently some wierdness with wchars / 
dchars equality that needs to be fixed [shouldn't be too much 
trouble...




If you try mixing char/wchar/dchar, you need encoding/decoding 
for utf-8, utf-16 and utf-32 ( maybe even LE/BE ). It become 
complicated very fast...






Re: Added copy constructors to "Programming in D"

2022-01-08 Thread vit via Digitalmars-d-announce

On Saturday, 8 January 2022 at 16:24:03 UTC, Ali Çehreli wrote:

On 1/8/22 5:49 AM, Stanislav Blinov wrote:

>> Of course, now I stress that postblit is discouraged.
>
> Bit early, methinks. Copy ctors aren't even fully supported
by the
> runtime yet.

Thanks. The spec discourages postblit as well. What's the best 
of saying it then? Something like "There are still limitations 
of copy constructors as of this writing." Or there are just 
bugs?


Ali


Bugs, for example:

When appending to dynamic array reallocate memory, then copy 
ctors are ignored.


Assignment of static arrays doesn't call copy constructor for 
elements.


dup/idup doesn't call copy constructors...

This is necessary to fix it:
[SAoC 2021] Replace druntime Hooks with Templates 
https://forum.dlang.org/thread/flwjoxilxfpvdjhee...@forum.dlang.org


Re: mixin does not work as expected

2022-01-05 Thread vit via Digitalmars-d-learn

On Wednesday, 5 January 2022 at 09:17:54 UTC, rempas wrote:

On Wednesday, 5 January 2022 at 09:02:53 UTC, vit wrote:

Try this:
```d
pragma(msg, type_check!("static if", "i8", "true", "5", "4", 
"10", "5"));

```

Result:

```d
static if(is_same!(num, i8)) {
mixin(base_digit!("5", "4", "10", "5"));
static if (true) {
  mixin(overflow_check!"i8.min"); }
  }
```
is_same - is undefined
i8 - is undefined
overflow_check!"i8.min" - ?


This code with mixins is horrible :)


Hi and thanks for your time. "pragma(msg, ...)" will indeed 
work but it will print the code in the standard output. Is 
there something that I'm missing?


1) That printed code on standard output is wrong, missing 
declaration for is_same and i8.


2) if-else must be in same mixin:
```d
mixin(""
+ type_check!("static if", "i8", "true", "5", "4", "10", 
"5")
+ type_check!("else static if", "i16", "true", "7", "6", 
"18", "8")
	+ type_check!("else static if", "i32", "true", "12", "10", 
"34", "13")

+ type_check!("else", "i64", "true", "21", "18", "66", "24")
);
```


3) last type_checkin signed and unsigned part of function test 
has else with condition.


```d
else(is_same!(num, i64)) {
mixin(base_digit!("21", "18", "66", "24"));
static if (true) {
  mixin(overflow_check!"i64.min"); }
  }
```



Re: mixin does not work as expected

2022-01-05 Thread vit via Digitalmars-d-learn

On Wednesday, 5 January 2022 at 08:40:15 UTC, rempas wrote:
I'm trying to use mixins and enums to "expand" code in place 
but the results are not what I expected and I'm getting an 
weird error. I have created the smallest possible example to 
reproduce the error and it is the following:


[...]


And you cannot have else statement in different mixin:

```d

extern (C) void main() {
///OK:
mixin("static if(true){}else{}");

///ERROR:
mixin("static if(true){}");
mixin("else{}");
}
```


Re: mixin does not work as expected

2022-01-05 Thread vit via Digitalmars-d-learn

On Wednesday, 5 January 2022 at 08:40:15 UTC, rempas wrote:
I'm trying to use mixins and enums to "expand" code in place 
but the results are not what I expected and I'm getting an 
weird error. I have created the smallest possible example to 
reproduce the error and it is the following:


[...]


Try this:
```d
pragma(msg, type_check!("static if", "i8", "true", "5", "4", 
"10", "5"));

```

Result:

```d
static if(is_same!(num, i8)) {
mixin(base_digit!("5", "4", "10", "5"));
static if (true) {
  mixin(overflow_check!"i8.min"); }
  }
```
is_same - is undefined
i8 - is undefined
overflow_check!"i8.min" - ?


This code with mixins is horrible :)


Re: opCast + dtor error

2021-12-29 Thread vit via Digitalmars-d-learn

On Wednesday, 29 December 2021 at 01:00:53 UTC, Tejas wrote:

On Tuesday, 28 December 2021 at 18:27:36 UTC, vit wrote:

[...]


Since a destructor ignores `const`, I think adding the `~this` 
to Foo manually is somehow making the compiler have to actually 
cast away const, which it is doing via `cast(Foo) foo`, which 
fails since you've declared your own `opCast` that only accepts 
arguments implicitly convertible to `bool`.


I say this because removing the specialisation in `opCast` and 
changing the return type of it to `Foo` works :


```d
struct Foo{
Foo opCast(T)()const {
assert(0);
return this;
}
~this() {}

}

struct Bar{
const Foo foo;

}

void main(){
//Bar bar = Bar(); //this will trigger the assertion failure


}
```


Thanks, you are right, generated Bar.~this() try use opCast to 
cast const away.

Is look like bug in compiler.

I stop using opCast for now.


opCast + dtor error

2021-12-28 Thread vit via Digitalmars-d-learn

Hi, why this code doesn't compile?

```d
struct Foo{
bool opCast(T : bool)()const{
assert(0);
}

~this(){}
}

struct Bar{
const Foo foo;
}

void main(){


}
```

Error: template instance `opCast!(Foo)` does not match template 
declaration `opCast(T : bool)()`






Re: How to properly use variadic templates (functions)?

2021-12-21 Thread vit via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 08:26:17 UTC, rempas wrote:

On Tuesday, 21 December 2021 at 08:11:39 UTC, Anonymouse wrote:


I'm not certain I understand, but won't `foreach (i, a; args) 
{ /* ... */ }` in his example do that?


As in, if you necessarily must index `args` instead of using a 
foreach variable,


```d
import core.stdc.stdio : putc, stdout;

void print(T...)(string prompt, T args)
{
foreach (i, a; args)
{
alias A = typeof(args[i]);

static if (is(A : string))
{
for (int j = 0; j < args[i].length; j++)
{
putc(args[i][j], stdout);
}
}
else
{
// handle your other types
print("", A.stringof);
}
}
}

void main()
{
print("Prompt (ignored)", "Hello", " world!\n", 123);
}
```


No it will not. I will try to explain it the best way I can. 
When I say I want to index args, I mean that I want to index 
and choose which argument to use rather than use them 
continuously one after another inside a `foreach`. For example 
check the following call:


`print("Hello %s!%c", "world", '\n');`

In that case I want to first print print from "H" up to (but 
not include) "%s". Then I want to print the first argument. 
After that, I want to print the '!' character and then I want 
to print the second argument. So I need a way to keep track 
which argument was the last one I printed and manually choose 
which argument to use. So `foreach` will not do in that case 
because I don't want to continuously use the arguments one 
after another. Is is more clear now? "writef" exists in phobos 
so I'm pretty sure that there is a way to do that.


You can use switch + static foreach:

```d
import std.stdio;

//this print args in reverse order:
void print(T...)(string prompt, T args)
{
void print_arg(size_t index){
switch(index){
static foreach(i, a; args){
case i:
// handle your other types
write(a);
return; 
}
default:
assert(0, "no impl");
}
}

write(prompt);
size_t len = args.length;
while(len --> 0)
print_arg(len);
}

void main(){
print("Prompt (ignored): ", "Hello", " world!\n", 123);
}

```


Re: dynamic array + copy ctor

2021-12-20 Thread vit via Digitalmars-d-learn
On Sunday, 19 December 2021 at 23:21:00 UTC, Stanislav Blinov 
wrote:

On Sunday, 19 December 2021 at 22:29:21 UTC, vit wrote:

Hello,
Why is copy ctor in this example not called?


Because D runtime isn't properly married to copy constructors 
yet. I.e. it's a bug, a variant of this one: 
https://issues.dlang.org/show_bug.cgi?id=20879


Thanks,
That bug is 1.5 years old. Are this problems with copy ctors hard 
to fix?

Are copy ctors still experimental functionality?


dynamic array + copy ctor

2021-12-19 Thread vit via Digitalmars-d-learn

Hello,
Why is copy ctor in this example not called?

```d
import std.stdio;

struct Foo {
int i;

this(int i){
this.i = i;
writeln("init: ", i);
}

this(ref typeof(this) rhs){
this.i = rhs.i;
writeln("copy: ", i);
}
~this() {
writeln("~dtor:", i);
}
}

void main(){
Foo[] foos;

foos ~= Foo(1);

while(foos.capacity > foos.length)
foos ~= Foo(0);

foos ~= Foo(2);

import core.memory;
GC.collect();
}
```
result:
```
init: 1
init: 2
~dtor:1
~dtor:2
~dtor:1
```

First Foo is destructed 2x.



Re: template ctor overload Segmentation fault

2021-12-14 Thread vit via Digitalmars-d-learn

On Tuesday, 14 December 2021 at 14:40:00 UTC, RazvanN wrote:

On Sunday, 12 December 2021 at 11:57:43 UTC, vit wrote:

Hello, why does this code fail to compile?

```d
struct Foo(T){
this(Rhs, this This)(scope Rhs rhs){
}

this(ref scope typeof(this) rhs){
}
}


struct Bar{
Foo!int foo;
}

void main(){
}
```

error: Segmentation fault (core dumped)


PR: https://github.com/dlang/dmd/pull/13427


Thanks,

I got it to work for now:

```d
struct Foo(T){
this(Rhs, this This)(auto ref scope Rhs rhs)
if(__traits(isRef, rhs) == false){
}

this(ref scope typeof(this) rhs){
}
}


struct Bar{
Foo!int foo;
}

void main(){
}

```


Re: template ctor overload Segmentation fault

2021-12-12 Thread vit via Digitalmars-d-learn

On Sunday, 12 December 2021 at 18:32:28 UTC, Imperatorn wrote:

On Sunday, 12 December 2021 at 11:57:43 UTC, vit wrote:

Hello, why does this code fail to compile?

```d
struct Foo(T){
this(Rhs, this This)(scope Rhs rhs){
}

this(ref scope typeof(this) rhs){
}
}


struct Bar{
Foo!int foo;
}

void main(){
}
```

error: Segmentation fault (core dumped)


What are you trying to accomplish?


Something like this:

```d
import std.traits : CopyConstness;

struct UniquePtr(T){
alias Type = T;

this(Rhs, this This)(scope Rhs rhs)
if(is(CopyConstness!(Rhs, Rhs.Type*) : CopyConstness!(This, 
This.Type*))){

//...
}

//one of copy ctors:
this(ref scope typeof(this) rhs){
//...
}

static UniquePtr make(Args...)(Args args){
return UniquePtr.init;
}
}


void main(){
const UniquePtr!(int) cui = UniquePtr!(const int).make(1);
const UniquePtr!(const int) cuci = UniquePtr!(const 
int).make(1);

UniquePtr!(const int) uci = UniquePtr!(int).make(1);
UniquePtr!(int) ui = UniquePtr!(int).make(1);

const UniquePtr!(int) xcui = UniquePtr!(immutable 
int).make(1);
const UniquePtr!(const int) xcuci = UniquePtr!(immutable 
int).make(1);


}
```

This work but UniquePtr canno't be inside struct because 
Segmentation fault.


template ctor overload Segmentation fault

2021-12-12 Thread vit via Digitalmars-d-learn

Hello, why does this code fail to compile?

```d
struct Foo(T){
this(Rhs, this This)(scope Rhs rhs){
}

this(ref scope typeof(this) rhs){
}
}


struct Bar{
Foo!int foo;
}

void main(){
}
```

error: Segmentation fault (core dumped)


autoptr (ref counted pointers)

2021-11-12 Thread vit via Digitalmars-d-announce

Hello,
I implemented reference counted pointers supporting:
- weak pointers (optional).
- aliasing.
- atomic/non-atomic counters.
- multithread ref counted pointers .
- arrays.
- destructors with attributes
- pure, const, immutable and shared support.
- limited dip1000 and @safe support.
- intrusive pointers
- unique pointers

Api is inspired with std::shared_ptr
Implementation is inspired by clang std::shared_ptr.

git: https://github.com/submada/autoptr
doc: https://submada.github.io/autoptr/
dub: https://code.dlang.org/packages/autoptr

Examples:
```d

import autoptr.shared_ptr;


///
pure nothrow @nogc unittest{

static class Foo{
int i;

this(int i)pure nothrow @safe @nogc{
this.i = i;
}
}

static class Bar : Foo{
double d;

this(int i, double d)pure nothrow @safe @nogc{
super(i);
this.d = d;
}
}

//implicit qualifier cast
{
SharedPtr!(const Foo) foo =  SharedPtr!Foo.make(42);
assert(foo.get.i == 42);
assert(foo.useCount == 1);

const SharedPtr!Foo foo2 = foo;
assert(foo2.get.i == 42);
assert(foo.useCount == 2);

}

//polymorphic classes:
{
SharedPtr!Foo foo = SharedPtr!Bar.make(42, 3.14);
assert(foo != null);
assert(foo.useCount == 1);
assert(foo.get.i == 42);

//dynamic cast:
{
SharedPtr!Bar bar = dynCast!Bar(foo);
assert(foo.useCount == 2);

assert(bar.get.i == 42);
assert(bar.get.d == 3.14);
}

}

//aliasing:
{
SharedPtr!Foo foo = SharedPtr!Bar.make(42, 3.14);
assert(foo.useCount == 1);

auto x = SharedPtr!int(foo, );
assert(foo.useCount == 2);
assert(x.useCount == 2);

assert(*x == 42);
}

//weak references:
{
auto x = SharedPtr!double.make(3.14);
assert(x.useCount == 1);
assert(x.weakCount == 0);

auto w = x.weak();  //weak pointer
assert(x.useCount == 1);
assert(x.weakCount == 1);
assert(*w.lock == 3.14);

SharedPtr!double.WeakType w2 = x;
assert(x.useCount == 1);
assert(x.weakCount == 2);

assert(w2.expired == false);
x = null;
assert(w2.expired == true);
}

//dynamic array
{
import std.algorithm : all;

{
auto arr = SharedPtr!(long[]).make(10, -1);

assert(arr.length == 10);
assert(arr.get.all!(x => x == -1));
}

{
auto arr = SharedPtr!(long[]).make(8);
assert(arr.length == 8);
assert(arr.get.all!(x => x == long.init));
}
}

//static array
{
import std.algorithm : all;

{
auto arr = SharedPtr!(long[4]).make(-1);
assert(arr.get[].all!(x => x == -1));

}

{
long[4] tmp = [0, 1, 2, 3];
auto arr = SharedPtr!(long[4]).make(tmp);
assert(arr.get[] == tmp[]);
}
}

}

///
pure nothrow @safe @nogc unittest{
//make SharedPtr object
static struct Foo{
int i;

this(int i)pure nothrow @safe @nogc{
this.i = i;
}
}

{
auto foo = SharedPtr!Foo.make(42);
auto foo2 = SharedPtr!Foo.make!Mallocator(42);  
//explicit stateless allocator

}

{
import std.experimental.allocator : make, dispose;

static void deleter(long* x)pure nothrow @trusted @nogc{
Mallocator.instance.dispose(x);
}
long* element = Mallocator.instance.make!long;

auto x = SharedPtr!long.make(element, );
}

{
auto arr = SharedPtr!(long[]).make(10); //dynamic array 
with length 10

assert(arr.length == 10);
}
}

///
nothrow unittest{
//alloc SharedPtr object
import std.experimental.allocator : make, dispose, 
allocatorObject;


auto allocator = allocatorObject(Mallocator.instance);

{
auto x = SharedPtr!long.alloc(allocator, 42);
}

{
static void deleter(long* x)pure nothrow @trusted @nogc{
Mallocator.instance.dispose(x);
}
long* element = Mallocator.instance.make!long;
auto x = SharedPtr!long.alloc(allocator, element, 
);

}

{
auto arr = SharedPtr!(long[]).alloc(allocator, 10); 
//dynamic array with length 10

assert(arr.length == 10);
}

}
```


Re: How to call destructor before free without dropping @nogc?

2021-08-19 Thread vit via Digitalmars-d-learn

On Thursday, 19 August 2021 at 08:25:23 UTC, Bienlein wrote:

On Thursday, 19 August 2021 at 07:30:38 UTC, Bienlein wrote:

Hello,

I allocate some instance of class C manually and then free the 
memory again:


class C {
int num;

~this() {
writeln("~this");
}
}

void foo() // @nogc
{
auto mem = cast(C)malloc(__traits(classInstanceSize, 
C));

auto c = emplace!(C)(mem);

c.num = 789;

destroy(c);
free(cast(void*) c);
c = null;
}

int main()
{
foo();
}

The code above works well as the destructor of c in class C is 
called by destroy. Problem is that destroy cannot be used once 
function foo is annotated with @nogc. There seems to be no way 
round it.


What I want is to keep the function foo annotated with @nogc, 
but still have the destructor of C be called before free is 
called. Is there a way to call the destructor through meta 
programming or some kind of reflection so that I can create 
some generic function that calls the destructor and then free 
for any kind of class?


Thanks, Bienlein


Oops, I just realized that you can also not call emplace when 
@nogc is present. Well that is at least consistent with not 
either being able to call destroy ;-).


So, I guess this means that you can forget about manually 
allocating and freeing some instance of a class and using @nogc 
as well. That's a pitty, @nogc was a good idea.


Try this:
```d
import std;
import core.stdc.stdlib : malloc, free;

class C {
int num;

~this() @nogc{
debug writeln("~this");
}
}

void foo()  @nogc
{
auto mem = cast(C)malloc(__traits(classInstanceSize, C));
auto c = emplace!(C)(mem);

c.num = 789;

destruct(c);
free(cast(void*) c);
c = null;
}

void main()
{
foo();
}



//https://github.com/atilaneves/automem/blob/master/source/automem/utils.d

void destruct(T)(T obj) if (is(T == class)) {
(cast(_finalizeType!T) _finalize)(() @trusted { return 
cast(void*) obj; }());

}


private extern(C){
	void rt_finalize(void* p, bool det = true) @trusted @nogc pure 
nothrow;


template _finalizeType(T) {
import std.traits: Unqual;
static if (is(Unqual!T == Object)) {
alias _finalizeType = typeof(_finalize);
} else {
import std.traits : BaseClassesTuple;
import std.meta : AliasSeq;
alias _finalizeType = typeof(function void(void* p, 
bool det = true) {
// generate a body that calls all the destructors 
in the chain,
// compiler should infer the intersection of 
attributes

foreach (B; AliasSeq!(T, BaseClassesTuple!T)) {
// __dtor, i.e. B.~this
static if (__traits(hasMember, B, "__dtor"))
() { B obj; obj.__dtor; } ();
// __xdtor, i.e. dtors for all RAII members
static if (__traits(hasMember, B, "__xdtor"))
() { B obj; obj.__xdtor; } ();
}
});
}
}
}
```


Re: input range with non copyable element

2021-08-09 Thread vit via Digitalmars-d-learn

On Monday, 9 August 2021 at 02:47:40 UTC, Mathias LANG wrote:

On Sunday, 8 August 2021 at 18:36:02 UTC, vit wrote:
Hello, is there reason why elements of input range must be 
copyable?


By design, not that I can think of. But it is assumed all over 
the place, unfortunately. You can make your `front` method 
return by `ref`, but you're still going to get bitten as soon 
as you do any `std.algorithm`-based operation, as storage 
classes are not inferred 
(https://issues.dlang.org/show_bug.cgi?id=9423) and things get 
passed by value to your delegates by default. The problem can 
also show up when you `foreach` over a range 
(https://issues.dlang.org/show_bug.cgi?id=15413). And finally, 
`std.algorithm` need to support it.


So currently you'll have to jump through a lot of hops to get 
it to work. It'll be much easier to use your own `map` & co to 
get the job done for the time being. Hopefully at some point in 
the near future that won't be needed anymore.


Look like I am not the first who has this problem: 
https://issues.dlang.org/show_bug.cgi?id=14478



I copy part of `std.algorithm` I use and change `isInputRange` to:
```d
enum bool isInputRange(R) = true
&& is(typeof(R.init) == R)  
///no change
&& is(ReturnType!((R r) => r.empty) == bool) 
///no change
	&& is(typeof((return ref R r) => (auto ref 
x){}(r.front)))	///Before: , is(typeof((return ref R r) => 
r.front))

&& !is(ReturnType!((R r) => r.front) == void)
///no change
&& is(typeof((R r) => r.popFront)); 
 ///no change



input range with non copyable element

2021-08-08 Thread vit via Digitalmars-d-learn
Hello, is there reason why elements of input range must be 
copyable?


For example this example works and copy ctor is never called:

```d
import std.algorithm : map;
import std.range;

struct Foo{
int i;

this(scope ref typeof(this) rhs)pure nothrow @safe @nogc{
//this.i = rhs.i;
assert(0, "no copy");
}
	@disable this(scope const ref typeof(this) rhs)pure nothrow 
@safe @nogc;

}


void main(){
Foo[] foos = [Foo(1), Foo(2), Foo(3)];

//this work (copy ctor is never called):
{
auto tmp = foos
.map!((ref foo) => foo.i)
.array;
}
}
```

This doesn't work:


```d

void main(){
const(Foo)[] foos = [Foo(1), Foo(2), Foo(3)];

//error:
{
auto tmp = foos
.map!((ref foo) => foo.i)
.array;
}
}
```

Source of my problem is in `isInputRange`:
```d
import std.range;
import std.traits : ReturnType;

alias R = const(Foo)[];
//enum bool isInputRange(R) =
static assert(is(typeof(R.init) == R)); 
///OK
static assert(is(ReturnType!((R r) => r.empty) == bool));
///OK
static assert(is(typeof((return ref R r) => 
r.front)));///ERROR, copy result of front

static assert(!is(ReturnType!((R r) => r.front) == void));   
///OK
static assert(is(typeof((R r) => r.popFront))); 
 ///OK
```

Is it possible to make lambda return `auto ref`?


compare types of functions.

2021-08-02 Thread vit via Digitalmars-d-learn

Hello,

Why this doesn't work:
```d
template DestructorType(T){

alias Get(T) = T;

alias DestructorType = Get!(typeof((void*){
T tmp;
}));
}

struct Foo{

~this()@safe{}
}
```


```d
void main(){
//Error: static assert:  `is(void function(void*) pure 
nothrow @nogc @safe : void function(void*) @safe)` is false
static assert(is(void function(void*)pure nothrow @safe @nogc 
: DestructorType!Foo));


}

```

but this work:
```d

void main(){

alias X = void function(void*)@safe;


static assert(is(void function(void*)pure nothrow @safe @nogc 
: DestructorType!Foo));


}
```


Re: cast to pure function stop work after upgrade

2021-08-02 Thread vit via Digitalmars-d-learn

On Monday, 14 June 2021 at 13:31:51 UTC, baby_tiger wrote:
this used work for me, after upgrade I get this error.  how to 
fix it ?



import std.traits;
enum LogLevel : ubyte {
INFO = 0,
WARN,
ERROR,
FATAL,
}


extern (C) string VFORMAT(LogLevel level, string file, 
size_t line, char[] tmp, bool line_break, string tag, string 
fmt, ...) @nogc nothrow {

return null;
}

template asPure(string P, alias Fn) if 
(isFunctionPointer!(typeof())) {

enum N = __traits(identifier, Fn);
enum string asPure = "private alias " ~ N ~ "_PURE 
= " ~ typeof().stringof ~ " pure;\n" ~ "__gshared immutable 
" ~ N ~ "_PURE " ~ P ~"= cast(" ~ N ~ "_PURE) &" ~ N ~ " ;" ;

}
enum xx = asPure!("VFORMATP", VFORMAT);
mixin(xx);

void main(){

}


 reinterpreting cast from `nothrow @nogc extern (C) 
string(LogLevel level, string file, ulong line, char[] tmp, 
bool line_break, string tag, string fmt, ...)*` to `pure 
nothrow @nogc extern (C) string(LogLevel, string, ulong, 
char[], bool, string, string, ...)*` is not supported in CTFE


```d
int foo(int x)@safe{
return x;
}

/*
This is valid.
@safe CTFE cast, systemFoo has less restrictive function type.
  */
auto systemFoo = cast(int function(int)@system)

/*
ERROR
UNSAFE CTFE cast, pureFoo has more restrictive function type.
*/
//auto pureFoo = cast(void function(int)pure)

int function(int)pure pureFoo;

shared static this(){

/*
This is valid.
UNSAFE RUNTIME cast.
*/
pureFoo = cast(int function(int)pure)
}


void main(){
assert(pureFoo(42) == 42);
}
```


Re: cast to pure function stop work after upgrade

2021-08-02 Thread vit via Digitalmars-d-learn

On Monday, 2 August 2021 at 11:28:46 UTC, Tejas wrote:

On Monday, 14 June 2021 at 13:31:51 UTC, baby_tiger wrote:

[...]



It seems to not work at runtime either. Maybe they've made this 
behaviour illegal now? Hopefully someone answers.


```d

import std.traits;
import core.stdc.stdarg;
enum LogLevel : ubyte {
INFO = 0,
WARN,
ERROR,
FATAL,
}


extern (C) string VFORMAT(LogLevel level, string file, size_t 
line, char[] tmp, bool line_break, string tag, string fmt, ...) 
@nogc nothrow {

return null;
}

extern (C) string function(LogLevel level, string file, size_t 
line, char[] tmp, bool line_break, string tag, string fmt, ...) 
@nogc nothrow pure fp;

void main(){
fp =  //fails
}
```


Try this:
```d
void main(){
fp = cast(typeof(fp)) //fails
}
```


Re: Destructors can't be @nogc?

2021-07-24 Thread vit via Digitalmars-d-learn

On Friday, 23 July 2021 at 20:24:02 UTC, Jim wrote:

Hello,

I've been playing with D and trying to understand how to work 
with @nogc. I must be doing something wrong, because even 
though I tagged the destructor for my class `@nogc`, I'm 
getting the following error: `.\min.d(27): Error: "@nogc" 
function "D main" cannot call non-@nogc function 
"object.destroy!(true, TestClass).destroy`


```D
import std.stdio : printf;
import core.lifetime : emplace;
import core.stdc.stdlib : malloc, free;

class TestClass {
int x;

this(int x) @nogc {
printf("TestClass's constructor called\n");
this.x = x;
}


~this() @nogc {
printf("TestClass's destructor called\n");
}
}

@nogc void
main() {
auto size = __traits(classInstanceSize, TestClass);
auto memory = malloc(size)[0..size];
TestClass x = emplace!(TestClass)(memory, 1);

printf("TestClass.x = %d\n", x.x);

destroy(x);
free(cast(void*)x);
}

```

What is the problem here? Should I not call `destroy`? If so, 
what should I call instead?


You can call function like `destroy` with right attributes for 
class variable if you known exact type of the class (no base 
class referece or interface):


https://github.com/atilaneves/automem/blob/master/source/automem/utils.d


Re: betterC shared static ctor

2021-07-21 Thread vit via Digitalmars-d-learn

On Wednesday, 21 July 2021 at 08:28:22 UTC, Mike Parker wrote:

On Wednesday, 21 July 2021 at 08:11:06 UTC, vit wrote:

Is it possible to call all shared static ctors in betterC?

```d
//-betterC

static immutable int i;

shared static this(){
i = 42;
}
extern(C) void main(){
assert(i != 42);

}
```


These rely on DRuntime, which is not linked in betterC mode. 
You'll need to use the `crt_constructor` and `crt_destructor` 
pragmas:


https://dlang.org/spec/pragma.html#crtctor

Apply them to any `extern(C) function for static ctor/dtor 
behavior.


Thanks, it works, but now I have different problem.
I need call static method for all instantions of template struct 
from `crt_constructor`.

Is there way to iterate over all instantions of template?

I need this to work but for all instantions of Foo, not only for 
Foo!1 a Foo!2



https://run.dlang.io/is/FNqHWh :
```d
pragma(crt_constructor)
extern(C)void shared_static_this(){
Foo!1.vtable_init();
Foo!2.vtable_init();
//Foo!3.vtable_init();
}

extern(C) void main(){
auto foo1 = Foo!1(null);
auto foo2 = Foo!2(null);
auto foo3 = Foo!3(null);

Base* b1 = 
Base* b2 = 
Base* b3 = 
assert(b1.getId() == 1);
assert(b2.getId() == 2);
//assert(b3.getId() == 3);  //vtable is not initialized

}

struct Vtable{
size_t offset;
size_t function(void* ) getId;
}
struct Base{
immutable Vtable* vptr;

this(immutable Vtable* vptr){
assert(vptr !is null);
this.vptr = vptr;
}

size_t getId(){
return vptr.getId((cast(void*)) - vptr.offset);
}
}

struct Foo(size_t id){
static immutable Vtable vtable;
Base base;


this(typeof(null) nil){
this.base = Base();
}

static size_t virtual_getId(Foo* foo){
return id;
}

static void vtable_init(){
Vtable* vtable = cast(Vtable*)
vtable.offset = base.offsetof;
vtable.getId = cast(typeof(Vtable.getId))_getId;
}
}

```


betterC shared static ctor

2021-07-21 Thread vit via Digitalmars-d-learn

Is it possible to call all shared static ctors in betterC?

```d
//-betterC

static immutable int i;

shared static this(){
i = 42;
}
extern(C) void main(){
assert(i != 42);

}
```


Re: Not allowed to globally overload operators?

2021-07-20 Thread vit via Digitalmars-d-learn

On Tuesday, 20 July 2021 at 06:20:34 UTC, Tejas wrote:

...
Initially, I was trying to create the spaceship operator of 
C++, but we aren't allowed to create new operators

...


D has spaceship operator: opCmp 
(https://dlang.org/spec/operatoroverloading.html#compare).





Re: record: C# like records for D

2021-07-16 Thread vit via Digitalmars-d-announce

On Wednesday, 14 July 2021 at 23:16:05 UTC, Dylan Graham wrote:

[DUB](https://code.dlang.org/packages/record)
[Github](https://github.com/hmmdyl/record)

This is record. It aims to implement records similar to what C# 
has by leveraging D's metaprogramming. [C# Example 
1](https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/records) [C# Example 2](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/records).


Future steps are going to be adding a record struct; default 
value support; init-only-setters like in C#, wherein at the end 
of construction or duplication, the init lambda for the field 
is called, and the field can be set that once.


What adventage has record over normal immutable/const class?



Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread vit via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 15:19:03 UTC, vit wrote:


```d
import   std.stdio;

struct abc{
int[100] a;

struct Proxy{
abc* ptr;
const int index;

int opUnary(string op : "++")(){
return ++ptr.a[index]; //add missing ++
}
}

Proxy opIndex(int index)return{
return Proxy(, index);
}
}

void main (){
abc s;
s[0]++;
++s[0];
}


```


Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread vit via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 15:01:45 UTC, wjoe wrote:

On Wednesday, 14 July 2021 at 14:39:03 UTC, vit wrote:

On Wednesday, 14 July 2021 at 13:16:49 UTC, Tejas wrote:

[...]



This work:

```d
import   std.stdio;

struct abc{
int[100] a;

ref int opIndex(int index)return{
return a[index];
}
}

void main (){
abc s;
s[0]++;
++s[0];
}

```


This does work for that example but I can't return by reference 
because what I'm operating on is a part of an int.

Some context:
```D
struct part_int_t(ARGS...)
{
   int _int;
   mixin(generate_parts!ARGS);
}

alias handle_t = part_int_t!("isAllocated", 1, "gen", 8, 
"index", 23);


handle_t handle;

static assert (is(handle.typeof_isAllocated): bool));
static assert (is(handle.typeof_gen): ubyte));
static assert (is(handle.typeof_index): uint));

handle[2] = true;
handle.gen = 1;
handle.index = 1234;

assert (handle.isAllocated);
assert (handle.gen = 1);
assert (handle[0] = 1234);

handle++;
assert (handle.index == 1235);

handle.gen++;
assert (handle.gen == 2);

handle.reset();
assert (!handle.isAllocated);
assert (handle.gen = 3);
assert (handle.index = 0);

```

generate_parts!ARGS produces bit masks, getters, setters, 
opIndex/OpAssign/Unary, etc. and it's impossible to return bits 
0-26 of _int by ref.


Try something like this:

```d
import   std.stdio;

struct abc{
int[100] a;

struct Proxy{
abc* ptr;
const int index;

int opUnary(string op : "++")(){
return ptr.a[index];
}
}

Proxy opIndex(int index)return{
return Proxy(, index);
}
}

void main (){
abc s;
s[0]++;
++s[0];
}
```


Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread vit via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 13:16:49 UTC, Tejas wrote:

On Wednesday, 14 July 2021 at 13:09:56 UTC, vit wrote:

On Wednesday, 14 July 2021 at 12:49:58 UTC, Tejas wrote:

[...]


From doc: https://dlang.org/spec/operatoroverloading.html
Postincrement e++ and Postdecrement e-- Operators
These are not directly overloadable, but instead are rewritten 
in terms of the ++e and --e prefix operators:


Postfix Operator Rewrites
op  rewrite
e-- (auto t = e, --e, t)
e++ (auto t = e, ++e, t)


Rewriting part doesn't work with operator overloading.


If the rewriting part doesn't work with overloading then why 
aren't we allowed to explicitly overload 
```post-increment/decrement``` operators?


How else will the OP solve their problem?

It must rewrite,  otherwise it's impossible (I think).



This work:

```d
import   std.stdio;

struct abc{
int[100] a;

ref int opIndex(int index)return{
return a[index];
}
}

void main (){
abc s;
s[0]++;
++s[0];
}

```


Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread vit via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 12:49:58 UTC, Tejas wrote:

On Wednesday, 14 July 2021 at 12:35:07 UTC, wjoe wrote:

On Wednesday, 14 July 2021 at 11:31:36 UTC, Tejas wrote:


``` {auto a = i[1] , ++i[1] , a} //note the , not the ;```

Sorry I can't provide something even more concrete.


Yes I saw that, and I suppose it would work just fine if it 
were rewritten to just  ```++i[1]```.
What I'm struggling to understand is the ```{auto a = i[1], 
... ,a}``` part. I can't parse that. What's up with the 
assignment and the comma stuff ?


I think it's a bug, because the following works:

```d

import   std.stdio;

struct abc{
int[100] a;
int opIndex(int index){
return a[index];
}
int opIndexUnary(string s)(int index)
if(s == "++"){
return ++a[index];
}
int[] opUnary(string s)() if (s == "++"){
return a[] += 1;
}
}

void main (){
abc s;
int[100] a;
int temp;
writeln (a[20]++);

writeln(a[20]);

writeln(++s[20]);

writeln(s[20]);

//writeln(s[0]++);// doesn't work for some reason

writeln(s[0]);

writeln(s++);//but this works!!

writeln(s);
}

```


From doc: https://dlang.org/spec/operatoroverloading.html
Postincrement e++ and Postdecrement e-- Operators
These are not directly overloadable, but instead are rewritten in 
terms of the ++e and --e prefix operators:


Postfix Operator Rewrites
op  rewrite
e-- (auto t = e, --e, t)
e++ (auto t = e, ++e, t)


Rewriting part doesn't work with operator overloading.




Re: Template arg deduction

2021-07-07 Thread vit via Digitalmars-d-learn

On Wednesday, 7 July 2021 at 19:14:52 UTC, Kevin Bailey wrote:
I'm trying to use some fairly simple template argument 
deduction, but
maybe I'm not getting the syntax correct. C++ doesn't event 
blink at

something like this, but D is giving me:

temptest.d(18): Error: template temptest.func cannot deduce 
function from argument types !()(bar), candidates are:

temptest.d(10):func(T)(foo!T.bar f)

I guess D can't crack open a type like that?

```
template foo(T)
{
class bar
{
T t;
}

}

void func(T)(// 10
foo!(T).bar f)
{
}

int main()
{
foo!int.bar fi;
func(fi);// 18
}
```


This work:

```d
template foo(T){
class bar{
T t;
}
}

void func(alias F : foo!T, T)(F.bar f){
}

void main(){

foo!int.bar fi;
func(fi);

}

```


Re: String front, back return code point/unit

2021-06-23 Thread vit via Digitalmars-d-learn

On Wednesday, 23 June 2021 at 15:48:57 UTC, Tejas wrote:

On Wednesday, 23 June 2021 at 15:31:04 UTC, vit wrote:

Hello,

I am implementing @nogc string struct similar to c++ 
std::basic_string (link 
https://code.dlang.org/packages/basic_string).


C++ string has methods front, back and pop_back 
returning/deleting code units.
D strings has functions (std.range) front, back and popBack 
returning/deleting code points (autodecoding?).


Which behavior is better?


I think this video will be helpful:
https://www.youtube.com/watch?v=d3qY4dZ2r4w

There was also a discussion about this in the group: 
https://forum.dlang.org/thread/diexjstekiyzgxlic...@forum.dlang.org


I wrongly formulated question.

My question is not about ranges/iterators but if is good idea 
autodecoding custom string or not.




String front, back return code point/unit

2021-06-23 Thread vit via Digitalmars-d-learn

Hello,

I am implementing @nogc string struct similar to c++ 
std::basic_string (link 
https://code.dlang.org/packages/basic_string).


C++ string has methods front, back and pop_back 
returning/deleting code units.
D strings has functions (std.range) front, back and popBack 
returning/deleting code points (autodecoding?).


Which behavior is better?






@trusted methods

2021-06-18 Thread vit via Digitalmars-d-learn
Are asserts enough to make method @trusted or is something like 
throw exception or return error code necessary? How it work in 
phobos?


Example:

```d
struct Slice(T){
private T[] data;

this(T[] data){
this.data = data;
}
inout(T)[] opSlice()inout scope return pure nothrow @safe 
@nogc{

return data;
}
inout(T)[] opSlice(size_t b, size_t e)inout scope return pure 
nothrow @safe @nogc{

return data[b .. e];
}

/*
Remove subset `slice` from `this.data`
`slice` is subset of `this.data`.
*/
void erase1(scope const(T)[] slice)scope pure nothrow 
@trusted @nogc{

assert(data.ptr <= slice.ptr);
assert((slice.ptr + slice.length) <= (data.ptr + 
data.length));


//...
}

// ditto
bool erase2(scope const(T)[] slice)scope pure nothrow 
@trusted @nogc{

if(data.ptr > slice.ptr)
return false;

if((slice.ptr + slice.length) > (data.ptr + data.length))
return false;

//...
assert(0, "TODO impl");
}

}


void main()@safe{
scope slice = Slice!int([1, 2, 3, 4]);
scope slice2 = Slice!int([1, 2, 3, 4]);


slice.erase2(slice2[1 .. 2]);   //return false
slice.erase1(slice2[1 .. 2]);   //assert error in debug

}

```


Re: cannot take address of scope local in safe function

2021-06-13 Thread vit via Digitalmars-d-learn

On Sunday, 13 June 2021 at 17:18:46 UTC, ag0aep6g wrote:

On Sunday, 13 June 2021 at 16:27:18 UTC, vit wrote:

Why I can take address of Foo variable but not Bar?

```d
//-dip1000

struct Foo{
private double d;
}

struct Bar{
private void* ptr;
}



void main()@safe{
///this is OK:
{
scope Foo x;
scope ptr = 
}

///Error: cannot take address of `scope` local `x` in 
`@safe` function `main`:

{
scope Bar x;
scope ptr = 
}
}
```


`scope` affects indirections (i.e. pointers). `Foo` doesn't 
contain any indirections, so `scope` doesn't mean anything for 
it. The compiler just ignores it. It's like you wrote `Foo x;` 
without `scope`.


`Bar` does contain an indirection, so `scope` actually matters 
and you get the error.


Thanks.

Is possible create and use scope output range allocated on stack 
in @safe code?


Example:
```d
//-dip1000

struct OutputRange{
private bool valid = true;
private void* ptr;
int count = 0;

void put(Val)(auto ref scope Val val){
assert(this.valid == true);
this.count += 1;
}


~this()scope pure nothrow @safe @nogc{
this.valid = false;
}


}

void main()@safe pure nothrow @nogc{
import std.algorithm : copy;
import std.range : only;

scope OutputRange or;

only(1, 2, 3, 4).copy();   ///Error: cannot take 
address of `scope` local `or` in `@safe` function `main`

assert(or.count == 4);
}

```


cannot take address of scope local in safe function

2021-06-13 Thread vit via Digitalmars-d-learn

Why I can take address of Foo variable but not Bar?

```d
//-dip1000

struct Foo{
private double d;
}

struct Bar{
private void* ptr;
}



void main()@safe{
///this is OK:
{
scope Foo x;
scope ptr = 
}

///Error: cannot take address of `scope` local `x` in `@safe` 
function `main`:

{
scope Bar x;
scope ptr = 
}
}
```


Re: GC.addRange in pure function

2021-02-10 Thread vit via Digitalmars-d-learn

On Wednesday, 10 February 2021 at 12:17:43 UTC, rm wrote:

On 09/02/2021 5:05, frame wrote:

On Sunday, 7 February 2021 at 14:13:18 UTC, vitamin wrote:
Why using 'new' is allowed in pure functions but calling 
GC.addRange or GC.removeRange isn't allowed?


Does 'new' violate the 'pure' paradigm? Pure functions can 
only call pure functions and GC.addRange or GC.removeRange is 
only 'nothrow @nogc'.


new allocates memory via the GC and the GC knows to scan this 
location. Seems like implicit GC.addRange.


Yes, this is my problem, if `new` can create object in pure 
function, then GC.addRange and GC.removeRange is may be pure too.


Can I call GC.addRange and GC.removeRange from pure function 
without problem? (using assumePure(...)() ).


Re: struct constructor with rvalue param of same struct type

2021-01-19 Thread vit via Digitalmars-d-learn

On Tuesday, 19 January 2021 at 06:49:06 UTC, Kyle Ingraham wrote:
I’m sorry that this isn’t a solution to your problem but your 
code caught my attention. What is your snippet supposed to do?


This is more specific example:
https://run.dlang.io/is/W7rd2u

import std.traits : CopyTypeQualifiers;

struct Ptr(T)
if(is(T == struct)){
private void* ptr;

static if(is(T == const))
this(ref const typeof(this) x)@trusted{
this.ptr = cast(typeof(this.ptr))x.ptr;
}

this(ref typeof(this) x)@safe{
this.ptr = x.ptr;
}

this(ref const typeof(this) x)const @safe{
this.ptr = x.ptr;
}

this(P : const Ptr!(U), U, this This)(auto ref P x)@trusted
if(true
//&& !is(R == T)
&& is(CopyTypeQualifiers!(P, U)* : 
CopyTypeQualifiers!(This, T)*)

){
this.ptr = cast(typeof(this.ptr))x.ptr;
}

}


struct Foo{
//@disable this(this);
}

T get_rvalue(T)(){  
return T.init;
}

void main()@safe{

///normal pointers
{
const(const(Foo)*) cpcf;///const(Foo*)

const(Foo*) cpf1 = cpcf;///OK   
const(Foo*) cpf2 = get_rvalue!(const(const(Foo)*)); ///OK   

const(Foo)* pcf1 = cpcf;///OK   
const(Foo)* pcf2 = const(const(Foo)*).init; ///OK
const(Foo)* pcf3 = get_rvalue!(const(const(Foo)*)); ///OK

}

//wrapped ptr:
{
const Ptr!(const Foo) cpcf;

const Ptr!(Foo) cpf1 = cpcf;///OK
const Ptr!(Foo) cpf2 =  get_rvalue!(const Ptr!(const 
Foo));	///OK


Ptr!(const Foo) pcf1 = cpcf;///OK
Ptr!(const Foo) pcf2 = const(Ptr!(const Foo)).init; ///OK
Ptr!(const Foo) pcf3 = get_rvalue!(const Ptr!(const 
Foo));	///ERROR!

}
}


Re: Why can I call a function with mismatched parameter type?

2020-12-11 Thread vit via Digitalmars-d-learn
On Friday, 11 December 2020 at 11:25:22 UTC, Andrey Zherikov 
wrote:

Here is the example:
alias f1 = (string  ) {}; f1(int   .init);
alias f2 = (string s) {}; f2(int   .init);
alias f3 = (int ) {}; f3(string.init);
alias f4 = (int i   ) {}; f4(string.init);

"f1" case compiles successfully and all others are not (error 
is "is not callable using argument types").


Question is why does f1 case compile?

Furthermore even these do compile:
f1(float.init);

struct S{}
f1(S.init);




alias f1 = (string  ) {}

"string" isn't type, but name of variable with generic type:

alias f1 = (/*auto type*/ string) {}


Re: Pass lambda into template

2018-09-03 Thread vit via Digitalmars-d-learn

On Monday, 3 September 2018 at 09:09:44 UTC, Andrey wrote:

Hello,

Here is a code with comments: https://run.dlang.io/is/BNl2Up.

I don't understand how to pass lambda into template.
I get an error:
onlineapp.d(18): Error: template instance `qwerty!((i) => "arg" 
~ i.to!string ~ "[0] == '?'", "||")` cannot use local __lambda1 
as parameter to non-global template qwerty(alias mapper, alias 
delimiter)


Try this:

if(mixin(qwerty!((int i) => "arg" ~ i.to!string ~ "[0] == '?'", 
"||")))


Re: Can't print enum values

2018-08-30 Thread vit via Digitalmars-d-learn

On Thursday, 30 August 2018 at 11:34:36 UTC, Andrey wrote:

On Thursday, 30 August 2018 at 11:09:40 UTC, vit wrote:

[...]


I want to create a reusable template for this purpose.
Why I can't use "staticMap" so that compiler it self would do 
this:

[...]
Just wrap some some symbol "args" with some expression at 
compile time.


It is the same as in C++:

[...]


D doesn't have expanding like C++

Unfortunately D has only simple automatic expading.


Re: Can't print enum values

2018-08-30 Thread vit via Digitalmars-d-learn

On Thursday, 30 August 2018 at 10:41:58 UTC, Andrey wrote:

Hello,
This code doesn't print enum values:

import std.meta;
import std.traits;
import std.stdio;

enum MyEnum : string
{
   First = "F_i_r_s_t",
   Second = "S_e_c_o_n_d"
}

alias QW(alias arg) = 
Alias!(cast(OriginalType!(typeof(arg)))arg);


void print(T...)(T args)
{
   writeln(cast(OriginalType!(typeof(args[0])))args[0]); // 
Works...
   writeln(QW!(args[0]));// 
Doesn't work... MUST!


   writeln(staticMap!(QW, args));// 
Doesn't work... MUST!

}

void main()
{
   bool runTimeBool = true;
   print(MyEnum.First, 7, runTimeBool, MyEnum.Second);
}


Must print "F_i_r_s_t" and "S_e_c_o_n_d", not just "First" and 
"Second".


args are runtime arguments.

import std.experimental.all;

enum MyEnum : string
{
First = "F_i_r_s_t",
Second = "S_e_c_o_n_d"
}

///alias QW(alias arg) = 
Alias!(cast(OriginalType!(typeof(arg)))arg);

auto QW(T)(const auto ref T x){
return cast(OriginalType!T)x;
}

void print(T...)(T args)
{
writeln(cast(OriginalType!(typeof(args[0])))args[0]); // 
Works...
///writeln(QW!(args[0]));// 
Doesn't work... MUST!

writeln(QW(args[0]));

static foreach(alias arg; args){
static if(is(typeof(arg) : MyEnum))write(QW(arg));
else write(arg);
}
write('\n');
//writeln(staticMap!(QW, args));// 
Doesn't work... MUST!

}

void main()
{
bool runTimeBool = true;
print(MyEnum.First, 7, runTimeBool, MyEnum.Second);
}



Re: Solving the impossible?

2018-08-29 Thread vit via Digitalmars-d-learn

On Wednesday, 29 August 2018 at 19:56:31 UTC, Everlast wrote:

On Tuesday, 28 August 2018 at 22:01:45 UTC, Paul Backus wrote:

[...]


One of the things that makes a good language is it's internal 
syntactic consistency. This makes learning a language easier 
and also makes remembering it easier. Determinism is a very 
useful tool as is abstraction consistency. To say "Just except 
D the way it is" is only because of necessity since that is the 
way D is, not because it is correct. (There are a lot of 
incorrect things in the world such as me "learning" D... since 
I've been programming in D on and off for 10 years, I just 
never used a specific type for variadics since I've always use 
a variadic type parameter)


To justify that a poor design choice is necessary is precisely 
why the poor design choice exists in the first place. These are 
blemishes on the language not proper design choices.  For 
example, it is necessary for me to pay taxes, but it does not 
mean that taxes are necessary.


Actual syntax work with more then slices...:

import std.algorithm : equal;

void foo(size_t N)(int[N] args...){
assert(args[].equal([1, 2, 3, 4, 5]));

}

void main(){
foo(1, 2, 3, 4, 5);
}


Re: Create constraint for each parameter in template arg pack

2018-08-28 Thread vit via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote:

Hello,
Let we have two variadic templates:

template Qwerty(Values...) {}
template Qaz(alias type, Data...) {}


Now I want to add a constraint to "Qwerty" so that each type in 
"Values" pack must be a "Qaz" template. I don't care about 
values of "type" or "Data" in "Qaz".

How to do it in D?


Generic solution:


template Qwerty(Values...)
if(allSatisfy!(isInstanceOf!Qaz, Values)){

}
class Qaz(alias type, Data...) {}



import std.meta : allSatisfy;
public import std.traits : isInstanceOf;
template isInstanceOf(alias T){
import std.traits : impl = isInstanceOf;
static enum isInstanceOf(alias X) = impl!(T, X);
static enum isInstanceOf(X) = impl!(T, X);
}






Re: Create constraint for each parameter in template arg pack

2018-08-28 Thread vit via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote:

Hello,
Let we have two variadic templates:

template Qwerty(Values...) {}
template Qaz(alias type, Data...) {}


Now I want to add a constraint to "Qwerty" so that each type in 
"Values" pack must be a "Qaz" template. I don't care about 
values of "type" or "Data" in "Qaz".

How to do it in D?



import std.meta : allSatisfy;

template Qwerty(Values...)
if(allSatisfy!(isQaz, Values)){

}
template Qaz(alias type, Data...) {}

enum isQaz(alias Q : Qaz!Args, Args...) = true;
enum isQaz(Args...) = false;

alias Foo = Qwerty!(Qaz!(i => i), Qaz!(i => i), Qaz!(i => i));


Re: Is there a simple way to check if value is null for every case?

2018-08-27 Thread vit via Digitalmars-d-learn

On Monday, 27 August 2018 at 12:54:59 UTC, SG wrote:
On Monday, 27 August 2018 at 03:21:04 UTC, rikki cattermole 
wrote:
Templates make it the easiest way, since common patterns, like 
arrays, classes and pointers have the exact same null check 
syntax.


I see.

That code is only for classes. C# also has structs which are a 
value type. Which it would not work for.


The same thing for struct in C#

Struct S{
   public int? i;
}

S.i == null; // This works nicely.

You don't need isNull function for Nullable because it has a 
method called it. That will be preferred (hence I specifically 
used isNull as the name).


For Variant, use hasValue.

bool isNull(Variant value) {
return !value.hasValue;
}


The problem I'm trying to solve is beyond that. This is just an 
example. But bear with me, right now all I want is a function 
to check the value from 'a' type and return if it is null.


The type could be a: Class, Struct, a Basic data type, Variant, 
Nullable and so.


And what I see, these types has different behaviors, while in 
C# at least for this same case, I would write the same thing in 
few lines to perform it, in D I found very hard.


Isn't counter intuitive the way D works? Because for each type 
Class/Nullable you check with .isNull, for Variant with 
.hasValue, for string (variable is null).


Thanks.


hasValue isn't equivalent of isNull or is null. 'null' is valid 
value in Variant:



import std.variant;
Variant v;

v = null;
assert(v.hasValue);//v has value
assert(v.get!(typeof(null)) is null);  //value in v is 
null


Nullable!T.isNull isn't equivalent of is null:

int* i = null;
Nullable!(int*) ni;
ni = i;
assert(ni.isNull == false); ///ni has value
assert(ni is null); ///ni value is null

string is null isn't equivalent of empty:

string str = "test";
str = str[0 .. 0];
assert(str !is null);   ///str isn't null
assert(str.empty);  ///str is empty




Re: Patterns to avoid GC with capturing closures?

2018-08-26 Thread vit via Digitalmars-d-learn

On Friday, 24 August 2018 at 15:18:13 UTC, Peter Alexander wrote:

Consider this code, which is used as an example only:

auto scaleAll(int[] xs, int m) {
  return xs.map!(x => m * x);
}

As m is captured, the delegate for map will rightly allocate 
the closure in the GC heap.


In C++, you would write the lambda to capture m by value, but 
this is not a facility in D.


I can write scaleAll like this:

auto scaleAll(int[] xs, int m) @nogc {
  return repeat(m).zip(xs).map!(mx => mx[0] * mx[1]);
}

So that repeat(m) stores m, but it is quite hacky to work like 
this.


I could write my own range that does this, but this is also not 
desirable.


Are there any established patterns, libraries, or language 
features that can help avoid the GC allocation in a principled 
way here?


I try pack/unpack solution, but it looks horrible.
Problem is when every part of chain (filter, map, ...) need 
capture different variables.
I implement modified version of algorithm (filter, map, until, 
tee): https://dpaste.dzfl.pl/929a7af4e87f


You don't need reimplement all of std.algorithm, only parts which 
can be in the middle of chain, things like any, all, each, count 
can be ignored.



example:
void main()@nogc{
import std.algorithm : any;
import std.range : iota;
import util.algorithm : map, filter;

const int
a = 1,
b = 2,
c = 3;

const x = iota(0, 10)
.map!((x, i) => x*i)(a)   ///map!((x) => x*a)
.map!((x, i) => x*i)(b)   ///map!((x) => x*b)
.filter!((x, i) => x%i)(c)///filter!((x) => x%c)
.any!(x => x % c);

assert(x == true);

}


Re: Make function alias

2018-08-20 Thread vit via Digitalmars-d-learn

On Monday, 20 August 2018 at 13:22:02 UTC, Andrey wrote:

On Monday, 20 August 2018 at 13:14:14 UTC, Andrey wrote:
Mistake... this is:

static void log(bool newline = true)(string text)
{
   alias print(T...) = newline ?  : 

   _file.print(text);
   text.print();
}


static void log(bool newline = true)(string text)
{
static if(newline)alias print = writeln;
else alias print = write;

_file.print(text);
text.print();
}



Re: Is @safe still a work-in-progress?

2018-08-17 Thread vit via Digitalmars-d

On Friday, 17 August 2018 at 13:02:20 UTC, Jonathan M Davis wrote:
On Friday, August 17, 2018 6:30:26 AM MDT Atila Neves via 
Digitalmars-d wrote:
On Friday, 17 August 2018 at 11:37:54 UTC, rikki cattermole 
wrote:

> On 17/08/2018 11:33 PM, Atila Neves wrote:
>> . Good luck figuring out why your template functions aren't 
>> @safe and coaxing the compiler to tell you why it's 
>> inferring the attributes it is. Bonus points if it's a 
>> Phobos function so you can't slap `@safe` on its definition.

>
> Sure you can. It's a template so it'll be initialized as its 
> required.

>
> I've done that to fix a bug in druntime before and in my own 
> libraries.


It's not easy though. You have to either be building your own 
phobos or sudo editing files in /usr/include. You can, but 
it's a pain. Then there's finding out exactly where in a chain 
of 10 template functions that it became @system...


The reality of the matter is that you tend to have to be very 
motivated to make your code @safe if you're doing much with 
templates (the same with other attributes such as pure). And 
sadly, it can quickly get to the point that it just feels like 
it's not worth it in spite of the fact that there is definitely 
value to be had in using them.


I wonder what it would take to make it so that the compiler 
could actually tell you where in the function call chain it 
first becomes @system.


- Jonathan M Davis


Does -dip1000 affect alias template parameters and closures?
example:

import std.experimental.all;


void main()@safe @nogc{
int i = 2;

const x = iota(0, 10)
.filter!((x)scope => x == i)
.map!((x)scope => x * x)
.front; 

assert(x == 4);
}

onlineapp.d(4): Error: function `D main` is @nogc yet allocates 
closures with the GC
onlineapp.d(8):onlineapp.main.__lambda1 closes over 
variable i at onlineapp.d(5)


Re: Is @safe still a work-in-progress?

2018-08-17 Thread vit via Digitalmars-d

On Friday, 17 August 2018 at 07:50:32 UTC, Jonathan M Davis wrote:
On Friday, August 17, 2018 1:19:25 AM MDT Peter Alexander via 
Digitalmars-d wrote:

[...]


That particular bug is a duplicate of 
https://issues.dlang.org/show_bug.cgi?id=8838, which was closed 
as fixed based on the fact that -dip1000 fixes the problem by 
treating marking the slice of a static array with scope. It's 
still quite broken without -dip1000 though.


[...]


What's the state of -dip1000?


Re: Concat enum of strings into one string

2018-08-14 Thread vit via Digitalmars-d-learn

On Tuesday, 14 August 2018 at 14:37:33 UTC, Andrey wrote:

On Tuesday, 14 August 2018 at 14:07:23 UTC, Timoses wrote:

Here's one version:

template StringEnumValues(alias Enum)
{
import std.traits : EnumMembers;
string[] StringEnumValues()
{
string[] enumValues;
static foreach (member; EnumMembers!Enum)
enumValues ~= member;
return enumValues;
}
}

import std.string : join;
pragma(msg, StringEnumValues!Type.join(" "));


Thank you. Hmm, I thought that standard library already has 
this stuff.



import std.traits : EnumMembers;
import std.string : join;
import std.algorithm : map;

pragma(msg, [EnumMembers!Type].map!(x => cast(string)x).join(" 
"));


Re: sumtype 0.5.0

2018-08-09 Thread vit via Digitalmars-d-announce

On Thursday, 9 August 2018 at 01:04:43 UTC, Paul Backus wrote:

On Thursday, 9 August 2018 at 00:11:22 UTC, Seb wrote:

On Thursday, 9 August 2018 at 00:07:05 UTC, Seb wrote:
(It uses the version from DUB and updates itself once daily, 
but somehow dub still lists 0.4.1 at the moment)


It looks like you didn't push the git tag to GitHub:

https://github.com/pbackus/sumtype/releases


One of these days, I'll learn. Should be there now.


ignore the message with opAssign, my version doesnt work :)


Re: sumtype 0.5.0

2018-08-09 Thread vit via Digitalmars-d-announce

On Thursday, 9 August 2018 at 01:04:43 UTC, Paul Backus wrote:

...


@safe opAssign can call @system postblit:

bool moved = false;
struct S{
this(this)@system{
moved = true;
}

}
void main()@safe{

auto st = SumType!(S).init;

st = S.init;
assert(moved == true);
}

change:
() @trusted { moveEmplace(rhs, storage.values[i]); }();

to:
moveEmplace(rhs, *(() @trusted => [i])());



Re: sumtype 0.5.0

2018-08-09 Thread vit via Digitalmars-d-announce

On Thursday, 9 August 2018 at 01:04:43 UTC, Paul Backus wrote:

On Thursday, 9 August 2018 at 00:11:22 UTC, Seb wrote:

On Thursday, 9 August 2018 at 00:07:05 UTC, Seb wrote:
(It uses the version from DUB and updates itself once daily, 
but somehow dub still lists 0.4.1 at the moment)


It looks like you didn't push the git tag to GitHub:

https://github.com/pbackus/sumtype/releases


One of these days, I'll learn. Should be there now.


SumType without initialization doesn't fail if first type has 
@disabled this().

In SumType need be something like this:

struct SumType(...){
///...

static if(Types.length > 0 && __traits(compiles, (){Types[0] 
tmp;}()) == false){

///Types[0] has disabled this()
@disable this();
}

///
}

method toString is not template. (why is there in the first 
place?)


SumType can have zero TypeArgs but then tryMatch fail:

auto st = SumType!();
st.tryMatch!((_) => 1);   //fail at compile time with bad error 
message.


in matchImpl can by something like this:

static if(Types.length == 0){
static if(exhaustive) {
static assert(0, "No value to match");
} else {
throw new MatchException("No value to match");
}
}
else{
///...
}

or:

struct SumType(TypeArgs...)
if(TypeArgs.length > 0){
}



Re: sumtype 0.5.0

2018-08-08 Thread vit via Digitalmars-d-announce

On Wednesday, 8 August 2018 at 20:54:13 UTC, Paul Backus wrote:
SumType is a generic sum type for modern D. It is meant as an 
alternative to `std.variant.Algebraic`.


Features:
  - Pattern matching, including support for structural matching 
(*)

  - Self-referential types, using `This`
  - Works with `pure`, `@safe`, `@nogc`, and `immutable` (*)
  - Zero runtime overhead compared to hand-written C
- No heap allocation
- Does not rely on runtime type information (`TypeInfo`) (*)

Starred features (*) are those that are missing from 
`Algebraic`.


Code examples are available in the documentation (linked below).

New since the last announced version, 0.3.0:
  - Types with destructors and postblits are now handled 
correctly.
  - Unreachable handlers in `match` calls are now a 
compile-time error.
  - `match` handlers can now operate on the stored value by 
reference.
  - A new method, `tryMatch`, allows for non-exhaustive pattern 
matching.

  - Various small improvements to the documentation.

Documentation: https://pbackus.github.io/sumtype/sumtype.html
DUB: https://code.dlang.org/packages/sumtype
Github: https://github.com/pbackus/sumtype


Nice,
but destructor SumType.~this() can call destroy on reference type 
like class:


bool destructed = false;
class C{
~this(){
destructed = true;
}
}
struct S{
~this(){
}

}
void main(){
auto c = new C;
{
auto st = SumType!(C, S)(c);
}
assert(destructed == true);
}


Re: float/double to string (pure nothrow @nogc)

2018-08-08 Thread vit via Digitalmars-d-learn

On Wednesday, 8 August 2018 at 17:40:11 UTC, ketmar wrote:

vit wrote:

Hello, is in phobos some function which convert float/double 
to string and is pure @nogc and nothrow?


i don't think that you can make it `pure`, but you certainly 
can make it `nothrow`, `@nogc` and ctfe-able. it's dangerous to 
go alone! take this[0].



[0] http://repo.or.cz/iv.d.git/blob_plain/HEAD:/ctfefloat.d


thanks, that code can be modified to pure nothrow @nogc @safe.
Is that lib ok? Is little complicated...



  1   2   >