Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 13:27:14 UTC, Vindex wrote:

Thanks everyone!

The solution that works for me now looks like this:


template ndim(T) {
static if (std.traits.isArray!T) {
static if (is(typeof(T.init[0]))) {
alias SubArrayType = typeof(T.init[0]);
enum ndim = ndim!SubArrayType + 1;
}
else enum ndim = 1;
}
else enum ndim = 0;
}
unittest {
assert(ndim!(int[]) == 1);
assert(ndim!(int[][]) == 2);
assert(ndim!(int[4][3]) == 2);
assert(ndim!(int[][2][]) == 3);
assert(ndim!(string) == 1);
}


Nice. You should look at Rumbu solution too. It possibly has a 
better behavior toward the recursive expansion. Also interesting 
to learn the more advanced use of "is".


Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 13:13:33 UTC, Basile B. wrote:

On Monday, 8 February 2021 at 13:09:53 UTC, Rumbu wrote:

On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote:

[...]


dimensionCount!string should be 2.

My take without std.traits:

template rank(T: U[], U)
{
   enum rank = 1 + rank!U;
}

template rank(T: U[n], size_t n)
{
enum rank = 1 + rank!U;
}

template rank(T)
{
enum rank = 0;
}


yeah you're right, strings were a special case (I remember now) 
so that stuff could be stored as literals.


well to OP just dont use my dimensionCount template ^^. it should 
have been declared with the "package" protection in first place; 
not public.


Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 13:09:53 UTC, Rumbu wrote:

On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote:

[...]


dimensionCount!string should be 2.

My take without std.traits:

template rank(T: U[], U)
{
   enum rank = 1 + rank!U;
}

template rank(T: U[n], size_t n)
{
enum rank = 1 + rank!U;
}

template rank(T)
{
enum rank = 0;
}


yeah you're right, strings were a special case (I remember now) 
so that stuff could be stored as literals.


Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote:

On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote:

[...]


yeah.

---
template dimensionCount(T)
{
static if (isArray!T)
{
static if (isMultiDimensionalArray!T)
{
alias DT = typeof(T.init[0]);
enum dimensionCount = dimensionCount!DT + 1;
}
else enum dimensionCount = 1;
}
else enum dimensionCount = 0;
}
///
unittest
{
static assert(dimensionCount!char == 0);
static assert(dimensionCount!(string[]) == 1);
static assert(dimensionCount!(int[]) == 1);
static assert(dimensionCount!(int[][]) == 2);
static assert(dimensionCount!(int[][][]) == 3);
}
---

that can be rewritten using some phobos traits too I think, but 
this piece of code is very old now, more like learner template.


well I didn't realize but static array are not handled. I think 
this is because in first place this was made for a specific usage 
that was a serializer.


Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote:

size_t ndim(A)(A arr) {
return std.algorithm.count(typeid(A).to!string, '[');
}

Is there a way to find out the number of dimensions in an array 
at compile time?


yeah.

---
template dimensionCount(T)
{
static if (isArray!T)
{
static if (isMultiDimensionalArray!T)
{
alias DT = typeof(T.init[0]);
enum dimensionCount = dimensionCount!DT + 1;
}
else enum dimensionCount = 1;
}
else enum dimensionCount = 0;
}
///
unittest
{
static assert(dimensionCount!char == 0);
static assert(dimensionCount!(string[]) == 1);
static assert(dimensionCount!(int[]) == 1);
static assert(dimensionCount!(int[][]) == 2);
static assert(dimensionCount!(int[][][]) == 3);
}
---

that can be rewritten using some phobos traits too I think, but 
this piece of code is very old now, more like learner template.


Re: core.atomic for ldc.

2021-01-31 Thread Basile B. via Digitalmars-d-learn

On Monday, 1 February 2021 at 06:12:59 UTC, vitamin wrote:
On Monday, 1 February 2021 at 05:23:52 UTC, rikki cattermole 
wrote:
The only difference between dmd, ldc and gdc (in effect) is 
the backend.
While druntime and Phobos will be patched for other platform 
targets, over all its the same library.


The same goes for core.atomic. You should not need to know 
that it has been patched. If you can call it and it gives you 
the right results, you can assume it worked.


Oh and $ dub build --compiler=ldc2


problem is when I build with ldc then id doesn't work and with 
dmd it does:


try compile this with ldc:
https://run.dlang.io/is/gngLFu

error on webite run.dlang.io is same as I have.


LDC has all LLVM intrinsics so try

---
import ldc.intrinsics;
ldc.intrinsics.llvm_atomic_rmw_add(...);
---


Re: How define accepted types in a template parameter?

2021-01-16 Thread Basile B. via Digitalmars-d-learn

On Saturday, 16 January 2021 at 18:39:03 UTC, Marcone wrote:
For example, I want my function template to only accept integer 
or string;


You can do that with either

- `static if` inside the body [1]

  import std.traits;
  void foo(T)(T t)
  {
static if (isIntegral!T) {}
else static assert false;
  }


- template constraint [2]

  import std.traits;
  void foo(T)(T t)
  if (isIntegral!T)
  {
  }

- template parameter specialization [3]

  void foo(T : ulong)(T t) // : meaning implictly convert to
  {
  }


2 and 3 being the more commonly used.
1 is more to use the same body instead of using N overloads

[1] : https://dlang.org/spec/version.html#staticif
[2] : https://dlang.org/spec/template.html#template_constraints
[3] : 
https://dlang.org/spec/template.html#parameters_specialization


Re: Template alias as template specialisation not recognized.

2021-01-15 Thread Basile B. via Digitalmars-d-learn

On Saturday, 16 January 2021 at 01:21:24 UTC, Paul wrote:
I'm having issues when trying to use a template alias as a 
template specialisation.

When using the following:

alias Vec(uint size, Type) = Mat!(size, 1, Type);


void setUniform(V : Vec!(L, bool), int L)(string name, V 
value) {...}



Vec!(4, bool) a;
setUniform("test", a);


I get the following error:
template `shader.Shader.setUniform` cannot deduce function 
from argument types `!()(string, Mat!(4u, 1u, bool))`, 
candidates are:DUB
shader.d(43, 7): `setUniform(V : Vec!(L, bool), uint L)(string 
name, V value)`


Meanwhile, when using the following, I have no issues:
void setUniform(V : Mat!(L, 1, bool), int L)(string name, V 
value) {}


In this case you can use a const template parameter:

  alias Vec(uint size, Type, const uint length = 1) = Mat!(size, 
length, Type);


Although this is not a generic workaround for the issue mentioned.


Re: Open question: what code pattern you use usually for null safety problem

2021-01-15 Thread Basile B. via Digitalmars-d-learn

On Thursday, 14 January 2021 at 18:24:44 UTC, ddcovery wrote:
I know there is other threads about null safety and the 
"possible" ways to support this in D and so on.

[...]
If it's not a bother, I'd like to know how you usually approach 
it


[...]

Thanks!!!


I have a opDispatch solution here [1], probably very similar to 
the other opDispatch solution mentioned. It is used in d-scanner 
since several years, e.g here [2]. I'd like to have this as a 
first class operator because as usual in D,  you can do great 
things with templates but then completion is totally unable to 
deal with them. Also There's a great difference between using the 
template to do refacts and using it to write new code. Very 
frustrating to write `safeAcess(stuff). ` and no completion popup 
appears.


[1]: 
https://gitlab.com/basile.b/iz/-/blob/master/import/iz/sugar.d#L1655
[2]: 
https://github.com/dlang-community/D-Scanner/blob/2963358eb4a24064b0893493684d4075361297eb/src/dscanner/analysis/assert_without_msg.d#L42





Re: Why many programmers don't like GC?

2021-01-14 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 13 January 2021 at 18:58:56 UTC, Marcone wrote:
I've always heard programmers complain about Garbage Collector 
GC. But I never understood why they complain. What's bad about 
GC?


Semi serious answer:

In the domain of hoby-ism and small companies programmers that 
work with statically typed languages all believe that they are 
super hero in the domain of memory managment. When they see "GC" 
they think that they are considered as 2nd grade student ^^


It's basically snobbism.


Re: Hardcoded filepaths in compiled exe

2020-12-29 Thread Basile B. via Digitalmars-d-learn
On Wednesday, 30 December 2020 at 01:21:37 UTC, Steven 
Schveighoffer wrote:

On 12/29/20 7:46 PM, Basile B. wrote:
On Tuesday, 29 December 2020 at 23:11:25 UTC, Steven 
Schveighoffer wrote:
But I would think a feature should exist that masks the base 
directory of exception file names.


Probably worth an enhancement request.



Also aren't dmd output binaries supposed to be "reproducible" ?


If you had an option to change __FILE__ to be canonical, then 
it could be.


i.e. instead of:

C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d

you stored:

(imports)\std\file.d

where (imports) (or maybe some other token) was substituted in 
for the base of every import. Files passed on the command line 
would just store the __FILE__ as it was passed.


-Steve


actually the string 
"C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d"

looks like it comes from how the ini file variables are expanded.

__FILE__ is not supposed to represent an absolute file name 
unless the compiler get passed absolute file names. That why 
__FILE_FULL_PATH__ was added at some point.


Re: Hardcoded filepaths in compiled exe

2020-12-29 Thread Basile B. via Digitalmars-d-learn
On Tuesday, 29 December 2020 at 23:11:25 UTC, Steven 
Schveighoffer wrote:
But I would think a feature should exist that masks the base 
directory of exception file names.


Probably worth an enhancement request.

-Steve


Also aren't dmd output binaries supposed to be "reproducible" ?


Re: Hardcoded filepaths in compiled exe

2020-12-29 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 29 December 2020 at 21:27:07 UTC, Raikia wrote:

Interesting.  I was able to clobber it with bbe with no issues.
 I'm surprised the compiler doesn't strip out this potentially 
sensitive metadata, but I guess I'll just patch it out as part 
of my build process.  Thanks!


Other super safe options are to use either a VM or a CI service 
to build the releases.


Re: dmd: enum to!string slows down compilation

2020-12-29 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 29 December 2020 at 22:42:16 UTC, kdevel wrote:

Why is the enum to!string conversion so slow?

~~~slowenumtostringconversion.d
private enum S { A, B, C, D, };

[...]


one factor is all the template constraints that are evaluated 
until the right std.conv.to overload gets selected.


Re: Hardcoded filepaths in compiled exe

2020-12-29 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 29 December 2020 at 16:13:53 UTC, Raikia wrote:

Hey all,

[...]
$ strings -a program.exe | grep 'dmd2'
C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d
C:\D\dmd2\windows\bin\..\..\src\phobos\std\utf.d
C:\D\dmd2\windows\bin\..\..\src\phobos\std\base64.d


This problem is more egregious when I am using a home folder, 
like "C:\Users\\" instead of "C:\D\".  Am I missing 
something?  Is there a way to compile D without leaking 
metadata like this in a production release binary?


I believe those are because of Exception constructors that use 
the __FILE__ special keyword. You might patch the final 
executable and replace the string content with spaces or 'x's.


Re: Get the code of any D-entity as string?

2020-12-27 Thread Basile B. via Digitalmars-d-learn

On Sunday, 27 December 2020 at 12:20:01 UTC, sighoya wrote:

On Sunday, 27 December 2020 at 04:13:53 UTC, Max Haughton wrote:
Not possible although implementing as a __trait would be about 
15 lines I think.




I think that too, and it would nicely reuse the work of the 
compiler to parse the whole project.


I think read only AST access in some form would actually be 
quite nice, if not for dmd's AST being fuckugly (the hierarchy 
is fine but it's more gcc than clang)


The point is, once we have that we can decide ourselves which 
framework is the best for meta modelling.


Is it pure string manipulation or token stream manipulation à 
la Rust or an AST manipulation à la Nim/Scala. It can be all 
defined on top.


A more concrete example of what you are trying to achieve would 
allow to show the D way.


Re: Get the code of any D-entity as string?

2020-12-26 Thread Basile B. via Digitalmars-d-learn

On Saturday, 26 December 2020 at 12:38:21 UTC, sighoya wrote:

On Friday, 25 December 2020 at 23:04:15 UTC, Ali Çehreli wrote:

I am probably misunderstanding it but there is the .stringof 
property for all types: T.stringof.


But does stringof really print the declaration as string and 
not the type name itself?


I found: https://dlang.org/spec/property.html#stringof

I am probably stating the obvious but you normally import the 
interesting modules of that library anyway and the type 
information is available that way.


Ali


Well, certainly, yes. But only if `stringof` would do the job. 
The best thing would be to retrieve whole modules (abstract 
files) as string. On top of that we can retrieve any value/type 
declaration.


with __traits(allMembers) you can rebuild the declaration. For a 
struct that works well.


---
struct E {int a;}
struct S
{
ulong[] a;
@E(0) const int b;
void v() const {}
void v(int) const {}
}

string getDeclaration(T)()
if (is(T == struct))
{
import std.traits, std.meta;
string result = "struct " ~ T.stringof ~ " {\n";
static foreach (m; __traits(allMembers, T))
{{
static if (isCallable!(__traits(getMember, T, m)))
alias sym = __traits(getOverloads, T, m);
else
alias sym = AliasSeq!(__traits(getMember, T, m));
static foreach (s; sym)
{
result ~= "";
static foreach (a; __traits(getAttributes, s))
result ~= "@" ~ a.stringof ~ " ";
static if (is(typeof(s)))
result ~= typeof(s).stringof ~ " " ~ m ~ ";\n";
}
}}
result ~= "}";
return result;
}

pragma(msg, getDeclaration!S);
---


Re: gdb + Windows 64: No debugging symbols found

2020-12-26 Thread Basile B. via Digitalmars-d-learn
On Saturday, 26 December 2020 at 11:55:58 UTC, Виталий Фадеев 
wrote:

We have:
[...]
Problem is:
$ gdb ./app.exe
GNU gdb (GDB) 9.2
...
(No debugging symbols found in ./app.exe)

What is a right way to build .exe and debug with gdb ?


Try to build with latest version of LDC and use the -gdwarf 
option.

