Re: Bug in D!!!

2017-09-02 Thread EntangledQuanta via Digitalmars-d-learn
On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 23:12:35 UTC, EntangledQuanta 
wrote:
On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 00:00:43 UTC, 
EntangledQuanta wrote:
On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
wrote:
I've love being able to inherit and override generic 
functions in C#. Unfortunately C# doesn't use templates and 
I hit so many other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every 
instantiated T, after all, the compiler can't know you have 
a finite known set of T unless you tell it.


But lets assume we've told the compiler that it is 
compiling all the source code and it does not need to 
compile for future linking.


First the compiler will need to make sure all virtual 
functions can be generated for the derived classes. In this 
case the compiler must note the template function and 
validate all derived classes include it. That was easy.


Next up each instantiation of the function needs a new 
v-table entry in all derived classes. Current compiler 
implementation will compile each module independently of 
each other; so this feature could be specified to work 
within the same module or new semantics can be written up 
of how the compiler modifies already compiled modules and 
those which reference the compiled modules (the object 
sizes would be changing due to the v-table modifications)


With those three simple changes to the language I think 
that this feature will work for every T.


Specifying that there will be no further linkage is the same 
as making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that 
is effectively compile time for D.


By simply extending the grammar slightly in an intuitive 
way, we can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor 
ambiguous, I believe.


While I agree that `in` does make sense for the semantics 
involved, it is already used to do a failable key lookup 
(return pointer to value or null if not present) into an 
associative array [1] and input contracts. It wouldn't be 
ambiguous AFAICT, but having a keyword mean three different 
things depending on context would make the language even more 
complex (to read).


Yes, but they are independent, are they not? Maybe not.

foo(T in Typelist)()

in, as used here is not a input contract and completely 
independent. I suppose for arrays it could be ambiguous.


The contexts being independent of each other doesn't change 
that we would still be overloading the same keyword with three 
vastly different meanings. Two is already bad enough imho (and 
if I had a good idea with what to replace the "in" for AA's I'd 
propose removing that meaning).


Why? Don't you realize that the contexts matters and it's what 
separates the meaning? In truly unambiguous contexts, it 
shouldn't matter. It may require one to decipher the context, 
which takes time, but there is nothing inherently wrong with it 
and we are limited to how many symbols we use(unfortunately we 
are generally stuck with the querty keyboard design, else we 
could use symbols out the ying yang and make things much clearer, 
but even mathematics, which is a near perfect language, 
"overloads" symbols meanings).


You have to do this sort of thing when you limit the number of 
keywords you use. Again, ultimately it doesn't matter. A symbol 
is just a symbol. For me, as long as the context is clear, I 
don't see what kind of harm it can cause. You say it is bad, but 
you don't give the reasons why it is bad. If you like to think of 
`in` has having only one definition then the question is why? You 
are limiting yourself. The natural languages are abound with such 
multi-definitions. Usually in an ambiguous way and it can cause a 
lot of problems, but for computer languages, it can't(else we 
couldn't actually compile the programs). Context sensitive 
grammars are provably more expressive than context free.


https://en.wikipedia.org/wiki/Context-sensitive_grammar

Again, I'm not necessarily arguing for them, just saying that one 
shouldn't avoid them just to avoid them.







For me, and this is just me, I do not find it ambiguous. I 
don't find different meanings ambiguous unless the context 
overlaps. Perceived ambiguity is not ambiguity, it's just 
ignorance... which can be overcome through learning. Hell, D 
has many cases where there are perceived ambiguities... as do 
most things.


It's not about ambiguity for me, it's about readability. The 
more significantly different meanings you overload some keyword 
- or symbol, for that matter - with, the harder it becomes to 
read.


I don't think that is true. Everything is hard to 

Re: 24-bit int

2017-09-02 Thread Ilya Yaroshenko via Digitalmars-d-learn
On Saturday, 2 September 2017 at 03:29:20 UTC, EntangledQuanta 
wrote:
On Saturday, 2 September 2017 at 02:49:41 UTC, Ilya Yaroshenko 
wrote:
On Friday, 1 September 2017 at 19:39:14 UTC, EntangledQuanta 
wrote:
Is there a way to create a 24-bit int? One that for all 
practical purposes acts as such? This is for 24-bit stuff 
like audio. It would respect endianness, allow for arrays 
int24[] that work properly, etc.


Hi,

Probably you are looking for bitpack ndslice topology:
http://docs.algorithm.dlang.io/latest/mir_ndslice_topology.html#.bitpack

sizediff_t[] data;
// creates a packed signed integer slice with max allowed 
value equal to `2^^24 - 1`.

auto packs = data[].sliced.bitpack!24;

packs has the same API as D arrays

Package is Mir Algorithm
http://code.dlang.org/packages/mir-algorithm

Best,
Ilya


Thanks. Seems useful.


Just added `bytegroup` topology. Released in v0.6.12 (will be 
available in DUB after few minutes.)


http://docs.algorithm.dlang.io/latest/mir_ndslice_topology.html#bytegroup

It is faster for your task then `bitpack`.

Best regards,
Ilya


Re: Bug in D!!!

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 2 September 2017 at 23:12:35 UTC, EntangledQuanta 
wrote:
On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
wrote:
I've love being able to inherit and override generic 
functions in C#. Unfortunately C# doesn't use templates and 
I hit so many other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every 
instantiated T, after all, the compiler can't know you have 
a finite known set of T unless you tell it.


But lets assume we've told the compiler that it is compiling 
all the source code and it does not need to compile for 
future linking.


First the compiler will need to make sure all virtual 
functions can be generated for the derived classes. In this 
case the compiler must note the template function and 
validate all derived classes include it. That was easy.


Next up each instantiation of the function needs a new 
v-table entry in all derived classes. Current compiler 
implementation will compile each module independently of 
each other; so this feature could be specified to work 
within the same module or new semantics can be written up of 
how the compiler modifies already compiled modules and those 
which reference the compiled modules (the object sizes would 
be changing due to the v-table modifications)


With those three simple changes to the language I think that 
this feature will work for every T.


Specifying that there will be no further linkage is the same 
as making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that 
is effectively compile time for D.


By simply extending the grammar slightly in an intuitive way, 
we can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor 
ambiguous, I believe.


While I agree that `in` does make sense for the semantics 
involved, it is already used to do a failable key lookup 
(return pointer to value or null if not present) into an 
associative array [1] and input contracts. It wouldn't be 
ambiguous AFAICT, but having a keyword mean three different 
things depending on context would make the language even more 
complex (to read).


Yes, but they are independent, are they not? Maybe not.

foo(T in Typelist)()

in, as used here is not a input contract and completely 
independent. I suppose for arrays it could be ambiguous.


The contexts being independent of each other doesn't change that 
we would still be overloading the same keyword with three vastly 
different meanings. Two is already bad enough imho (and if I had 
a good idea with what to replace the "in" for AA's I'd propose 
removing that meaning).




For me, and this is just me, I do not find it ambiguous. I 
don't find different meanings ambiguous unless the context 
overlaps. Perceived ambiguity is not ambiguity, it's just 
ignorance... which can be overcome through learning. Hell, D 
has many cases where there are perceived ambiguities... as do 
most things.


It's not about ambiguity for me, it's about readability. The more 
significantly different meanings you overload some keyword - or 
symbol, for that matter - with, the harder it becomes to read.




But in any case, I could care less about the exact syntax. It's 
just a suggestion that makes the most logical sense with regard 
to the standard usage of in. If it is truly unambiguous then it 
can be used.


Well, yes, as I wrote, I think it is unambiguous (and can thus be 
used), I just think it shouldn't be used.




Another alternative is

foo(T of Typelist)

which, AFAIK, of is not used in D and even most programming 
languages. Another could be


foo(T -> Typelist)

or even

foo(T from Typelist)


I would much rather see it as a generalization of existing 
template specialization syntax [1], which this is t.b.h. just a 
superset of (current syntax allows limiting to exactly one, you 
propose limiting to 'n'):


---
foo(T: char)  // Existing syntax: Limit T to the single type 
`char`

foo(T: (A, B, C)) // New syntax:  Limit T to one of A, B, or C
---

Strictly speaking, this is exactly what template specialization 
is for, it's just that the current one only supports a single 
type instead of a set of types.
Looking at the grammar rules, upgrading it like this is a fairly 
small change, so the cost there should be minimal.




or whatever. Doesn't really matter. They all mean the same to 
me once the definition has been written in stone. Could use 
`foo(T eifjasldj Typelist)` for all I care.


That's okay, but it does matter to me.

