Re: meaning of "auto ref const"?

2016-12-20 Thread Picaud Vincent via Digitalmars-d-learn

On Tuesday, 20 December 2016 at 20:08:32 UTC, Ali Çehreli wrote:


If the purpose is optimization, the good news are


Yes it is :)

* Classes are already reference types so there is no lvalue or 
rvalue reference distinction there


Ok, this one is quite intuitive.


import std.stdio;
...


Thank you for the illustrative example, I have reproduced it.


There is a surprising difference in D:

In D, non-constness of an object seems to be more important in 
overload resolution: Notice how mutable lvalue above is passed 
to by-copy instead of the potentially-more-optimal by-const-ref 
above. D realizes that a mutable object is for mutation and 
because by-const-ref cannot mutate it, D passes it to the 
by-copy function. (This may be seen as a bug by some.)


Thank you for pointing out this. I was not aware of that, and for 
sure this is not the C++  behavior.


Interestingly, enabling the by-mutable-ref overload above, now 
the mutable object goes to by-ref and there is no automatic 
copy:


Ok, that is "moral" and without surprise.


--- rvalue ---
constructor   1
foo(by-copy)  1
destructor for1

--- mutable lvalue ---
constructor   2
foo(by-ref)   2
destructor for2

--- const lvalue ---
constructor   3
foo(by-ref-const) 3
destructor for3

Ali

[1] I have an issue with "rvalue reference" as rvalue 
references can be references to lvalues as well. :p


Thank you for your time and these valuable explanations, I learnt 
a lot.

--Vincent


Re: meaning of "auto ref const"?

2016-12-20 Thread Picaud Vincent via Digitalmars-d-learn

On Tuesday, 20 December 2016 at 19:24:32 UTC, Ali Çehreli wrote:
As a general rule, 'auto ref' should probably be const. If the 
purpose of 'ref' is so that the argument would be mutated, then 
allowing a copy of an rvalue to this function could very well 
be a bug:


struct S {
int i;
}

void foo()(auto ref S s) {
s.i = 42;  // <-- Cannot be observed if the arg is rvalue
}

void main() {
foo(S(1));
}


Thank you Ali! This is effectively a trap I had not realized, you 
probably save me from some long debugging time.


Re: meaning of "auto ref const"?

2016-12-18 Thread Picaud Vincent via Digitalmars-d-learn

On Sunday, 18 December 2016 at 14:32:08 UTC, kinke wrote:

TypeInfo_Struct apparently requires (or used to require) an 
`int opCmp(ref const T rhs)` overload, i.e., a version taking 
the rhs lvalue argument by reference (see 
https://dlang.org/spec/operatoroverloading.html#compare). Note 
that there are other overloads afterwards which take the rhs 
argument by value, thereby allowing rhs rvalues too.


Thank you for your complementary answer and explanation. All 
these look less strange to me now.


Re: meaning of "auto ref const"?

2016-12-18 Thread Picaud Vincent via Digitalmars-d-learn

On Sunday, 18 December 2016 at 14:25:04 UTC, Basile B. wrote:

...
As you can see, auto ref is more flexible with the parameter. 
This make sense for templated functions.


Thank you for your detailed answer, things are perfectly clear 
now. Also sorry for the doc linksI should have found it before 
asking my question.


meaning of "auto ref const"?

2016-12-18 Thread Picaud Vincent via Digitalmars-d-learn

Reading std/bigint.d code:

https://github.com/dlang/phobos/blob/00c1cc3b0d354363793c8b419ce84da722578138/std/bigint.d#L589

I have seen this:

bool opEquals()(auto ref const BigInt y) const pure @nogc
{
   return sign == y.sign && y.data == data;
}

my problem is that I do not understand the role/meaning of "auto" 
in this context.


Moreover in the opCmp code, "auto" is not present anymore, which 
is an extra source of confusions for me.


int opCmp(ref const BigInt y) pure nothrow @nogc const
{
   // Simply redirect to the "real" opCmp implementation.
   return this.opCmp!BigInt(y);
}

What is the rational?

-

Another interrogation for me, who come from C++, is how to 
translate into D:


template void foo(T&& t);




Re: [Semi-OT] I don't want to leave this language!

2016-12-07 Thread Picaud Vincent via Digitalmars-d-learn

On Wednesday, 7 December 2016 at 16:15:32 UTC, Chris wrote:



I don't understand this discussion at all. Why not have both? I 
don't need bare metal stuff at the moment but I might one day, 
and I perfectly understand that people may need it. At the same 
time, there are people who are happy with runtime/Phobos/GC. In 
my opinion it's not a question of "either or" but of "both and".


Yes, I do agree, that is not exclusive. I only said that IMHO it 
would be very useful to have a clear "mechanism" (pragma, 
compiler flags...) to generate code close to what can be done 
with C. The goal being to have appealing (= fast & low memory 
footprint) libraries to attract people. That said, D with all its 
features GC, ... is great, but maybe that is not the feature that 
catches potential user attention the most.


-- Vincent


Re: [Semi-OT] I don't want to leave this language!

2016-12-07 Thread Picaud Vincent via Digitalmars-d-learn

On Wednesday, 7 December 2016 at 11:48:32 UTC, bachmeier wrote:

I write D code all the time for my research. I want to write 
correct code quickly. My time is too valuable to spend weeks 
writing code to cut the running time by a few minutes. That 
might be fun for some people, but it doesn't pay the bills. 
It's close enough to optimized C performance out of the box. 
But ultimately I need a tool that provides fast code, has 
libraries to do what I want, and allows me to write a correct 
program with a limited budget.


This is, of course, not universal, but zero overhead is not 
important for most of the numerical code that is written.


I understand and I do agree with these points, honestly. These 
points are also the reason why I will maybe try to use D for my 
own codes (D is really much better than C++ concerning template, 
meta programming syntax, embedded unit tests etc...).


However I think that to popularize/attract people to use D, it is 
very important, to have a mechanism/feature that allows you to be 
close to the "zero overhead" situation.


If you have two concurrent libraries (even in different 
languages), people will adopt the fastest one... As an example, 
look at the BLAS lib, people do not try to read/understand the 
code to see how nice it is, they just look at benchmarks and take 
the fastest implementation for their architecture. IMHO that is 
the reason why D must let the opportunity, for those who want 
(library developers for instance) of coding down to the metal: 
the goal is to have visibility in benchmarks and to attract users.


At least it is my point of view.

-- Vincent



Re: [Semi-OT] I don't want to leave this language!

2016-12-06 Thread Picaud Vincent via Digitalmars-d-learn
On Tuesday, 6 December 2016 at 17:00:35 UTC, Jonathan M Davis 
wrote:
So, while there are certainly folks who would prefer using D as 
a better C without druntime or Phobos, I think that you're 
seriously overestimating how many folks would be interested in 
that. Certainly, all of the C++ programmers that I've worked 
with professionally would have _zero_ interest in D as a better 
C.


- Jonathan M Davis


Considering scientific/numerical applications, I do agree with 
Ilya: it is mandatory to have zero overhead and a 
straightforward/direct interoperability with C. I am impressed by 
the Mir lib results and I think "BetterC" is very 
attractive/important.


-- Vincent


Re: fPIC Error

2016-11-19 Thread Picaud Vincent via Digitalmars-d-learn

On Thursday, 3 November 2016 at 05:16:11 UTC, Dlang User wrote:
I am running Debian Testing and I think I have run into the 
recent fPIC issue.  This is the source code for the test 
project I am using:


import std.stdio;

void main()
{
writeln("Edit source/app.d to start your project.");
readln();
}


When I try to compile a project, I get the following errors 
(truncated for brevity):



/usr/bin/ld: 
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libphobos2.a(thread_26c_155.o): relocation R_X86_64_32 against symbol `__dmd_personality_v0' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on 
output

collect2: error: ld returned 1 exit status
dmd failed with exit code 1.
Exit code 2
Build complete -- 1 error, 0 warnings



I got the same problem, still under Debian. A fix is to use these 
flags:


dmd -shared -m64 -fPIC -defaultlib=libphobos2.so app.d

You can also use another compiler:

dub --compiler=ldc2

or

rdmd --compiler=ldc2

Note that it is not recommended to use gdc because it is not up 
to date, use dmd or ldc2.


Also note, that if you use Emacs + Org Mode,

http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-C.html

you will encounter the same problem. A fix is to add the 
following line in your .emacs file:


(setq org-babel-D-compiler "rdmd --compiler=ldc2")


Vincent



A curated list of links related to D (github/awesome D)

2016-11-15 Thread Picaud Vincent via Digitalmars-d-learn
Maybe interesting (hoping it is not too redundant with the links 
here)


https://github.com/zhaopuming/awesome-d

Vincent


Re: static array internal & dangling reference

2016-11-14 Thread Picaud Vincent via Digitalmars-d-learn
On Monday, 14 November 2016 at 17:15:43 UTC, Steven Schveighoffer 
wrote:


What has happened is that the stack allocated for f() (and 
since released) is still referenced by sb[]. In a weird way, 
since you haven't called any other functions, that data is 
still "valid"!


Thank you for the clarification. I am convinced, I think this is 
the "true" reason why Valgrind does not react.


I'm not sure what valgrind uses to determine what data is 
uninitialized or allocated, but in a very real sense, this code 
is deterministic, and will always result in the same result. Is 
it good practice? No. It's very fragile, and would break as 
soon as you called another function or reallocated that stack 
space (as your second example shows).


I understand you, and for sure this is not a good practice.

I think it is time for me to ruminate on something else...
Thank you

- Vincent


Re: static array internal & dangling reference

2016-11-13 Thread Picaud Vincent via Digitalmars-d-learn
On Monday, 14 November 2016 at 06:10:38 UTC, Jonathan M Davis 
wrote:



I would have hoped that it would have complained about the 
first one. I don't know why it isn't. It definitely results in 
having a pointer to memory that should no longer be referenced.


Yes I would have hoped too, because it has the unfortunate 
consequence that we can not rely 100% that there is no dangling 
pointer even if valgrind said OK.


Regardless, there's no question that returning a dynamic array 
which is a slice of a static array is not something that is 
valid to do when that static array is a local variable. 
Valgrind just isn't managing to catch it in this case, 
unfortunately.


I do agree, this is not a construct to use, I only have done this 
for testing purpose to see how D reacts.


Vincent



Re: static array internal & dangling reference

2016-11-13 Thread Picaud Vincent via Digitalmars-d-learn
On Sunday, 13 November 2016 at 23:39:37 UTC, Steven Schveighoffer 
wrote:


Note that he is declaring an int[10] inside the function and 
then returning it. The compiler must see that the int[10] will 
be returned, and so it reuses the pre-allocated buffer for 
returning as the same address to avoid copying.


I would guess it's probably fine, with no dangling reference.


Thank you for your comment.

On my side there is still something mysterious. I one case:

int[] f()
{
  int[10] sa;
  foreach(int i, ref sa_i;sa){
sa_i=i;
  }
  int[] sb=sa;
  return sb;
}

void f_test()
{
  auto sb=f();
  sb[2]=100; // Valgrind ok
}

Valgrind does not complain.

But on the other case:

// same int[] f() function

void f_test() {
auto sb=f();
sb[2] = 100;
writeln(sb[2]);
int test[100];  // these two lines make Valgrind panicking
writeln(sb[2]); //
}

it complains with "Conditional jump or move depends on 
uninitialised value(s)"



I think my two examples are creating a dangling pointer. But I 
would be happy to understand why Valgrind is not complaining for 
the first one.


Vincent




Re: static array internal & dangling reference

2016-11-12 Thread Picaud Vincent via Digitalmars-d-learn

On Saturday, 12 November 2016 at 11:03:31 UTC, Mike Parker wrote:

Thank you very much for your clarifications & explanations, I am 
reassured to see that things work like in C.


I will also look the links you provided, thank you again for your 
time.


Vincent





Re: static array internal & dangling reference

2016-11-12 Thread Picaud Vincent via Digitalmars-d-learn

Thank you for your answer cym13.

I reproduced your result for:

On Saturday, 12 November 2016 at 10:45:23 UTC, cym13 wrote:

void f_test() {
auto sb=f();
sb[2] = 100;
writeln(sb[2]); // prints 100
int test[100];
writeln(sb[2]); // prints 0
}


now I am convinced of the invalid access, and this time valgrind 
was not happy, insulting me with:


==13545== Conditional jump or move depends on uninitialised 
value(s)
==13545==at 0x10A6BA: 
_D3std4conv55__T11toTextRangeTiTS3std5stdio4File17LockingTextWriterZ11toTextRangeFNfiS3std5stdio4File17LockingTextWriterZv (indexType.d:5123)
==13545==by 0x10ABED: 
_D3std5stdio4File14__T5writeTiTaZ5writeMFNfiaZv (stdio.d:1424)
==13545==by 0x10A08C: 
_D3std5stdio14__T7writelnTiZ7writelnFNfiZv (stdio.d:3211)



However for my first example, I have checked again and

void f_test()
{
  auto sb=f();
  sb[2]=100;
}

Valgrind is silent... I thought it was because of a compiler 
optimization that removed the unusued "sb[2]=100" statement, but 
even with:



void f_test()
{
  auto sb=f();
  sb[2]=100;
  writeln(sb[2]);
}

which prints 100, Valgrind still do not complain... ?!?

I will try to investigate this and give a feedback if I find an 
explanation.


Vincent


static array internal & dangling reference

2016-11-12 Thread Picaud Vincent via Digitalmars-d-learn

Hi all,
Still learning... This time what surprised me is how static 
arrays work.
I assume (is it true?) that for efficiency reason static size 
arrays like int[10] are on the stack and do not involve dynamic 
memory allocation:


First surprise: it is possible to share a static array:

void main() {

  int[10] sa;
  foreach(int i, ref sa_i;sa){
sa_i=i;
  }
  writeln("\n vect init sa",sa);

  int[] sb=sa[3..6];   // <- did not think it was possible
  sb[2]=100;

  writeln("\n vect sa ",sa);
  writeln("\n vect sb ",sb);
}

which prints:

 vect init sa[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 vect sa [0, 1, 2, 3, 4, 100, 6, 7, 8, 9]  // <- sa and sb are 
really shared


 vect sb [3, 4, 100]

Second surprise: I tried to create a dangling reference with:

int[] f()
{
  int[10] sa;
  foreach(int i, ref sa_i;sa){
sa_i=i;
  }
  int[] sb=sa;
  return sb;
}

void f_test()
{
  auto sb=f();
  sb[2]=100; // I expected an "invalid access" (it points to 
"sa", a local variable)

}

However calling f_test seems ok and valgrind tool does not 
complain...


So my questions are:
0/ does I miss something? (in C++ for sure you create a dangling 
pointer)
1/ what is the internal mechanism for that? Is the GC involved? 
Performance impact?

2/ any link describing this in more details is welcome

Thank you



Re: cross_module function overloading & alias & template: how to ?

2016-11-10 Thread Picaud Vincent via Digitalmars-d-learn
On Thursday, 10 November 2016 at 20:12:10 UTC, Jonathan M Davis 
wrote:
On Thursday, November 10, 2016 17:41:02 Picaud Vincent via 
Digitalmars-d- learn wrote:
It is certainly a compiler problem: I used gdc -> compile 
error, but with dmd it compiles and runs fine. Full details in 
the git repo.


Don't bother with gdc at this point. Unless there's a 
development version of it that's actually up-to-date and hasn't 
been released yet, it's too old to be reliable with regards to 
what correct D is. If something doesn't work in gdc, it could 
easily be because of a bug that has since been fixed. 
Unfortunately, the gdc folks have never managed to release an 
updated gdc that uses the D version of the compiler front-end, 
so as I understand it, they're still stuck at 2.067 (which is 
over 2 years old), whereas dmd is now at 2.072. ldc should be 
reasonably up-to-date if you want an alternative to dmd, and I 
expect that the gdc guys will get there eventually, but they 
haven't yet.


- Jonathan M Davis


I just have compiled my example with ldc and everything is ok!
I was not aware of that concerning gdc. Thank you for this 
information, I lost around 2 hours struggling with initial code 
trying to guess what was wrong.

Conclusion: now I will only use ldc and dmd.
Thanks to Steven too for his clarification concerning 
template<->symbol

Vincent



Re: cross_module function overloading & alias & template: how to ?

2016-11-10 Thread Picaud Vincent via Digitalmars-d-learn
On Thursday, 10 November 2016 at 17:12:32 UTC, Jonathan M Davis 
wrote:
On Thursday, November 10, 2016 15:46:11 Picaud Vincent via 
Digitalmars-d- learn wrote:

[...]


Honestly, I'm surprised that the compiler let you alias
std.algorithm.comparison.min, because it's a templated 
function, and in the
case of templates, you alias instantiations of templates, not 
the templates
themselves. std.algorithm.comparison.min is just a template for 
a function,

not an actual function. Something like
std.algorithm.comparison.min!(int, int) would be an actual 
function.


[...]


Hi Jonathan,

I just read your answer, thank you a lot
Unfortunately I have not the time right now to answer (I am 
leaving my job it is 6:53PM).

I will answer later.
However I just created a github repo to reproduce my observations:

https://github.com/vincent-picaud/DLang_overloading

It is certainly a compiler problem: I used gdc -> compile error, 
but with dmd it compiles and runs fine. Full details in the git 
repo.


More answers later... I have to leave



cross_module function overloading & alias & template: how to ?

2016-11-10 Thread Picaud Vincent via Digitalmars-d-learn

Hi All,

In my adventure to learn a little bit of D coming from C++ I am 
now faced with the following problem:


I have read about "cross-module overloading", §5.5.2 page 146 of 
Andrei Alexandrescu book.

That makes sense to me and this is interesting.

As a concrete example here the scenario: I want to define a 
specialized version of the min function.


In D knowing that if there is an ambiguity between modules the 
compiler generates an error, the following example does NOT work:


==

// I am the my_min.d file
module my_min;

int min(int a,int b)
{
  return (a use my_min.min
  auto dc=min(4.5,b);  // OK! -> use std.algorithm.comparison.min
}

==

But now I have the following problem: if I use a parametrized 
function min:


==

module my_min;
import std.algorithm.comparison;

T min(T)(T a,T b)
{
  return (a What am I missing? What is the right way to do that?

Thank you :)


Re: New to D and mimicking C++ : how to implement std::integral_constant<>?

2016-11-08 Thread Picaud Vincent via Digitalmars-d-learn

Hi Basile,
Thank you for your code, it allowed me to grasp a little bit more 
about how to do things in D.

Vincent



Re: New to D and mimicking C++ : how to implement std::integral_constant<>?

2016-11-07 Thread Picaud Vincent via Digitalmars-d-learn

On Monday, 7 November 2016 at 23:07:27 UTC, Picaud Vincent wrote:

typo...
auto capacity = max(0,(size_-1)*stride_+1);


To be more correct I have something like:

alias IntergralConstant!(int,0) Zero_c;
alias IntergralConstant!(int,1) One_c;

auto capacity = max(Zero_c,(size_-One_c)*stride_+One_c);

with "smooth" implicit conversion IntegralConstant -> int for 
cases where size_ or stride_ are "int" and not both 
IntegralConstant types.




Re: New to D and mimicking C++ : how to implement std::integral_constant<>?

2016-11-07 Thread Picaud Vincent via Digitalmars-d-learn

On Monday, 7 November 2016 at 22:18:56 UTC, Jerry wrote:
On Monday, 7 November 2016 at 21:37:50 UTC, Picaud Vincent 
wrote:
  static if ( isIntegralConstant!(typeof(required_capacity()) 
)

{
}
else
{
}

}


Premature post send by error sorry Well something like:

   static if ( isIntegralConstant!(typeof(required_capacity()) 
)

 ElementType[required_capacity()] data_;
   else
 ElementType[] data_;
}

For that, at least in C++, I need integral_constant<> type 
with compile-time arithmetic and smooth integration with 
"usual" size_t/ptrdiff_t types.


2/ I also would like to test some implementations concerning 
automatic differentiation.

I have my own C++ libs, inspired, but ~20% faster than Adept:
http://www.met.reading.ac.uk/clouds/adept/
and I would like to know how I can do that in D

Well... That is the idea... I hope I will get some results and 
I will be happy to share if it is something interesting.


Vincent


Ah I get what you mean, you can do that without using a special 
type.


struct Vector(T, Args...) if(Args.length == 1)
{
static if(is(Args[0] == size_t))
{
size_t size;
}
else static if(Args[0] != 0) // would error if it's a 
type that's not size_t

{
enum size = Args[0];
}
else
{
static assert(0);
}
}

Vector!(int, 10) a;
Vector!(int, size_t) b; // both work with IntegralConstant

could use __traits(compiles) to see if it's not a type, for 
that second static if. Which would probably be better, so if 
you pass a float or something, it won't give a weird error.


Thank you again Jerry!

For sure my way of thinking is twisted by my C++ habits! :-/

The positive point is that D seems to offer much shorter 
solutions (this is my hope).


However I still need some investigations and/or some guidance:

-> not sure that it is ok for me as I really want to track 
"static constants" all the

   way long.
   That is the reason why I introduced the IntegralConstant type
   (with operator overloading, work in progress)

For instance, the code:

 enum int a=1,b=2;
 auto c = a+b;

 pragma(msg,typeof(c));   // prints "int"
 static assert(c==3); // compilation fails: "variable c 
cannot be read at compile time"


To implement my vector structs I need:

1/ a way to detect compile-time constant vs "dynamic" values
2/ to perform and to propagate compile-time constants across 
"arithmetic" computations.
   For instance to compute the required capacity to store vector 
data, I need something

like

auto capacity = max(0,(size_-1)*stride_);

and this expression must make sense for both "dynamic" values and 
compile-time constant.


In one case I expect
   typeof(capacity) -> int,
in the other
   typeof(capacity) -> IntegralConst



Re: New to D and mimicking C++ : how to implement std::integral_constant<>?

2016-11-07 Thread Picaud Vincent via Digitalmars-d-learn

On Monday, 7 November 2016 at 21:23:37 UTC, Picaud Vincent wrote:

On Monday, 7 November 2016 at 18:59:24 UTC, Jerry wrote:
On Monday, 7 November 2016 at 18:42:37 UTC, Picaud Vincent 
wrote:

template isIntegralConstant(ANY)
{
enum bool 
isIntegralConstant=__traits(identifier,ANY)=="IntegralConstant";

}


A bit more elegant way of doing that would be:

enum isIntegralConstant(T) = is(T : IntegralConstant!U, U...);


I would be very graceful for any help/advice that explains 
the right way to implement C++ std::integral_constant in the D language.


Vincent


Now the question is, do you really need IntegralConstant? I've 
never used it in C++ so I don't really know any of the use 
cases for it. But generally in D if you need something to be a 
compile time constant value you can just use "enum". It can be 
any type as well, so long as it can be evaluated at compile 
time.


enum long someConstant = 1 << 32;


Hi Jerry,

Thank you so much for your quick answer! I tried your 
suggestion and it works.


My main interest is numerical computations. I have some C++ 
libs using meta-programming and I want to see how I can 
translate some parts in D. The goal is to check: productivity & 
code readability & performance. I will try to implement 2 toy 
examples:


1/ A basic example of strided dense vector structure dealing 
with the dynamic/static size in an uniform way. In D I thing 
this can be done with something like this (not tried yet to 
compile it, but that is the idea to mimick my C++ 
implementation)


struct Vector(T,SIZE,STRIDE) if( 
(is(SIZE==size_t)||isIntegralConstant!SIZE) ...)

{
  alias T ElementType;

  private SIZE size_;
  private STRIDE stride_;

  ...

  auto required_capacity() { return size_*stride_; } // return 
a size_t or a IntegralConst


  static if ( isIntegralConstant!(typeof(required_capacity()) )
{
}
else
{
}

}


Premature post send by error sorry Well something like:

   static if ( isIntegralConstant!(typeof(required_capacity()) )
 ElementType[required_capacity()] data_;
   else
 ElementType[] data_;
}

For that, at least in C++, I need integral_constant<> type with 
compile-time arithmetic and smooth integration with "usual" 
size_t/ptrdiff_t types.


2/ I also would like to test some implementations concerning 
automatic differentiation.

I have my own C++ libs, inspired, but ~20% faster than Adept:
http://www.met.reading.ac.uk/clouds/adept/
and I would like to know how I can do that in D

Well... That is the idea... I hope I will get some results and I 
will be happy to share if it is something interesting.


Vincent



Re: New to D and mimicking C++ : how to implement std::integral_constant<>?

2016-11-07 Thread Picaud Vincent via Digitalmars-d-learn

On Monday, 7 November 2016 at 18:59:24 UTC, Jerry wrote:
On Monday, 7 November 2016 at 18:42:37 UTC, Picaud Vincent 
wrote:

template isIntegralConstant(ANY)
{
enum bool 
isIntegralConstant=__traits(identifier,ANY)=="IntegralConstant";

}


A bit more elegant way of doing that would be:

enum isIntegralConstant(T) = is(T : IntegralConstant!U, U...);


I would be very graceful for any help/advice that explains the 
right way to implement C++ std::integral_constant 
in the D language.


Vincent


Now the question is, do you really need IntegralConstant? I've 
never used it in C++ so I don't really know any of the use 
cases for it. But generally in D if you need something to be a 
compile time constant value you can just use "enum". It can be 
any type as well, so long as it can be evaluated at compile 
time.


enum long someConstant = 1 << 32;


Hi Jerry,

Thank you so much for your quick answer! I tried your suggestion 
and it works.


My main interest is numerical computations. I have some C++ libs 
using meta-programming and I want to see how I can translate some 
parts in D. The goal is to check: productivity & code readability 
& performance. I will try to implement 2 toy examples:


1/ A basic example of strided dense vector structure dealing with 
the dynamic/static size in an uniform way. In D I thing this can 
be done with something like this (not tried yet to compile it, 
but that is the idea to mimick my C++ implementation)


struct Vector(T,SIZE,STRIDE) if( 
(is(SIZE==size_t)||isIntegralConstant!SIZE) ...)

{
  alias T ElementType;

  private SIZE size_;
  private STRIDE stride_;

  ...

  auto required_capacity() { return size_*stride_; } // return a 
size_t or a IntegralConst


  static if ( isIntegralConstant!(typeof(required_capacity()) )
{
}
else
{
}

}


New to D and mimicking C++ : how to implement std::integral_constant<>?

2016-11-07 Thread Picaud Vincent via Digitalmars-d-learn

Hi all,

I have ~15y of C++ and now I want to test D, because it seems 
really intersting and "cleaner" than C++.


As an exercice I m trying to implement something equivalent to 
the C++ std::integral_constant in D.


In D:

struct IntegralConstant(T, T VALUE) {
 ...
}

But I do not know how to write a compile-time type check. I tried

template isIntegralConstant(ANY)
{
enum bool 
isIntegralConstant=__traits(identifier,ANY)=="IntegralConstant";

}

But when using it with ANY=long type, I get a compile-time error:

"argument long has no identifier"

A workaround that worked is:

struct IntegralConstantTag {}

struct IntegralConstant(T, T VALUE) {
  private IntegralConstantTag selfTag_;
  alias selfTag_ this;
}

template isIntegralConstant(ANY)
{
enum bool isIntegralConstant=is(ANY : IntegralConstantTag);
}

But now I'm sticked by a compiler issue when I want to introduce 
2 "alias this" to allow implicit conversion:


struct IntegralConstant(T, T VALUE) {
  private IntegralConstantTag selfTag_;
  alias selfTag_ this;
  T value_=VALUE;
  alias value_ this;
}

Compiler error message is "integralConstant.d:16:3: error: there 
can be only one alias this".



I would be very graceful for any help/advice that explains the 
right way to implement C++ std::integral_constant in 
the D language.


Vincent