This will generate debug info that GDB can understand.


Re: Slice allocation after appending

2020-12-22 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 22 December 2020 at 22:12:29 UTC, Rekel wrote:
According to the D slice article 
(https://dlang.org/articles/d-array-article.html), slices do 
not care where they start, only where they end, when checking 
whether expanding in place is permitable, or at least that is 
what I understood regarding it.


Now I'm unsure how to check this, I tried to a bit using the 
online editor and a bit of pointer usage which seemed to 
confirm my suspicion, but does this mean that taking a (small) 
slice at the end of a (possibly) very large dynamic array can 
lead to problematic behavior?


No there's some runtime and GC magic under the hood. Appending on 
the slice is more like a smart "copy on append" operation so "a" 
will always ends with -1 and "b" with 2. It's described here : 
https://dlang.org/articles/d-array-article.html#how-it-works


Re: Can I use dub to generate docs?

2020-12-14 Thread Basile B. via Digitalmars-d-learn

On Monday, 14 December 2020 at 02:54:12 UTC, Jack wrote:

like dmd's -D flag?


you can try

   $ dub run harbored-mod -- $(find -iname *.d)

That will generate doc for all d source in the current working 
directory.




Re: How to check that function gets ref parameter?

2020-12-13 Thread Basile B. via Digitalmars-d-learn
On Sunday, 13 December 2020 at 16:41:06 UTC, Andrey Zherikov 
wrote:
I'm trying to check that function has 'ref' parameter. The only 
way I found so far is to use std.traits.Parameters.


Here is the code I have:
void f(int) {}
void g(ref int) {}
void main()
{
writeln(Parameters!f[0].stringof);
writeln(__traits(isRef, Parameters!f[0]));
writeln(Parameters!g.stringof);
writeln(Parameters!g[0].stringof);
writeln(__traits(isRef, Parameters!g[0]));
}

The output is:
int
false
(ref int)
int
false

"Parameters!g[0]" strips off 'ref' qualifier as you can see. 
How can I make it work?


You use the wrong traits, try ParameterStorageClassTuple instead:

  void f(int) {}
  void g(ref int) {}
  import std.traits : ParameterStorageClass, 
ParameterStorageClassTuple;
  static assert(ParameterStorageClassTuple!g[0] == 
ParameterStorageClass.ref_);
  static assert(ParameterStorageClassTuple!f[0] != 
ParameterStorageClass.ref_);





Re: Is this a compiler error? "recursive template expansion"

2020-12-08 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 8 December 2020 at 20:11:40 UTC, Nathan S. wrote:
The following code fails to compile. Is this a compiler error 
or if not what is wrong with the code?


What is wrong is that partial specialization is not correct.
The correct partial specialization is:

---
struct Template2(T)
{
enum tString = T.stringof;
static if (is(T == class))
enum tLinkage = __traits(getLinkage, T);
}

struct Template1(Param1, Param2 = Template2!Param1) {}

alias AliasTemplate1S(SecondParam) = Template1!(S,SecondParam);
//^here

class S
{
Template1!int x;
}
---

Now that being said, the compiler could complain about the 
incorrect partial spec instead of falling in the nonsensical 
error message.


There is a gap because the second template param looks optional 
so you dont put it the partial specialization but it is still 
required.


Anyway. This case is either a "bad diagnostic" or an 
"enhancement" request.

Or should be specified.


Re: betterC question

2020-11-19 Thread Basile B. via Digitalmars-d-learn
On Thursday, 19 November 2020 at 00:07:12 UTC, Dibyendu Majumdar 
wrote:

I have simple test program:

import core.stdc.stdio : printf;

void test() {
int* a;
printf("a == null %d\n", a == null);
}

int function() fp = test;

extern (C) void main() {
fp();
}

Why do I get:

\d\dmd-2.092.1\windows\bin64\dmd.exe -betterC tests.d
tests.d(5): Error: printf cannot be interpreted at compile 
time, because it has no available source code


This is on Windows


IMO another problem here is that `function` and `delegate` are 
special cases of the `*` postfix. With a syntax like


int()* fp = test

it would be more obvious to new comers that `&` is missing.
This is a syntax I experiment in STYX for example [1].


Note that then there's also the problem with functions pointers 
requiring a context. This context is not necessarily a `this` 
(for closures it's a frame obviously).


[1] 
https://gitlab.com/basile.b/styx/-/blob/master/tests/backend/function_pointers.sx#L10


Re: Best way to confine project to 64 bit builds only?

2020-10-17 Thread Basile B. via Digitalmars-d-learn

On Saturday, 17 October 2020 at 14:50:47 UTC, NonNull wrote:
I have inherited an open source C project that assumes that the 
size of a long and the size of a pointer are the same, and I 
have translated it into very similar D just like 
https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/


D has the size of long fixed at 64 bits, so a pointer now has 
to be 64 bits.


No it's wrong. A pointer always has the size of a general purpose 
register.


So I want to put something into the source to ensure an attempt 
to make a 32 bit build fails. What is the best way to do this?


anyway you have several options:

---
version(X86)
static assert (false, "not for i386");
---

or

---
static assert (size_t.sizeof != 4, "blablalala");
---


Re: Count template parameters of method

2020-10-11 Thread Basile B. via Digitalmars-d-learn

On Sunday, 11 October 2020 at 06:53:59 UTC, Andrey wrote:

Hello,

How to count a number of parameters in uninitialized template 
method?


For example:

struct Test
{
void abc(int a, bool status, string text)() {}
{


The method "Test.abc" has three template paramenters.

I know that "TemplateArgsOf" exists but it is used only for 
INITIALIZED templates...


You can count the commas in the text representation  but this is 
not a good solution. The default value of a 
TemplateValueParameter can lead to wrong results, for example if 
it's an array literal or a string literal.


---
size_t countTP(alias T)()
{
import std.algorithm : count;
return T.stringof.count(',') + 1;
}

template T1(A){}
template T2(A,B){}
template T3(A,B,C){}

void main()
{
pragma(msg, countTP!T1);
pragma(msg, countTP!T2);
pragma(msg, countTP!T3);
}
---

probably the countTP function can be enhanced to handle corner 
cases I mentioned.


Re: Deprecation in traits

2020-09-30 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 29 September 2020 at 17:08:40 UTC, Frak wrote:

Hi folks,

I've this:

/Users/frak/dlang/ldc-1.23.0/bin/../import/std/traits.d(3711): 
Deprecation: function 
`std.typecons.Nullable!long.Nullable.get_` is deprecated - 
Implicit conversion with `alias Nullable.get this` will be 
removed after 2.096. Please use `.get` explicitly.


I'm trying to find out WHERE this is generated to fix it, 
dependency included, without success.


Suggestions?


The problem has been observed already and it is an official 
enhancement request [1].
I think it is legit because deprecation are sometimes used to 
help into refactoring, so to have the use site is a essential.


[1] https://issues.dlang.org/show_bug.cgi?id=21176


Re: How to get the element type of an array?

2020-08-24 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote:
What's the best way to get the element type of an array at 
compile time?


Something like std.range.ElementType except that works on any 
array type. There is std.traits.ForeachType, but it wasn't 
clear if that was the right thing.


--Jon


I'm curious to know what are the array types that were not 
accepted by ElementType ( or ElementEncodingType ) ?


Re: Introspecting a package for submodules

2020-08-24 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 25 August 2020 at 00:09:38 UTC, Adam D. Ruppe wrote:

On Monday, 24 August 2020 at 22:32:52 UTC, Anonymouse wrote:

How do I do this? (Is there some other way?)


Not really a way. A package doesn't quite exist in D; there is 
no formal construct that is a package and has a defined list if 
stuff.


Wrong. Packages and modules exist in D as derived of 
ScopeDsymbol. OP just encounters a small bug.


https://github.com/dlang/dmd/pull/11619


Re: alias restriction??!

2020-07-19 Thread Basile B. via Digitalmars-d-learn

On Sunday, 19 July 2020 at 15:00:59 UTC, Paul Backus wrote:

On Sunday, 19 July 2020 at 12:42:47 UTC, Carl Sturtivant wrote:

On Sunday, 19 July 2020 at 12:08:07 UTC, Paul Backus wrote:


Easiest workaround:

ref inout(long) Second() inout { return second.one; }


Was trying to avoid this for performance reasons. In fact what 
are the performance implications of this sort of thing with 
current implementations? --- relative to using a simple offset.


Almost certainly no difference at all. Even DMD can inline this 
function:


https://d.godbolt.org/z/7ve6M8


The alias proposal matches to the "code fast" moto. When you do 
object composition with several level of nesting this would be a 
time saver.


Re: alias restriction??!

2020-07-18 Thread Basile B. via Digitalmars-d-learn

On Saturday, 18 July 2020 at 22:49:18 UTC, Dennis wrote:
On Saturday, 18 July 2020 at 18:46:16 UTC, Carl Sturtivant 
wrote:
Is there any way to avoid the duplication of the entries in 
the anonymous union, aside from using a mixin template?


I think this would be fixed if 
https://github.com/dlang/dmd/pull/11273 gets merged.


The feature still needs some work. With this PR aliases of 
members only works when they are declared in a function scope and 
not in the aggregate scope.


Example:

---
struct Inner
{
int a;
}

struct TopLevel
{
Inner inner;
alias ia = inner.a;
}

void main()
{
TopLevel tl;
alias ia = tl.inner.a;
ia = 42;// OK with PR 11273
tl.ia = 42; // NG Error: need `this` for `a` of type `int`
}
---

I think it's not good to merge until the second case works.
Also it requires approval. For now it is specified that 
expressions cant be aliased.


Re: Uploading coverage to Codecov doesn't work

2020-07-14 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 14 July 2020 at 17:52:25 UTC, Basile B. wrote:

On Tuesday, 14 July 2020 at 11:05:17 UTC, Mitacha wrote:

On Saturday, 11 July 2020 at 09:43:39 UTC, Basile B. wrote:

On Wednesday, 8 July 2020 at 15:55:58 UTC, Mitacha wrote:
I filed an issue on codecov community forum 
https://community.codecov.io/t/uploading-d-lang-coverage-doesnt-work/1740

So hopefully, someone will look at this.


Bookmarked. Thanks much for taking the time to register on 
their forums, I didn't want to.


Forgot to say. In my case I suspect that this is caused by a 
force push, like here 
https://community.codecov.io/t/force-push-intermittently-leads-to-codecov-not-updating-pr/68/2. But a problem can hide another I might be afected by this one plus the same as you, who knows.


Re: Uploading coverage to Codecov doesn't work

2020-07-14 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 14 July 2020 at 11:05:17 UTC, Mitacha wrote:

On Saturday, 11 July 2020 at 09:43:39 UTC, Basile B. wrote:

On Wednesday, 8 July 2020 at 15:55:58 UTC, Mitacha wrote:
I filed an issue on codecov community forum 
https://community.codecov.io/t/uploading-d-lang-coverage-doesnt-work/1740

So hopefully, someone will look at this.


Bookmarked. Thanks much for taking the time to register on their 
forums, I didn't want to.


Re: Uploading coverage to Codecov doesn't work

2020-07-11 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 8 July 2020 at 15:55:58 UTC, Mitacha wrote:

Hello there,

I've been trying to setup bitbucket pipelines to submit 
coverage to codecov, but with no luck.
I use `dub run -b unittest-cov` and it generates .lst files 
correctly, then `bash <(curl -s https://codecov.io/bash) -t 
$CODECOV_TOKEN` is called, but all I get is:


```
==> Bitbucket detected.
project root: .
Yaml not found, that's ok! Learn more at 
http://docs.codecov.io/docs/codecov-yaml

==> Running gcov in . (disable via -X gcov)
==> Python coveragepy not found
==> Searching for coverage reports in:
+ .
--> No coverage report found.
Please visit http://docs.codecov.io/docs/supported-languages
```
No reports were uploaded.

The thing I'm concerned about is "--> No coverage report 
found.". I checked and token is supplied. I ran same commands 
locally and get same result.


Is there some magic configuration in yaml file necessary, to 
make that work?


It's broken for me too, on gitlab,...

---
GitLab CI detected.
project root: .
--> token set from env
Yaml found at: ./.codecov.yml
==> Running gcov in . (disable via -X gcov)
==> Python coveragepy not found
==> Searching for coverage reports in:
+ .
--> No coverage report found.
Please visit http://docs.codecov.io/docs/supported-languages
---

That used to work perfectly. Note that it's broken for DMD test 
suite too.


Re: Generating struct .init at run time?

2020-07-02 Thread Basile B. via Digitalmars-d-learn

On Thursday, 2 July 2020 at 10:37:27 UTC, kinke wrote:
I don't think a struct should ever be that large, as it can 
probably only live on the heap anyway and only passed around by 
refs. I'd probably use a thin struct instead, containing and 
managing a `double[]` member (or `double[elementCount]*`).


so right but the compiler should definitively not crash.



Re: filter custom version id from __traits code

2020-06-09 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 9 June 2020 at 18:08:01 UTC, Stanislav Blinov wrote:

On Tuesday, 9 June 2020 at 17:40:10 UTC, Basile B. wrote:


Any idea ?


As I replied in the issue report:


Instead of

static if (!is(mixin(member) == module) && 
!(is(mixin(member


use

static if (is(typeof(mixin(member


Yes thanks again for the help.


filter custom version id from __traits code

2020-06-09 Thread Basile B. via Digitalmars-d-learn
I don't see how to filter a custom version identifier from this 
traits code:


---
module test;

import std.traits   : isCallable;
version(all) version = my_version;

private bool onlyFuncs()
{
bool result = true;
foreach (member; __traits(allMembers, mixin(__MODULE__)))
{
static if (!is(mixin(member) == module) && 
!(is(mixin(member
static if (__traits(getOverloads, mixin(__MODULE__), 
member, true).length == 0)

{
pragma(msg, "`", member, "` ", "is not a type or a 
function");

result = false;
break;
}
}
return result;
}
static assert(onlyFuncs(), "this script must hide globals as 
local static variable in a getter");


void main(){}
---


: Error: undefined identifier my_version in module test
onlineapp.d(12): Error: module test.my_version cannot be 
resolved

onlineapp.d(21):called from here: onlyFuncs()
onlineapp.d(21):while evaluating: static


Any idea ?


Re: non-constant expression while initializing two dim array

2020-06-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 June 2020 at 06:37:18 UTC, tirithen wrote:

How can I initialize my two dimensional array?

When I try to run the code below I get the error:

Error: non-constant expression ["user":[cast(Capability)0], 
"administrator":[cast(Capability)1]]


Code:

enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private Capabilities[string] roleCapabilities = [
  "user" : [Capability.self], "administrator" : 
[Capability.administer]

];

I have tried adding more const and immutable prefixes but it 
still gives me the same error. The goal is that 
roleCapabilities should be an immutable/const two dimensional 
array.


What you declare here is not a two dim array it's an associative 
array.
Associative array implementation have limitations. To initialize 
one that doesn't have const expr as key you can use a static 
module constructor:


---
enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private Capabilities[string] roleCapabilities;

static this()
{
roleCapabilities = [
  "user" : [Capability.self], "administrator" : 
[Capability.administer]

];
}
---

which is done at runtime, just before the D main() get executed.

Notes:

1. You can also use a function containing a switch statement 
instead of an assoc array.
2. the other way would work because it would be a static array, 
the enum member giving an integer index:


---
enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private string[Capability.max + 1] roleCapabilities = [
Capability.self : "user",
Capability.administer : "administrator",
];
---

but I suppose that is different.


Re: Dub Error Message "Invalid variable: DUB"

2020-06-07 Thread Basile B. via Digitalmars-d-learn

On Sunday, 7 June 2020 at 12:24:13 UTC, Russel Winder wrote:
On Sun, 2020-06-07 at 10:30 +, Basile B. via 
Digitalmars-d-learn wrote: […]
What is the docker image that you use ?  If it is an older 
version maybe that the $DUB env variable is not yet supported 
by the dub version that's installed (it exists since 2.084.0 
according to [1]).


I am using ubuntu:focal. ubuntu:bionic has ldc 1.8 which is far 
too old. Focal has ldc 1.20.


I think the dub version is 1.19.

I am having to manually symbolically link /usr/bin/gcc and 
/usr/bin/cc so I suspect the installation of focal is not going 
quite right. Especially as I have to manually set a TZ variable 
to avoid a lock up.


In my .gitalab-ci.yml I use 'dlang2/ldc-ubuntu' [2] or 
'dlang2/dmd-ubuntu' [3] which give always recent versions of D.


[1] https://dlang.org/changelog/2.084.0.html
[2] https://hub.docker.com/r/dlang2/ldc-ubuntu
[3] https://hub.docker.com/r/dlang2/dmd-ubuntu


I shall have to investigate these docker images in favour of 
working with a bare Ubuntu.


Yes because that works reasonably well on gitlab.
The only problem is that you might have to setup other things as 
their ubuntu image is very light. Software like zip or even git 
are not there by default.


A simple example of `.gitlab-ci.yml` file to support D is

---
job:
  image: dlang2/dmd-ubuntu
  before_script:
  # tools that are not in their base ubuntu image
  - apt-get update -y
  - apt-get install -y supplemental_package_x
  - apt-get install -y supplemental_package_y
  # similarly to what's done on most of the other CI services
  script:
  - bash some_script.sh
  - dub build
  - dub test
  # - etc.
---


Re: Dub Error Message "Invalid variable: DUB"

2020-06-07 Thread Basile B. via Digitalmars-d-learn

On Sunday, 7 June 2020 at 10:06:14 UTC, Russel Winder wrote:

On Sun, 2020-06-07 at 10:24 +0100, Russel Winder wrote:

Hi,

Why on earth is Dub sending out this error message (Invalid 
variable: DUB)

on
GitLab but not on Travis-CI or locally?

OK, that was slightly rhetorical, more reasonably, why is dub 
sending out

this
message at all?


I am assuming that the error comes from the line:

preBuildCommands "$DUB run --compiler=$$DC unit-threaded -c 
gen_ut_main -- -f generated/ut_dub_main.d -d $DUB"


in the unittest configuration as suggested for using 
unit-threaded. The question is why does the symbol DUB not need 
to be defined locally or on Travis-CI, but only on GitLab?


|> printenv | grep -i dub
|>

On Travis-CI and locally Dub find where it is, why does it not 
do this on GitLab? It is at /usr/bin/dub in all cases.


What is the docker image that you use ?  If it is an older 
version maybe that the $DUB env variable is not yet supported by 
the dub version that's installed (it exists since 2.084.0 
according to [1]).


In my .gitalab-ci.yml I use 'dlang2/ldc-ubuntu' [2] or 
'dlang2/dmd-ubuntu' [3] which give always recent versions of D.


[1] https://dlang.org/changelog/2.084.0.html
[2] https://hub.docker.com/r/dlang2/ldc-ubuntu
[3] https://hub.docker.com/r/dlang2/dmd-ubuntu


Re: Should it compile?

2020-06-06 Thread Basile B. via Digitalmars-d-learn

On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:

Should it compile?

```d
import std.algorithm.mutation;

void main() {
const char a = void;
const char b ='b';
moveEmplace(b, a); // mutation.d: Error: cannot modify 
const expression target

assert(a == 'b');
}
```
I think, it should.


maybe it shouldn't but then with another message, for example

Error, cannot `void` initialize a `const` declaration.

since that makes very little sense, at least as a local variable. 
(as a member, this can be initialized in a constructor)




Re: Fastest way to check using if identifier has already been defined, using static if or similar?

2020-06-03 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 3 June 2020 at 10:24:44 UTC, Simen Kjærås wrote:

On Wednesday, 3 June 2020 at 09:39:34 UTC, Basile B. wrote:

You can use this template:

  enum Exists(alias T) = is(typeof(T));

I don't know if there's a faster way bu this technic is used, 
notatbly in phobos, to workaroud issues of double declaration 
in `static foreach`


enum Exists(alias T) = is(typeof(T));
static assert(!Exists!bar); // undefined identifier bar

--
  Simen


This is because the template parameter must be resolved to a 
valid symbol or type.

This version other version bypass the problem:

---
enum Exists(string s) = is(typeof(mixin(s)));

void main()
{
static if (!Exists!"foo")
int foo;
foo = 42;
}
---


Re: Fastest way to check using if identifier has already been defined, using static if or similar?

2020-06-03 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 3 June 2020 at 09:03:22 UTC, drathier wrote:
I'm generating some code. Some of the generated types need to 
be overridden, so I define them manually at the top of the 
generated file. Then I need to guard against redefining the 
identifier (type/value/function) later on, in the generated 
code.


I'm currently using `static if (!__traits(compiles, thingy)) {` 
to avoid redefining things twice.


Of course the proper fix is to not generate code for the 
identifiers which are already manually defined, and not 
generate any `static if`s at all, but until then, is there a 
faster way than `static if (__traits(compiles, ...` to check if 
a type/value/function has already been defined?


You can use this template:

  enum Exists(alias T) = is(typeof(T));

I don't know if there's a faster way bu this technic is used, 
notatbly in phobos, to workaroud issues of double declaration in 
`static foreach`


Re: Making alias of a struct field needs "this".

2020-06-02 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 09:07:08 UTC, Basile B. wrote:

On Tuesday, 2 June 2020 at 08:56:13 UTC, realhet wrote:

[...]


There's a language rule, expressions cant be aliased, however D 
has a bug, some expressions
that look like type can be aliased, then when you use them you 
have an error about 'this' but in first place here you should 
really have an error saying 'cant alias expression'.


Note that most of the time attempts to alias expressions is 
detected. This is a particular bug, a "corner case".


Re: Making alias of a struct field needs "this".

2020-06-02 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 08:56:13 UTC, realhet wrote:

Hello,

I have a 2 level nested struct structure with nice descriptive 
field names.
And I thought it will be easy to alias those identifierLists 
with a few letter names and do some calculations on them.

But I'm having an error.

struct A{
  struct B{ int c; }
  B b;

  auto f(){
alias d = b.c;
return d;  //Compiler Error: need 'this' for c of type int.
  }
}

There's the this and it's called "b."

Why is this? If I copy paste the aliased expression "b.c", it 
compiled fine.


Thanks in advance!


There's a language rule, expressions cant be aliased, however D 
has a bug, some expressions
that look like type can be aliased, then when you use them you 
have an error about 'this' but in first place here you should 
really have an error saying 'cant alias expression'.


Re: Postblit segfault.

2020-06-02 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 06:34:14 UTC, MaoKo wrote:

On Monday, 1 June 2020 at 19:52:39 UTC, Basile B. wrote:

On Monday, 1 June 2020 at 15:55:45 UTC, H. S. Teoh wrote:
On Mon, Jun 01, 2020 at 03:27:11PM +, Basile B. via 
Digitalmars-d-learn wrote: [...]
Possibly a backend bug (keyword "wrong code"), caused by 
either of [1] or

[2]

[1] https://github.com/dlang/dmd/pull/9357
[2] https://github.com/dlang/dmd/pull/9623/files


Yeah, it looks like a backend bug.  The struct address was 
somehow either not loaded correctly, or not passed correctly 
(didn't look into more detail which case).


A regression should be filed for this, if not already.


T


yeah done. culprit commit confirmed and reduced w/o phobos:

https://issues.dlang.org/show_bug.cgi?id=20890


Ok cool. I hesitate to report an issue because the bug was too 
"simple".

This is a proof that dmd user use the GC a lot :).


Mmmmh I don't follow you, this has nothing to do with the GC. 
It's rather a problem with the backend (i.e the translation to an 
IR andthe generation of byte code)


Anyway someone already pushed a fix so next point release (~1 or 
2 weeks) will not produce invalid code for the case you've found.


Re: Postblit segfault.

2020-06-01 Thread Basile B. via Digitalmars-d-learn

On Monday, 1 June 2020 at 15:55:45 UTC, H. S. Teoh wrote:
On Mon, Jun 01, 2020 at 03:27:11PM +, Basile B. via 
Digitalmars-d-learn wrote: [...]
Possibly a backend bug (keyword "wrong code"), caused by 
either of [1] or

[2]

[1] https://github.com/dlang/dmd/pull/9357
[2] https://github.com/dlang/dmd/pull/9623/files


Yeah, it looks like a backend bug.  The struct address was 
somehow either not loaded correctly, or not passed correctly 
(didn't look into more detail which case).


A regression should be filed for this, if not already.


T


yeah done. culprit commit confirmed and reduced w/o phobos:

https://issues.dlang.org/show_bug.cgi?id=20890


Re: Postblit segfault.

2020-06-01 Thread Basile B. via Digitalmars-d-learn

On Monday, 1 June 2020 at 14:53:43 UTC, H. S. Teoh wrote:
On Mon, Jun 01, 2020 at 01:53:09PM +, Bastiaan Veelo via 
Digitalmars-d-learn wrote:

On Monday, 1 June 2020 at 09:42:44 UTC, Boris Carvajal wrote:
> On Monday, 1 June 2020 at 06:35:36 UTC, MaoKo wrote:
> > Hello, I don't understand why this code segfault on
> 
> Reduced to:
> 
> import std.stdio;
> 
> struct S {}
> 
> void main() {

>   S[1] s;
>   writeln(s);
> }

This used to work up to dmd 2.084.1. It fails since 2.085.1. 
Please file a regression report at 
https://issues.dlang.org/enter_bug.cgi?product=D

[...]

Tracked the segfault to Phobos, writeUpToNextSpec():

1216if (trailing[i] != '%') continue;

Apparently `trailing` has an invalid pointer.


T


Possibly a backend bug (keyword "wrong code"), caused by either 
of [1] or [2]


[1] https://github.com/dlang/dmd/pull/9357
[2] https://github.com/dlang/dmd/pull/9623/files


Re: redirect std out to a string?

2020-05-21 Thread Basile B. via Digitalmars-d-learn

On Thursday, 21 May 2020 at 04:29:30 UTC, Kaitlyn Emmons wrote:
is there a way to redirect std out to a string or a buffer 
without using a temp file?


yes:

---
#!dmd -betterC
module runnable;

extern(C) int main()
{
import core.sys.posix.stdio : fclose, stdout, fmemopen, 
printf, fflush;

import core.stdc.stdlib : malloc;

char* buff;
enum s = "this will use a buffer from the heap that has, " ~
 "just like a file, a FD thanks to fmemopen()";

fclose(stdout);
buff = cast(char*) malloc(4096);
buff[0..4096] = '\0';
stdout = fmemopen(buff, 4096, "wr+");
printf(s);
fflush(stdout);
assert(buff[0..s.length] == s);
return 0;
}
---

something similar should be possible using mmap().


Re: Template type deduction question

2020-05-21 Thread Basile B. via Digitalmars-d-learn

On Thursday, 21 May 2020 at 07:16:11 UTC, Basile B. wrote:

On Thursday, 21 May 2020 at 04:46:02 UTC, data pulverizer wrote:

I'd like to pass kernel functions using:

```
auto calculateKernelMatrix(K, T)(K!(T) Kernel, Matrix!(T) data)
{
  ...
}

```

and call it using `calculateKernelMatrix(myKernel, myData);` 
but I get a type deduction error and have to call it using 
`calculateKernelMatrix!(typeof(myKernel), float)(myKernel, 
myData);`


How do I resolve this?


The problem is that "K" is a template type parameter [1].
When the compiler deduces the parameter that ends up with a 
symbol, i.e not a type.
To permit a symbol to be deduced you can use a template alias 
parameter[2] instead:


---
struct Matrix(T) {}
struct Kernel(T) {}

void calculateKernelMatrix(alias K, T)(K!T kernel, Matrix!T 
data) { }


void main()
{
Matrix!float m;
Kernel!float k;
calculateKernelMatrix(k,m); // OK
}
---

However I think that there could be an useful error message, as 
the current one is of no usefulness. Note that maybe that under 
the hood there's one but the compiler uses a system of gagging 
when trying uncertain operations, so that other things can be 
tried, in case of failure.


[1] 
https://dlang.org/spec/template.html#template_type_parameters

[2] https://dlang.org/spec/template.html#aliasparameters


I've found that even with a template constraint the diagnostic is 
sub-optimal, see issue  20851 [1].


[1] https://issues.dlang.org/show_bug.cgi?id=20851


Re: Template type deduction question

2020-05-21 Thread Basile B. via Digitalmars-d-learn

On Thursday, 21 May 2020 at 04:46:02 UTC, data pulverizer wrote:

I'd like to pass kernel functions using:

```
auto calculateKernelMatrix(K, T)(K!(T) Kernel, Matrix!(T) data)
{
  ...
}

```

and call it using `calculateKernelMatrix(myKernel, myData);` 
but I get a type deduction error and have to call it using 
`calculateKernelMatrix!(typeof(myKernel), float)(myKernel, 
myData);`


How do I resolve this?


The problem is that "K" is a template type parameter [1].
When the compiler deduces the parameter that ends up with a 
symbol, i.e not a type.
To permit a symbol to be deduced you can use a template alias 
parameter[2] instead:


---
struct Matrix(T) {}
struct Kernel(T) {}

void calculateKernelMatrix(alias K, T)(K!T kernel, Matrix!T data) 
{ }


void main()
{
Matrix!float m;
Kernel!float k;
calculateKernelMatrix(k,m); // OK
}
---

However I think that there could be an useful error message, as 
the current one is of no usefulness. Note that maybe that under 
the hood there's one but the compiler uses a system of gagging 
when trying uncertain operations, so that other things can be 
tried, in case of failure.


[1] https://dlang.org/spec/template.html#template_type_parameters
[2] https://dlang.org/spec/template.html#aliasparameters




Re: GUI library for DMD 2.090 or DMD 2.091

2020-04-24 Thread Basile B. via Digitalmars-d-learn

On Friday, 24 April 2020 at 13:45:22 UTC, Phrozen wrote:
I'm too new to DLang and I have a lot to learn. Probably that's 
why I have a lot of difficulties. Has anyone tried using a GUI 
library to the latest DMD 2.090 or DMD 2.091? I plan to use 
this language for a specific Thermal calculator application for 
Windows, but for two days I've been struggling with dub and 
elementary examples in GUI libraries. I need something simple - 
a modal window with 3 buttons and a two text boxes. So far I 
have tested DWT, TKD, DFL, dlangui without success.
Can anyone help me with advice or some more recent tutorial. 
Thank you!


you also have GTK-D[1], and you have up to date sources to 
learn[2] it.


[1] https://code.dlang.org/packages/gtk-d
[2] https://gtkdcoding.com/


Re: How to use import std.algorithm.iteration.permutations?

2020-04-19 Thread Basile B. via Digitalmars-d-learn

On Sunday, 19 April 2020 at 20:25:23 UTC, Basile B. wrote:

On Sunday, 19 April 2020 at 17:57:21 UTC, David Zaragoza wrote:

[...]


`permutation()` returns a lazy range (i.e an iterator). To turn 
a permutation into a concrete data type use .array on each one.


---
void test(int[] array){}

void main()
{
int[] a = [1,1,2,2,3,3];
foreach (p; a.permutations)
{
test(p.array);
}
}
---


forgot to put the imports:

---
import std.algorithm.iteration, std.array;
---


Re: How to use import std.algorithm.iteration.permutations?

2020-04-19 Thread Basile B. via Digitalmars-d-learn

On Sunday, 19 April 2020 at 17:57:21 UTC, David Zaragoza wrote:

Hi

When I try to build the following:

import std.algorithm.iteration;

void test(int[] array);

void main()
{
int[] a = [1,1,2,2,3,3];
foreach (p; a.permutations)
{
test(p);
}
}

I get the error:

.\permutations_example.d(10): Error: function 
permutations_example.test(int[] array) is not callable using 
argument types (Indexed!(int[], ulong[]))
.\permutations_example.d(10):cannot pass argument p of 
type Indexed!(int[], ulong[]) to parameter int[] array


What's the proper way to obtain the array of permutations of a?

Kind regards
David


`permutation()` returns a lazy range (i.e an iterator). To turn a 
permutation into a concrete data type use .array on each one.


---
void test(int[] array){}

void main()
{
int[] a = [1,1,2,2,3,3];
foreach (p; a.permutations)
{
test(p.array);
}
}
---


Why Pegged action dont not work in this case ?

2020-04-19 Thread Basile B. via Digitalmars-d-learn
I 've started experimenting Pegged action. Quickly i got blocked 
by this problem. The start action works where I use the rule but 
not directly in the rule. Test program:


gdb_commander.d:
---
/+dub.sdl:
dependency "pegged" version="~>0.4.4"
versions "dub_run"
+/
module gdb_commander;

import core.stdc.string, std.json;
import pegged.grammar, pegged.peg;

enum gdbMiOutput = `GdbmiOutput:

Output  < OutOfBandRecord* ResultRecord? '(gdb)' 
#HERE before ResRec OK
ResultRecord< {beginResultRecord} Token? '^' ResultClass 
(',' Result)* {endResultRecord}

OutOfBandRecord < AsyncRecord
/ StreamRecord
AsyncRecord < ExecAsyncOutput
/ StatusAsyncOutput
/ NotifyAsyncOutput
ExecAsyncOutput < Token? '*' AsyncOutput
StatusAsyncOutput   < Token? '+' AsyncOutput
NotifyAsyncOutput   < Token? '=' AsyncOutput
AsyncOutput < AsyncClass ( ',' Result )*
ResultClass < 'done'
/ 'running'
/ 'connected'
/ 'error'
/ 'exit'
AsyncClass  < 'stopped'
Result  < Variable '=' Value
Variable< String
Value   < Const / Object / List
Const   < CString
Object  < '{}'
/ '{' Result ( ',' Result )* '}'
List< '[]'
/ '[' Value ( ',' Value )* ']'
/ '[' Result ( ',' Result )* ']'
StreamRecord< ConsoleStreamOutput
/ TargetStreamOutput
/ LogStreamOutput
ConsoleStreamOutput < '~' CString
TargetStreamOutput  < '@' CString
LogStreamOutput < '&' CString
Token   <~ [a-zA-Z_][a-zA-Z0-9_]*
CString <~ "\"" (EscapedQuotes / (!"\"" .) )* :"\""
EscapedQuotes   <~ backslash doublequote
String  <~ [a-zA-Z0-9_\-]*`;

T beginResultRecord(T)(T t)
{
import std.stdio;
writeln(__PRETTY_FUNCTION__);
return t;
}

T endResultRecord(T)(T t)
{
import std.stdio;
writeln(t);
return t;
}

mixin(grammar(gdbMiOutput));

version(dub_run)
{
import std.stdio, std.path, std.file, std.process;
import pegged.tohtml;

enum testString01 = `^done,path="/usr/bin"
(gdb)`;
enum testString02 = `^done,threads=[
{id="2",target-id="Thread 0xb7e14b90 (LWP 21257)",
frame={level="0",addr="0xe410",func="__kernel_vsyscall",
args=[]},state="running"},
{id="1",target-id="Thread 0xb7e156b0 (LWP 21254)",
frame={level="0",addr="0x0804891f",func="foo",
args=[{name="i",value="10"}],

file="/tmp/a.c",fullname="/tmp/a.c",line="158",arch="i386:x86_64"},

state="running"}],
current-thread-id="1"
(gdb)`;
enum testString03 = `^done,new-thread-id="3",
frame={level="0",func="vprintf",
args=[{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""},

{name="arg",value="0x2"}],file="vprintf.c",line="31",arch="i386:x86_64"}

(gdb)`;

void exportHTMLandBrowse(T)(auto ref T tree, string name)
{
string fname = __FILE_FULL_PATH__.dirName ~ "/" ~ name ~ 
".html";

if (fname.exists)
remove(fname);
toHTML(tree, fname);
browse(fname);
}

void main()
{
GdbmiOutput(testString01).exportHTMLandBrowse("t1");
GdbmiOutput(testString02).exportHTMLandBrowse("t2");
GdbmiOutput(testString03).exportHTMLandBrowse("t3");
}
}
---

---
$ dub gdb_commander.d
---

Also I'd like to report that actions dont work with partially 
specialized templates:


---
T handleResultRecord(bool end,  T)(T t);
// then you use handleResultRecord!true and 
handleResultRecord!false in the PEG.

---


Re: Can a lib file converted to 1 ob file?

2020-04-19 Thread Basile B. via Digitalmars-d-learn

On Sunday, 19 April 2020 at 11:33:15 UTC, Andre Pany wrote:

On Sunday, 19 April 2020 at 10:53:09 UTC, Basile B. wrote:

On Sunday, 19 April 2020 at 10:48:04 UTC, Basile B. wrote:
This should work if you pass the static library files to the 
linker. It is exactly its job to select what's used from the 
archive. So you would have to pass your stuff and optionally 
phobos2 as a static library (but this would also work if 
linking against phobos2.dll)


BTW I have an example here [1], but it's for FreePascal and 
under linux, and in the end i've decided to use dynamic 
library (but with static linking) [2]


[1] https://gitlab.com/basile.b/link-with-d
[2] https://gitlab.com/basile.b/dexed/-/merge_requests/6


The only thing I found so far is, Delphi does not support 
linking .lib files.

(Mac os 64 bit compiler though seems to support it).

I understand from you, that FreePascal is able to link .lib 
files.


Was my impression false and I can link .lib files with Delphi?


No (sorry for the false hope) I also find this (‑‑linker-option 
for iOS only).

Very surprising.

Looks like you would have to use a dll. Note that with static 
linking of the dll


  cdecl; external 'mydll';

You don't have to use a loader.


Re: Can a lib file converted to 1 ob file?

2020-04-19 Thread Basile B. via Digitalmars-d-learn

On Sunday, 19 April 2020 at 10:48:04 UTC, Basile B. wrote:
This should work if you pass the static library files to the 
linker. It is exactly its job to select what's used from the 
archive. So you would have to pass your stuff and optionally 
phobos2 as a static library (but this would also work if 
linking against phobos2.dll)


BTW I have an example here [1], but it's for FreePascal and under 
linux, and in the end i've decided to use dynamic library (but 
with static linking) [2]


[1] https://gitlab.com/basile.b/link-with-d
[2] https://gitlab.com/basile.b/dexed/-/merge_requests/6




Re: Can a lib file converted to 1 ob file?

2020-04-19 Thread Basile B. via Digitalmars-d-learn

On Sunday, 19 April 2020 at 07:50:13 UTC, Andre Pany wrote:

Hi,

My understanding is, a lib file is a collection of multiple obj 
files.


This is exact.

From a delphi app I want to call D coding without using a dll. 
Delphi does not know the concept of lib files but can link obj 
files.


Linking all single obj files of DRuntime, phobos and my library 
might be possible but I wonder whether there is a better way.


Therefore the question, if I have a d lib file which contains 
all the obj files of DRuntime, phobos and my custom code, is it 
possible to convert it to exactly 1 obj file?


Or must 1 obj file correspond to exactly 1 d module?

Kind regards
Andre


This should work if you pass the static library files to the 
linker. It is exactly its job to select what's used from the 
archive. So you would have to pass your stuff and optionally 
phobos2 as a static library (but this would also work if linking 
against phobos2.dll)


Re: mir: How to change iterator?

2020-04-16 Thread Basile B. via Digitalmars-d-learn

On Thursday, 16 April 2020 at 19:56:21 UTC, Basile B. wrote:

On Tuesday, 14 April 2020 at 20:24:05 UTC, jmh530 wrote:

[...]


`approxEqual` cant work with ranges. If you look at the 
signature there is a use of the constructor syntax, e.g const 
`T maxRelDiff = T(0x1p-20f)` so when `T` is not a basic FP type 
that just does not compile (note the error message if you try 
with .array on both operands)


I'd just use zip(...).each!(...), e.g

assert(zip(y, [2.5, 2.5].sliced(2)).each!(a => 
assert(approxEqual(a[0], a[1];


And remove the extra assert() BTW... I don't know why this is 
accepted.


Re: mir: How to change iterator?

2020-04-16 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 14 April 2020 at 20:24:05 UTC, jmh530 wrote:
In the code below, I multiply some slice by 5 and then check 
whether it equals another slice. This fails for mir's 
approxEqual because the two are not the same types (yes, I know 
that isClose in std.math works). I was trying to convert the y 
variable below to have the same double* iterator as the term on 
the right, but without much success. I tried std.conv.to and 
the as, slice, and sliced functions in mir.


I figure I am missing something basic, but I can't quite figure 
it out...



/+dub.sdl:
dependency "mir-algorithm" version="~>3.7.28"
+/

import mir.math.common: approxEqual;
import mir.ndslice.slice : sliced;

void main() {
auto x = [0.5, 0.5].sliced(2);
auto y = x * 5.0;

assert(approxEqual(y, [2.5, 2.5].sliced(2)));
}


`approxEqual` cant work with ranges. If you look at the signature 
there is a use of the constructor syntax, e.g const `T maxRelDiff 
= T(0x1p-20f)` so when `T` is not a basic FP type that just does 
not compile (note the error message if you try with .array on 
both operands)


I'd just use zip(...).each!(...), e.g

assert(zip(y, [2.5, 2.5].sliced(2)).each!(a => 
assert(approxEqual(a[0], a[1];


But I don't know MIR at all.


Re: __init unresolved external when using C library structs converted with dstep

2020-04-16 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 14 April 2020 at 17:51:58 UTC, Robert M. Münch wrote:
I use a C libary and created D imports with dstep. It 
translates the C structs to D structs.


When I now use them, everything compiles fine but I get an 
unresolved external error:


WindowsApp1.obj : error LNK2019: unresolved external symbol 
"myCstruct.__init" (_D7myCStruct6__initZ) referenced in 
function _Dmain


Any idea what this is about and how to fix it? I'm wondering 
why D tries to find the __init function in the C library and 
not compile it from the import.


One way to prevent the problem is to do void initialization each 
time you declare a variable of this type.


Re: How can I fully include "libdruntime-ldc.a" and "libphobos2-ldc.a" in my .so lib ?

2020-04-16 Thread Basile B. via Digitalmars-d-learn

On Thursday, 16 April 2020 at 12:45:21 UTC, kinke wrote:

On Thursday, 16 April 2020 at 10:04:54 UTC, Basile B. wrote:

Just got it to work using

  "libs" : [
"druntime-ldc",
"phobos2-ldc"
  ]


$ ldc2 -help | grep -- -link-defaultlib-shared
  --link-defaultlib-shared   - Link with shared 
versions of default libraries. Defaults to true when generating 
a shared library (-shared).
Boolean options can take an optional value, e.g., 
-link-defaultlib-shared=.


Thanks. The first solution was not working acutally, got SIGABRT 
when running


Re: How can I fully include "libdruntime-ldc.a" and "libphobos2-ldc.a" in my .so lib ?

2020-04-16 Thread Basile B. via Digitalmars-d-learn

On Thursday, 16 April 2020 at 09:48:21 UTC, Basile B. wrote:

My dub recipe includes this

  "dflags" : [
"bin/libdruntime-ldc.a",
"bin/libphobos2-ldc.a"
  ]

so that ideally I'll get everything in the library but this 
does not work. For example rt_init and rt_term are no visible 
in the exports


  $ nm -D libdexed-d.so | grep rt_init
  $

and the project that uses the library does not link anyway, 
unless I instruct LD to use libdruntime-ldc.so.


Just got it to work using

  "libs" : [
"druntime-ldc",
"phobos2-ldc"
  ]

instead of what was in the original question.


How can I fully include "libdruntime-ldc.a" and "libphobos2-ldc.a" in my .so lib ?

2020-04-16 Thread Basile B. via Digitalmars-d-learn

My dub recipe includes this

  "dflags" : [
"bin/libdruntime-ldc.a",
"bin/libphobos2-ldc.a"
  ]

so that ideally I'll get everything in the library but this does 
not work. For example rt_init and rt_term are no visible in the 
exports


  $ nm -D libdexed-d.so | grep rt_init
  $

and the project that uses the library does not link anyway, 
unless I instruct LD to use libdruntime-ldc.so.


Re: Can I use Dlang in Qt5 instead C++ for develop Android Apps?

2020-04-14 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 14 April 2020 at 09:27:35 UTC, Basile B. wrote:

On Tuesday, 14 April 2020 at 01:50:22 UTC, evilrat wrote:

On Monday, 13 April 2020 at 21:01:50 UTC, Baby Beaker wrote:
I want develop Android apps using Qt5. But C++ is very hard. 
I want to use Dlang becouse Dlang is very easy.


In theory nothing stops you from doing that. In practice 
however you have to deal with C++ anyway, how API matches ABI, 
and many more low level underlying things. You also need to 
know how your OS works.
Don't forget that you have to know the tools as well, dealing 
with Android means you will have to do cross-compilation. Must 
know how to use compilers, linkers and debuggers, and shell 
scripts as well as bonus.
Oh and don't forget that you have to make bindings to 
interface these 2 domains, and that requires knowledge of both 
D and C++.


So if you're too brave yet go ahead and try.


There was some Qt attempts such as this one 
https://code.dlang.org/packages/qte5
But since the last release was in 2016 it is probably no 
longer compiles, and I have no idea if it supports Android.


I agree. I think ABI compliance is an easy step but one will 
have to take care to memory managment, that's the big thing OMO,


IMO ʕ •`ᴥ•´ʔ



Re: Can I use Dlang in Qt5 instead C++ for develop Android Apps?

2020-04-14 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 14 April 2020 at 01:50:22 UTC, evilrat wrote:

On Monday, 13 April 2020 at 21:01:50 UTC, Baby Beaker wrote:
I want develop Android apps using Qt5. But C++ is very hard. I 
want to use Dlang becouse Dlang is very easy.


In theory nothing stops you from doing that. In practice 
however you have to deal with C++ anyway, how API matches ABI, 
and many more low level underlying things. You also need to 
know how your OS works.
Don't forget that you have to know the tools as well, dealing 
with Android means you will have to do cross-compilation. Must 
know how to use compilers, linkers and debuggers, and shell 
scripts as well as bonus.
Oh and don't forget that you have to make bindings to interface 
these 2 domains, and that requires knowledge of both D and C++.


So if you're too brave yet go ahead and try.


There was some Qt attempts such as this one 
https://code.dlang.org/packages/qte5
But since the last release was in 2016 it is probably no longer 
compiles, and I have no idea if it supports Android.


I agree. I think ABI compliance is an easy step but one will have 
to take care to memory managment, that's the big thing OMO, i.e 
"this thing is allocated in C++ so it must not me mutated by D" 
or "this thing is allocated by D so it must not be mutated by 
C++".


Re: Get symbols (and/or UDAs) of subclass from superclass

2020-03-15 Thread Basile B. via Digitalmars-d-learn

On Sunday, 15 March 2020 at 20:18:03 UTC, James Blachly wrote:
I would like to programmatically retrieve members of a subclass 
to create a self-documenting interface. I am afraid that my 
approach is not possible due to need for compile time __traits 
/ std.traits, and runtime typeinfo. My proposed approach is as 
follows:


class Base
{
string whatever;

string toString()
{
// loop over __traits(allMembers, typeof(this)) or 
getSymbolsByUDA, etc.

}
}

/// There may be a dozen Derived classes
class Derived1 : Base
{
@Config("a name", "a description")
float probability;
}
class Derived2 : Base
{
@Config("another", "more description")
int replicates;
}
...

Unfortunately, I am afraid this doesn't look possible because 
of the need for compile-time UDAs and runtime TypeInfo. Is 
there a way to do this without re-implementing toString in 
every single derived class? I expect there to be many derived 
classes.


Other ideas welcomed, as I usually write C-style D and am only 
recently taking a stab at OO Inheritance features.


Thanks in advance.
James


A few years ago I've been faced to a similar problem and I ended 
up by using an array, defined in the base class which was filled 
by "hybdrid" runtime/compile-time reflection (explanations about 
this come later).


In each derived class the constructor performed reflection, using 
__traits(derivedMembers) + UDA filtering and the array from the 
base class received the new stuff...


More concrectly:

---
class Base
{
Stuff[] stuff;
}

/// There may be a dozen Derived classes
class Derived1 : Base
{
@Config("a name", "a description")
float probability;

this()
{
foreach(dm; __traits(derivedMembers, this))
{ /* UDA filtering, then add to stuff*/ }
}

}
class Derived2 : Base
{
@Config("another", "more description")
int replicates;

this()
{
foreach(dm; __traits(derivedMembers, this))
{ /* UDA filtering, then add to stuff*/ }
}
}
---

This worked and would work for you but you'll be faced to several 
issues, for example the most obvious is what is the type of 
Stuff...


Another, less immediate, is that because of overridden methods 
some already existing entries in the array of Stuff may have to 
be replaced.


Oterwise the thing to get here is that altough you use 
compile-time reflection, the reflection code is only executed at 
runtime, to fill the array of Stuff.


Re: Cool name for Dub packages?

2020-03-07 Thread Basile B. via Digitalmars-d-learn

On Saturday, 7 March 2020 at 10:49:24 UTC, Paolo Invernizzi wrote:

On Saturday, 7 March 2020 at 09:31:27 UTC, JN wrote:

Do we have any cool name for Dub packages?


tapes.



Rust has 'crates'
Crystal has 'shards'
Python has 'wheels'
Ruby has 'gems'


Frankly, I simply hate all that shuffle around names ... it's 
so difficult to understand people when it's referring to them 
...we already had to remember a gazillion on things, including 
horrible ubuntu names instead of simple numbers! :-)


That's something else, it's more related to the internal codename.
Very common for Operating systems. I've seen usage for other 
software.

Often they are forgotten quickly.



Packages are ... well packages!

:-P

/P





Re: DMD: Is it possible change compile time errors to runtime errors in Dlang?

2020-03-06 Thread Basile B. via Digitalmars-d-learn

On Friday, 6 March 2020 at 04:56:28 UTC, Marcone wrote:
Is it possible change compile time errors to runtime errors in 
Dlang?


no


If yes, how can I make it?


if you deactivate all the errors emitted during the semantic then 
there are very good chance that the compiler crashes while 
generating code.


Re: Idiomatic way to express errors without resorting to exceptions

2020-02-29 Thread Basile B. via Digitalmars-d-learn

On Saturday, 29 February 2020 at 12:50:59 UTC, Adnan wrote:
I have a struct that has to arrays. Each of those must have the 
same sizes.


So while constructing the array, if you pass two arrays of 
different sizes the constructor must return nothing.


In Rust I could easily use Option. D has no answer to 
Optional types as far as I am concerned. Is throwing exceptions 
the only idiomatic way?



---

What I already considered:

* Using Nullable!T: Okay but Nullable!T has all the overloads 
for regular T which makes the  API even more unpredictable.


In Rust you don't just add a Some(44) and 34; No overloads for 
Some and i32 are allowed (purposefully).


* Option!T from the optional package: Has even worse problem 
IMO. Not only it allows None + int but also it returns a `[]`. 
This API is not to my liking. You could say well Haskell has 
fmap for Optional etc, and I am aware of that, so does Rust 
with map etc. But I am talking about basic things: like `+`.


* Value-based error handling like Go and C: well, that works 
but the error checking is opt-in. There's no such thing as 
[[nodiscard]] in D too so the user of the API might as well 
forget to check for error value.


* if specialization: Clever workaround but sometimes the struct 
may fail for complex reasons, not only for a single condition.


There's no idiomatic way since D lang is based on exceptions...

However I'd use one of those system:

1. return error, write result in ref parameter.

alias CheckedValueProto(RT, P...) = bool function(ref RT, P 
params);


2. the same using a special struct and no more ref param. So more 
like Nullable/Optional but with a dedicated generic type that 
contain a single opover used to indicate if there's been an error 
or not.


struct CheckedValue(T) {
bool noError;
T t;
B opCast(B : bool)() inout pure nothrow @safe {
return noError;
}
}

and you make your functions to return CheckedValues...

CheckedValue!int strToInt(string input);

if (const CheckedValue!int = strToInt("a") {} else {}

Although
- both still require self-discpline or a specialized linter to 
detect unchecked calls ;

- the whole standard library is incompatible ;

I have a personal preference for 2. even if it causes problems 
when T is of same size as a pointer. Now the question is also 
what's the more costly ? try/catch or this non atomic return ?


Re: Should getSymbolsByUDA work with member variables?

2020-02-28 Thread Basile B. via Digitalmars-d-learn

On Friday, 28 February 2020 at 18:34:08 UTC, cc wrote:

This compiles:

class Foo {
int x;
@(1) void y() {}
this() {
static foreach (idx, field; getSymbolsByUDA!(Foo, 1)) {
}
}
}

This does not:

class Foo {
@(1) int x;
void y() {}
this() {
static foreach (idx, field; getSymbolsByUDA!(Foo, 1)) {
}
}
}

Error: value of `this` is not known at compile time

Is there an equivalent for getSymbolsByUDA for member 
variables, or is this a bug?


I dont see a bug, the error message is correct.
I'd say that you have two options:

1. drop the `static` before `foreach`, for example to use the 
symbols during run-time

2. to do metaprog adopt another style of loop, e.g

class Foo {
@(1) int x;
void y() {}
this() {
alias AtOne = getSymbolsByUDA!(Foo, 1);
static foreach (i; 0 .. AtOne.length) {
pragma(msg, __traits(identifier, AtOne[i]));
}
}
}


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-28 Thread Basile B. via Digitalmars-d-learn
On Thursday, 27 February 2020 at 21:46:08 UTC, Bruce Carneal 
wrote:

On Thursday, 27 February 2020 at 19:46:23 UTC, Basile B. wrote:

[...]


The code below is the test jig that I'm using currently.  It is 
adopted from yours but has added the -d=distribution command 
line option.


[...]


Yes I finally can see the branchless version beating the original 
with -dedig.

Thanks for your time.


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-27 Thread Basile B. via Digitalmars-d-learn
On Thursday, 27 February 2020 at 17:17:32 UTC, Bruce Carneal 
wrote:

On Thursday, 27 February 2020 at 17:11:48 UTC, Basile B. wrote:
On Thursday, 27 February 2020 at 15:29:02 UTC, Bruce Carneal 
wrote:
On Thursday, 27 February 2020 at 08:52:09 UTC, Basile B. 
wrote:
I will post my code if there is any meaningful difference in 
your subsequent results.


give me something I can compile and verify. I'm not there to 
steal, if you found something you can still propose it to the 
repos that would take advantage of the optim.


I'm not at all concerned about theft of trivial code.  I am 
concerned that a simple error in my code will live on in a 
copy/paste environment.


Regardless, I'll post the code once I get home.  It may be the 
only way to communicate the central problem as I see it: 
imprecision in the test specification (the input specification).


Yes please, post the benchmark method. You see the benchmarks I 
run with your version are always slowest. I'm aware that rndGen 
(and generaly any uniform rnd func) is subject to a bias but I 
dont thing this bias maters much in the case we talk about.


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-27 Thread Basile B. via Digitalmars-d-learn
On Thursday, 27 February 2020 at 15:29:02 UTC, Bruce Carneal 
wrote:

On Thursday, 27 February 2020 at 08:52:09 UTC, Basile B. wrote:
I will post my code if there is any meaningful difference in 
your subsequent results.


give me something I can compile and verify. I'm not there to 
steal, if you found something you can still propose it to the 
repos that would take advantage of the optim.


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-27 Thread Basile B. via Digitalmars-d-learn

On Thursday, 27 February 2020 at 14:12:35 UTC, Basile B. wrote:

On Wednesday, 26 February 2020 at 22:07:30 UTC, Johan wrote:
On Wednesday, 26 February 2020 at 00:50:35 UTC, Basile B. 
wrote:

[...]


Hi Basile,
  I recently saw this presentation: 
https://www.youtube.com/watch?v=Czr5dBfs72U


Andrei made a talk about this too a few years ago.

It has some ideas that may help you make sure your 
measurements are good and may give you ideas to find the 
performance bottleneck or where to optimize.
llvm-mca is featured on godbolt.org: 
https://mca.godbolt.org/z/YWp3yv


cheers,
  Johan


https://www.youtube.com/watch?v=Qq_WaiwzOtI


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-27 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 26 February 2020 at 22:07:30 UTC, Johan wrote:

On Wednesday, 26 February 2020 at 00:50:35 UTC, Basile B. wrote:

[...]


Hi Basile,
  I recently saw this presentation: 
https://www.youtube.com/watch?v=Czr5dBfs72U


Andrei made a talk about this too a few years ago.

It has some ideas that may help you make sure your measurements 
are good and may give you ideas to find the performance 
bottleneck or where to optimize.
llvm-mca is featured on godbolt.org: 
https://mca.godbolt.org/z/YWp3yv


cheers,
  Johan




Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-27 Thread Basile B. via Digitalmars-d-learn

On Thursday, 27 February 2020 at 09:41:20 UTC, Basile B. wrote:
On Thursday, 27 February 2020 at 09:33:28 UTC, Dennis Cote 
wrote:

[...]


Sorry but no. I think that you have missed how this has changed 
since the first message.
1. the way it was tested initially was wrong because LLVM was 
optimizing some stuff in some tests and not others, due to 
literals constants.
2. Apparently there would be a branchless version that's fast 
when testing with unbiased input (to be verified)


this version is:

---
ubyte decimalLength9_4(const uint v) pure nothrow
{
return 1 +  (v >= 10) +
(v >= 100) +
(v >= 1000) +
(v >= 1) +
(v >= 10) +
(v >= 100) +
(v >= 1000) +
(v >= 1) ;
}
---

but i cannot see the improvment when use time on the test 
program and 1 calls feeded with a random number.


see 
https://forum.dlang.org/post/ctidwrnxvwwkouprj...@forum.dlang.org for the latest evolution of the discussion.


maybe just add you version to the test program and run

time ./declen -c1 -f0 -s137 // original
time ./declen -c1 -f4 -s137 // the 100% branchless
time ./declen -c1 -f5 -s137 // the LUT + branchless for 
the bit num that need attention

time ./declen -c1 -f6 -s137 // assumed to be your version

to see if it beats the original. Thing is that i cannot do it 
right now but otherwise will try tomorrow.


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-27 Thread Basile B. via Digitalmars-d-learn

On Thursday, 27 February 2020 at 09:33:28 UTC, Dennis Cote wrote:

On Wednesday, 26 February 2020 at 00:50:35 UTC, Basile B. wrote:
So after reading the translation of RYU I was interested too 
see if the decimalLength() function can be written to be 
faster, as it cascades up to 8 CMP.


Perhaps you could try something like this.


int decimalDigitLength(ulong n) {
if (n < 1)
if (n < 100)
return n < 10 ? 1 : 2;
else
return n < 1000 ? 3 : 4;
else
if (n < 1)
if (n < 100)
return n < 10 ? 5 : 6;
else
return n < 1000 ? 7 : 8;
else
if (n < 1)
if (n < 100)
return n < 10 ? 9 : 10;
else
return n < 1000 ? 11 : 12;
else
if (n < 1)
if (n < 100)
return n < 10 ? 13 
: 14;
else
return n < 1000 ? 
15 : 16;
else
if (n < 100)
return n < 10 ? 
17 : 18;
else
return n < 1000 
? 19 : 20;
}   


This uses at most 6 compares for any 64 bit number and only 3 
for the most common small numbers less than 1.


I was glad to see that with ldc at run.dlang.io using the -O3 
optimization I could change the function signature to match 
yours and the compiler eliminated all the unreachable dead code 
for larger values. The compiler produced the following assembler



	.section	.text.ubyte 
onlineapp.decimalLength9(uint),"axG",@progbits,ubyte 
onlineapp.decimalLength9(uint),comdat

.globl  ubyte onlineapp.decimalLength9(uint)
.p2align4, 0x90
.type   ubyte onlineapp.decimalLength9(uint),@function
ubyte onlineapp.decimalLength9(uint):
.cfi_startproc
cmpl$, %edi
ja  .LBB1_5
cmpl$99, %edi
ja  .LBB1_4
cmpl$10, %edi
movb$2, %al
sbbb$0, %al
retq
.LBB1_5:
cmpl$, %edi
ja  .LBB1_9
cmpl$99, %edi
ja  .LBB1_8
cmpl$10, %edi
movb$6, %al
sbbb$0, %al
retq
.LBB1_4:
cmpl$1000, %edi
movb$4, %al
sbbb$0, %al
retq
.LBB1_9:
cmpl$10, %edi
movb$10, %al
sbbb$0, %al
retq
.LBB1_8:
cmpl$1000, %edi
movb$8, %al
sbbb$0, %al
retq
.Lfunc_end1:
	.size	ubyte onlineapp.decimalLength9(uint), .Lfunc_end1-ubyte 
onlineapp.decimalLength9(uint)

.cfi_endproc


for the same body with signature ubyte decimalLength9(uint n).

This may be faster than your sequential comparison function 
depending upon the distribution of numbers. In real 
applications, small numbers are far more common so the reduced 
number of compares for those values should be beneficial in 
most cases.


Sorry but no. I think that you have missed how this has changed 
since the first message.
1. the way it was tested initially was wrong because LLVM was 
optimizing some stuff in some tests and not others, due to 
literals constants.
2. Apparently there would be a branchless version that's fast 
when testing with unbiased input (to be verified)


this version is:

---
ubyte decimalLength9_4(const uint v) pure nothrow
{
return 1 +  (v >= 10) +
(v >= 100) +
(v >= 1000) +
(v >= 1) +
(v >= 10) +
(v >= 100) +
(v >= 1000) +
(v >= 1) ;
}
---

but i cannot see the improvment when use time on the test program 
and 1 calls feeded with a random number.


see 
https://forum.dlang.org/post/ctidwrnxvwwkouprj...@forum.dlang.org 
for the latest evolution of the discussion.


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-27 Thread Basile B. via Digitalmars-d-learn

On Thursday, 27 February 2020 at 04:44:56 UTC, Basile B. wrote:
On Thursday, 27 February 2020 at 03:58:15 UTC, Bruce Carneal 
wrote:


Maybe you talked about another implementation of 
decimalLength9 ?


Yes.  It's one I wrote after I saw your post. Psuedo-code here:

  auto d9_branchless(uint v) { return 1 + (v >= 10) + (v >= 
100) ... }


Using ldc to target an x86 with the above yields a series of 
cmpl, seta instruction pairs in the function body followed by 
a summing and a return.  No branching.


Let me know if the above is unclear or insufficient.


No thanks, it's crystal clear now.


although I don't see the performance gain. Now for me an hybrid 
version based on a LUT and  on the branchless one is the fatest 
(decimalLength9_5), although still slowest then the original.


updated program, incl your branchless version (decimalLength9_4):

---
#!ldmd -boundscheck=off -release -inline -O -mcpu=native 
-mattr=+sse2,+sse3,+sse4.1,+sse4.2,+fast-lzcnt,+avx,+avx2,+cmov,+bmi,+bmi2

import core.memory;
import core.bitop;
import std.stdio;
import std.range;
import std.algorithm;
import std.getopt;
import std.random;

ubyte decimalLength9_0(const uint v)
{
if (v >= 1) { return 9; }
if (v >= 1000) { return 8; }
if (v >= 100) { return 7; }
if (v >= 10) { return 6; }
if (v >= 1) { return 5; }
if (v >= 1000) { return 4; }
if (v >= 100) { return 3; }
if (v >= 10) { return 2; }
return 1;
}

ubyte decimalLength9_1(const uint v) pure nothrow
{
if (v == 0) // BSR and LZCNT UB when input is 0
return 1;
const ubyte lzc = cast(ubyte) bsr(v);
ubyte result;
switch (lzc)
{
case 0 :
case 1 :
case 2 : result =  1; break;
case 3 : result =  v >= 10 ? 2 : 1; break;
case 4 :
case 5 : result =  2; break;
case 6 : result =  v >= 100 ? 3 : 2; break;
case 7 :
case 8 : result =  3; break;
case 9 : result =  v >= 1000 ? 4 : 3; break;
case 10:
case 11:
case 12: result =  4; break;
case 13: result =  v >= 1 ? 5 : 4; break;
case 14:
case 15: result =  5; break;
case 16: result =  v >= 10 ? 6 : 5; break;
case 17:
case 18: result =  6; break;
case 19: result =  v >= 100 ? 7 : 6; break;
case 20:
case 21:
case 22: result =  7; break;
case 23: result =  v >= 1000 ? 8 : 7; break;
case 24:
case 25: result =  8; break;
case 26: result =  v >= 1 ? 9 : 8; break;
case 27:
case 28:
case 29:
case 30:
case 31: result =  9; break;
default: assert(false);
}
return result;
}

private ubyte decimalLength9_2(const uint v) pure nothrow
{
if (v == 0) // BSR and LZCNT UB when input is 0
return 1;
const ubyte lzc = cast(ubyte) bsr(v);
static immutable pure nothrow ubyte function(uint)[32] tbl =
[
0 : (uint a) => ubyte(1),
1 : (uint a) => ubyte(1),
2 : (uint a) => ubyte(1),
3 : (uint a) => a >= 10  ? ubyte(2) : ubyte(1),
4 : (uint a) => ubyte(2),
5 : (uint a) => ubyte(2),
6 : (uint a) => a >= 100  ? ubyte(3) : ubyte(2),
7 : (uint a) => ubyte(3),
8 : (uint a) => ubyte(3),
9 : (uint a) => a >= 1000  ? ubyte(4) : ubyte(3),
10: (uint a) => ubyte(4),
11: (uint a) => ubyte(4),
12: (uint a) => ubyte(4),
13: (uint a) => a >= 1  ? ubyte(5) : ubyte(4),
14: (uint a) => ubyte(5),
15: (uint a) => ubyte(5),
16: (uint a) => a >= 10  ? ubyte(6) : ubyte(5),
17: (uint a) => ubyte(6),
18: (uint a) => ubyte(6),
19: (uint a) => a >= 100  ? ubyte(7) : ubyte(6),
20: (uint a) => ubyte(7),
21: (uint a) => ubyte(7),
22: (uint a) => ubyte(7),
23: (uint a) => a >= 1000  ? ubyte(8) : ubyte(7),
24: (uint a) => ubyte(8),
25: (uint a) => ubyte(8),
26: (uint a) => a >= 1  ? ubyte(9) : ubyte(8),
27: (uint a) => ubyte(9),
28: (uint a) => ubyte(9),
29: (uint a) => ubyte(9),
30: (uint a) => ubyte(9),
31: (uint a) => ubyte(9),
];
return tbl[lzc](v);
}

ubyte decimalLength9_3(const uint v) pure nothrow
{
if (v == 0) // BSR and LZCNT UB when input is 0
return 1;
ubyte result;
enum ubyte doSwitch = ubyte(0);
const ubyte lzc = cast(ubyte) bsr(v);
const ubyte[32] decimalLength9LUT =
[
0 : ubyte(1),
1 : ubyte(1),
2 : ubyte(1),
3 : doSwitch,
4 : ubyte(2),
5 : ubyte(2),
6 : doSwitch,
7 : ubyte(3),
8 : ubyte(3),
9 : doSwitch,
10: ubyte(4),
11: ubyte(4),
12: ubyte(4),
13: doSwitch,
14: ubyte(5),
15: ubyte(5),
16: doSwitch,
17: ubyte(6),
18: ubyte(6),
19: doSwitch,
20: ubyte(7),
21: ubyte(7),
22: ubyte(7),
23: doSwitch,
24: ubyte(8),
25: ubyte(8),
26: doSwitch,
27: ubyte(9),
28: ubyte(9),
29: 

Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-26 Thread Basile B. via Digitalmars-d-learn
On Thursday, 27 February 2020 at 03:58:15 UTC, Bruce Carneal 
wrote:


Maybe you talked about another implementation of 
decimalLength9 ?


Yes.  It's one I wrote after I saw your post. Psuedo-code here:

  auto d9_branchless(uint v) { return 1 + (v >= 10) + (v >= 
100) ... }


Using ldc to target an x86 with the above yields a series of 
cmpl, seta instruction pairs in the function body followed by a 
summing and a return.  No branching.


Let me know if the above is unclear or insufficient.


No thanks, it's crystal clear now.


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-26 Thread Basile B. via Digitalmars-d-learn
On Wednesday, 26 February 2020 at 20:44:31 UTC, Bruce Carneal 
wrote:
The winning function implementation lines up with that 
distribution.  It would not fare as well with higher entropy 
input.


Using sorted equi-probable inputs (N 1 digit numbers, N 2 digit 
numbers, ...) decimalLength9_0 beats a simple branchless 
implementation by about 10%.


After shuffling the input, branchless wins by 2.4X (240%).


I've replaced the input by the front of a rndGen (that pops for 
count times and starting with a custom seed) and I never see the 
decimalLength9_3 (which seems to be the closest to the original 
in term of performances) doing better.


Maybe you talked about another implementation of decimalLength9 ?


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-26 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 26 February 2020 at 22:07:30 UTC, Johan wrote:

On Wednesday, 26 February 2020 at 00:50:35 UTC, Basile B. wrote:

[...]


Hi Basile,
  I recently saw this presentation: 
https://www.youtube.com/watch?v=Czr5dBfs72U
It has some ideas that may help you make sure your measurements 
are good and may give you ideas to find the performance 
bottleneck or where to optimize.
llvm-mca is featured on godbolt.org: 
https://mca.godbolt.org/z/YWp3yv


cheers,
  Johan


yes llvm-mca looks excellent, although I don't know if it worth 
continuing... You see this function is certainly not a 
bottleneck, it's just that I wanted to try better than the naive 
implementation.


Fundamentatlly the problem is that
1. the original is smaller, faster to decode
2. the alternatives (esp. the 3rd) is conceptually better but the 
cost of the jump table + lzcnt wastes it.


Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-26 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 26 February 2020 at 00:50:35 UTC, Basile B. wrote:

How is that possible ?


It turns out that there's a problem with the benchmarking method. 
With command line argument the different optimization passes of 
LLVM don't fuck up with the literal constants.


It appears that none of the alternatives based on the "most 
significant bit trick" are faster (at least when covering a 
decent range of numbers):


---
#!ldmd -boundscheck=off -release -inline -O -mcpu=native 
-mattr=+sse2,+sse3,+sse4.1,+sse4.2,+fast-lzcnt,+avx,+avx2,+cmov,+bmi,+bmi2

import core.memory;
import core.bitop;
import std.stdio;
import std.range;
import std.algorithm;
import std.getopt;

ubyte decimalLength9_0(const uint v)
{
if (v >= 1) { return 9; }
if (v >= 1000) { return 8; }
if (v >= 100) { return 7; }
if (v >= 10) { return 6; }
if (v >= 1) { return 5; }
if (v >= 1000) { return 4; }
if (v >= 100) { return 3; }
if (v >= 10) { return 2; }
return 1;
}

ubyte decimalLength9_1(const uint v) pure nothrow
{
if (v == 0) // BSR and LZCNT UB when input is 0
return 1;
const ubyte lzc = cast(ubyte) bsr(v);
ubyte result;
switch (lzc)
{
case 0 :
case 1 :
case 2 : result =  1; break;
case 3 : result =  v >= 10 ? 2 : 1; break;
case 4 :
case 5 : result =  2; break;
case 6 : result =  v >= 100 ? 3 : 2; break;
case 7 :
case 8 : result =  3; break;
case 9 : result =  v >= 1000 ? 4 : 3; break;
case 10:
case 11:
case 12: result =  4; break;
case 13: result =  v >= 1 ? 5 : 4; break;
case 14:
case 15: result =  5; break;
case 16: result =  v >= 10 ? 6 : 5; break;
case 17:
case 18: result =  6; break;
case 19: result =  v >= 100 ? 7 : 6; break;
case 20:
case 21:
case 22: result =  7; break;
case 23: result =  v >= 1000 ? 8 : 7; break;
case 24:
case 25: result =  8; break;
case 26: result =  v >= 1 ? 9 : 8; break;
case 27:
case 28:
case 29:
case 30:
case 31: result =  9; break;

default: assert(false);
}
return result;
}

private ubyte decimalLength9_2(const uint v) pure nothrow
{
if (v == 0) // BSR and LZCNT UB when input is 0
return 1;
const ubyte lzc = cast(ubyte) bsr(v);
static immutable pure nothrow ubyte function(uint)[32] tbl =
[
0 : (uint a) => ubyte(1),
1 : (uint a) => ubyte(1),
2 : (uint a) => ubyte(1),
3 : (uint a) => a >= 10  ? ubyte(2) : ubyte(1),
4 : (uint a) => ubyte(2),
5 : (uint a) => ubyte(2),
6 : (uint a) => a >= 100  ? ubyte(3) : ubyte(2),
7 : (uint a) => ubyte(3),
8 : (uint a) => ubyte(3),
9 : (uint a) => a >= 1000  ? ubyte(4) : ubyte(3),
10: (uint a) => ubyte(4),
11: (uint a) => ubyte(4),
12: (uint a) => ubyte(4),
13: (uint a) => a >= 1  ? ubyte(5) : ubyte(4),
14: (uint a) => ubyte(5),
15: (uint a) => ubyte(5),
16: (uint a) => a >= 10  ? ubyte(6) : ubyte(5),
17: (uint a) => ubyte(6),
18: (uint a) => ubyte(6),
19: (uint a) => a >= 100  ? ubyte(7) : ubyte(6),
20: (uint a) => ubyte(7),
21: (uint a) => ubyte(7),
22: (uint a) => ubyte(7),
23: (uint a) => a >= 1000  ? ubyte(8) : ubyte(7),
24: (uint a) => ubyte(8),
25: (uint a) => ubyte(8),
26: (uint a) => a >= 1  ? ubyte(9) : ubyte(8),
27: (uint a) => ubyte(9),
28: (uint a) => ubyte(9),
29: (uint a) => ubyte(9),
30: (uint a) => ubyte(9),
31: (uint a) => ubyte(9),
];
return tbl[lzc](v);
}

ubyte decimalLength9_3(const uint v) pure nothrow
{
if (v == 0) // BSR and LZCNT UB when input is 0
return 1;
ubyte result;
const ubyte lzc = cast(ubyte) bsr(v);
const ubyte[32] decimalLength9LUT =
[
0 : ubyte(1),
1 : ubyte(1),
2 : ubyte(1),
3 : ubyte(10),
4 : ubyte(2),
5 : ubyte(2),
6 : ubyte(11),
7 : ubyte(3),
8 : ubyte(3),
9 : ubyte(12),
10: ubyte(4),
11: ubyte(4),
12: ubyte(4),
13: ubyte(12),
14: ubyte(5),
15: ubyte(5),
16: ubyte(13),
17: ubyte(6),
18: ubyte(6),
19: ubyte(14),
20: ubyte(7),
21: ubyte(7),
22: ubyte(7),
23: ubyte(15),
24: ubyte(8),
25: ubyte(8),
26: ubyte(16),
27: ubyte(9),
28: ubyte(9),
29: ubyte(9),
30: ubyte(9),
31: ubyte(9),
];
ubyte resultOrSelector = decimalLength9LUT[lzc];
if (resultOrSelector < 10)
result = resultOrSelector;
else switch (lzc)
{
case 3 : result =  v >= 10 ? 2 : 1; break;
case 6 : result =  v >= 100 ? 3 : 2; break;
case 9 : result =  v >= 1000 ? 4 : 3; break;
case 13: result =  v >= 1 ? 5 : 4; break;
case 16: result =  v >= 10 ? 6 : 5; break;
case 19: result =  

Re: Strange counter-performance in an alternative `decimalLength9` function

2020-02-25 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 26 February 2020 at 01:10:07 UTC, H. S. Teoh wrote:
On Wed, Feb 26, 2020 at 12:50:35AM +, Basile B. via 
Digitalmars-d-learn wrote: [...]

#!dmd -boundscheck=off -O -release -inline

[...]

TBH, I'm skeptical of any performance results using dmd.  I 
wouldn't pay attention to performance numbers obtained this 
way, and rather look at the ldmd/ldc2 numbers.


I didn't use DMD. The script line is actually interpreted by the 
IDE. It drops the compiler name and just parse the arg and pass 
them to a compiler that's defined by non overridable options. In 
my case I used LDMD (this is LDC you see, but with a DMD like 
options syntax)


Strange counter-performance in an alternative `decimalLength9` function

2020-02-25 Thread Basile B. via Digitalmars-d-learn
So after reading the translation of RYU I was interested too see 
if the decimalLength() function can be written to be faster, as 
it cascades up to 8 CMP.


After struggling with bad ideas I finally find something that 
looks nice:


- count the leading zero of the input
- switch() this count to have in the worst of the cases only 1 
CMP (when the bit number possibly changes the digit count, e.g 9 
-> 10 (when bsr(input) == 4)


after writing all the values allowing to know the cases where a 
comparison is necessary...


  min2 = 0b10
  max2 = 0b11
  min3 = 0b100
  max3 = 0b111
  ...
  ...
  min32 = 0b100...0
  max32 = 0b111...1

...I finally write the "nice" thing.

---
#!dmd -boundscheck=off -O -release -inline
import std.stdio;

ubyte decimalLength9(const uint v)
{
if (v >= 1) { return 9; }
if (v >= 1000) { return 8; }
if (v >= 100) { return 7; }
if (v >= 10) { return 6; }
if (v >= 1) { return 5; }
if (v >= 1000) { return 4; }
if (v >= 100) { return 3; }
if (v >= 10) { return 2; }
return 1;
}

ubyte fdecimalLength9(const uint v) pure nothrow
{
import core.bitop;
const ubyte lzc = cast(ubyte) (bsr(v) + 1);
ubyte result;
switch (lzc)
{
case 0 :
case 1 :
case 2 :
case 3 : result =  1; break;
case 4 : result =  v >= 10  ? 2 : 1; break;
case 5 :
case 6 : result =  2; break;
case 7 : result =  v >= 100  ? 3 : 2; break;
case 8 :
case 9 : result =  3; break;
case 10: result =  v >= 1000  ? 4 : 3; break;
case 11:
case 12:
case 13: result =  4; break;
case 14: result =  v >= 1  ? 5 : 4; break;
case 15:
case 16: result =  5; break;
case 17: result =  v >= 10  ? 6 : 5; break;
case 18:
case 19: result =  6; break;
case 20: result =  v >= 100  ? 7 : 6; break;
case 21:
case 22:
case 23: result =  7; break;
case 24: result =  v >= 1000  ? 8 : 7; break;
case 25:
case 26: result =  8; break;
case 27: result =  v >= 1  ? 9 : 8; break;
case 28:
case 29:
case 30:
case 31:
case 32: result =  9; break;
default: assert(false);
}
return result;
}

private ubyte ffdecimalLength9(const uint v) pure nothrow
{
import core.bitop;
const ubyte lzc = cast(ubyte) (bsr(v) + 1);
static immutable pure nothrow ubyte function(uint)[33] tbl =
[
0 : (uint a) => ubyte(1),
1 : (uint a) => ubyte(1),
2 : (uint a) => ubyte(1),
3 : (uint a) => ubyte(1),
4 : (uint a) => a >= 10  ? ubyte(2) : ubyte(1),
5 : (uint a) => ubyte(2),
6 : (uint a) => ubyte(2),
7 : (uint a) => a >= 100  ? ubyte(3) : ubyte(2),
8 : (uint a) => ubyte(3),
9 : (uint a) => ubyte(3),
10: (uint a) => a >= 1000  ? ubyte(4) : ubyte(3),
11: (uint a) => ubyte(4),
12: (uint a) => ubyte(4),
13: (uint a) => ubyte(4),
14: (uint a) => a >= 1  ? ubyte(5) : ubyte(4),
15: (uint a) => ubyte(5),
16: (uint a) => ubyte(5),
17: (uint a) => a >= 10  ? ubyte(6) : ubyte(5),
18: (uint a) => ubyte(6),
19: (uint a) => ubyte(6),
20: (uint a) => a >= 100  ? ubyte(7) : ubyte(6),
21: (uint a) => ubyte(7),
22: (uint a) => ubyte(7),
23: (uint a) => ubyte(7),
24: (uint a) => a >= 1000  ? ubyte(8) : ubyte(7),
25: (uint a) => ubyte(8),
26: (uint a) => ubyte(8),
27: (uint a) => a >= 1  ? ubyte(9) : ubyte(8),
28: (uint a) => ubyte(9),
29: (uint a) => ubyte(9),
30: (uint a) => ubyte(9),
31: (uint a) => ubyte(9),
32: (uint a) => ubyte(9),
];
return tbl[lzc](v);
}

void main()
{
import std.datetime.stopwatch, std.range, std.algorithm;

int s1, s2, s3;
benchmark!({ iota(1u).each!(a => s1 += 
decimalLength9(a+1)); })(10).writeln;
benchmark!({ iota(1u).each!(a => s2 += 
fdecimalLength9(a+1));})(10).writeln;
benchmark!({ iota(1u).each!(a => s3 += 
ffdecimalLength9(a+1));})(10).writeln;

assert(s1 == s2);
assert(s1 == s3);
}
---

Then bad surprise. Even with ldmd (so ldc2 basically) feeded with 
the args from the script line. Maybe the fdecimalLength9 version 
is slightly faster. Only *slightly*. Good news, I've lost my 
time. So I try an alternative version that uses a table of 
delegates instead of a switch (ffdecimalLength9) and surprise, 
"tada", it is like **100x** slower then the two others.


How is that possible ?


Re: Custom asset handler messes unit test summary report

2020-02-23 Thread Basile B. via Digitalmars-d-learn

On Monday, 24 February 2020 at 00:50:38 UTC, ric maicle wrote:

[dmd 2.090.1 linux 64-bit]

The following code does not report the correct unit test 
summary.

The report says 1 unit test passed.

~
shared static this() {
import core.exception;
assertHandler();
}

void
cah(string file, ulong line, string msg) nothrow {
import core.stdc.stdio: printf;
printf("==\n");
printf("Assert error: %s %d: %s\n", file.ptr, line, 
msg.ptr);

printf("==\n");
}

unittest {
assert(false);
}
~


Looks like you have to throw an Error at the end of your custom 
handler, e.g:


---
void
cah(string file, ulong line, string msg) nothrow {
import core.stdc.stdio: printf;
import core.exception : AssertError;
printf("==\n");
printf("Assert error: %s %d: %s\n", file.ptr, line, msg.ptr);
printf("==\n");
throw new AssertError("");
}
---

For a betterC program you can use an HLT:

---
void
cah(string file, ulong line, string msg) nothrow {
import core.stdc.stdio: printf, fflush, stdout;
printf("==\n");
printf("Assert error: %s %d: %s\n", file.ptr, line, msg.ptr);
printf("==\n");
fflush(stdout);
asm nothrow { hlt; }
}
---


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Basile B. via Digitalmars-d-learn

On Sunday, 23 February 2020 at 17:14:33 UTC, Per Nordlöw wrote:
I would like to setup auto-generation of online documentation 
for my public D libraries residing on Github and Gitlab.


What alternatives do I have?


for gitlab they have a system of pages that's quite easy to setup:

something like

.gitlab-ci.yml
---
#to get dmd and dub
image: dlang2/dmd-ubuntu

#special section to generate gitlab "pages"
pages:
  before_script:
  - apt-get install -y 
  - 
  script:
  - 
  artifacts:
paths:
- public
  only:
  - master
  - 
---

and then your doc is online and updated for each push.
It can be downloaded from the artifacts too, maybe in an 
automated way I think, but havent used this for now so cant say.


Re: dscanner and ref parameters

2020-02-23 Thread Basile B. via Digitalmars-d-learn

On Sunday, 23 February 2020 at 12:28:41 UTC, mark wrote:
On Sunday, 23 February 2020 at 09:35:30 UTC, Jacob Carlborg 
wrote:

On 2020-02-23 10:03, mark wrote:

Then this would not only help dscanner, but also make it 
clear to programmers that the argument could be modified.


It's not necessary for dscanner. It should look at the 
signature of `getKeyval` to see that it takes an argument by 
`ref`.


Just realised that the arg is 'out' not 'ref'; don't know if 
that makes a difference to dscanner. Anyway, I've made a bug 
report: https://github.com/dlang-community/D-Scanner/issues/793


This like
https://github.com/dlang-community/D-Scanner/issues/366 or
https://github.com/dlang-community/D-Scanner/issues/298, so a 
false positive due to limlitations.


D-Scanner:
- only works at the module level (i.e cant see declaration from 
an import) ;
- does not perform regular semantic (even not the ones done for 
DCD) ;


People who care should just start developing a new linter based 
on DMD as a library.

It's pretty clear (IMO) that these problems will never be fixed.


Re: How to get the name of an object's class at compile time?

2020-02-17 Thread Basile B. via Digitalmars-d-learn

On Monday, 17 February 2020 at 22:34:31 UTC, Stefan Koch wrote:


Upon seeing this I just implemented typeid(stuff).name;

https://github.com/dlang/dmd/pull/10796

With any luck this will be possible in the next release ;)


Can this work using `stuff.classinfo.name` too ?
This is the same as `typeid(stuff).name`


operator overload for sh-like scripting ?

2020-02-17 Thread Basile B. via Digitalmars-d-learn

eg

   Sh(echo) < "meh";

struct Sh
{
 // you see the idea we have op overload for < here
}


Re: How to iterate over range two items at a time

2020-02-17 Thread Basile B. via Digitalmars-d-learn

On Monday, 17 February 2020 at 09:41:35 UTC, Adnan wrote:

On Monday, 17 February 2020 at 07:50:02 UTC, Mitacha wrote:

On Monday, 17 February 2020 at 05:04:02 UTC, Adnan wrote:
What is the equivalent of Rust's chunks_exact()[1] method in 
D? I want to iterate over a spitted string two chunks at a 
time.



[1] 
https://doc.rust-lang.org/beta/std/primitive.slice.html#method.chunks_exact


It sounds similar to `slide` 
https://dlang.org/phobos/std_range.html#slide


The key difference here is that slide seems to overlap, which 
is a big no-no for my current problem.


I have just gone with a classic for loop. Error prone, but just 
works.


Yeah your analysis is right. slide is specifically made to 
overlapp, if overlapping is not needed slide is not needed.


Re: dub / use git branch

2020-02-16 Thread Basile B. via Digitalmars-d-learn
On Sunday, 16 February 2020 at 14:01:13 UTC, Robert M. Münch 
wrote:
I want to use a specific branch version if a package. I 
specified the branch version in a dub.selections.json file.


But it seems that dub requires a ZIP file that can be 
downloaded from code.dlang.org, which of course fails because 
the branch is only available on github.


Fetching rtree ~fix-#3 (getting selected version)...
Downloading https://code.dlang.org/packages/rtree/~fix-#3.zip 
failed with 404 (Not Found).


How am I supposed to switch to a branch version of a package to 
try a bug-fix version for example?


We fail to get the most basic support for git since a full year 
now:


https://github.com/dlang/dub/pull/1802
https://github.com/dlang/dub/pull/1798
https://github.com/dlang/dub/pull/1403

So for now you have two options:

1/ in your project recipe, you can add the dependency as a path 
to the git submodule representing the DUB package and do the 
branch checkout manually or using a DUB pregenerate command.


2/ ask to the dependency maintainer to add a git tag in the 
branch you'd like to use.
the DUB registry will automatically create a new version of the 
package, using the right branch. This is done for example for stx 
allocator and so far this work.


Re: Dscanner: is it possible to switch off style checks case-by-case?

2020-02-14 Thread Basile B. via Digitalmars-d-learn

On Thursday, 13 February 2020 at 17:15:50 UTC, mark wrote:

I'm starting out with GtkD and have this function:

void main(string[] args) {
Main.init(args);
auto game = new GameWindow();
Main.run();
}

and this method:

void quit(Widget widget) {
Main.quit();
}

When I run dscanner --styleCheck it reports:

./src/app.d(10:10)[warn]: Variable game is never used.
./src/app.d(22:22)[warn]: Parameter widget is never used.

These are correct. However, is it possible to switch them off 
individually?


Yes you can but in the present case the analysis is right because 
you can write


void main(string[] args) {
Main.init(args);
new GameWindow();
Main.run();
}

and for the other

void quit(Widget) {
Main.quit();
}

or even

void quit() {
Main.quit();
}

Otherwise here is an example of how you can tune the different 
checks:



https://raw.githubusercontent.com/dlang/phobos/master/.dscanner.ini


See also the last section of


https://raw.githubusercontent.com/dlang-community/D-Scanner/master/README.md


Re: Strange instruction sequence with DMD while calling functions with float parameters

2020-02-14 Thread Basile B. via Digitalmars-d-learn

On Friday, 14 February 2020 at 22:36:20 UTC, PatateVerte wrote:

Hello
I noticed a strange behaviour of the DMD compiler when it has 
to call a function with float arguments.


I build with the flags "-mcpu=avx2 -O  -m64" under windows 64 
bits using "DMD32 D Compiler v2.090.1-dirty"


I have the following function :
   float mul_add(float a, float b, float c); //Return a * b + c

When I try to call it :
   float f = d_mul_add(1.0, 2.0, 3.0);

I tested with other functions with float parameters, and there 
is the same problem.


Then the following instructions are generated :
//Loads the values, as it can be expected
vmovss xmm2,dword [rel 0x64830]
vmovss xmm1,dword [rel 0x64834]
vmovss xmm0,dword [rel 0x64838]
//Why ?
movq r8,xmm2
movq rdx,xmm1
movq rcx,xmm0
//
call 0x400   //0x400 is where the mul_add function is located

My questions are :
 - Is there a reason why the registers xmm0/1/2 are saved in 
rcx/rdx/r8 before calling ? The calling convention specifies 
that the floating point parameters have to be put in xmm 
registers, and not GPR, unless you are using your own calling 
convention.
 - Why is it done using non-avx instructions ? Mixing AVX and 
non-AVX instructions may impact the speed greatly.


Any idea ? Thank you in advance.


It's simply the bad codegen (or rather a missed opportunity to 
optimize) from DMD, its backend doesn't see that the parameters 
are already in the right order and in the right registers so it 
copy them and put them in the regs for the inner func call.


I had observed this in the past too, i.e unexplained round 
tripping from GP to SSE regs. For good FP codegen use LDC2 or GDC 
or write iasm (but loose inlining).


For other people who'd like to observe the problem: 
https://godbolt.org/z/gvqEqz.
By the way I had to deactivate AVX2 targeting because otherwise 
the result is even more weird (https://godbolt.org/z/T9NwMc)


Re: Is it possible to use DMD as a library to compile strings at runtime?

2020-02-10 Thread Basile B. via Digitalmars-d-learn

On Monday, 10 February 2020 at 12:31:03 UTC, Basile B. wrote:

On Friday, 31 January 2020 at 14:25:30 UTC, Basile B. wrote:

[...]


about [1] (llvm) I've made a better binding this weekend:

https://gitlab.com/basile.b/llvmd-d

Seriouly I cant believe that at some point in the past I 
translated by hand. dstep can handle big C libraries.


ah ah ah, I meant

https://gitlab.com/basile.b/llvm-d


Re: Is it possible to use DMD as a library to compile strings at runtime?

2020-02-10 Thread Basile B. via Digitalmars-d-learn

On Friday, 31 January 2020 at 14:25:30 UTC, Basile B. wrote:

On Friday, 31 January 2020 at 11:19:37 UTC, Saurabh Das wrote:
I see that DUB has DMD as a library package, but I was not 
able to understand how to use it.


Is it possible to use DMD as a library within a D program to 
compile a string to machine code and run the compiled code at 
runtime?


Thanks,
Saurabh


Fundamentally DMD as a library is a front-end. Jitting is to 
the backend side.
You'll be able to lex and parse the source to get an AST, to 
perform the semantic passes on this AST and that's all.


Then to run this code you would need to make an AST visitor 
that will generate the binary code to execute. Even using a 
specialized library with jitting abilities, such as LLVM-d [1] 
or libfirm-d [2], this would be *quite* a journey.


[1] https://github.com/MoritzMaxeiner/llvm-d
[2] https://gitlab.com/basile.b/libfirm-d


about [1] (llvm) I've made a better binding this weekend:

https://gitlab.com/basile.b/llvmd-d

Seriouly I cant believe that at some point in the past I 
translated by hand. dstep can handle big C libraries.


Re: total newbie + IDE

2020-02-08 Thread Basile B. via Digitalmars-d-learn

On Saturday, 8 February 2020 at 03:59:22 UTC, Borax Man wrote:

As linked before, dexed is available here
https://github.com/akira13641/dexed

and I compiled it just a few days ago with success.


It is a fork (check the count of commits).
The most recent version is here https://gitlab.com/basile.b/dexed.


Re: Does D have an equvalent of: if (auto = expr; expr)

2020-02-07 Thread Basile B. via Digitalmars-d-learn

On Friday, 7 February 2020 at 08:52:44 UTC, mark wrote:

Some languages support this kind of thing:

if ((var x = expression) > 50)
  print(x, " is > 50")

Is there anything similar in D?


Yes assuming that the expression is bool evaluable. This includes

- pointers: `if (auto p = giveMeSomePtr()){}`
- classes references: `if (auto p = giveMeSomeClasses()){}`
- integers `if (auto p = giveMeAnInt()){}`

and using the in operators as you've been answered previously.
The problem is that this support only one variable and that the 
If condition must be either a variable or a relational 
expression. Not both.


To overcome the limitation of a single variable I've made a 
little template:


---
/**
 * Encapsulates several variables in a tuple that's usable as a 
if condition,
 * as a workaround to the single declaration allowed by the 
language.

 *
 * Params:
 *  a = The expressions giving the variables.
 *  The variables must be evaluable to $(D bool).
 *
 * Returns:
 *  A tuple containing the variables.
 */
auto ifVariables(A...)(auto ref A a)
if (A.length)
{
static struct IfVariables(A...)
{
private A tup;
alias tup this;

this() @disable;
this(this) @disable;

this(ref A a)
{
tup = a;
}

bool opCast(T : bool)() const
{
static foreach (i; 0 .. A.length)
if (!tup[i])
return false;
return true;
}
}
return IfVariables!A(a);
}
///
unittest
{
assert(ifVariables(new Object, true, new Object));
assert(!ifVariables(new Object, false, new Object));
// typical usage
bool isDlangExpressive(){return true;}
if (auto a = ifVariables(new Object, isDlangExpressive())) {}
// use the variables
if (auto a = ifVariables(new Object, new Object))
{
assert(a.length == 2);
assert(a[0] !is a[1]);
}
}

---


Re: total newbie + IDE

2020-02-07 Thread Basile B. via Digitalmars-d-learn

On Friday, 7 February 2020 at 18:10:07 UTC, bachmeier wrote:

On Friday, 7 February 2020 at 17:02:18 UTC, solnce wrote:

Hi guys,

I am total newbie and trying to learn a little bit of 
programming for personal purposes (web scrapping, small 
databases for personal use etc.). I've been trying to install 
any of IDE available, but had no success.


I use Manjaro, so for the most task I use its AUR, where:

Dexed points to obsolete github 
(https://github.com/Basile-z/dexed)


[...]
[...] The new Github link for Dexed is 
https://github.com/akira13641/dexed


No I've reuploaded the most recent version here 
https://gitlab.com/basile.b/dexed.

However,

1. no more binaries
2. don't care about requests anymore.
3. code for the Windows version is not maintained.

So it's not recommened for newbies, or only those who can manage 
things by themselves.


Re: Is it possible to use DMD as a library to compile strings at runtime?

2020-01-31 Thread Basile B. via Digitalmars-d-learn

On Friday, 31 January 2020 at 11:19:37 UTC, Saurabh Das wrote:
I see that DUB has DMD as a library package, but I was not able 
to understand how to use it.


Is it possible to use DMD as a library within a D program to 
compile a string to machine code and run the compiled code at 
runtime?


Thanks,
Saurabh


Fundamentally DMD as a library is a front-end. Jitting is to the 
backend side.
You'll be able to lex and parse the source to get an AST, to 
perform the semantic passes on this AST and that's all.


Then to run this code you would need to make an AST visitor that 
will generate the binary code to execute. Even using a 
specialized library with jitting abilities, such as LLVM-d [1] or 
libfirm-d [2], this would be *quite* a journey.


[1] https://github.com/MoritzMaxeiner/llvm-d
[2] https://gitlab.com/basile.b/libfirm-d


Re: list of all defined items in a D file

2020-01-25 Thread Basile B. via Digitalmars-d-learn

On Friday, 24 January 2020 at 14:28:03 UTC, berni44 wrote:

On Friday, 24 January 2020 at 12:22:49 UTC, Dennis wrote:
You can pass the -X flag to dmd, which makes it generate a 
.json file describing the compiled file.


Great, that's what I was looking for - although it's also good 
to know the __traits approach!


Thanks!


a 3rd approach is to use libdparse and make your own AST 
serializer by writing a visitor. (or even with DMD front end as a 
library). Although if it's a matter of time the dmd -X flag is 
great in the sense that the output format is standard and 
straightforward.


  1   2   3   4   5   6   7   >