The import thing for me is that such a simple syntax exists 
rather than the "complex syntax's" that have already been 
given(which are ultimately syntax's as 

Re: std.algorithm.joiner unexpected behavior

2017-09-02 Thread Sergei Degtiarev via Digitalmars-d-learn
Let me clarify, what I was going to create was a small utility, 
analogous to Perl <> operator, taking a list of file names and 
allowing forward iteration as it would be single stream of text 
lines. It would take no time to write the range from scratch, but 
what are all the phobos primitives for then? So it looks like 
this:

auto catFiles(string[] args)
{
File[] files=args.map!(a => File(a)).array;
if(files.empty)
files~=stdin;
return joiner(files.map!(a => a.byLine));
}
but unfortunately it does not work.
It seems, everybody agreed the problem is likely in the line 
buffer reused, however, replacing .byLine() with .byLineCopy() 
yields same result. Also, neither .byLine() nor .byLineCopy() 
return ForwardRange, just InputRange, so no .save() is probably 
called on them. And last, the utility is supposed to be fast, so 
using .byLineCopy() is very undesirable. Transient ranges may be 
uneasy to handle, but they allow to retain status of D as "better 
C" suitable for system programming. Using unsolicited internal 
copies is more typical for high-level scripting languages, and is 
one of the reasons of slower execution and high memory 
consumption.
In short, I agree with your arguments, but still believe this is 
a bug, probably in joiner rather than in .byLine(). I'm going to 
take look at the code and will tell if find anything.

Thank you for the discussion.



Re: 24-bit int

2017-09-02 Thread solidstate1991 via Digitalmars-d-learn
On Friday, 1 September 2017 at 19:39:14 UTC, EntangledQuanta 
wrote:
Is there a way to create a 24-bit int? One that for all 
practical purposes acts as such? This is for 24-bit stuff like 
audio. It would respect endianness, allow for arrays int24[] 
that work properly, etc.


If you need to perform math on integer audio, I strongly suggest 
to use int32 for this purpose to avoid performance degradation, 
then convert back to int24 when you're finished. Probably going 
to add such feature into my PCM library.


Re: Help required on Array appender

2017-09-02 Thread Vino.B via Digitalmars-d-learn
On Saturday, 2 September 2017 at 22:39:33 UTC, Nicholas Wilson 
wrote:

On Saturday, 2 September 2017 at 21:11:17 UTC, Vino.B wrote:

On Saturday, 2 September 2017 at 15:47:31 UTC, Vino.B wrote:
On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas 
Wilson wrote:

[...]


Hi,

[...]


Hi,

  Was able to resolve the above issue, but again getting the 
same for other lines such as below when i tried to add the 
appender.


auto CleanDirlst = appender([]);
CleanDirlst ~= PVStore[1][i].to!string.split(",");


Error: cannot implicitly convert expression appender([]) of 
type Appender!(void[]) to string[].


You want `Appender!(string[])`


Hi,

  Thank you very much, was able to resolve the issue.



Re: string to character code hex string

2017-09-02 Thread Ali Çehreli via Digitalmars-d-learn

On 09/02/2017 11:02 AM, lithium iodate wrote:
> On Saturday, 2 September 2017 at 17:41:34 UTC, Ali Çehreli wrote:
>> You're right but I think there is no intention of interpreting the
>> result as UTF-8. "f62026" is just to be used as "f62026", which can be
>> converted byte-by-byte back to "ö…". That's how understand the
>> requirement anyway.
>>
>> Ali
>
> That is not possible, because you cannot know whether "f620" and "26" or
> "f6" and "2026" (or any other combination) should form a code point
> each. Additional padding to constant width (8 hex chars) is needed.

Ok, I see that I made a mistake but I still don't think the conversion 
is one way. If we can convert byte-by-byte, we should be able to convert 
back byte-by-byte, right? What I failed to ensure was to iterate by code 
units. The following is able to get the same string back:


import std.stdio;
import std.string;
import std.algorithm;
import std.range;
import std.utf;
import std.conv;

auto toHex(R)(R input) {
// As Moritz Maxeiner says, this format is expensive
return input.byCodeUnit.map!(c => format!"%02x"(c)).joiner;
}

int hexValue(C)(C c) {
switch (c) {
case '0': .. case '9':
return c - '0';
case 'a': .. case 'f':
return c - 'a' + 10;
default:
assert(false);
}
}

auto fromHex(R, Dst = char)(R input) {
return input.chunks(2).map!((ch) {
auto high = ch.front.hexValue * 16;
ch.popFront();
return high + ch.front.hexValue;
}).map!(value => cast(Dst)value);
}

void main() {
assert("AAA".toHex.fromHex.equal("AAA"));

assert("ö…".toHex.fromHex.equal("ö…".byCodeUnit));
// Alternative check:
assert("ö…".toHex.fromHex.text.equal("ö…"));
}

Ali



Re: Bug in D!!!

2017-09-02 Thread EntangledQuanta via Digitalmars-d-learn
On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
wrote:
I've love being able to inherit and override generic 
functions in C#. Unfortunately C# doesn't use templates and I 
hit so many other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every 
instantiated T, after all, the compiler can't know you have a 
finite known set of T unless you tell it.


But lets assume we've told the compiler that it is compiling 
all the source code and it does not need to compile for 
future linking.


First the compiler will need to make sure all virtual 
functions can be generated for the derived classes. In this 
case the compiler must note the template function and 
validate all derived classes include it. That was easy.


Next up each instantiation of the function needs a new 
v-table entry in all derived classes. Current compiler 
implementation will compile each module independently of each 
other; so this feature could be specified to work within the 
same module or new semantics can be written up of how the 
compiler modifies already compiled modules and those which 
reference the compiled modules (the object sizes would be 
changing due to the v-table modifications)


With those three simple changes to the language I think that 
this feature will work for every T.


Specifying that there will be no further linkage is the same 
as making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that 
is effectively compile time for D.


By simply extending the grammar slightly in an intuitive way, 
we can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor 
ambiguous, I believe.


While I agree that `in` does make sense for the semantics 
involved, it is already used to do a failable key lookup 
(return pointer to value or null if not present) into an 
associative array [1] and input contracts. It wouldn't be 
ambiguous AFAICT, but having a keyword mean three different 
things depending on context would make the language even more 
complex (to read).


Yes, but they are independent, are they not? Maybe not.

foo(T in Typelist)()

in, as used here is not a input contract and completely 
independent. I suppose for arrays it could be ambiguous.


For me, and this is just me, I do not find it ambiguous. I don't 
find different meanings ambiguous unless the context overlaps. 
Perceived ambiguity is not ambiguity, it's just ignorance... 
which can be overcome through learning. Hell, D has many cases 
where there are perceived ambiguities... as do most things.


But in any case, I could care less about the exact syntax. It's 
just a suggestion that makes the most logical sense with regard 
to the standard usage of in. If it is truly unambiguous then it 
can be used.


Another alternative is

foo(T of Typelist)

which, AFAIK, of is not used in D and even most programming 
languages. Another could be


foo(T -> Typelist)

or even

foo(T from Typelist)

or whatever. Doesn't really matter. They all mean the same to me 
once the definition has been written in stone. Could use `foo(T 
eifjasldj Typelist)` for all I care. The import thing for me is 
that such a simple syntax exists rather than the "complex 
syntax's" that have already been given(which are ultimately 
syntax's as everything is at the end of the day).



W.r.t. to the idea in general: I think something like that 
could be valuable to have in the language, but since this 
essentially amounts to syntactic sugar (AFAICT), but I'm not 
(yet) convinced that with `static foreach` being included it's 
worth the cost.




Everything is syntactic sugar. So it isn't about if but how much. 
We are all coding in 0's and 1's whether we realize it or not. 
The point if syntax(or syntactic sugar) is to reduce the amount 
of 0's and 1's that we have to *effectively* code by grouping 
common patterns in to symbolic equivalents(by definition).


This is all programming is. We define certain symbols to mean 
certain bit patterns, or generic bit matters(an if keyword/symbol 
is a generic bit pattern, a set of machine instructions(0's and 
1's) and substitution placeholders that are eventually filled 
with 0's and 1's).


No one can judge the usefulness of syntax until it has been 
created because what determines how useful something is is its 
use. But you can't use something if it doesn't exist. I think 
many fail to get that. The initial questions should be: Is there 
a gap in the language? (Yes in this case). Can the gap be filled? 
(this is a theoretical/mathematical question that has to be 
answered. Most people jump the gun here and make assumptions) 
Does the gap need 

Re: nested module problem

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 2 September 2017 at 23:02:18 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 21:56:15 UTC, Jean-Louis Leroy 
wrote:

[...]

Hmmm I see...I was thinking of spinning the runtime part of my 
openmethods library into its own module (like here 
https://github.com/jll63/openmethods.d/tree/split-runtime/source/openmethods) but it looks like a bad idea...


Why does it look like a bad idea (I don't see an immediate 
issue the module structure either way)?


* in the module structure


Re: nested module problem

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 2 September 2017 at 21:56:15 UTC, Jean-Louis Leroy 
wrote:

[...]

Hmmm I see...I was thinking of spinning the runtime part of my 
openmethods library into its own module (like here 
https://github.com/jll63/openmethods.d/tree/split-runtime/source/openmethods) but it looks like a bad idea...


Why does it look like a bad idea (I don't see an immediate issue 
the module structure either way)?


Re: Help required on Array appender

2017-09-02 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 2 September 2017 at 21:11:17 UTC, Vino.B wrote:

On Saturday, 2 September 2017 at 15:47:31 UTC, Vino.B wrote:
On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson 
wrote:

[...]


Hi,

[...]


Hi,

  Was able to resolve the above issue, but again getting the 
same for other lines such as below when i tried to add the 
appender.


auto CleanDirlst = appender([]);
CleanDirlst ~= PVStore[1][i].to!string.split(",");


Error: cannot implicitly convert expression appender([]) of 
type Appender!(void[]) to string[].


You want `Appender!(string[])`


Re: nested module problem

2017-09-02 Thread Jean-Louis Leroy via Digitalmars-d-learn
On Saturday, 2 September 2017 at 21:42:59 UTC, Moritz Maxeiner 
wrote:
On Saturday, 2 September 2017 at 21:24:19 UTC, Jean-Louis Leroy 
wrote:

[...]


Yes, these now both fail because you cannot have a module `foo` 
and a package `foo` at the same time (they share a namespace), 
I forgot about that.



[...]


(same as before, no issue here)


[...]


You created the 'foo' package by specifying `module foo.bar` in 
foo/bar.d.



[...]


AFAIK you can't; consider:

-- baz.d ---
import foo;


in the same directory as foo.d. If foo/package.d exists (with 
`module foo` inside), what should baz.d import? foo.d or 
foo/package.d?
The point being that we could have either used foo/package.d or 
foo.d for a package file, but not both (as that would allow 
ambiguity) and package.d was chosen.


[1] https://dlang.org/spec/module.html#package-module


Hmmm I see...I was thinking of spinning the runtime part of my 
openmethods library into its own module (like here 
https://github.com/jll63/openmethods.d/tree/split-runtime/source/openmethods) but it looks like a bad idea...


Re: nested module problem

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 2 September 2017 at 21:24:19 UTC, Jean-Louis Leroy 
wrote:
On Saturday, 2 September 2017 at 20:48:22 UTC, Moritz Maxeiner 
wrote:
So the compiler wants you to import it by the name it has 
inferred for you (The fix being either specifying the module 
name in foo/bar.d as `module foo.bar`, or importing it as via 
`import bar;` in foo.d).

[1] https://dlang.org/spec/module.html


I thought of doing that, it merely changed the error. OK now I 
have:


in foo.d:
module foo;
import foo.bar;

in foo/bar.d:
module foo.bar;

$ dmd -c foo.d foo/bar.d
foo/bar.d(1): Error: package name 'foo' conflicts with usage as 
a module name in file foo.d


If I compile separately:
jll@ORAC:~/dev/d/tests/modules$ dmd -I. -c foo.d
foo/bar.d(1): Error: package name 'foo' conflicts with usage as 
a module name in file foo.d


Yes, these now both fail because you cannot have a module `foo` 
and a package `foo` at the same time (they share a namespace), I 
forgot about that.



jll@ORAC:~/dev/d/tests/modules$ dmd -I. -c foo/bar.d


(same as before, no issue here)



It believes that 'foo' is a package...because there is a 'foo' 
directory?


You created the 'foo' package by specifying `module foo.bar` in 
foo/bar.d.




I see that a workaround is to move foo.d to foo/package.d but I 
would like to avoid that.


AFAIK you can't; consider:

-- baz.d ---
import foo;


in the same directory as foo.d. If foo/package.d exists (with 
`module foo` inside), what should baz.d import? foo.d or 
foo/package.d?
The point being that we could have either used foo/package.d or 
foo.d for a package file, but not both (as that would allow 
ambiguity) and package.d was chosen.


[1] https://dlang.org/spec/module.html#package-module


Re: templated type reduction

2017-09-02 Thread ag0aep6g via Digitalmars-d-learn

On 09/02/2017 11:07 PM, EntangledQuanta wrote:

struct X(T)
{
string type = T.stringof;
T t;
}

[...]

void* x = new X!int;

(passed around the program)

switch(x.type)
{
 case "int" : break;
}

which is invalid yet perfectly valid! Is there any way to make this work 
legitly in D?


Not with `void*`, I think. `void*` explicitly tells the compiler to 
forget anything it knows about the type.


You could make a new type `struct XBase { string type; }` and use 
`XBase*` instead of `void*`.


If you're going to `new` the instances anyway, classes could also help:

class XBase { string type; }
class X(T) : XBase { T t; }


[...]

note that it is really no different from

struct X(T)
{
string type = "asdf";
T t;
}

in which we can do

string type = (cast(X!int)x).type; // = asdf

or

string type = (cast(X!float)x).type; // = asdf

but even this is a bit fishy.


I think this is the best you can do with `void*`. Maybe add an assert in 
X that checks that the field `type` is always at the same offset (0).



Heres some code that does the offset hack:


struct X(T)
{
 string type = T.stringof;
 T x;
}

int main(string[] args)
{

 void* x = new X!int;

 int o = (X!float).type.offsetof;
 auto y = *cast(string*)(x + o);
 writeln(y);
 return 0;
}


I don't think `.offsetof` buys you anything over `(cast(X!int)x).type`.

By the way, `void main()` is valid. You don't need to return 0 or 
declare `args` if you don't use them.


Re: nested module problem

2017-09-02 Thread Jean-Louis Leroy via Digitalmars-d-learn
On Saturday, 2 September 2017 at 20:48:22 UTC, Moritz Maxeiner 
wrote:
So the compiler wants you to import it by the name it has 
inferred for you (The fix being either specifying the module 
name in foo/bar.d as `module foo.bar`, or importing it as via 
`import bar;` in foo.d).

[1] https://dlang.org/spec/module.html


I thought of doing that, it merely changed the error. OK now I 
have:


in foo.d:
module foo;
import foo.bar;

in foo/bar.d:
module foo.bar;

$ dmd -c foo.d foo/bar.d
foo/bar.d(1): Error: package name 'foo' conflicts with usage as a 
module name in file foo.d


If I compile separately:
jll@ORAC:~/dev/d/tests/modules$ dmd -I. -c foo.d
foo/bar.d(1): Error: package name 'foo' conflicts with usage as a 
module name in file foo.d

jll@ORAC:~/dev/d/tests/modules$ dmd -I. -c foo/bar.d

It believes that 'foo' is a package...because there is a 'foo' 
directory?


I see that a workaround is to move foo.d to foo/package.d but I 
would like to avoid that.






Re: Bug in D!!!

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
wrote:
I've love being able to inherit and override generic functions 
in C#. Unfortunately C# doesn't use templates and I hit so 
many other issues where Generics just suck.


I don't think it is appropriate to dismiss the need for the 
compiler to generate a virtual function for every instantiated 
T, after all, the compiler can't know you have a finite known 
set of T unless you tell it.


But lets assume we've told the compiler that it is compiling 
all the source code and it does not need to compile for future 
linking.


First the compiler will need to make sure all virtual 
functions can be generated for the derived classes. In this 
case the compiler must note the template function and validate 
all derived classes include it. That was easy.


Next up each instantiation of the function needs a new v-table 
entry in all derived classes. Current compiler implementation 
will compile each module independently of each other; so this 
feature could be specified to work within the same module or 
new semantics can be written up of how the compiler modifies 
already compiled modules and those which reference the 
compiled modules (the object sizes would be changing due to 
the v-table modifications)


With those three simple changes to the language I think that 
this feature will work for every T.


Specifying that there will be no further linkage is the same as 
making T finite. T must be finite.


C# uses generics/IR/CLR so it can do things at run time that is 
effectively compile time for D.


By simply extending the grammar slightly in an intuitive way, 
we can get the explicit finite case, which is easy:


foo(T in [A,B,C])()

and possibly for your case

foo(T in )() would work

or

foo(T in )()

the `in` keyword makes sense here and is not used nor 
ambiguous, I believe.


While I agree that `in` does make sense for the semantics 
involved, it is already used to do a failable key lookup (return 
pointer to value or null if not present) into an associative 
array [1] and input contracts. It wouldn't be ambiguous AFAICT, 
but having a keyword mean three different things depending on 
context would make the language even more complex (to read).


W.r.t. to the idea in general: I think something like that could 
be valuable to have in the language, but since this essentially 
amounts to syntactic sugar (AFAICT), but I'm not (yet) convinced 
that with `static foreach` being included it's worth the cost.


[1] https://dlang.org/spec/expression.html#InExpression


Re: Help required on Array appender

2017-09-02 Thread Vino.B via Digitalmars-d-learn

On Saturday, 2 September 2017 at 15:47:31 UTC, Vino.B wrote:
On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson 
wrote:

[...]


Hi,

[...]


Hi,

  Was able to resolve the above issue, but again getting the same 
for other lines such as below when i tried to add the appender.


auto CleanDirlst = appender([]);
CleanDirlst ~= PVStore[1][i].to!string.split(",");


Error: cannot implicitly convert expression appender([]) of type 
Appender!(void[]) to string[].


Re: templated type reduction

2017-09-02 Thread EntangledQuanta via Digitalmars-d-learn
I should point out that I know it isn't safe in some cases(I 
already mentioned about the order mattering in some cases) but in 
that case a compiler error could be thrown. It's safe in some 
cases and I have the ability to create a safe case since I'm the 
designer of the code(e.g., put things in correct order).






templated type reduction

2017-09-02 Thread EntangledQuanta via Digitalmars-d-learn

Suppose one had the need to template a something like

struct X(T)
{
   string type = T.stringof;
   T t;
}


But one needs to get the type to know how to interpret X!T but 
one only has a void* to a type X!T. That is, we know it is an "X" 
but we don't know the specific T.


Now, this is easy as X!void or X!int or adding any specific but 
arbitrary type T, if the value we want is not dependent T... but 
in this case it is:



void* x = new X!int;

(passed around the program)

switch(x.type)
{
case "int" : break;
}

which is invalid yet perfectly valid! Is there any way to make 
this work legitly in D? I could get the offset of the string then 
parse it, but that's a hack I'd rather not use and isn't really 
safe(change the order and it will break).


note that it is really no different from

struct X(T)
{
   string type = "asdf";
   T t;
}

in which we can do

string type = (cast(X!int)x).type; // = asdf

or

string type = (cast(X!float)x).type; // = asdf

but even this is a bit fishy.


Heres some code that does the offset hack:


struct X(T)
{
string type = T.stringof;
T x;
}

int main(string[] args)
{

void* x = new X!int;

int o = (X!float).type.offsetof;
auto y = *cast(string*)(x + o);
writeln(y);
return 0;
}




Re: Using closure causes GC allocation

2017-09-02 Thread Vino.B via Digitalmars-d-learn
On Saturday, 2 September 2017 at 20:10:58 UTC, Moritz Maxeiner 
wrote:

On Saturday, 2 September 2017 at 18:59:30 UTC, Vino.B wrote:

[...]


Cannot reproduce under Linux with dmd 2.076.0 (with commented 
out Windows-only check). I'll try to see what happens on 
Windows once I have a VM setup.



[...]


You changed the type of dFiles, which you return from 
cleanFiles, without changing the return type of cleanFiles. 
Change the return type of cleanFiles to the type the compiler 
error above tells you it should be (`Tuple!(string, string)[]` 
instead of `string[][]`), or let the compiler infer it via auto 
(`auto cleanFiles(...`).


Hi,

 Thank you very much, was able to resolve the second code issue 
by changing the return type of the function.


Re: nested module problem

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 2 September 2017 at 20:03:48 UTC, Jean-Louis Leroy 
wrote:

So I have:

jll@ORAC:~/dev/d/tests/modules$ tree
.
├── foo
│   └── bar.d
└── foo.d

foo.d contains:
import foo.bar;

bar.d is empty.


This means bar.d's module name will be inferred by the compiler 
[1], which will ignore the path you put it under, yielding the 
module name "bar", not "foo.bar" (one of the issues of doing 
otherwise would be how the compiler should know at which path 
depth the inference should start - and any solution to that other 
than simply ignoring the path would be full of special cases):


Modules have a one-to-one correspondence with source files. 
The module name is, by default, the file name with the path 
and extension stripped off, and can be set explicitly with the 
module declaration.




Now I try compiling:
jll@ORAC:~/dev/d/tests/modules$ dmd -c foo.d


This looks like a compiler bug to me (accepts invalid), though 
I'm not certain.



jll@ORAC:~/dev/d/tests/modules$ dmd -c foo/bar.d


(No issue here, just an empty module being compiled separately)



So far so good. Now I try it the way dub does it:
jll@ORAC:~/dev/d/tests/modules$ dmd -c foo.d foo/bar.d
foo.d(1): Error: module bar from file foo/bar.d must be 
imported with 'import bar;'


What's up?


This doesn't work, because of the inferred module name for 
foo/bar.d being "bar".
So the compiler wants you to import it by the name it has 
inferred for you (The fix being either specifying the module name 
in foo/bar.d as `module foo.bar`, or importing it as via `import 
bar;` in foo.d).

[1] https://dlang.org/spec/module.html


Re: Bug in D!!!

2017-09-02 Thread EntangledQuanta via Digitalmars-d-learn
On Saturday, 2 September 2017 at 16:20:10 UTC, Jesse Phillips 
wrote:
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
Regardless of the implementation, the idea that we should 
throw the baby out with the bathwater is simply wrong. At 
least there are a few who get that. By looking in to it in a 
serious manner an event better solution might be found. Not 
looking at all results in no solutions and no progress.


Problem is that you didn't define the problem. You showed some 
code the compiler rejected and expressed that the compiler 
needed to figure it out. You did change it to having the 
compiler instantiate specified types, but that isn't defining 
the problem.


I think the problem is clearly defined, it's not my job to be a D 
compiler researcher and spell everything out for everyone else. 
Do I get paid for solving D's problems?


You didn't like the code needed which would generate the 
functions and you hit a Visual D with the new static foreach.


This sentence makes no sense. "hit a Visual D" what? Do you mean 
bug? If that is the case, how is that my fault? Amd I suppose to 
know off the bat that an access violation is caused by Visual D 
and not dmd when there is no info about the violation? Is it my 
fault that someone didn't code one of those tools good enough to 
express enough information for one to figure it out immediately?


All of these are problems you could define, and you could have 
evaluated static foreach as a solution but instead stopped at 
problems with the tooling.


Huh? I think you fail to understand the real problem. The problem 
has nothing to do with tooling and I never said it did. The 
static foreach "solution" came after the fact when SEVERAL 
people(ok, 2) said it was an impossible task to do. That is where 
all this mess started. I then came up with a solution which 
proved that it is possible to do on some level, that is a 
solution to a problem that was defined, else the solution 
wouldn't exist.



You also don't appear to care about the complexity of the 
language. I expressed three required changes some of which may 
not play nicely with least surprise. You went straight to, we 
just need to define a syntax for that instead of expressing 
concern that the compiler will also need to handle errors to 
the use, such that the user understands that a feature they use 
is limited to very specific situations.


Do you not understand that if a library solution exists then 
there is no real complexity added? It is called "lowering" by 
some. The compiler simply "rewrites" whatever new syntax is added 
in a form that the library solution realized. You are pretended, 
why?, that what I am proposed will somehow potentially affect 
every square micron of the D language and compiler, when it won't.


Not all additions to a compiler are add *real* complexity. That 
is a failing of you and many on the D forums who resist change.


Consider if you have a module defined interface, is that 
interface only available for use in that module? If not, how 
does a different model inherent the interface, does it need a 
different syntax.


What does that have to do with this problem? We are not talking 
about interfaces. We are talking about something inside 
interfaces, so the problem about interfaces is irrelevant to this 
discussion because it applies to interfaces in general... 
interfaces that already exist and the problem exists regardless 
of what I


There is a lot more to a feature then having a way to express 
your desires. If your going to stick to a stance that it must 
exist and aren't going to accept there are problems with the 
request why expect others to work through the request.



No, your problem is your ego and your inability to interpret 
things outside of your own mental box. You should always keep in 
mind that you are interpreting someone elses mental wordage in 
your own way and it is not a perfect translation, in fact, we are 
lucky if 50% is interpreted properly. Now, if I do not have a 
right to express my desires, then at least state that, but I do 
have a right not to express any more than that. As far as 
motivating other people, that is isn't my job. I could care less 
actually. D is a hobby for me and I do it because I like the 
power D has, but D is the most frustrating language I have ever 
used. It's the most(hyperbole) buggy, most incomplete(good docs 
system: regardless of what the biased want to claim, tool, etc), 
most uninformative(errors that just toss the whole kitchen sink 
at you), etc.  But I do have hope... which is the only reason I 
use it. Maybe I'm just an idiot and should go with the crowed, it 
would at least save me some frustration. C#, since you are 
familiar with it, you should know there is a huge difference. If 
D was like C# as far as the organizational structure(I do not 
mean MS, I mean the docs, library, etc) you would surely agree 
that D would most likely be the #1 language on this planet? C# 
has 

Re: string to character code hex string

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 2 September 2017 at 20:02:37 UTC, bitwise wrote:
On Saturday, 2 September 2017 at 18:28:02 UTC, Moritz Maxeiner 
wrote:


In UTF8:

--- utfmangle.d ---
void fun_ༀ() {}
pragma(msg, fun_ༀ.mangleof);
---

---
$ dmd -c utfmangle.d
_D6mangle7fun_ༀFZv
---

Only universal character names for identifiers are allowed, 
though, as per [1]


[1] https://dlang.org/spec/lex.html#identifiers


What I intend to do is this though:

void fun(string s)() {}
pragma(msg, fun!"ༀ".mangleof);

which gives:
_D7mainMod21__T3funVAyaa3_e0bc80Z3funFNaNbNiNfZv

where "e0bc80" is the 3 bytes of "ༀ".


Interesting, I wasn't aware of that (though after thinking about 
it, it does make sense, as identifiers can only have visible 
characters in them, while a string could have things such as 
control characters inside), thanks! That behaviour is defined 
here [1], btw (the line `CharWidth Number _ HexDigits`).


[1] https://dlang.org/spec/abi.html#Value


Re: string to character code hex string

2017-09-02 Thread bitwise via Digitalmars-d-learn
On Saturday, 2 September 2017 at 18:28:02 UTC, Moritz Maxeiner 
wrote:

[...]


Code will eventually look something like the following.
The point is to be able to retrieve the exported function at 
runtime only by knowing what the template arg would have been.


export extern(C) const(Reflection) dummy(string fqn)(){ ... }

int main(string[] argv)
{
enum ARG = "AA";
auto hex = toAsciiHex(ARG);

// original
writeln(dummy!ARG.mangleof);

// reconstructed at runtime
auto remangled = dummy!"".mangleof;

remangled = remangled.replaceFirst(
"_D7mainMod17", "_D7mainMod" ~ (17 + 
hex.length).to!string);


remangled = remangled.replaceFirst(
"VAyaa0_", "VAyaa" ~ ARG.length.to!string ~ "_" ~ hex);

writeln(remangled);

return 0;
}




Re: Web servers in D

2017-09-02 Thread bauss via Digitalmars-d-learn

On Saturday, 2 September 2017 at 20:18:17 UTC, bauss wrote:

On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote:

[...]


Here is another template engine that can be used along with 
vibe. I actually made it for the same reason you don't wanna 
use vibe. Because I didn't like the template language and I was 
more familiar with razor templates from ASP.NET


https://github.com/bausshf/Diamond


To add onto this you can use mysql-native with vibe.d.

https://github.com/mysql-d/mysql-native


Re: Web servers in D

2017-09-02 Thread bauss via Digitalmars-d-learn

On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote:
What libraries are people using to run webservers other than 
vibe.d?


Don't get me wrong I like the async-io aspect of vibe.d but I 
don't like the weird template language and the fact that it 
caters to mongo crowd.


I think for D to a have good web story it needs to appeal to 
serious backend developers, not hipsters who go after fads 
(mongodb is a fad, jade/haml is a fad).


I probably need to combine several libraries, but the features 
I'm looking for are:


- Spawn an HTTP server listening on a port, and routing 
requests to functions/delegates, without hiding the details of 
the http request/response objects (headers, cookies, etc).


- Support for websockets

- Runs delegates in fibers/coroutines

- Basic database connectivity (No "orm" needed; just raw sql).

- When iterating the result set of a sql query, has the ability 
to automatically map each row against a struct, and throw if 
the structure does not match.


- More generally, map any arbitrary object (such as json) to a 
struct. Something like Zewo/Reflection package for swift[0].


[0]: https://github.com/Zewo/Reflection

I feel like Vibe.d satisfies my first 3 requirements, but for 
the rest I will probably have to look for something else.


Here is another template engine that can be used along with vibe. 
I actually made it for the same reason you don't wanna use vibe. 
Because I didn't like the template language and I was more 
familiar with razor templates from ASP.NET


https://github.com/bausshf/Diamond


Re: Using closure causes GC allocation

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 2 September 2017 at 18:59:30 UTC, Vino.B wrote:
On Saturday, 2 September 2017 at 18:32:55 UTC, Moritz Maxeiner 
wrote:

On Saturday, 2 September 2017 at 18:08:19 UTC, vino.b wrote:
On Saturday, 2 September 2017 at 18:02:06 UTC, Moritz 
Maxeiner wrote:

On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote:

[...]


Line 25 happens because of `[a.name]`. You request a new 
array: the memory for this has to be allocated (the reason 
why the compiler says "may" is because sometimes, e.g. if 
the array literal itself contains only literals, the 
allocations needn't happen at runtime and no GC call is 
necessary). Since you don't actually use the array, get rid 
of it:


[...]


Hi,

  Thank you for your help and the DMD version that i am using 
is DMD 2.076.0 and yes I am on windows.


Please post a compilable, minimal example including how that 
function gets called that yields you that compiler output.


Hi,

 Please find the example code below,

[...]


Cannot reproduce under Linux with dmd 2.076.0 (with commented out 
Windows-only check). I'll try to see what happens on Windows once 
I have a VM setup.




Another similar issue :
 I removed the [a.name] and the issue in line 25 has resolved, 
but for another function i am getting the same error


string[][] cleanFiles(string FFs, string Step) {
	auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => 
a.isFile).map!(a =>[a.name , a.timeCreated.toSimpleString[0 .. 
20]]).array;  -> Issue in this line

if (Step == "run")
dFiles.each!(a => a[0].remove);
return dFiles;
}

if the replace the line in error as below then i am getting the 
error "Error: cannot implicitly convert expression dFiles of 
type Tuple!(string, string)[] to string[][]"


auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => 
a.isFile).map!(a => tuple(a.name, 
a.timeCreated.toSimpleString[0 .. 20])).array;


You changed the type of dFiles, which you return from cleanFiles, 
without changing the return type of cleanFiles. Change the return 
type of cleanFiles to the type the compiler error above tells you 
it should be (`Tuple!(string, string)[]` instead of 
`string[][]`), or let the compiler infer it via auto (`auto 
cleanFiles(...`).


nested module problem

2017-09-02 Thread Jean-Louis Leroy via Digitalmars-d-learn

So I have:

jll@ORAC:~/dev/d/tests/modules$ tree
.
├── foo
│   └── bar.d
└── foo.d

foo.d contains:
import foo.bar;

bar.d is empty.

Now I try compiling:
jll@ORAC:~/dev/d/tests/modules$ dmd -c foo.d
jll@ORAC:~/dev/d/tests/modules$ dmd -c foo/bar.d

So far so good. Now I try it the way dub does it:
jll@ORAC:~/dev/d/tests/modules$ dmd -c foo.d foo/bar.d
foo.d(1): Error: module bar from file foo/bar.d must be imported 
with 'import bar;'


What's up?



Re: string to character code hex string

2017-09-02 Thread bitwise via Digitalmars-d-learn
On Saturday, 2 September 2017 at 18:28:02 UTC, Moritz Maxeiner 
wrote:


In UTF8:

--- utfmangle.d ---
void fun_ༀ() {}
pragma(msg, fun_ༀ.mangleof);
---

---
$ dmd -c utfmangle.d
_D6mangle7fun_ༀFZv
---

Only universal character names for identifiers are allowed, 
though, as per [1]


[1] https://dlang.org/spec/lex.html#identifiers


What I intend to do is this though:

void fun(string s)() {}
pragma(msg, fun!"ༀ".mangleof);

which gives:
_D7mainMod21__T3funVAyaa3_e0bc80Z3funFNaNbNiNfZv

where "e0bc80" is the 3 bytes of "ༀ".

The function will be internal to my library. The only thing 
provided from outside will be the string template argument, which 
is meant to represent a fully qualified type name.





Re: Using closure causes GC allocation

2017-09-02 Thread Vino.B via Digitalmars-d-learn
On Saturday, 2 September 2017 at 18:32:55 UTC, Moritz Maxeiner 
wrote:

On Saturday, 2 September 2017 at 18:08:19 UTC, vino.b wrote:
On Saturday, 2 September 2017 at 18:02:06 UTC, Moritz Maxeiner 
wrote:

On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote:

[...]


Line 25 happens because of `[a.name]`. You request a new 
array: the memory for this has to be allocated (the reason 
why the compiler says "may" is because sometimes, e.g. if the 
array literal itself contains only literals, the allocations 
needn't happen at runtime and no GC call is necessary). Since 
you don't actually use the array, get rid of it:


[...]


Hi,

  Thank you for your help and the DMD version that i am using 
is DMD 2.076.0 and yes I am on windows.


Please post a compilable, minimal example including how that 
function gets called that yields you that compiler output.


Hi,

 Please find the example code below,

import std.stdio: File,writeln;
import std.datetime.systime: Clock, days, SysTime;
import std.file: SpanMode, dirEntries, exists, isFile, mkdir, 
remove;

import std.typecons: tuple;
import std.algorithm:  filter, map, each;
import std.array: array;

void logClean (string[] Lglst, int LogAge) {
if (!Lglst[0].exists) { mkdir(Lglst[0]); }
auto ct1 = Clock.currTime();
auto st1 = ct1 + days(-LogAge);
	auto dFiles = dirEntries(Lglst[0], SpanMode.shallow).filter!(a 
=> a.exists && a.isFile && a.timeCreated < st1).map!(a => 
tuple(a.name)).array;

  dFiles.each!(a => a[0].remove);
}

void main () {
string[] LogDir = 
["C:\\Users\\bheev1\\Desktop\\Current\\Script\\D\\Logs"];

int  LogAge = 1;
logClean(LogDir,LogAge);
}

Another similar issue :
 I removed the [a.name] and the issue in line 25 has resolved, 
but for another function i am getting the same error


string[][] cleanFiles(string FFs, string Step) {
	auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => 
a.isFile).map!(a =>[a.name , a.timeCreated.toSimpleString[0 .. 
20]]).array;  -> Issue in this line

if (Step == "run")
dFiles.each!(a => a[0].remove);
return dFiles;
}

if the replace the line in error as below then i am getting the 
error "Error: cannot implicitly convert expression dFiles of type 
Tuple!(string, string)[] to string[][]"


auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => 
a.isFile).map!(a => tuple(a.name, a.timeCreated.toSimpleString[0 
.. 20])).array;




Re: Using closure causes GC allocation

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 2 September 2017 at 18:08:19 UTC, vino.b wrote:
On Saturday, 2 September 2017 at 18:02:06 UTC, Moritz Maxeiner 
wrote:

On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote:

[...]


Line 25 happens because of `[a.name]`. You request a new 
array: the memory for this has to be allocated (the reason why 
the compiler says "may" is because sometimes, e.g. if the 
array literal itself contains only literals, the allocations 
needn't happen at runtime and no GC call is necessary). Since 
you don't actually use the array, get rid of it:


[...]


Hi,

  Thank you for your help and the DMD version that i am using 
is DMD 2.076.0 and yes I am on windows.


Please post a compilable, minimal example including how that 
function gets called that yields you that compiler output.


Re: string to character code hex string

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 2 September 2017 at 18:07:51 UTC, bitwise wrote:
On Saturday, 2 September 2017 at 17:45:30 UTC, Moritz Maxeiner 
wrote:


If this (unnecessary waste) is of concern to you (and from the 
fact that you used ret.reserve I assume it is), then the easy 
fix is to use `sformat` instead of `format`:




Yes, thanks. I'm going to go with a variation of your approach:

private
string toAsciiHex(string str)
{
import std.ascii : lowerHexDigits;
import std.exception: assumeUnique;

auto ret = new char[str.length * 2];
int i = 0;

foreach(c; str) {
ret[i++] = lowerHexDigits[(c >> 4) & 0xF];
ret[i++] = lowerHexDigits[c & 0xF];
}

return ret.assumeUnique;
}


If you never need the individual character function, that's 
probably the best in terms of readability, though with a decent 
compiler, that and the two functions one should result in the 
same opcode (except for bitshift swap).




I'm not sure how the compiler would mangle UTF8, but I intend 
to use this on one specific function (actually the 100's of 
instantiations of it).


In UTF8:

--- utfmangle.d ---
void fun_ༀ() {}
pragma(msg, fun_ༀ.mangleof);
---

---
$ dmd -c utfmangle.d
_D6mangle7fun_ༀFZv
---

Only universal character names for identifiers are allowed, 
though, as per [1]


[1] https://dlang.org/spec/lex.html#identifiers



Re: Using closure causes GC allocation

2017-09-02 Thread vino.b via Digitalmars-d-learn
On Saturday, 2 September 2017 at 18:02:06 UTC, Moritz Maxeiner 
wrote:

On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote:

[...]


Line 25 happens because of `[a.name]`. You request a new array: 
the memory for this has to be allocated (the reason why the 
compiler says "may" is because sometimes, e.g. if the array 
literal itself contains only literals, the allocations needn't 
happen at runtime and no GC call is necessary). Since you don't 
actually use the array, get rid of it:


[...]


Hi,

  Thank you for your help and the DMD version that i am using is 
DMD 2.076.0 and yes I am on windows.


From,
Vino.B


Re: string to character code hex string

2017-09-02 Thread bitwise via Digitalmars-d-learn
On Saturday, 2 September 2017 at 17:45:30 UTC, Moritz Maxeiner 
wrote:


If this (unnecessary waste) is of concern to you (and from the 
fact that you used ret.reserve I assume it is), then the easy 
fix is to use `sformat` instead of `format`:




Yes, thanks. I'm going to go with a variation of your approach:

private
string toAsciiHex(string str)
{
import std.ascii : lowerHexDigits;
import std.exception: assumeUnique;

auto ret = new char[str.length * 2];
int i = 0;

foreach(c; str) {
ret[i++] = lowerHexDigits[(c >> 4) & 0xF];
ret[i++] = lowerHexDigits[c & 0xF];
}

return ret.assumeUnique;
}

I'm not sure how the compiler would mangle UTF8, but I intend to 
use this on one specific function (actually the 100's of 
instantiations of it). It will predictably named though.


   Thanks!




Re: string to character code hex string

2017-09-02 Thread lithium iodate via Digitalmars-d-learn

On Saturday, 2 September 2017 at 17:41:34 UTC, Ali Çehreli wrote:
You're right but I think there is no intention of interpreting 
the result as UTF-8. "f62026" is just to be used as "f62026", 
which can be converted byte-by-byte back to "ö…". That's how 
understand the requirement anyway.


Ali


That is not possible, because you cannot know whether "f620" and 
"26" or "f6" and "2026" (or any other combination) should form a 
code point each. Additional padding to constant width (8 hex 
chars) is needed.


Re: Using closure causes GC allocation

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 2 September 2017 at 17:43:08 UTC, Vino.B wrote:

Hi All,

   Request your help on how to solve the issue in the below 
code as when i execute the program with -vgc it state as below:


NewTD.d(21): vgc: using closure causes GC allocation
NewTD.d(25): vgc: array literal may cause GC allocation

void logClean (string[] Lglst, int LogAge) {   //Line 21
if (!Lglst[0].exists) { mkdir(Lglst[0]); }
auto ct1 = Clock.currTime();
auto st1 = ct1 + days(-LogAge);
	auto dFiles = dirEntries(Lglst[0], SpanMode.shallow).filter!(a 
=> a.exists && a.isFile && a.timeCreated < st1).map!(a 
=>[a.name]).array;  // Line 25

  dFiles.each!(f => f[0].remove);
}


Line 25 happens because of `[a.name]`. You request a new array: 
the memory for this has to be allocated (the reason why the 
compiler says "may" is because sometimes, e.g. if the array 
literal itself contains only literals, the allocations needn't 
happen at runtime and no GC call is necessary). Since you don't 
actually use the array, get rid of it:


---
void logClean (string[] Lglst, int LogAge) {   //Line 21
if (!Lglst[0].exists) { mkdir(Lglst[0]); }
auto ct1 = Clock.currTime();
auto st1 = ct1 + days(-LogAge);
	auto dFiles = dirEntries(Lglst[0], SpanMode.shallow).filter!(a 
=> a.exists && a.isFile && a.timeCreated < st1).array;  // Line 25

  dFiles.each!(f => f.remove);
}
---

I cannot reproduce the line 21 report, though.
Since you use `timeCreated` I assume you're on Windows, but 
what's your D compiler, which D frontend version are you using, 
etc. (all the things needed to attempt to reproduce the error).


Re: string to character code hex string

2017-09-02 Thread bitwise via Digitalmars-d-learn

On Saturday, 2 September 2017 at 17:41:34 UTC, Ali Çehreli wrote:


You're right but I think there is no intention of interpreting 
the result as UTF-8. "f62026" is just to be used as "f62026", 
which can be converted byte-by-byte back to "ö…". That's how 
understand the requirement anyway.


Ali


My intention is compute the mangling of a D template function 
that takes a string as a template parameter without having the 
symbol available. I think that means that converting each byte of 
the string to hex and tacking it on would suffice.




Re: string to character code hex string

2017-09-02 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 2 September 2017 at 16:23:57 UTC, bitwise wrote:

On Saturday, 2 September 2017 at 15:53:25 UTC, bitwise wrote:

[...]


This seems to work well enough.

string toAsciiHex(string str)
{
import std.array : appender;

auto ret = appender!string(null);
ret.reserve(str.length * 2);
foreach(c; str) ret.put(format!"%x"(c));
return ret.data;
}


Note: Each of those format calls is going to allocate a new 
string, followed by put copying that new string's content over 
into the appender, leaving you with \theta(str.length) tiny 
memory chunks that aren't used anymore for the GC to eventually 
collect.


If this (unnecessary waste) is of concern to you (and from the 
fact that you used ret.reserve I assume it is), then the easy fix 
is to use `sformat` instead of `format`:


---
string toHex(string str)
{
import std.format : sformat;
import std.exception: assumeUnique;

auto   ret = new char[str.length * 2];
size_t len;

foreach (c; str)
{
auto slice = sformat!"%x"(ret[len..$], c);
//auto slice = toHex(ret[len..$], c);
assert (slice.length <= 2);
len += slice.length;
}

return ret[0..len].assumeUnique;
}
---

If you want to cut out the format import entirely, notice the 
`auto slice = toHex...` line, which can be implemented like this 
(always returns two chars):


---
char[] toHex(char[] buf, char c)
{
import std.ascii : lowerHexDigits;

assert (buf.length >= 2);
buf[0] = lowerHexDigits[(c & 0xF0) >> 4];
buf[1] = lowerHexDigits[c & 0x0F];

return buf[0..2];
}
---


Using closure causes GC allocation

2017-09-02 Thread Vino.B via Digitalmars-d-learn

Hi All,

   Request your help on how to solve the issue in the below code 
as when i execute the program with -vgc it state as below:


NewTD.d(21): vgc: using closure causes GC allocation
NewTD.d(25): vgc: array literal may cause GC allocation

void logClean (string[] Lglst, int LogAge) {   //Line 21
if (!Lglst[0].exists) { mkdir(Lglst[0]); }
auto ct1 = Clock.currTime();
auto st1 = ct1 + days(-LogAge);
	auto dFiles = dirEntries(Lglst[0], SpanMode.shallow).filter!(a 
=> a.exists && a.isFile && a.timeCreated < st1).map!(a 
=>[a.name]).array;  // Line 25

  dFiles.each!(f => f[0].remove);
}

From,
Vino.B


Re: string to character code hex string

2017-09-02 Thread Ali Çehreli via Digitalmars-d-learn

On 09/02/2017 10:07 AM, lithium iodate wrote:

>> Lazy version, which the user can easily generate a string from by
>> appending .array:
>>
>> import std.stdio;
>>
>> auto hexString(R)(R input) {
>> import std.conv : text;
>> import std.string : format;
>> import std.algorithm : map, joiner;
>> return input.map!(c => format("%02x", c)).joiner;
>> }
>>
>> void main() {
>> writeln("AAA".hexString);
>> }
>>
>> To generate string:
>>
>> import std.range : array;
>> writeln("AAA".hexString.array);
>>
>> Ali
>
> Please correct my if i'm wrong, but it think this has issues regarding
> unicode.
> "ö…" becomes "f62026", which, interpreted as UTF-8, is a control
> character ~ " &", so you either need to add padding or use ..byCodeUnit
> so it becomes "c3b6e280a6" (correct UTF-8) instead.

You're right but I think there is no intention of interpreting the 
result as UTF-8. "f62026" is just to be used as "f62026", which can be 
converted byte-by-byte back to "ö…". That's how understand the 
requirement anyway.


Ali



Re: string to character code hex string

2017-09-02 Thread Ali Çehreli via Digitalmars-d-learn

On 09/02/2017 09:23 AM, bitwise wrote:

On Saturday, 2 September 2017 at 15:53:25 UTC, bitwise wrote:

[...]


This seems to work well enough.

string toAsciiHex(string str)
{
import std.array : appender;

auto ret = appender!string(null);
ret.reserve(str.length * 2);
foreach(c; str) ret.put(format!"%x"(c));
return ret.data;
}



Lazy version, which the user can easily generate a string from by 
appending .array:


import std.stdio;

auto hexString(R)(R input) {
import std.conv : text;
import std.string : format;
import std.algorithm : map, joiner;
return input.map!(c => format("%02x", c)).joiner;
}

void main() {
writeln("AAA".hexString);
}

To generate string:

import std.range : array;
writeln("AAA".hexString.array);

Ali



Re: string to character code hex string

2017-09-02 Thread bitwise via Digitalmars-d-learn

On Saturday, 2 September 2017 at 15:53:25 UTC, bitwise wrote:

[...]


This seems to work well enough.

string toAsciiHex(string str)
{
import std.array : appender;

auto ret = appender!string(null);
ret.reserve(str.length * 2);
foreach(c; str) ret.put(format!"%x"(c));
return ret.data;
}



Re: Bug in D!!!

2017-09-02 Thread Jesse Phillips via Digitalmars-d-learn
On Saturday, 2 September 2017 at 00:00:43 UTC, EntangledQuanta 
wrote:
Regardless of the implementation, the idea that we should throw 
the baby out with the bathwater is simply wrong. At least there 
are a few who get that. By looking in to it in a serious manner 
an event better solution might be found. Not looking at all 
results in no solutions and no progress.


Problem is that you didn't define the problem. You showed some 
code the compiler rejected and expressed that the compiler needed 
to figure it out. You did change it to having the compiler 
instantiate specified types, but that isn't defining the problem.


You didn't like the code needed which would generate the 
functions and you hit a Visual D with the new static foreach.


All of these are problems you could define, and you could have 
evaluated static foreach as a solution but instead stopped at 
problems with the tooling.


You also don't appear to care about the complexity of the 
language. I expressed three required changes some of which may 
not play nicely with least surprise. You went straight to, we 
just need to define a syntax for that instead of expressing 
concern that the compiler will also need to handle errors to the 
use, such that the user understands that a feature they use is 
limited to very specific situations.


Consider if you have a module defined interface, is that 
interface only available for use in that module? If not, how does 
a different model inherent the interface, does it need a 
different syntax.


There is a lot more to a feature then having a way to express 
your desires. If your going to stick to a stance that it must 
exist and aren't going to accept there are problems with the 
request why expect others to work through the request.


string to character code hex string

2017-09-02 Thread bitwise via Digitalmars-d-learn
I need to convert a string of characters to a string of their hex 
representations.


"AAA" -> "414141"

This seems like something that would be in the std lib, but I 
can't find it.

Does it exist?

  Thanks


Re: Help required on Array appender

2017-09-02 Thread Vino.B via Digitalmars-d-learn
On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson 
wrote:

On Saturday, 2 September 2017 at 10:15:04 UTC, Vino.B wrote:

Hi All,

 Can you please guide me how can i use array appender for the 
below piece of code


string[][] cleanFiles (string FFs, string Step) {
auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => 
a.isFile).map!(a => tuple(a.name , a.timeCreated)).array;

foreach (d; dFiles) {
if (Step == "dryrun")
{
Subdata ~=  [d[0], d[1].toSimpleString[0 
.. 20]];

 }
else if (Step == "run")
 {
remove(d[0]);
if (!d[0].exists)
Subdata ~=  [d[0], d[1].toSimpleString[0 .. 
20]];
}
}
return Subdata;
}

From,
Vino.B


If you're wanting to use appender just make an appender and 
replace the ~= to calls to appender.put(data);


if you're trying to make it faster, consider that Step could be 
a bool, your return type could be string[2][], the `if 
(!d[0].exists)` is redundant since `remove` will throw if it 
fails. That leaves you with


string[2][] cleanFiles(string FFs, bool dryrun)
{
auto dFiles = dirEntries(FFs, SpanMode.shallow)
  .filter!(a => a.isFile)
  .map!(a =>[a.name , 
a.timeCreated.toSimpleString[0 .. 20])

  .array;
if (! dryrun)
dFiles.each!(f => f[0].remove);
}


Hi,

 Thank you very much, and your idea help a lot, and the reason to 
use appender is for both faster and performance as my program 
use's many ~= function and found that using appender is the best 
way when compared with the ~= e.g;(MCresult.get ~= 
MCleanTaskData;)


void mCleanFiles (string[] Dirlist, File logF, File logE, string 
Step) {

 try {
 string[][] MCtext;
 string[][] MCEresult;
 auto MCresult = taskPool.workerLocalStorage(MCtext);
 logF.writeln("Function \t : List of the File's which are not 
placed in correct Location and list those deleted");

 logF.writeln("Dir. Scanned \t :", Dirlist);
 
logF.writeln("");

 logF.writefln("%-63s %.20s", "File Name", "CreationTime");
 
logF.writeln("");

 foreach (string Fs; parallel(Dirlist[0 .. $], 1)) {
auto FFs = Fs.strip;
auto MCleanTask = task(, FFs, Step);
MCleanTask.executeInNewThread();
auto MCleanTaskData = MCleanTask.workForce;
MCresult.get ~= MCleanTaskData;
}
foreach(i; MCresult.toRange)
			logF.writefln("%(%-(%-63s %)\n%)", i.sort!((a,b) => a[0] < 
b[0]).uniq);

logF.writeln("");
} catch (Exception e) { logE.writeln(e.msg); }
}

From,
Vino.B


Re: -betterC not working

2017-09-02 Thread Azi Hassan via Digitalmars-d-learn

On Friday, 1 September 2017 at 22:13:53 UTC, SrMordred wrote:

On Wednesday, 30 August 2017 at 23:12:07 UTC, SrMordred wrote:
On Wednesday, 30 August 2017 at 22:45:27 UTC, Adam D. Ruppe 
wrote:

On Wednesday, 30 August 2017 at 22:18:07 UTC, SrMordred wrote:

DMD64 D Compiler v2.075.1


-betterC as described recently is not yet released.

https://dlang.org/changelog/2.076.0_pre.html

is where it gets the new behavior, and that isn't scheduled 
for formal release until the end of the week.


(it seriously bothers me that Walter has been advertising 
this so much when the little bit that is implemented isn't 
even released yet, and what is implemented is barely usable.)



The betterC switch itself is not new, but it does virtually 
nothing until that latest prerelease compiler.


ooops, little missed detail ;)

At least its near.


Hello again.
Downloaded last version.

//fail at my example, so its working as intended
dmd -betterC source/app.d app.d

//compiles. so problem with dub only
dub run --config=application --arch=x86_64 --build=debug 
--compiler=dmd


Running dub run with --verbose indicates that dub is actually 
running both the "dmd -g -c -betterC source/app.d -ofd_betterc.o" 
and the "dmd -ofd_betterc d_betterc.o -g" commands. Note that the 
second dmd call doesn't include the -betterC flag. Running the 
second dmd command manually with the -betterC flag does give the 
expected undefined reference errors.


Re: Help required on Array appender

2017-09-02 Thread Azi Hassan via Digitalmars-d-learn
On Saturday, 2 September 2017 at 12:54:48 UTC, Nicholas Wilson 
wrote:


If you're wanting to use appender just make an appender and 
replace the ~= to calls to appender.put(data);


Just making Subdata an Appender!(string[][]) (or 
Appender!(Tuple!(string, string)[])) is enough since it already 
overloads the ~= operator.


Performance aside, a small nitpick is that it's possible to write 
filter!isFile instead of filter!(a => a.isFile) since isFile only 
accepts one argument.


Re: Help required on Array appender

2017-09-02 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 2 September 2017 at 10:15:04 UTC, Vino.B wrote:

Hi All,

 Can you please guide me how can i use array appender for the 
below piece of code


string[][] cleanFiles (string FFs, string Step) {
auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => 
a.isFile).map!(a => tuple(a.name , a.timeCreated)).array;

foreach (d; dFiles) {
if (Step == "dryrun")
{
Subdata ~=  [d[0], d[1].toSimpleString[0 .. 
20]];

 }
else if (Step == "run")
 {
remove(d[0]);
if (!d[0].exists)
Subdata ~=  [d[0], d[1].toSimpleString[0 .. 
20]];
}
}
return Subdata;
}

From,
Vino.B


If you're wanting to use appender just make an appender and 
replace the ~= to calls to appender.put(data);


if you're trying to make it faster, consider that Step could be a 
bool, your return type could be string[2][], the `if 
(!d[0].exists)` is redundant since `remove` will throw if it 
fails. That leaves you with


string[2][] cleanFiles(string FFs, bool dryrun)
{
auto dFiles = dirEntries(FFs, SpanMode.shallow)
  .filter!(a => a.isFile)
  .map!(a =>[a.name , 
a.timeCreated.toSimpleString[0 .. 20])

  .array;
if (! dryrun)
dFiles.each!(f => f[0].remove);
}


Re: Web servers in D

2017-09-02 Thread Seb via Digitalmars-d-learn
On Saturday, 2 September 2017 at 09:26:27 UTC, Andrew Chapman 
wrote:

On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote:

[...]



[...]


Don't use these components :-)


[...]


Vibe.d does this - just don't use the automatic API generation 
feature if you don't like it.  Note, you can get access to the 
request/response objects even if you do use the API generation 
by using an @before method.  E.g. in an interface you may have 
something like this:


There is built-in support for authentication in vibe.d:

https://github.com/rejectedsoftware/vibe.d/tree/master/examples/web-auth


Problems with std.experimental.allocator

2017-09-02 Thread Igor via Digitalmars-d-learn
I realize these are not yet stable but I would like to know if I 
am doing something wrong or is it a lib bug.


My first attempt was to do this:

theAllocator = allocatorObject(Region!MmapAllocator(1024*MB));

If I got it right this doesn't work because it actually does this:

1. Create Region struct and allocate 1024MB from MMapAllocator
2. Wrap the struct in IAllocator by copying it because it has 
state

3. Destroy original struct which frees the memory
4. Now the struct copy points to released memory

Am I right here?

Next attempt was this:

	theAllocator = 
allocatorObject(Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB)));


Since I give actual memory instead of the allocator to the Region 
it can not dealocate that memory so even the copy will still 
point to valid memory. After looking at what will the 
allocatorObject do in this case my conclusion is that it will 
take a "copyable" static if branch and create an instance of 
CAllocatorImpl which will have a "Region!() impl" field within 
itself but given Region!() struct is never copied into that field.


Am I right here?

If I am right about both are then these considered as lib bugs?

I finally got it working with:

	auto newAlloc = 
Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB));

theAllocator = allocatorObject();

Next I tried setting processAllocator instead of theAllocator by 
using:


auto newAlloc = 
Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB));

processAllocator = sharedAllocatorObject();

but that complained how it "cannot implicitly convert expression 
`pa` of type `Region!()*` to `shared(Region!()*)`" and since 
Region doesn't define its methods as shared does this mean one 
can not use Region as processAllocator? If that is so, what is 
the reason behind it?


Help required on Array appender

2017-09-02 Thread Vino.B via Digitalmars-d-learn

Hi All,

 Can you please guide me how can i use array appender for the 
below piece of code


string[][] cleanFiles (string FFs, string Step) {
auto dFiles = dirEntries(FFs, SpanMode.shallow).filter!(a => 
a.isFile).map!(a => tuple(a.name , a.timeCreated)).array;

foreach (d; dFiles) {
 if (Step == "dryrun")
{ Subdata ~=  [d[0], d[1].toSimpleString[0 .. 20]]; 
}
  else if (Step == "run") {
remove(d[0]);
if (!d[0].exists)
Subdata ~=  [d[0], 
d[1].toSimpleString[0 .. 20]];
}
}
return Subdata;
}

From,
Vino.B


Re: 24-bit int

2017-09-02 Thread Biotronic via Digitalmars-d-learn
On Saturday, 2 September 2017 at 00:43:00 UTC, Nicholas Wilson 
wrote:

On Friday, 1 September 2017 at 22:10:43 UTC, Biotronic wrote:

struct int24 {
ubyte[3] _payload;

this(int x) {
value = x;
}

...
}


You may also want to put an align(1) on it so that you dont 
waste 25% of the allocated memory in an array of int24's


The very first test in my code checks this:

int24[3] a;
assert(a.sizeof == 9);

On the other hand, using Mir's well-tested code instead of 
something I hacked together in 10 minutes is probably a good idea.


--
  Biotronic


Re: Web servers in D

2017-09-02 Thread Andrew Chapman via Digitalmars-d-learn

On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote:
What libraries are people using to run webservers other than 
vibe.d?


Don't get me wrong I like the async-io aspect of vibe.d but I 
don't like the weird template language and the fact that it 
caters to mongo crowd.


I think for D to a have good web story it needs to appeal to 
serious backend developers, not hipsters who go after fads 
(mongodb is a fad, jade/haml is a fad).


I probably need to combine several libraries, but the features 
I'm looking for are:


- Spawn an HTTP server listening on a port, and routing 
requests to functions/delegates, without hiding the details of 
the http request/response objects (headers, cookies, etc).


- Support for websockets

- Runs delegates in fibers/coroutines

- Basic database connectivity (No "orm" needed; just raw sql).

- When iterating the result set of a sql query, has the ability 
to automatically map each row against a struct, and throw if 
the structure does not match.


- More generally, map any arbitrary object (such as json) to a 
struct. Something like Zewo/Reflection package for swift[0].


[0]: https://github.com/Zewo/Reflection

I feel like Vibe.d satisfies my first 3 requirements, but for 
the rest I will probably have to look for something else.


Don't get me wrong I like the async-io aspect of vibe.d but I 
don't like the weird template language and the fact that it 
caters to mongo crowd.


Don't use these components :-)

- Spawn an HTTP server listening on a port, and routing 
requests to functions/delegates, without hiding the details of 
the http request/response objects (headers, cookies, etc).


Vibe.d does this - just don't use the automatic API generation 
feature if you don't like it.  Note, you can get access to the 
request/response objects even if you do use the API generation by 
using an @before method.  E.g. in an interface you may have 
something like this:


@method(HTTPMethod.POST)
@before!getRequestInfo("requestInfo")
@property Token login(LoginRequestMeta login, RequestInfo 
requestInfo);


And then define your getRequestInfo method like this:

static RequestInfo getRequestInfo(HTTPServerRequest req, 
HTTPServerResponse res)

{
RequestInfo requestInfo;
requestInfo.headers = req.headers;
requestInfo.ipAddress = req.clientAddress.toAddressString();
	requestInfo.userAgent = requestInfo.headers.get("User-Agent", 
"");


return requestInfo;
}

In this case I've grabbed the ip address and user agent of the 
user, but you could also grab cookies etc.


- When iterating the result set of a sql query, has the ability 
to automatically map each row against a struct, and throw if 
the structure does not match.


You can do this with MySQL Native whilst using vibe.d.  You might 
do something like this:


Prepared prepared = prepare(this.conn, sql);
prepared.setArgs(params);

auto row = prepared.queryRow();

if (row.isNull()) {
throw new Exception("Query returned an empty row");
}

T item;
try {
row.toStruct!T(item);
} catch(Exception e) {

}

Where T is your struct type that you're trying to convert the row 
to.


As for the template language, you could try:
http://code.dlang.org/packages/diamond
https://github.com/repeatedly/mustache-d
There are probably others.



Re: 24-bit int

2017-09-02 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 2 September 2017 at 07:20:07 UTC, kinke wrote:


struct int24 {
ubyte[3] _payload;
}

static assert(int24.sizeof == 3);
static assert(int24.alignof == 1);

Making absolute sense. ubytes don't need any specific alignment 
to be read efficiently.


Yes, that does make sense. It doesn't make sense that I didn't 
realize it.


Re: 24-bit int

2017-09-02 Thread kinke via Digitalmars-d-learn

On Saturday, 2 September 2017 at 02:37:08 UTC, Mike Parker wrote:
It's not a bug, but a feature. Data structure alignment is 
important for efficient reads, so several languages (D, C, C++, 
Ada, and more) will automatically pad structs so that they can 
maintain specific byte alignments. On a 32-bit system, 4-byte 
boundaries are the default. So a struct with 3 ubytes is going 
to be padded with an extra byte at the end. Telling the 
compiler to align on a 1-byte boundary (essentially disabling 
alignment) will save you space, but will will generally cost 
you cycles in accessing the data.


struct int24 {
ubyte[3] _payload;
}

static assert(int24.sizeof == 3);
static assert(int24.alignof == 1);

Making absolute sense. ubytes don't need any specific alignment 
to be read efficiently.