Re: the best language I have ever met(?)

2016-11-25 Thread Artur Skawina via Digitalmars-d-learn
On 11/25/16 18:33, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Friday, November 25, 2016 18:20:11 Artur Skawina via Digitalmars-d-learn 
> wrote:
>> On 11/25/16 17:30, Jonathan M Davis via Digitalmars-d-learn wrote:
>>> On Friday, November 25, 2016 17:03:32 Artur Skawina via
>>>>enum T[N] staticArray(T, alias ELS, size_t N=ELS.length) = ELS;
>>>>auto arr = staticArray!(ubyte, [1, 2, 3, 4]);
>>>
>>> That won't work with variables. e.g.
>>>
>>> ubyte a;
>>> auto arr = staticArray!(ubyte, [1, 2, 3, 4, a]);
>>>
>>> would fail to compile. It only works when all of the values are known at
>>> compile time, whereas
>>>
>>> ubyte a;
>>> ubyte[5] arr = [1, 2, 3, 4, a];
>>>
>>> would compile just fine.
>>
>> Now you're trying to change the scope. Of course this is a hack,
>> that's only useful in certain contexts, such as initializing static
>> arrays with known values, which this subthread is about.
> 
> How is it changing the scope? What has been asked for on several occasions -
> and what int[$] was supposed to fix - was the ability to intialize a static
> array while inferring its size.

It's a known language limitation, which can be worked around using
hacks such as the one I showed, that help in the very common cases
that appeared in this thread, add zero RT costs and work with VRP.
I didn't realize you were suggesting to use the function helper
route for the general case - no scope change, sorry.

> ubyte a;
> ubyte[5] arr = [1, 2, 3, 4, a];
> 
> is a perfectly legitimate example of initializing a static array, and
> there's no reason why it shouldn't be a goal to have it work with a function
> that infers the size of the static array.

The problem with such a function is that, just like every other function,
it's type can not depend on RT data, and that `typeof([1,a])` is `int[]`.
The information is lost at the function boundary. So the possible
improvements are a) changing the array literal semantics, and b)
improving IFTI. 

> We'd actually have it right now with
> 
> T[n] staticArray(T, size_t n)(auto ref T[n] arr)
> {
> return arr;
> }
> 
> except that VRP only works right now if no inferrence is done when
> instantiating the template.
> 
> auto sa = staticArray!(ubyte, 4)([1, 2, 3, 4]);
> 
> compiles just fine, but that obviously defeats the purpose of the template.
> If the compiler is improved so that
> 
> auto sa = staticArray!ubyte([1, 2, 3, 4]);
> 
> also works with VRP, then everything works just like it would with
> 
> ubyte a;
> ubyte[5] arr = [1, 2, 3, 4, a];
> 
> except that with the function, the size would be inferred.
> 
> ubyte a;
> auto arr = staticArray!ubyte([1, 2, 3, 4, a]);

IOW you want to improve IFTI, so that `n` is inferred from the
length of the passed argument. That would indeed work for array
literals and CTFE-able expressions. Any improvement to IFTI is a
good thing, but the RT cost of this helper could be high if it ever
doesn't get inlined and completely optimized away.
If the cost isn't an issue and a different syntax is acceptable
then this should already work:

   template staticArray(T, E...) {
  T[E.length] staticArray() @property { return [E]; }
   }
   template staticArray(E...) {
  typeof([E][0])[E.length] staticArray() @property { return [E]; }
   }

   ubyte a;
   auto sa = staticArray!(ubyte, 1, 2, 3, 4, a);
   auto sb = staticArray!(1, 2, 3, 4, a);

artur


Re: the best language I have ever met(?)

2016-11-25 Thread Artur Skawina via Digitalmars-d-learn
On 11/25/16 17:30, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Friday, November 25, 2016 17:03:32 Artur Skawina via Digitalmars-d-learn 
> wrote:
>> On 11/25/16 15:51, Jonathan M Davis via Digitalmars-d-learn wrote:
>>> On Friday, November 25, 2016 14:27:39 Igor Shirkalin via
>>> Digitalmars-d-learn>
>>> wrote:
>>>> I think you may write it (I mean actual D) with using some
>>>> template like this:
>>>>
>>>> auto array = static_array!uint(1, 2, 3, 4)
>>>>
>>>> Could you please help to writeown this template in the best and
>>>> clear manner?
>>>
>>> That's easy. The problem is if you want it to have the same semantics as
>>>
>>> uint[4] arr = [1, 2, 3, 4];
>>>
>>> In particular, VRP (Value Range Propagation) is a problem. This compiles
>>>
>>> ubyte[4] arr = [1, 2, 3, 4];
>>>
>>> because each of the arguments is known to fit in a ubyte. However,
>>> making
>>>
>>> auto arr = staticArray!ubyte(1, 2, 3, 4);
>>>
>>> do the same without forcing a cast is difficult. [...]
>>
>>enum T[N] staticArray(T, alias ELS, size_t N=ELS.length) = ELS;
>>auto arr = staticArray!(ubyte, [1, 2, 3, 4]);
> 
> That won't work with variables. e.g.
> 
> ubyte a;
> auto arr = staticArray!(ubyte, [1, 2, 3, 4, a]);
> 
> would fail to compile. It only works when all of the values are known at
> compile time, whereas
> 
> ubyte a;
> ubyte[5] arr = [1, 2, 3, 4, a];
> 
> would compile just fine.

Now you're trying to change the scope. Of course this is a hack,
that's only useful in certain contexts, such as initializing static
arrays with known values, which this subthread is about.

It actually makes the source code (look) worse; having to use lots of 
such module- or project-local hacks doesn't scale, and is a symptom
of language problems.

The point, however, was that that is the only way to get VRP - the
values must be available at CT for VRP to work effectively.
Your suggestion to "fix" VRP would break CTFE (different implicit
conversions would be allowed at CT and RT) and could result in
code compiling or not depending on the function arguments used,
possibly in a very unintuitive way (eg depending on if the function
args values happened to be CTFE-able).

artur



Re: the best language I have ever met(?)

2016-11-25 Thread Artur Skawina via Digitalmars-d-learn
On 11/25/16 15:51, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Friday, November 25, 2016 14:27:39 Igor Shirkalin via Digitalmars-d-learn 
> wrote:
>> I think you may write it (I mean actual D) with using some
>> template like this:
>>
>> auto array = static_array!uint(1, 2, 3, 4)
>>
>> Could you please help to write down this template in the best and
>> clear manner?
> 
> That's easy. The problem is if you want it to have the same semantics as
> 
> uint[4] arr = [1, 2, 3, 4];
> 
> In particular, VRP (Value Range Propagation) is a problem. This compiles
> 
> ubyte[4] arr = [1, 2, 3, 4];
> 
> because each of the arguments is known to fit in a ubyte. However, making
> 
> auto arr = staticArray!ubyte(1, 2, 3, 4);
> 
> do the same without forcing a cast is difficult. [...]

   enum T[N] staticArray(T, alias ELS, size_t N=ELS.length) = ELS;
   auto arr = staticArray!(ubyte, [1, 2, 3, 4]);

artur


Re: a lambda with arguments has type void?

2016-06-09 Thread Artur Skawina via Digitalmars-d-learn
On 06/09/16 07:20, cy via Digitalmars-d-learn wrote:
> Like this is why it doesn't really make sense:
> 
> import std.stdio;
> 
> auto foo(Callable)(Callable c) {
>   return c(42);
> }
> 
> auto foo2(alias c)() {
>   return c(42);
> }
> 
> void main() {
>   // this works, when you know it's an int delegate(int) beforehand...
>   writeln(foo!(int delegate(int))((arg) => arg + 1));
>   // and this can infer that your argument is an int delegate(int)
>   writeln(foo2!((arg) => arg + 1));

No. `a=>a+1` is a /template/ and is passed as-is to `foo2`. Hence
`c` is a template and it's only instantiated inside that function.
This would compile too:

   auto foo2(alias c)() {
  return c(3.14);
   }


>   // so why doesn't this work, if the compiler can infer that the
>   // argument is an int delegate(int)?
>   static assert(!__traits(compiles,
>  writeln(foo((arg) => arg + 1;
> }

It can't. It's a template. Templates are not values and can not be
used as runtime function arguments.

The only magic that the compiler does is that it lets you call
callable templates directly - it automatically instantiates them
(using the types of the arguments used for that call). 

artur


Re: Issue Turning Template into Variadic Template

2016-03-31 Thread Artur Skawina via Digitalmars-d-learn
On 03/30/16 20:12, jmh530 via Digitalmars-d-learn wrote:
> I wrote a version of cartesianProduct that will return the cartesian product 
> when the some of the types are not ranges. The original code is below.
> 
> My issue is that I can't figure out how to turn it into a variadic template.

> auto mixedCartesianProduct(T, U)(T x, U y)
> {
> import std.algorithm : cartesianProduct;
> 
> return cartesianProduct(conditionalOnly(x), conditionalOnly(y));
> }

   auto mixedCartesianProduct(T...)(T x)
   {
   import std.range, std.algorithm : cartesianProduct;

   return 
mixin(`cartesianProduct(`~iota(T.length).map!`"conditionalOnly(x["~text(a)~"])"`().join(",")~`)`);
   }

artur


Re: static if else behavior and is type comparison

2016-03-11 Thread Artur Skawina via Digitalmars-d-learn
On 03/11/16 09:21, Ali Çehreli via Digitalmars-d-learn wrote:
> You've been bitten by a common usability issue. :)
> 
> On 03/11/2016 12:02 AM, Fynn Schröder wrote:
>>  static if (is(U == ubyte)) {

>>  } else if (is(U == ushort)) {
> 
> You mean 'else static if'. (Not your fault: I (and others) wish the compiler 
> warned about this problem.)

It can not warn about this "problem" - because it's a perfectly
fine and relatively common construct (a RT check guarded by a CT
check).
The problem comes from the static-if pseudo-keyword hack --
"static if" is effectively a keyword; if the syntax was eg "#if"
then such mistakes would be less likely. Obviously, it's a bit late
for such language change. One thing that the compiler could warn
about is: a RT-if that depends only on the result of an is-expression;
that would have caught the case above and rarely be wrong (with an
easy way to make the compiler happy). It would still miss more
complex cases, but those can't be warned about as they can occur
legitimately in generic code.

artur


Re: Decoding Pattern to a Tuple

2016-02-22 Thread Artur Skawina via Digitalmars-d-learn
On 02/19/16 19:10, Nordlöw via Digitalmars-d-learn wrote:
> Have anybody put together a generalised form of findSplit that can split and 
> decode using a compile time parameters somewhat like
> 
> "(1)-(2.0)".decode!("(", int, ")", char, "(", double, ")")
> 
> evaluates to
> 
> to a
> 
> tuple!(int, char, double)
> 
> with value
> 
> tuple(1, '-', 2.0)

In practice, that isn't necessarily a good idea, because this kind
of project-local helpers add a level of obfuscation. But as the
language is missing /real/ pattern-matching, this functionality is
reinvented again and again. Here's a simple version that takes a
single pattern string with the individual patterns placed between
"{%" and "%}", and that doesn't support `char` directly (char can be
easily gotten from the string).

   template decode(string P, alias S) {
  alias T(A...) = A;
  static if (P.length) {
 import std.algorithm, std.conv;
 enum PS = findSplit(P, `{%`);
 static assert (PS[0]==S[0..PS[0].length]);
 enum PE = findSplit(PS[2], `%}`);
 enum PP = findSplit(PE[2], "{%")[0];
 enum SS = findSplit(S[PS[0].length..$], PP);
 alias decode = T!(mixin(`to!(`~PE[0]~`)(SS[0])`), 
decode!(PE[2][PP.length..$], SS[2]));
  }
  else
 alias decode = T!();
   }

   enum a = decode!("({%int%}){%string%}({%double%})", "(1)-(2.0)");
   pragma(msg, typeof(a));
   pragma(msg, a);


Just a POC hack; don't use as-is; does not support user defined types
(it would have to be a mixin to be able to do that).

artur


Re: print function

2016-02-05 Thread Artur Skawina via Digitalmars-d-learn
On 02/05/16 14:38, Ola Fosheim Grøstad via Digitalmars-d-learn wrote:
> On Friday, 5 February 2016 at 12:35:14 UTC, Artur Skawina wrote:
>> call used to print diagnostics. What I saw made me never use or look at D's 
>> std lib again. Except for meta programing and toy/example programs where it 
>> doesn't matter.
> 
> What do you use instead? A buffer and Posix write() and aio_write()?

For ad-hoc temporary debugging usually a local wrapper

   @noinline writeln(A...)(A a) {
  import std.stdio;
  std.stdio.writeln(a);
   }

[the reason for @noinline is to not disturb the caller]
This is where the `print` function would be useful. It
could even be made to work at CT (w/ compiler help; this
has been a often requested feature).

For programs that output one or few text lines to stdout
(results, status updates etc) - `printf` -- it's already
there in libc anyway, so zero-cost and GC-free.

For everything else - the C/Posix functions.


artur


Re: print function

2016-02-05 Thread Artur Skawina via Digitalmars-d-learn
On 02/05/16 08:04, cy via Digitalmars-d-learn wrote:
> On Thursday, 4 February 2016 at 15:32:48 UTC, Artur Skawina wrote:
>>void print(A...)(A a) {
>>   foreach (N, ref e; a)
>>  write(e, N==A.length-1?"\n":" ");
>>}
> 
>>> will be unrolled at compile time
> 
> Mind if I elaborate on this a bit? If that is unrolled, I understand it will 
> unroll into several calls to write, as in print("1","2","3") => write("1"," 
> ");write("2"," ");write("3","\n");

Yes, and they are all using the same `write!(string, string)` instance
(there will be one for every printed type, `write!(typeof(A[N]), string)`).


> Any literal string you pass to std.stdio.write will be expanded into 1 fwrite 
> invocation per character.

D's std lib implementations are sometimes really awful, but in
this case it's not actually that bad:

   print("hi","there");

->

   fwrite("hi", 1, 2, 0x7ff68d0cb640) = 2
   fwrite(" ", 1, 1, 0x7ff68d0cb640)  = 1
   fwrite("there", 1, 5, 0x7ff68d0cb640)  = 5
   fwrite("\n", 1, 1, 0x7ff68d0cb640) = 1


What happens between `print` and `fwrite` - I have no idea.
Years ago I had to investigate why phobos showed up in the
perf profile of a program, when the only used part was some
`write` call used to print diagnostics. What I saw made me
never use or look at D's std lib again. Except for meta
programing and toy/example programs where it doesn't matter.

artur


Re: print function

2016-02-04 Thread Artur Skawina via Digitalmars-d-learn
On 02/04/16 18:53, ixid via Digitalmars-d-learn wrote:
> On Thursday, 4 February 2016 at 17:34:33 UTC, Artur Skawina wrote:
>> On 02/04/16 16:32, Artur Skawina wrote:
>> but that seems too expensive, when the use is just in toy programs and 
>> debugging.
> 
> I hadn't really considered the relative cost-benefit, it's just a habit to 
> try to hardcode things at compile time. =) It certainly seems to make sense 
> to do it that way.

Just to clarify -- *all* versions work at CT; the static-foreach
will be unrolled at CT, and the mixin argument will be fully
evaluated at CT too. The only difference is in a) readability, b)
the `write` template instantiations (and potential re-use).

Using the std lib `write*` templates has a huge cost; for any
kind of /real/ programs, that care about performance at all, they
are better avoided. (But it probably doesn't matter if you already
heavily rely on GC and don't print much, other than that they add
tons of code to the executable)


artur


Re: print function

2016-02-04 Thread Artur Skawina via Digitalmars-d-learn
On 02/04/16 16:32, Artur Skawina wrote:
> 
>void print(A...)(A a) {
>   foreach (N, ref e; a)
>  write(e, N==A.length-1?"\n":" ");
>}

BTW, that was *deliberately* written that way as a compromise
between efficiency and template bloat. It can of course be
done like

   void print(alias SEP=" ", alias EOL="\n", A...)(A a) {
  
mixin(`write(`~iota(A.length).map!(a=>"a["~text(a)~"],")().join("SEP,")~"EOL);");
   }

but that seems too expensive, when the use is just in toy
programs and debugging.


artur


Re: print function

2016-02-04 Thread Artur Skawina via Digitalmars-d-learn
On 02/04/16 15:02, ixid via Digitalmars-d-learn wrote:
> On Thursday, 4 February 2016 at 13:46:46 UTC, Dejan Lekic wrote:
>> On Thursday, 4 February 2016 at 00:23:07 UTC, ixid wrote:
>>> It would be nice to have a simple writeln that adds spaces automatically 
>>> like Python's 'print' in std.stdio, perhaps called print.

> I have written an attempt at it but my point was that a print function would 
> be a good addition to the standard library rather than asking someone to 
> write an implementation for me.
> 
> string makePrintString(T)(T length) {
> import std.conv : to;
>
> string s = "writeln(";
> foreach( i; 0 .. length) {
> s ~= "a[" ~ i.to!string ~ "]";
> if(i != length - 1)
> s ~= ",\" \",";
> else s ~= ");";
> }
>
> return s;
> }   
> 
> void print(A...)(A a) {   
> static if(a.length) {
> mixin(makePrintString(a.length));
> } else writeln;
> }

   void print(A...)(A a) {
  foreach (N, ref e; a)
 write(e, N==A.length-1?"\n":" ");
   }


artur


Re: how do I tell if something is lvalue?

2016-02-01 Thread Artur Skawina via Digitalmars-d-learn
On 02/01/16 21:42, Artur Skawina wrote:
> On 02/01/16 20:47, Meta via Digitalmars-d-learn wrote:
>> That looks much nicer. It still needs work to properly handle functions with 
>> non-empty argument lists.
> 
> Then it gets a bit long for a one-liner ;)
> 
>enum isLvalue(A...) = is(typeof((ref _){}(A[0](A[1..$] || 
> is(typeof((ref _){}(A[0])));

And it's of course wrong in case there is a zero-args ref-returning
overload present. So...

   enum isLvalue(A...) = A.length>1?is(typeof((ref 
_){}(A[0](A[1..$]:is(typeof((ref _){}(A[0])));


artur


Re: how do I tell if something is lvalue?

2016-02-01 Thread Artur Skawina via Digitalmars-d-learn
On 02/01/16 20:47, Meta via Digitalmars-d-learn wrote:
> On Monday, 1 February 2016 at 18:28:05 UTC, Artur Skawina wrote:
>> On 01/31/16 23:11, Steven Schveighoffer via Digitalmars-d-learn wrote:
>>> Thanks! I was surprised this is not straightforward.
>>
>>enum isLvalue(alias A) = is(typeof((ref _){}(A)));
> 
> That looks much nicer. It still needs work to properly handle functions with 
> non-empty argument lists.

Then it gets a bit long for a one-liner ;)

   enum isLvalue(A...) = is(typeof((ref _){}(A[0](A[1..$] || is(typeof((ref 
_){}(A[0])));

> Also, can alias parameters take runtime variables? I can't remember.

Yes.

> 
> struct S
> {
> int w(int n) { return 1; }
  ref int wl(int n) { return x; }
> }
> 
> static assert(isLvalue!(S.w));


   static assert(!isLvalue!(S.w, 1));
   static assert(isLvalue!(S.wl, 1));


artur


Re: how do I tell if something is lvalue?

2016-02-01 Thread Artur Skawina via Digitalmars-d-learn
On 01/31/16 23:11, Steven Schveighoffer via Digitalmars-d-learn wrote:
> Thanks! I was surprised this is not straightforward.

   enum isLvalue(alias A) = is(typeof((ref _){}(A)));

artur


Re: Forward declaration issue

2015-12-04 Thread Artur Skawina via Digitalmars-d-learn
On 12/04/15 09:12, Andre via Digitalmars-d-learn wrote:
> Hi,
> 
> I have a strange issue with following coding.
> 
> void baz(); // forward declaration
> 
> void foo()
> {
> void bar()
> {
> baz(); // (1) without f.d. syntax error
> }
> 
> void baz()
> {
> bar();
> }
> 
> baz(); // (2) No linker error if line is removed
> }
> 
> void main()
> {
> foo();
> }
> 
> Without the forward declaration, there is a syntax error at (1)
> With the forward declaration there is no syntax error but
> a linker error at (2). This linker error disappears if line at (2)
> is removed.
> It looks like a bug, is it?

No, it's how D is designed -- inside functions the order of
declarations matters (and forward declarations don't work).

Your version wrongly declares another `baz` at module scope,
and, as there's no definition, you end up with the linker error.

Two workarounds:

1) Templatize the functions:

   void foo()
   {
  void bar()()
  {
  baz();
  }

  void baz()()
  {
  bar();
  }

  baz();
   }

2) Use a struct:

   void foo()
   {
  struct Hack {
 void bar()
 {
 baz();
 }

 void baz()
 {
 bar();
 }
  }

  Hack hack;

  hack.baz();
   }

artur


Re: Binding to GSL library

2015-11-26 Thread Artur Skawina via Digitalmars-d-learn
On 11/25/15 17:11, Radek via Digitalmars-d-learn wrote:
> Hi, I'm making a trying to bind a gsl library 
> http://www.gnu.org/software/gsl/ so far it was working but when i started 
> binding complex numbers some functions won't work, like trigonometric 
> functions - called they return null.
> 
> in gsl code complex struct looks like:
> 
> typedef struct
>   {
> double dat[2];
>   }
> gsl_complex;
> 
> 
> my complex struct looks like that:
> 
> struct _gsl_complex {
>   double dat[2];
> }
> alias gsl_complex = _gsl_complex*;
> 
> So, what im doing wrong?

That's not a struct but a pointer to a struct.

Also, you can just drop the `typedef` hack (which is used
in C to avoid having to type the 'struct' keyword), so:

   struct gsl_complex {
  double[2] dat;
   }

artur


Re: Check template parameter whether it has "length"

2015-10-08 Thread Artur Skawina via Digitalmars-d-learn
On 10/08/15 11:29, tcak via Digitalmars-d-learn wrote:
> I am "trying" to write a function that takes an array of items, and returns 
> the length of longest item.
> 
> [code]
> size_t maxLength(A)( const A[] listOfString ) if( __traits( hasMember, A, 
> "length" ) )
> {
> return 0; // not implemented yet
> }
> [/code]
> 
> I tried it with
> 
> if( __traits( compiles, A.length ) )
> 
> as well. But compiler doesn't match it.

Use `A.init.length` instead of `A.length`.


You could also use something like

   if(is(typeof(A.init.length):size_t))


artur


Re: Get template parameter value

2015-09-29 Thread Artur Skawina via Digitalmars-d-learn
On 09/29/15 12:13, rumbu via Digitalmars-d-learn wrote:
> On Tuesday, 29 September 2015 at 09:53:39 UTC, Kagamin wrote:
>> On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin wrote:
>>> Welcome to the weird and wonderful work of  
>>> http://dlang.org/expression.html#IsExpression
>>
>> No, use template pattern matching instead:
>>
>> struct A(int s){}
>> template B(T:A!s, int s){ enum B=s; }
>> static assert(B!(A!4)==4);
> 
> Thank you, this is perfect.

There's always room for improvement... ;)

   enum B(T:A!s, int s) = s;

artur



Re: What is the corect behavour for lazy in foreach variadic template

2015-09-25 Thread Artur Skawina via Digitalmars-d-learn
On 09/25/15 17:47, Ali Çehreli via Digitalmars-d-learn wrote:

> Perhaps we need an enhancement that either works in your original code [...]

His original code does work (`foreach` evaluates `args[N]` and
assigns the result to `arg`).

If he wanted to delay the evaluation, he would have written it
like this:

   void test(T...)(lazy T args)
   {
   foreach(I, _; typeof(args))
   {
   writeln("about to process arg");
   writefln("processing arg %s",args[I]);
   }
   }

artur


Re: Why is the constructor of B called?

2015-09-24 Thread Artur Skawina via Digitalmars-d-learn
On 09/24/15 13:26, Marc Schütz via Digitalmars-d-learn wrote:
> On Thursday, 24 September 2015 at 01:01:09 UTC, Nicholas Wilson wrote:
>> On Wednesday, 23 September 2015 at 21:25:15 UTC, tcak wrote:
>>> On Wednesday, 23 September 2015 at 21:14:17 UTC, Adam D. Ruppe wrote:
 On Wednesday, 23 September 2015 at 21:08:37 UTC, tcak wrote:
> I wouldn't expect B's constructor to be called at all unless "super" is 
> used there.

 "If no call to constructors via this or super appear in a constructor, and 
 the base class has a constructor, a call to super() is inserted at the 
 beginning of the constructor. "


 from http://dlang.org/class.html#constructors

 the idea is to make sure the base class construction work is done too.
>>>
>>> Is there any way to prevent this behaviour?
>>>
>>> Quickly checked whether Java acts in the same way. Answer is yes.
>>
>> You might be able to swap out the vtbl entry  for a stub call it and trick 
>> the compiler and swap it back, but...
> 
> Urgh...
> 
> If you can modify the base class, and you really need it, you can check the 
> dynamic type:
> 
> class Base {
> this() {
> if(!cast(Base) this) return;
> // do the initialization
> }
> }

If you're going to do this then you can just use overloading.
That will both avoid the runtime check and require the hack
to be explicitly enabled in the derived class. IOW:

   class B {
   this() {
   writeln("B.constructor");
   foo();
   }

   struct SkipBCtor {}
   this(SkipBCtor) {}

   void foo() {
   writeln("B.foo");
   }
   }

   class D : B {
   this() {
   super(SkipBCtor());
   writeln("D.constructor");
   }

   override void foo() {
   writeln("D.foo overrides B.foo");
   }
   }

artur


Re: __traits(allMembers) and aliases

2015-08-26 Thread Artur Skawina via Digitalmars-d-learn
On 08/26/15 14:42, Mike Parker via Digitalmars-d-learn wrote:
> This doesn't help me distinguish aliased function names.

[...]

> I don't want to put any restrictions on what the user can have in the 
> module/class/struct that contains the function pointer. It's just that 
> aliased function names pass both tests as they are synonyms for the functions 
> they alias.

If it's just about functions then you can check identity (the address
obtained via the alias will be the same). That will also work for
other non-tls objects. It won't work for tls objects because the
compiler will (incorrectly) reject the equality check at CT.
Because of D's implicit TLS in module and static scopes, a lot of
objects will unintentionally be made thread local, so this solution
won't be practical until the compiler limitation goes away, yes.

artur 


Re: Problem with casting instance reference to void* and back.

2015-07-27 Thread Artur Skawina via Digitalmars-d-learn
On 07/27/15 14:03, Vlad Leberstein via Digitalmars-d-learn wrote:
> Hi! My use case requires interaction with C API which in turn implies storing 
> object instance reference as void *. I'm using gdc 4.9.2 and everything 
> worked fine with "object -> void * -> object" conversion, but "object -> void 
> * -> interface" failed. The stripped-down example is something like this:
> 
> interface TestInterface {
> void testMethod();
> }
> 
> class TestImpl : TestInterface {
> void testMethod() {
> writefln("TestImpl::testMethod\n");
> }
> };
> 
> void testDispathcer(void *rawSelf) {
> auto self = cast(TestInterface) rawSelf;
> // nothing happens
> self.testMethod();
> }
> 
> 
> int main(string[] args) {
> auto t = new TestImpl();
> testDispathcer(cast(void *) t);
> return 0;
> }

> Is there any way to handle such situation without resorting to templating 
> dispatcher with every *Impl type?

auto self = cast(TestInterface)cast(Object) rawSelf

[you should probably check for null, and consider using
 a reinterpret-cast (`testDispathcer(*cast(void **)&t)`)
 because a "normal" one can be overridden by the class,
 sometimes accidentally]

artur


Re: turning an array of structs into a struct of arrays

2015-07-04 Thread Artur Skawina via Digitalmars-d-learn
On 07/03/15 12:52, Laeeth Isharc via Digitalmars-d-learn wrote:
> I have an array of structs eg
> 
> struct PriceBar
> {
>   DateTime date;
>   double open;
>   double high;
>   double low;
>   double close;
> }
> 
> (which fields are present in this particular struct will depend on template 
> arguments).
> 
> what is the best way to turn these at compile time into a struct of arrays? eg
> 
> struct PriceBars
> {
>   DateTime[] dates;
>   double[] opens;
>   double[] highs;
>   double[] lows;
>   double[] closes;
> }
> 
> I can use FieldTypeTuple and FieldNameTuple, but I am a bit lost as to how 
> without static foreach to loop through these in order to generate a mixin to 
> declare the new type.  I can turn it into a string, but what is the better 
> option?

The simplest solution is something like:

   template SOA(Struct, size_t LENGTH) {
  struct SOA  {
 enum MEMBERNAME(size_t N) = __traits(identifier, Struct.tupleof[N]);

 static __gentypes() {
string ret;
foreach (I, TYPE; typeof(Struct.tupleof))
   ret ~= "align(16) 
typeof(Struct.tupleof["~I.stringof~"])["~LENGTH.stringof~"] "
   ~ MEMBERNAME!I ~ ";";
return ret;
 }
 mixin(__gentypes());
  }
   }

   alias PriceBars = SOA!(PriceBar, 8);

which you'll have to adjust to your requirements (eg drop the
'"~LENGTH.stringof~"' part to get a struct-of-slices, which
is what your example above shows). 

artur


Re: Call-ie return on behalf of caller?

2015-06-04 Thread Artur Skawina via Digitalmars-d-learn
On 06/04/15 00:37, Tofu Ninja via Digitalmars-d-learn wrote:
> Is there a way other than exceptions for a called function to force the 
> caller to return?
> 
> Specifically, I know the return type of the caller(its always bool) and under 
> certain circumstances I would like the caller to just give up and return 
> false if the called function fails. With as little boiler plate as possible 
> on the call site. In c++ I could do it very easily with macros, but I am 
> failing to see a similar way to do it in D other than maybe string mixins but 
> that seems like a bit much to do every time I want to call this thing.
> 
> I would be willing to put some boilerplate code in the beginning of the 
> caller, I could just put that in a mixin.
> 
> I know exceptions are really what I should be using but they are such a pain 
> to work with. I don't want to have to put try catch blocks every time I call 
> the caller.
> 
> Any ideas?

Without a preprocessing step, you probably won't find anything
that's much better than:

   enum caught(string C, string R = "typeof(return).init") =
  `try {`~C~`} catch return (`~R~`);`;

   bool f(int a) nothrow {
  mixin (caught!q{ code_that_throws(a); });
  return 1;
   }

artur


Re: Destructured Tuple Assignment

2015-05-15 Thread Artur Skawina via Digitalmars-d-learn
   import std.algorithm;

   template magicassign(A...) {
  void magicassign(B)(B b) @property {
 foreach(I, ref a; A)
static if (!is(typeof(A[I]):typeof(null)))
   a = b[I];
  }
   }

   template let(string D) {
  mixin({
 enum sdsl = D.findSplit("=");
 mixin(`struct S { int `~sdsl[0]~`; }`);
 string code = `auto v = ` ~ sdsl[2] ~ `;`;
 foreach (I, _; typeof(S.tupleof))
code ~= `auto ` ~ S.tupleof[I].stringof ~ ` = v[`~I.stringof~`]; `;
 return code;
  }());
   }

   void main(string[] args) {
  import std.stdio;

  string a, b;
  magicassign!(a, null, b) = args[1].findSplit("-");
  writeln(a);
  writeln(b);

  mixin let!q{ c, _, d = args[1].findSplit("-") };
  writeln(c);
  writeln(d);
   }

artur


Re: Multiple template alias parameters

2015-05-09 Thread Artur Skawina via Digitalmars-d-learn
On 05/08/15 23:56, Brian Schott via Digitalmars-d-learn wrote:
> On Friday, 8 May 2015 at 12:44:31 UTC, Artur Skawina wrote:
>> On 05/08/15 03:53, Brian Schott via Digitalmars-d-learn wrote:
>>> The problem occurs when I want to register multiple modules to scan for 
>>> functions. The grammar does not allow this syntax:
>>>
>>> ```
>>> template (alias Modules ...) {
>>> ...
>>> ```
>>
>> The grammar allows omitting the 'alias' keyword.
>>
>> artur
> 
> alias parameters are different from normal template parameters. They're not 
> necessary for this problem, but they are for others.

I was trying to hint at the fact that D's template tuple parameters
already have the required magic.
Hence, the trailing '...' makes that 'alias' unnecessary.

> As an example:
> 
> 
> void traceVar(alias var, size_t line = __LINE__, string file = __FILE__)()
> {
> import std.stdio: stderr;
> stderr.writeln(file, "(", line, ") ", var.stringof, ": ", var);
> }
> 
> This allows you to print a variable's name and value by only passing the 
> variable once as a template argument. Allowing "template Tem(alias Args ...)" 
> syntax would let me trace multiple variables at once.
> 
> If you omit "alias", "var.stringof" evaluates to "var" instead of its name in 
> the calling context.

   template traceVar(VARS...) {
  void traceVar(size_t line = __LINE__, string file = __FILE__)() {
 import std.stdio: stderr;
 foreach (I, ref var; VARS)
stderr.writeln(file, "(", line, ") ", VARS[I].stringof, ": ", var);
  }
   }

artur



Re: Multiple template alias parameters

2015-05-08 Thread Artur Skawina via Digitalmars-d-learn
On 05/08/15 03:53, Brian Schott via Digitalmars-d-learn wrote:
> The problem occurs when I want to register multiple modules to scan for 
> functions. The grammar does not allow this syntax:
> 
> ```
> template (alias Modules ...) {
> ...
> ```

The grammar allows omitting the 'alias' keyword.

artur


Re: Reducing source code: weak+alias values in array

2015-05-02 Thread Artur Skawina via Digitalmars-d-learn
On 05/02/15 05:28, Jens Bauer via Digitalmars-d-learn wrote:
> On Saturday, 2 May 2015 at 03:21:38 UTC, Jens Bauer wrote:
>> For some reason, my build time has increased dramatically...
>>
>> Building with 1 vector takes 0.6 seconds.
>> Building with 2 vector takes 0.7 seconds.
>> Building with 4 vector takes 0.9 seconds.
>> Building with 8 vector takes 1.1 seconds.
>> Building with 16 vectors takes 1.7 seconds.
>> Building with 32 vectors takes 3.4 seconds.
>> Building with 64 vectors takes 12.4 seconds.
>> Building with 112 vectors takes 55.5 seconds.
>> Building with 113 vectors takes 56.7 seconds.

Apparently CTFE can be very inefficient sometimes -- compiler
issue. Can't think of a workaround right now; manually parsing
(instead of using mixins) might help, but that would make the
solution less obvious...

> Here's the source code for the file I'm building:
> 
> http://pastebin.com/pCh9e7hQ

For some reason I was never really affected by the horrible
CTFE perf. For example, your code from that link, after a few
tweaks to get it to build, compiles in ~3s for me. (64 bit x86
linux gdc build)

artur


Re: Reducing source code: weak+alias values in array

2015-05-01 Thread Artur Skawina via Digitalmars-d-learn
On 05/01/15 22:29, Jens Bauer via Digitalmars-d-learn wrote:
> On Wednesday, 29 April 2015 at 13:58:14 UTC, Artur Skawina wrote:
>> On 04/27/15 19:49, Jens Bauer via Digitalmars-d-learn wrote:
>>> I was wondering if there's a way to reduce my bulky startup files a bit.
> {snip}
> 
>> Just create a helper module, which the startup files can all
>> use to generate the data from a dsl. Eg
> {snip}
> 
> I've experimented a little with the code, but ran into two minor problems.
> 
> code ~= `@weakalias("`~M.n~`") extern (C) void ` ~ 
> __traits(identifier, A.tupleof[I]) ~ "();\n";
> 
> The above part gives me some problems; I do not know how to create the 
> @weakalias.

My fault; I only looked at the generated code, but never actually tested it.

Use `@weakalias!"blah"` instead:

   enum weakalias(string A) = gcc.attribute.attribute("alias", A);

   @weakalias!"defaultResetHandler" extern (C) void Reset_Handler();

   

> I also had some trouble with the exception vectors not being generated, and 
> it turned out that my array was dynamic instead of static.
> 
> For now, I've just made the array a constant size (100 elements); eg. changed 
> ...
> code ~= "\n@isr_vector VectorFunc[] g_pfnVectors = [\n";
> ... to ...
> code ~= "\n@isr_vector VectorFunc[100] g_pfnVectors = [\n";
> ... Is it possible to generate a static array without specifying a fixed 
> array size ?

No, but you can just do:

   code ~= "\n@isr_vector VectorFunc[" ~ A.tupleof.length.stringof ~ "] 
g_pfnVectors = [\n";

> Apart from the above two mentioned problems, the code builds and produces the 
> expected results. I even started to understand some parts of it, and I find 
> it pretty awesome. ;)

(Ab)using the compiler for the DSL parsing gets really awesome once you
use other D features like multiple named member initializers, lambdas and/or
static-ifs etc /inside/ the DSL. Next thing you know you'll be using DSLs
that generate other DSLs that emit plain D code, with a few layers of
expression templates in between... :)

artur


Re: Reducing source code: weak+alias values in array

2015-04-29 Thread Artur Skawina via Digitalmars-d-learn
On 04/27/15 19:49, Jens Bauer via Digitalmars-d-learn wrote:
> I was wondering if there's a way to reduce my bulky startup files a bit.
> 
> If using the GNU Assembler (GAS), then one can reduce the code using a macro 
> like this:
> 
> 
> /* The EXC macro makes a weak+alias for the
>  * symbol 'value', then it stores the value in memory: */
> .macroEXCvalue,defaultValue
> .ifnb\defaultValue
> .weakref\value,\defaultValue
> .else
> .weakref\value,defaultExceptionVector
> .endif
> .4byte\value
> .endm
> 
> 
> /* The exception vector now looks quite simple: */
> isr_vector:
> .4byte_stack
> EXCReset_Handler,defaultResetHandler
> EXCNMI_Handler
> EXCHardFault_Handler
> EXCMemManage_Handler
> EXCBusFault_Handler
> EXCUsageFault_Handler
> .4byte0
> .4byte0
> .4byte0
> .4byte0
> EXCSVC_Handler
> EXCDebugMon_Handler
> .4byte0
> EXCPendSV_Handler
> EXCSysTick_Handler
> 
> An example on one of my bulky startup files:
> https://github.com/jens-gpio/MCU/blob/master/startup/stm/stm32f439_startup.d

Just create a helper module, which the startup files can all
use to generate the data from a dsl. Eg

   import my.helper.mod;
   
   mixin(VectorFuncs!(q{
  PTR stack = {`_stack`};
  EXC Reset_Handler = {`defaultResetHandler`};
  EXC NMI_Handler;
  EXC HardFault_Handler;
  PAD pad01;
  PAD pad02;
  //...
   }));


// Then, in my.helper.mod:

   @property /*@section("discard.etc")*/ VectorFuncs(string dsl)() {
  static struct A {
 struct PTR { string n; @property s() {return `cast(VectorFunc)&`~n;} }
 struct PAD { string n; @property s() {return `cast(VectorFunc)null`;} }
 struct EXC { string n = `defaultExceptionHandler`; @property s() 
{return null;} }
 mixin(dsl);
  }
  string code;

  foreach (I, M; A.init.tupleof)
 static if (is(typeof(M)==A.EXC))
code ~= `@weakalias("`~M.n~`") extern (C) void ` ~ 
__traits(identifier, A.tupleof[I]) ~ "();\n";

  code ~= "\n@isr_vector VectorFunc[] g_pfnVectors = [\n";
  foreach (I, M; A.init.tupleof)
code ~= "   " ~ (M.s?M.s:"&"~__traits(identifier, A.tupleof[I])) ~ 
",\n";
  code ~= "];\n";

  return code;
   }

and what the compiler will see when building the startup modules will look like

   @weakalias("defaultResetHandler") extern (C) void Reset_Handler();
   @weakalias("defaultExceptionHandler") extern (C) void NMI_Handler();
   @weakalias("defaultExceptionHandler") extern (C) void HardFault_Handler();

   @isr_vector VectorFunc[] g_pfnVectors = [
  cast(VectorFunc)&_stack,
  &Reset_Handler,
  &NMI_Handler,
  &HardFault_Handler,
  cast(VectorFunc)null,
  cast(VectorFunc)null,
   ];

artur


Re: Make a type tuple from an array

2015-04-11 Thread Artur Skawina via Digitalmars-d-learn
On 04/10/15 17:36, John Colvin via Digitalmars-d-learn wrote:
> On Friday, 10 April 2015 at 15:13:54 UTC, Marc Schütz wrote:
>> Is there a way to turn an array (known at compile time) into a TypeTuple? 

> For input ranges in general:
> 
> import std.range : isInputRange;
> 
> template TypeTupleOf(TL...)
> if (TL.length == 1 && isInputRange!(typeof(TL[0])))
> {
> import std.typetuple : TT = TypeTuple;
> enum r = TL[0];
> static if (r.empty)
> alias TypeTupleOf = TT!();
> else
> {
> enum f = r.front;
> alias TypeTupleOf = TT!(
> f,
> TypeTupleOf!(
> { auto tmp = r; tmp.popFront(); return tmp; }()
> )
> );
> }
> }

Neat, but very unreadable...

   import std.array, std.range : isInputRange, dropOne;

   template TypeTupleOf(alias R) if (isInputRange!(typeof(R))) {
  import std.typetuple : TT = TypeTuple;
  static if (R.empty)
 alias TypeTupleOf = TT!();
  else
 alias TypeTupleOf = TT!(R.front(), TypeTupleOf!(R.dropOne()));
   }

artur


Re: Creating a microcontroller startup file

2015-04-09 Thread Artur Skawina via Digitalmars-d-learn
On 04/08/15 18:10, Jens Bauer via Digitalmars-d-learn wrote:
> On Wednesday, 8 April 2015 at 11:17:12 UTC, Mike wrote:
>> On Tuesday, 7 April 2015 at 20:33:26 UTC, Jens Bauer wrote:
>>
>> enum weak = gcc.attribute.attribute("weak");
>> enum isrDefault = gcc.attribute.attribute("alias", "defaultHandler");
>>
>> extern @weak @isrDefault void NMI_Handler();
>> extern @weak @isrDefault void HardFault_Handler();
> 
> This is indeed helpful. I've now reduced each of the approximately 100 lines 
> declaring exception vectors to something like these:
> 
> @weak @ar void Reset_Handler();
> @weak @ae void NMI_Handler();
> 
> -It would be neat, if @attribute("weak") and @attribute("alias","function") 
> could be combined into one, but I haven't found a way to do that 

http://forum.dlang.org/post/mailman.2672.1403379235.2907.digitalmar...@puremagic.com

artur


Re: enum and static if

2015-03-11 Thread Artur Skawina via Digitalmars-d-learn
On 03/11/15 15:41, ketmar via Digitalmars-d-learn wrote:
> On Wed, 11 Mar 2015 14:36:07 +, wobbles wrote:
> 
>> On Wednesday, 11 March 2015 at 14:34:32 UTC, ketmar wrote:
>>> On Wed, 11 Mar 2015 13:48:45 +, Namespace wrote:
>>>
 This code does not work:

 
 enum Test {
  Foo,
 static if (__VERSION__ >= 2067)
  Bar,
 }
  Quatz
 }
 

 Any chance that this could work?
>>>
>>> nope. `static if` is statement, so it works only where statement is
>>> allowed. the same is true for `version`. this is by design.
>>
>> You can do something like static if (__VERSION__ >= 2067)
>>  enum Test{ ... }
>> else
>>  enum Test{ ... }
>>
>> as a workaround?
> 
> sure, but you have to copypaste the whole enum in both places. maybe 
> allowing `version` in enums worth a ER...

   mixin(`
   enum Test {
   Foo,`
   ~(__VERSION__>=2067?`
   Bar,`:``)
   ~`  Quatz
   }`);

artur


Re: Initializing defaults based on type.

2015-03-06 Thread Artur Skawina via Digitalmars-d-learn
On 03/06/15 22:29, Artur Skawina wrote:
> No, you implement it using CTFE magic, and then that code becomes:

>#foreach (N; 0..PairInitValues.length/2) {
>   enum PairInitValue(T:PairInitValues[$N*2]) = PairInitValues[$N*2+1];
>}

> Seriously though, avoid using `.stringof` when generating code - it will
> break if the symbol is not available at the string-mixin scope.

Ie try to access the types/parms/etc directly; eg `PairInitValues[i]` will
usually work, when `i` is a constant or a static-foreach variable.

[The code above obviously isn't plain D and won't work as-is w/o a magic
 ctfe preprocessor.]

artur


Re: Initializing defaults based on type.

2015-03-06 Thread Artur Skawina via Digitalmars-d-learn
On 03/06/15 19:27, Kagamin via Digitalmars-d-learn wrote:
> On Friday, 6 March 2015 at 16:39:56 UTC, Ali Çehreli wrote:
>> mixin (makePairInitValueDefinitions());
> 
> Oh, so that's how you do static foreach.

No, you implement it using CTFE magic, and then that code becomes:

   import std.typetuple;

   alias PairInitValues = TypeTuple!(
   int, 1,
   double, 0,
   );

   #foreach (N; 0..PairInitValues.length/2) {
  enum PairInitValue(T:PairInitValues[$N*2]) = PairInitValues[$N*2+1];
   }

   struct Pair(T)
   {
  T x = PairInitValue!T;
  T y = PairInitValue!T;

  alias x c;
  alias y r;
   }


Seriously though, avoid using `.stringof` when generating code - it will
break if the symbol is not available at the string-mixin scope.

artur 


Re: Labels in struct

2015-01-31 Thread Artur Skawina via Digitalmars-d-learn
On 01/31/15 17:04, tcak via Digitalmars-d-learn wrote:
> 
> struct CommunicationMessage{
[...]
> content:
> }
> 
> 
> Example I defined something like above. I am using it as a base structure, 
> and don't know how long the content of message will be. But I know that it 
> will be at the end. I could use that "content" label to find out about end of 
> struct. But unfortunately, it doesn't seem like it is supported.
> 
> I could say "void* endOfStruct = &struct + sizeof(struct)", but then struct 
> wouldn't be self explanatory with that content label at the end.

The traditional way (ie C-like) would be

   ubyte[0] content; // zero-sized; use casts etc to access data.

as the last member. D supports that too, and just like
many other D features it works for ~80% of cases. IOW
you should be able to get it to work, but you might run
into problems if you need to access/manipulate such types.

artur


Re: How to copy object of class A to another object of class B?

2015-01-28 Thread Artur Skawina via Digitalmars-d-learn
On 01/28/15 10:44, zhmt via Digitalmars-d-learn wrote:
> I have a struct created by thrift:
> 
> struct Card {
>   long id;
>   string pwd;
>   long agentId;
>   bool valid;
>   long rmb;
>   long createDate;
>   long soldDate;
>   long chargeDate;
> 
>   mixin TStructHelpers!([
> TFieldMeta(`id`, 1, TReq.OPTIONAL),
> TFieldMeta(`pwd`, 2, TReq.OPTIONAL),
> TFieldMeta(`agentId`, 3, TReq.OPTIONAL),
> TFieldMeta(`valid`, 4, TReq.OPTIONAL),
> TFieldMeta(`rmb`, 5, TReq.OPTIONAL),
> TFieldMeta(`createDate`, 6, TReq.OPTIONAL),
> TFieldMeta(`soldDate`, 7, TReq.OPTIONAL),
> TFieldMeta(`chargeDate`, 8, TReq.OPTIONAL)
>   ]);
> }
> 
> and another class created for hibernated:
> 
> class Card
> {
> import hibernated.core;
> 
> @Id
> @Generated
> long id;
> @UniqueKey
> string pwd;
> //index
> long agentId;
> bool valid;
> long rmb;
> long createDate;
> long soldDate;
> long chargeDate;
> }
> 
> 
> Sometime , I need to copy them:
> 
> thrift.Card tc;
> 
> db.Card dc;
> 
> dc.id = tc.id;
> dc.pwd = tc.pwd;
> ...
> 
> 
> It is boring coding, I want a solution to copy them automatically:

You could just add a method to the db class:

void fields(B)(auto ref B b) @property {
  foreach (I, _; typeof(this.tupleof))
 this.tupleof[I] = mixin(`b.`~__traits(identifier, this.tupleof[I]));
}

then

   dc.fields = tc;

will work.

artur


Re: static class vs. static struct

2015-01-27 Thread Artur Skawina via Digitalmars-d-learn
On 01/27/15 10:40, Daniel Kozak via Digitalmars-d-learn wrote:
> On Tuesday, 27 January 2015 at 09:36:49 UTC, Daniel Kozak wrote:
>> On Tuesday, 27 January 2015 at 09:01:39 UTC, ref2401 wrote:
>>> For several times I've met struct(or static struct) usage in Phobos for 
>>> singleton pattern implementation. Unfortunately now i can remember only 
>>> core.runtime.Runtime.
>>> So I've got a question. Why do Phobos guys use struct or static struct for 
>>> or singleton pattern implementation? Why don't use static final class for 
>>> this purpose?
>>
>> I do not think this is a singleton pattern (no instance). I see it much more 
>> like namespace in case of core.runtime.Runtime. And yes static final class 
>> could do that too but struct looks better than final class and you can 
>> disable this on structs
> 
> import std.stdio;
> import std.conv;
> 
> struct S
> {
> @disable this();
> }
> 
> final class C
> {
> }
> 
> void main() {
> writeln(C.sizeof);
> writeln(S.sizeof);
> }

D's `class` magically adds a level of indirection, so C.sizeof
gives you just the size of the _reference_.

For the true (ie instance/payload) size you'd have to use 

   __traits(classInstanceSize, C)

artur


Re: reinterpret array

2015-01-13 Thread Artur Skawina via Digitalmars-d-learn
On 01/13/15 21:52, Dominikus Dittes Scherkl via Digitalmars-d-learn wrote:
> On Tuesday, 13 January 2015 at 20:11:45 UTC, anonymous wrote:
>> On Tuesday, 13 January 2015 at 20:00:57 UTC, Dominikus Dittes Scherkl wrote:
>>> So if I have a function that allowes to do this:
>>>
>>> uint a;
>>> a.bit[16] = true;
>>> writeln(a); // 65536
>>>
>>> Is it also already available?
>>
>> a |= 1 << 16;
> 
> Of course you can calculate it, but the
> syntax looks quite different if you want to do
> a.bit[22] = false:
> 
> a &= ~(1<<16);
> 
> Or if you want to test a bit:
> 
> if(a.bit[16])
> 
> instead of
> 
> if(a & (1<<16))
> 
> much more convenient for arrays:
> 
> ulong[100] a;
> 
> a.bit[3000] = true;
> 
> doing this directly with shifts is lousy (and error prone)
> 
> But ok. I see, it's not really awesome :-/

It's neat, but the real problems with it are:
1) obfuscation - it hides those trivial bit ops behind layers of
functions and operator overloads, which everyone reading the
code must then figure out;
2) safety - `a.bit` could potentially outlive `a`; D does not
handle object lifetimes, so there's no 100% safe way to prevent
such bugs.

Hence you probably don't actually want to use this.


   struct Bits(E, size_t UB=1) {
  E* e;

  bool opIndexAssign(bool v, size_t idx) {
 auto o = idx/(E.sizeof*8);
 idx %= E.sizeof*8;
 if (o>=UB)
assert (0);
 if (v)
e[o] |=   1L<=UB)
assert (0);
 return !!(e[o] & 1L<

Re: Copy only frame pointer between objects of nested struct

2015-01-06 Thread Artur Skawina via Digitalmars-d-learn
On 01/06/15 23:14, Peter Alexander via Digitalmars-d-learn wrote:
> auto foo(T)(T a) {
> T b;  // Error: cannot access frame pointer of main.X
> b.data[] = 1;
> return b;
> }
> 
> void main() {
> struct X {
> this(int) {}
> int[4096] data;
> }
> foo(X());   
> }
> 
> Note the error is because you cannot construct the main.X object without a 
> frame pointer.
> 
> You could do `T b = a` here to get a's frame pointer, but it would also copy 
> all of a's data, which is expensive and unnecessary.
> 
> Is there a way to only copy a's frame pointer into b?

The obvious hack would be

T b = void;
b.tupleof[$-1] = a.tupleof[$-1];

but you probably don't want to do it like that...

> (Note: this is just an illustrative example, real problem here: 
> https://issues.dlang.org/show_bug.cgi?id=13935)

That shows a static struct, so I'm not sure it's the same problem.

artur


Re: `shared Mutex`?

2014-12-28 Thread Artur Skawina via Digitalmars-d-learn
On 12/28/14 10:24, Aiden via Digitalmars-d-learn wrote:
> Is `shared` in a workable state?

No.

> Shouldn't Mutex, Condition, etc be shared since they are basically only ever 
> useful when used in multiple threads?

Yes, but there are so many problems with 'shared' that
using it that way (even only as a type constructor) is
impractical.

artur


Re: transversal sum

2014-11-06 Thread Artur Skawina via Digitalmars-d-learn
On 11/06/14 18:32, bearophile via Digitalmars-d-learn wrote:
> Marc Schütz:
> 
>> We'd need something taking and returning a RoR that "mirrors" them 
>> diagonally. Then we could simply apply `map!(r => r.sum)` on the result.
> 
> A simple solution is to create a row of values, and then sum them correctly 
> while you scan the rows.

The simplest solution is probably something like:

   auto transversal_sum(FR)(FR rr) {
  static struct TS {
 FR rr;
 bool empty() @property const { return rr.front.empty; }
 auto front() @property {
import std.algorithm;
return reduce!((a, b)=>a+b.front)(rr.front.front.init, rr);
 }
 void popFront() { foreach (ref r; rr) r.popFront(); }
  }
  return TS(rr);
   }

but I think OP wanted a ready-made phobos solution, w/o all the
range boilerplate...

artur


Re: Error with constraints on a templated fuction

2014-08-25 Thread Artur Skawina via Digitalmars-d-learn
On 08/25/14 18:52, Jonathan M Davis via Digitalmars-d-learn wrote:
> Another commonly used one is is(typeof(foo)). typeof(foo) gets the type of foo
> and will result in void if foo doesn't exist, and is(void) is false, whereas

D is not quite that simple. ;)

   static assert(is(void)==true);

(a) `typeof(invalid)` is an error;
(b) the `is(...)` expression swallows errors;

hence (a)+(b) ->

   static assert(is(typeof(invalid))==false);

artur


Re: @safe, pure and nothrow at the beginning of a module

2014-08-16 Thread Artur Skawina via Digitalmars-d-learn
On 08/16/14 13:58, Philippe Sigaud via Digitalmars-d-learn wrote:
> On Sat, Aug 16, 2014 at 1:30 PM, Artur Skawina via Digitalmars-d-learn

>> http://forum.dlang.org/post/mailman.125.1397731134.2763.digitalmar...@puremagic.com
> 
> Okay...
> 
> So @safe includes child scopes. I suppose @trusted and @system work in
> the same way.
> 
> *but*
> 
> nothrow, @nogc and UDA's do not include child scopes. Putting them at
> the beginning of a module will not affect methods in aggregates...
> 
> What's the situation for pure? (I don't have a D compiler handy right
> now, or I would test it myself).

@safe, @trusted, @system, shared, immutable, const, inout and `extern (...)`
affect child scopes. `synchronized` does too, but in a rather unintuitive
way; hopefully nobody uses this. ;)

Other attributes, including 'pure' and 'nothrow' only affect symbols
in the current scope.

artur


Re: @safe, pure and nothrow at the beginning of a module

2014-08-16 Thread Artur Skawina via Digitalmars-d-learn
On 08/16/14 13:18, Philippe Sigaud via Digitalmars-d-learn wrote:
> We indeed need to put annotations inside aggregates to
> affect their innards.
> 
> If that's true, I have a lot of annotation sprinkling to do.

It's not true for @safe, but true for some other attributes.

http://forum.dlang.org/post/mailman.125.1397731134.2763.digitalmar...@puremagic.com

artur


Re: opDispatch compiles fine, but still fails to resolve?

2014-08-09 Thread Artur Skawina via Digitalmars-d-learn
On 08/09/14 03:20, Vlad Levenfeld via Digitalmars-d-learn wrote:
> More opDispatch woes. This feature keeps biting me, yet I keep trying to use 
> it.
> 
> This time I'm trying to access elements of a vector GLSL-style (without 
> swizzling... for now).
> 
> Here's the relevant code:
> 
> struct Vector (uint length, Element = double)
> {
> ref @property component (string c)()
> {
> enum mat = q{xyzw};
> enum col = q{rgba};
> enum tex = q{uv};
> 
> static if (mat.canFind (c))
> return components[mat.countUntil (c)];
> else static if (col.canFind (c))
> return components[col.countUntil (c)];
> else static if (tex.canFind (c))
> return components[tex.countUntil (c)];
> else static assert (0);
> }
> 
> ref @property opDispatch (string c)()
> if (c.length == 1)
> {
> auto v = component!c;
> pragma(msg, typeof(v)); // this outputs the expected result
> return v; // so everything is fine, right? wrong...
> }
> 
> Element[length] components;
> }
> 
> Calling vector.component!`x` or something works fine, but calling vector.x 
> fails with "Error: no property" etc.
> 
> Now, I'm used to opDispatch silently failing when it can't compile (very 
> annoying btw), but in this case, I tested every line with a pragma (msg, 
> __traits(compiles...)) and everything checks out. All expressions are 
> verified CTFE-able. The compiler apparently makes it all the way through the 
> method without a hitch, but then just fails symbol resolution anyway.
> 
> Is this just a bug? Does anyone have any advice on what else to try?

v.opDispatch!`x`;

Your opDispatch is returning a reference to a local stack-allocated
variable. D does not support real references; that 'auto v=...'
declaration creates a copy.

   ref @property opDispatch (string c)() { return component!c; }

[opDispatch works for every kind of symbol, there's no problem with
 @property]

artur


Re: Inner struct accessing host member

2014-08-05 Thread Artur Skawina via Digitalmars-d-learn
On 08/05/14 22:32, Philippe Sigaud via Digitalmars-d-learn wrote:
> I'd have thought that this would work:
> 
> struct A
> {
> int[] i;
> B b;
> 
> struct B
> {
> void foo() { i ~= 1;}
> }
> }
> 
> void main()
> {
> A a;
> a.b.foo();
> }
> 
> But the compiler tells me 'need this for i of type int[]'.
> Is there any way I can gain access on i inside B?

Not directly, but as you ask for /any/ way -- yes:

   struct B
   {
 void foo() { outer.i ~= 1; }
 ref A outer() inout @property { return 
*cast(A*)(cast(void*)&this-A.b.offsetof); }
   }

Note this will work only as long as you have just one B
instance in A and B is never created or copied outside of A.

artur


Re: auto ref function parameters in a free function

2014-08-03 Thread Artur Skawina via Digitalmars-d-learn
On 08/03/14 23:19, Vlad Levenfeld via Digitalmars-d-learn wrote:
> 
> I made less_than to serve as a default sorting predicate, so in a few places 
> there is something like this:
> 
> void sort (R, T = ElementType!R, alias compare = less_than!T)(R range, T item)
> {...}

 void sort (R, T = ElementType!R, alias compare = less_than)(R range, T item)

[should work iff the sort implementation only calls the predicate]

artur


Re: Showing a user specified error message when no overloads match

2014-07-29 Thread Artur Skawina via Digitalmars-d-learn
On 07/29/14 17:45, H. S. Teoh via Digitalmars-d-learn wrote:
> You're right, opDispatch behaves like SFINAE. I've had trouble debugging
> it before, because when it works, it works very well, but when you
> accidentally make a typo, it just "disappears" -- you get an error that
> the property is missing, but the actual error inside opDispatch has been
> gagged and it's almost impossible to get at the actual error message.

D's overloaded operators are (usually) normal (templated) functions, you
can use `a.opDispatch!"blah"` instead of `a.blah` to see what's wrong.

What's really nasty is the way phobos handles `toString` - if that method
fails to compile then you get a usually not very helpful default, and no
warning that something is wrong. It's easy to break `toString` w/o noticing
anything. Figuring out later what exactly broke can be "interesting". Still
doable via the above mentioned trick, but you'll need to create a mock `sink`
etc.

artur


Re: Compile time regex matching

2014-07-14 Thread Artur Skawina via Digitalmars-d-learn
On 07/14/14 13:42, Philippe Sigaud via Digitalmars-d-learn wrote:
> asserts get an entire copy of the parse tree. It's a bit wasteful, but
> using 'immutable' directly does not work here, but this is OK:
> 
> enum res = MyRegex("abcabcdefFOOBAR"); // compile-time parsing
> immutable result = res; // to avoid copying the enum value everywhere   
 
   static immutable result = MyRegex("abcabcdefFOOBAR"); // compile-time parsing


> The static asserts then works (not the toString, though). Maybe

diff --git a/pegged/peg.d b/pegged/peg.d
index 98959294c40e..307e8a14b1dd 100644
--- a/pegged/peg.d
+++ b/pegged/peg.d
@@ -55,7 +55,7 @@ struct ParseTree
 /**
 Basic toString for easy pretty-printing.
 */
-string toString(string tabs = "")
+string toString(string tabs = "") const
 {
 string result = name;
 
@@ -262,7 +262,7 @@ Position position(string s)
 /**
 Same as previous overload, but from the begin of P.input to p.end
 */
-Position position(ParseTree p)
+Position position(const ParseTree p)
 {
 return position(p.input[0..p.end]);
 }

[completely untested; just did a git clone and fixed the two
 errors the compiler was whining about. Hmm, did pegged get
 faster? Last time i tried (years ago) it was unusably slow;
 right now, compiling your example, i didn't notice the extra
 multi-second delay that was there then.]

artur


Re: template mixins for boilerplate

2014-06-21 Thread Artur Skawina via Digitalmars-d-learn
On 06/21/14 18:01, Philippe Sigaud via Digitalmars-d-learn wrote:
> In what way is a template more reliable than the equivalent function?

> mixin template Function(string name) {
> mixin("public static int " ~ name ~ "() { return other.module." ~
> name ~"; }");
> }
> 
> struct S {
>   mixin Function!"fctn1";
> }
> 
> And this double-mixin construction seems needlessly complicated to me,

It does not make much difference for this simple case, but doing it this
way allows for other declarations that do not need to be mixed in.
IOW if 'Function' contains more boilerplate, then it does not all need
to be written inside a string. Not to mention it saves two sets of parens. :)
A mixin template *is* slightly more reliable than a function, because
it won't be (ab-)usable in many context where a normal function call works.
But I think this choice is mostly an aesthetical (ie subjective) one.

artur


Re: template mixins for boilerplate

2014-06-21 Thread Artur Skawina via Digitalmars-d-learn
On 06/21/14 05:32, Paul D Anderson via Digitalmars-d-learn wrote:
> I can't use a template mixin:
> 
> mixin template Function(string name)
> {
>   const char[] Function =
> "public static int " ~ name ~ "() { return other.module." ~ name ~"; }";
> }
> 
> Error: mixin templates are not regular templates.

   mixin template Function(string name) {
  mixin("public static int " ~ name ~ "() { return other.module." ~ name 
~"; }");
   }

   struct S {
  mixin Function!"fctn1";
   }

artur


Re: C structs

2014-06-21 Thread Artur Skawina via Digitalmars-d-learn
On 06/20/14 14:42, Dicebot via Digitalmars-d-learn wrote:
> On Friday, 20 June 2014 at 12:17:22 UTC, Johann Lermer wrote:
>> So, why is there no init routine for the rectangle? There's only one for the 
>> matrix.
> 
> That needs actually building deimos cairo and checking symbols in object 
> files so I will do as soon as have a bit more spare time ;)

If i were to guess: the compiler optimizes the init-blitting into
a memset(-equivalent) when all the members are default initted to
zero; D's doubles are initialized to NaN, so this optimization is
not happening when a struct contains such fields.

artur


Re: C++'s "defaulted comparison operators" proposal

2014-06-18 Thread Artur Skawina via Digitalmars-d-learn
On 06/18/14 07:49, Ali Çehreli via Digitalmars-d-learn wrote:

> The idea is to be able to have standard comparison behavior for structs 
> without boilerplate. For example, if the ordering should consider all members 
> of the following struct one after the other (first 'i', then 'l', and finally 
> 's'):

Isn't this already implicitly done? (I thought it was just my old compiler
version that did not yet support this)

Anyway, something like this wrapped in an appropriate template
should do:

   int opCmp()(const typeof(this) b) const {
  foreach (I, _; typeof(this.tupleof))
 static if (is(typeof(this.tupleof[I].opCmp(b.tupleof[I] {
if (auto d = this.tupleof[I].opCmp(b.tupleof[I]))
return d;
 } else {
if (auto d = this.tupleof[I] - b.tupleof[I])
return d;
 }
  return 0;
   }

and

http://forum.dlang.org/post/mailman.1230.1333044904.4860.digitalmar...@puremagic.com

artur


Re: Splitting Ranges using Lambda Predicates

2014-06-11 Thread Artur Skawina via Digitalmars-d-learn
On 06/11/14 16:05, monarch_dodra via Digitalmars-d-learn wrote:
> Well, (IMO) it's a problem with no real solution. But for what it's worth, 
> most (if not all) of the algorithms in the standard lib know how to handle 
> strings efficiently and correctly (split, find, etc...). Things only start 
> getting funny once you start mixing indexing and element counts.

If the recommended approach for writing a really trivial string transformation
is to copy and modify ~60 lines of std lib code then something is very wrong.
The consequence is that such code will often end up being eager, as it's much
easier to write it that way... That is why, after seeing your solution, I wrote
the most compact lazy version I could think of - let's not scare people away
from using ranges.

AFAIUI the OP basically wanted a version of splitter that does not eat the
separators and a predicate that keeps around previous state. The latter can
already be achieved via a lambda, so the missing bit is an optional splitter
template parameter (eg consume=false). So at least in this case the problem
could be easily handled.

artur


Re: Splitting Ranges using Lambda Predicates

2014-06-11 Thread Artur Skawina via Digitalmars-d-learn
On 06/11/14 15:44, Artur Skawina wrote:
> If, instead, you create a string-specific 'countUntil' that returns
> a type that holds both the byte and code-point counts and implicitly
> converts to the latter, then you can have a 'takeExactly' overload
> that uses the extra info to avoid the unnecessary decoding and is able
> to directly return slices. The overhead is minimal; one extra integer
> that's passed around, and often completely eliminated by function inlining.
> But now you don't need to write a string-specific version of every
> algorithm. (Of course this description is slightly oversimplified)

Well, for safety, you'd most likely want to pass around the range too
(ie string slice, or just the pointer as the min-length is implied);
so it's two size_ts, not one. Still, the overhead is tiny and the
advantage of not having to special-case for strings everywhere is worth
it.

artur



Re: Splitting Ranges using Lambda Predicates

2014-06-11 Thread Artur Skawina via Digitalmars-d-learn
On 06/11/14 14:40, monarch_dodra via Digitalmars-d-learn wrote:
> For example, you should avoid "countUntil" and "takeExactly" when dealing 
> with strings, since these are not O(1) operations, and don't actually return 
> string slices. EG:
> string s = "someGGGreatVariableName".slicer().front;
> Error: cannot implicitly convert expression 
> (slicer("someGGGreatVariableName").front()) of type Result to string

That's a problem with D's string handling. For both examples and rarely
called code, i always prefer correctness over performance. Of course if
that code ends up being perf significant it could be further optimized by
adding a specialization for D strings...

> That's why the splitter code uses the more verbose "r.length - r.find!pred".

... but that's the wrong approach. You end up writing a string-specific
(or -aware) special version for practically every algorithm...

If, instead, you create a string-specific 'countUntil' that returns
a type that holds both the byte and code-point counts and implicitly
converts to the latter, then you can have a 'takeExactly' overload
that uses the extra info to avoid the unnecessary decoding and is able
to directly return slices. The overhead is minimal; one extra integer
that's passed around, and often completely eliminated by function inlining.
But now you don't need to write a string-specific version of every
algorithm. (Of course this description is slightly oversimplified)

There is a reason why I never use D's std lib.

artur


Re: Splitting Ranges using Lambda Predicates

2014-06-11 Thread Artur Skawina via Digitalmars-d-learn
On 06/11/14 00:31, "Nordlöw" via Digitalmars-d-learn wrote:
>> Either way, it shouldn't be too hard to implement. Base it off 
>> "splitter!pred", which is actually quite trivial. AFAIK, your
> 
> What do you mean by basing it off splitter!pred - should I start with some 
> existing splitter algorithm in Phobos or start from scratch?

Starting from scratch is actually not a bad idea, at least for this kind
of trivial functionality. A working version can be written in less time
than copying, analyzing and modifying another implementation...

For example (using monarch_dodra's test inputs):

   auto slicer(alias PRED, R)(R r) {
  import std.algorithm, std.array, std.range;
  struct Slicer {
 R r;
 size_t c;
 bool empty() @property const { return r.empty; }
 auto front() @property {
c = r.dropExactly(1).countUntil!PRED()+1;
if (c==0)
   c = r.length;
return r.takeExactly(c);
 }
 void popFront() { r.popFrontN(c); }
  }
  return Slicer(r);
   }

   auto slicer(R)(R r) {
  import std.uni;
  return slicer!(a=>isUpper(a))(r);
   }

   void main() {
  import std.stdio, std.range;
  "SomeGreatVariableName"  .slicer().writeln();
  "someGGGreatVariableName".slicer().join(" ").writeln();
  "".slicer().writeln();
  "a".slicer().writeln();
  "A".slicer().writeln();
   }

artur


Re: enum template shorthand and short circuit evaluation

2014-06-10 Thread Artur Skawina via Digitalmars-d-learn
On 06/10/14 02:28, Byron via Digitalmars-d-learn wrote:
> Should this work?  It seems like the short circuit booleans are not 
> working:
> 
> enum isPrimitive(T) = isBasicType!T || (isArray!T && isBasicType!
> (ForeachType!T));

[...]

> But this style works:
> 
> template isPrimitive(T) 
> {
> static if(isBasicType!T || (isArray!T && isBasicType!(ForeachType!T))) 
> {
> enum isPrimitive = true;
> } else {
> enum isPrimitive = false;
> }
> }

Static-if is special. Outside of static-if [1], code needs to be valid, 
even if it ends up never being executed.

> Should this work?

No. Allowing invalid code just because it will be skipped when the code
executes (either at RT or CT) would create other problems, while only
solving a minor and relatively rare one (the verbosity of static-if).

artur

[1] and a few other contexts, like in template constraints, is-expressions etc.


Re: alias with lambda syntax: alias fun2=a=>fun(a);

2014-06-05 Thread Artur Skawina via Digitalmars-d-learn
> On 06/05/14 08:58, Timothee Cour via Digitalmars-d-learn wrote:

>>   //none of those work:
>>   //alias fun2=a=>fun(a);

  alias fun2=ALIAS!(a=>fun(a));

That 'ALIAS' template will need to be in module scope.
  
  alias ALIAS(alias A) = A;

artur


Re: alias with lambda syntax: alias fun2=a=>fun(a);

2014-06-05 Thread Artur Skawina via Digitalmars-d-learn
On 06/05/14 08:58, Timothee Cour via Digitalmars-d-learn wrote:
> Is there a way to do this?
> 
> auto fun(T)(T a){return a;}
> 
> template fun2(T){auto fun2(T a){return fun(a);}}//OK but heavy syntax and 
> cannot be nested inside test()
  
   alias fun2(T) = fun!T;

But this will prevent IFTI, so you'd either need to use 'fun2!int' or
introduce another alias ...

> void main(){
>   //alias fun2=fun!int; //OK but needs to specify template params

... like this one.

If you want the params inferred, then

   static auto ref fun2(A...)(A a) { return fun(a); }

will mostly work. [1]

>   //none of those work:
>   //alias fun2=a=>fun(a);
>   //alias fun2(T)=(T a)=>fun(a);
>   //alias fun2(T)=(T a){return fun(a);}
>   auto b=[1].map!fun2;
>   assert(b.equal([1]));
> }
> 

artur

[1] no perfect forwarding; there's no terse way to do that in D.


Re: [Rosettacode] Growable slices

2014-05-16 Thread Artur Skawina via Digitalmars-d-learn
On 05/16/14 17:20, bearophile via Digitalmars-d-learn wrote:
> Artur Skawina:
> 
>> Ugh. So how does it perform wrt the D version that I wrote for
>> you last time? [1]
> 
> I have done a benchmark with the various version (the first 3 are the ones on 
> the Rosettacode site, and the #4 is yours):
> 
> lzw1: 0.39
> lzw2: 0.17
> lzw3: 0.21
> lzw4: 0.17
> 
> I think your comment was about an older version of the first entry, that is 
> non meant to be fast, just short and simple.

While I don't remember the numbers, I did test w/ gdc back then and
both of your versions (from that thread) performed very poorly in
a micro benchmark - I wasn't exaggerating when I said /an order
of magnitude/, there really was a ~10 times perf difference.
I didn't read the current entries on that page, so that might no
longer apply, if you've modified them since.

My point is that this third version that you announced here as almost-
idiomatic-D is not even close to that goal; it's more or less a direct
translation from C, and not like anything that would be written from
scratch in D, hence the "ugh". Your own numbers above suggest that 
not even the "more efficient" claim is true. 

> I think the second version is enough. Do you agree?

I don't see the point of the third ("C-in-D") one, other than to
show how a direct C to D translation would look like.

If /I/ was looking for a D code sample, then
  
  OUT[] compress(OUT=int, R)(R original) {
 IDAA!(OUT, const typeof(cast()original.front)[]) dictionary;
 OUT[] result;
 size_t l = 1;

 while (original.length>=l) {
if (original.takeExactly(l) in dictionary)
   { ++l; continue; }
result ~= dictionary[original.takeExactly(l-1)];
dictionary[original.takeExactly(l)] = cast(OUT)dictionary.length;
original.popFrontN(l-1);
l = 1;
 }

 return original.empty ? result : (result ~ dictionary[original]);
  }

would have been much more useful than any of the currently available
examples... Your #1 is more readable and easier to understand for
someone not familiar with D and ranges, but extremely inefficient
and not something that anyone would like to use in real life.

Many of the rosettacode entries are very misleading and unidiomatic,
they give a very wrong picture of the language they're trying to
show off. This is probably not specific to D, but true for most
of the represented languages.

artur


Re: [Rosettacode] Growable slices

2014-05-16 Thread Artur Skawina via Digitalmars-d-learn
On 05/16/14 11:47, bearophile via Digitalmars-d-learn wrote:
>> There are of course ways to implement a really efficient ZLW compressor in 
>> D, and such implementation could be added as third D entry if it manages to 
>> be not too much long,
> 
> Third version added:
> http://rosettacode.org/wiki/LZW_compression#More_Efficient_Version
> 
> I have tried to make it idiomatic D, but some of the C style is probably 
> still present. 

Ugh. So how does it perform wrt the D version that I wrote for
you last time? [1]

[1] 
http://forum.dlang.org/post/mailman.2132.1353592965.5162.digitalmar...@puremagic.com)

artur


Re: Temporary silence output (stdout)

2014-05-10 Thread Artur Skawina via Digitalmars-d-learn
On 05/10/14 22:24, MarisaLovesUsAll via Digitalmars-d-learn wrote:
> I sometimes got a useless messages in stdout from SDL_Image
> library, and I want to temporary silence it. How do I do?

One way would be something like:

   import std.stdio;

   void writeOutput () {
  static c = 1;
  printf("%d\n", c++);
   }

   void main() {
  writeOutput();

  {
 auto ex = PushFD!1("/dev/null".ptr);
 writeOutput();
  }

  writeOutput();
   }

   struct PushFD(int fd) {
  import core.sys.posix.fcntl, core.sys.posix.unistd;
  int old;
  this(const char* fn) { //
 old = dup(fd);
 auto nfd = open(fn, O_RDWR);
 dup2(nfd, fd);
 close(nfd);
  }
  ~this() { dup2(old, fd); close(old); }
   }

// In real code you'll want to check for errors from dup/dup2/open/close.

artur


Re: Need help with movement from C to D

2014-05-06 Thread Artur Skawina via Digitalmars-d-learn
On 05/06/14 16:45, via Digitalmars-d-learn wrote:
> On Tuesday, 6 May 2014 at 14:25:01 UTC, Artur Skawina via Digitalmars-d-learn 
> wrote:
>> I'm not sure why you'd want to wrap the .offsetof expression in
>> a template, but it can easily be done like this:
>>
>>enum offsetOf(alias A, string S) = mixin("A."~S~".offsetof");
> 
> Great, that's even shorter.
> 
> Somehow I was fixated on converting the symbol to a string first, but of 
> course the name is directly available in the mixin:
> 
> enum offsetof(alias typenfield) = mixin("typenfield.offsetof");

I didn't realize that worked, but it does. So...

   enum offsetOf(alias A) = A.offsetof;


But I have no idea why anybody would want to wrap this trivial
expression like that. 

And, I have no idea if the, hmm, /unconventional/ D offsetof semantics
are in the bugzilla. It's not really a "bug", but a design mistake...

artur


Re: Need help with movement from C to D

2014-05-06 Thread Artur Skawina via Digitalmars-d-learn
I'm not sure why you'd want to wrap the .offsetof expression in
a template, but it can easily be done like this:

   enum offsetOf(alias A, string S) = mixin("A."~S~".offsetof");


Keep in mind that D's offsetof is flawed - if the object does not
contain the requested member, but implicitly converts to another one
that does have such field then the expression compiles, but yields
a bogus value. Eg

   struct S { int a, b, c; S2 s2; alias s2 this; }
   struct S2 { int d, e; }
   static assert(S.e.offsetof==4); // Oops.

artur


Re: Postblit not invokable with MyStruct(MyStruct()); ?

2014-05-03 Thread Artur Skawina via Digitalmars-d-learn
On 05/03/14 01:05, Mark Isaacson via Digitalmars-d-learn wrote:
> 2) I ran into this issue while attempting to leverage the postblit for 
> code-reuse. In particular, I have a setup that is similar to:
> 
> struct A {
>   this(B b) { /* Stuff */ }
> }
> 
> struct B {
> }
> 
> void foo(T)(T param) {
>   auto a = A(param);
>   /* Stuff */
> }
> 
> unittest {
>   foo(A()); //Fails
>   foo(B()); //Succeeds
> }
> 
> The notion being that A and B are 2 ways to represent the same thing, why not 
> convert everything to the A format and proceed from there; I figured the 
> compiler would optimize out the pointless copy when T == A. Alas, as shown in 
> my unittest, foo fails to accept arguments of type A.

What actually fails is the initialization of 'a'.
Add another

   this(A a) { /* Stuff */ }

constructor to the 'A' struct, and it will work.


And, yes, the missing cpctors are a language problem.

artur


Re: Making enum join variadic

2014-05-02 Thread Artur Skawina via Digitalmars-d-learn
On 05/02/14 17:27, Meta via Digitalmars-d-learn wrote:
> On Friday, 2 May 2014 at 15:18:06 UTC, Artur Skawina via Digitalmars-d-learn 
> wrote:
>> On 05/02/14 15:38, "Nordlöw" via Digitalmars-d-learn wrote:
>>>
>>> template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E))
>>> {
>>> bool[string] allMembers;   // used to detect member collisions
>>> mixin({
>>> string r = "enum MemberNamesUnion { ";
>>> foreach (T; E) {
>>> import std.range: join;
>>> foreach (member; __traits(allMembers, T)) {
>>> static assert (member in allMembers, "Member 
>>> collision");
>>> allMembers[member] = true;
>>> }
>>> r ~= [__traits(allMembers, T)].join(",") ~ ",";
>>> }
>>> return r ~ " }";
>>> }());
>>> }
>>>
>>> It fails as
>>>
>>> enums.d(25,46): Error: static variable allMembers cannot be read at compile 
>>> time
>>> enums.d(25,21):while evaluating: static assert("a" in allMembers)
>>>
>>> Is there a solution to this problem?
>>
>> Move the AA declaration to inside the lambda, remove the 'static'
>> from the assert, and fix the condition ("member !in allMembers"), then
>> it will work.
> 
> But that will also move the compile time check to a runtime one.

No; mixin arguments are always evaluated at CT.

artur


Re: Making enum join variadic

2014-05-02 Thread Artur Skawina via Digitalmars-d-learn
On 05/02/14 15:38, "Nordlöw" via Digitalmars-d-learn wrote:
> 
> template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E))
> {
> bool[string] allMembers;   // used to detect member collisions
> mixin({
> string r = "enum MemberNamesUnion { ";
> foreach (T; E) {
> import std.range: join;
> foreach (member; __traits(allMembers, T)) {
> static assert (member in allMembers, "Member collision");
> allMembers[member] = true;
> }
> r ~= [__traits(allMembers, T)].join(",") ~ ",";
> }
> return r ~ " }";
> }());
> }
> 
> It fails as
> 
> enums.d(25,46): Error: static variable allMembers cannot be read at compile 
> time
> enums.d(25,21):while evaluating: static assert("a" in allMembers)
> 
> Is there a solution to this problem?

Move the AA declaration to inside the lambda, remove the 'static'
from the assert, and fix the condition ("member !in allMembers"), then
it will work.

artur


Re: Making enum join variadic

2014-05-01 Thread Artur Skawina via Digitalmars-d-learn
On 05/02/14 00:24, "Nordlöw" via Digitalmars-d-learn wrote:
> How can I make `join` variadic (by filling in njoin) in the following code?

   import std.array, std.range, std.algorithm;
   import std.stdio;

   template Njoin(ES...) {
  mixin({
 string r = "enum Njoin { ";
 foreach (E; ES)
r ~= [__traits(allMembers, E), " "].join(",");
 return r ~ "}";
  }());
   }

   void main(string[] args)
   {
   enum E1 { A, B, C }
   enum E2 { E, F, G }
   alias E12 = Njoin!(E1, E2);
   E12 e12;
   writeln(e12.min, ",", e12.max);
   }

artur


Re: import with renaming and public import inside module

2014-04-29 Thread Artur Skawina via Digitalmars-d-learn
On 04/29/14 11:57, ketmar via Digitalmars-d-learn wrote:
> On Monday, 28 April 2014 at 15:57:16 UTC, anonymous wrote:
>> `zmod.symbol` works, too.
> no, it's not. at least on latest GDC.

It certainly works here; if it didn't it would be a frontend problem.

>> I don't think so. The point of the renamed import is that you have to use 
>> the new name.
> but i renamed only my.module, not others. nothing hints me that renaming is 
> SO global. it's counterintuitive.

You did not /rename/ it, you *named* it - so now you have to use
that name to access all symbols inside the module, *including* any
symbols imported from other modules.

>> If you want the new name to be optional
> no, i don't. i don't want my.module symbols in global scope at all (it was 
> static import in a fact, i relaxed it later).

I'm not sure what you want to achieve, but one solution could be
creating a module like:

   module mymodule;
   public import zmod = myzmodmodule;
   public import my.whatever1;
   version(blah)
  public import my.whatever2;

then:
   
   import mymodule;
   // ...

>> As far as I can see, everything works as intended.
> so it's broken beyond any repair. so sad.

The D module system has a lot of problems and certainly needs
to be completely redesigned from scratch, but it does work as
documented and can already handle simple cases as yours.

artur


Re: Extern Keyword for Function Type

2014-04-15 Thread Artur Skawina
On 04/15/14 22:15, Jeroen Bollen wrote:
> exten(C) {
> testFunction(int function(int));
> }
> 
> testFunction now requires an external function as parameter. It can't be 
> called with a pointer to a D function.
> 
> Logical Solution:
> 
> extern(C) {
> testFunction(extern(D) int function(int)); // DOES NOT COMPILE
> }
> 
> How do you fix this without moving it outside the global extern block?

   extern(C) {
   extern (D) alias FP = int function(int);
   void testFunction(FP);
   }

artur


Re: Iterate over symbols in tupleof without instance

2014-04-15 Thread Artur Skawina
On 04/15/14 13:33, Dicebot wrote:
> On Tuesday, 15 April 2014 at 11:25:14 UTC, Artur Skawina wrote:
>>void iterate(T)()
>>{
>>foreach (index, member; typeof(T.tupleof))
>>{
>>pragma(msg, __traits(identifier, T.tupleof[index]));
>>}
>>}
> 
> So ashamed :D

I would have not thought of that either, if Jacob didn't mention it... :)

http://forum.dlang.org/post/jl9gil$i9l$1...@digitalmars.com

artur


Re: Converting function pointers to delegates

2014-04-15 Thread Artur Skawina
On 04/15/14 13:30, Andrej Mitrovic wrote:
> On 4/15/14, Artur Skawina  wrote:
>> It *is* true. Classes are /reference types/, not references to classes.
> 
> I meant the part where he said you can't cast a reference to a pointer. You 
> can.

He obviously meant that you can't get a pointer to the object, that the
reference points to, just by casting and w/o address-of.

   int* f(ref int r) { return cast(int*)r; }

   void main() {   
  int a = 42;

  import std.stdio;
  writeln(&a);
  writeln(f(a));
   }

Yes, this will compile, and, yes, you can "cast a reference to a pointer",
but this does not mean that you will get a pointer to 'a'.

The D situation wrt to refs and classes is bad enough; saying that you
"can cast a reference to a pointer" will only confuse people. 

artur


Re: Converting function pointers to delegates

2014-04-15 Thread Artur Skawina
On 04/14/14 19:51, Andrej Mitrovic wrote:
> On Monday, 14 April 2014 at 17:48:31 UTC, Adam D. Ruppe wrote:
>> On Monday, 14 April 2014 at 17:45:52 UTC, Ryan Voots wrote:
>>> src/yage/core/misc.d(164): Error: e2ir: cannot cast this of type S to type 
>>> void*
>>
>>
>> Try taking the address of this before casting it. So more like
>>
>> cast(void*)&this
>>
>>
>> IIRC in D1 this was a pointer, whereas in D2 this is a reference. You can't 
>> cast a reference to pointer directly.
> 
> That's not true.
> 
> And I think the issue in his diagnostic is that he used it with a struct. You 
> can't cast 'this' of a struct to a pointer (you'd have to use &this), but you 
> can cast a class reference to a pointer.

It *is* true. Classes are /reference types/, not references to classes.
[There's no such thing as a "class payload" in D. Also, you can have a
 D-ref to a D-class.]

D doesn't have "true" references, just a storage-class based hack, that
only supports a small subset of ref functionality. But these pseudo-refs
still act as the objects they point to.

artur


Re: Iterate over symbols in tupleof without instance

2014-04-15 Thread Artur Skawina
On 04/15/14 12:45, Dicebot wrote:
> void iterate(T)()
> {
> foreach (index, member; T.init.tupleof)
> {
> pragma(msg, __traits(identifier, T.tupleof[index]));
> }
> }
> 
> struct A
> {
> int a, b, c;
> }
> 
> void main()
> {
> iterate!A();
> }
> 
> Reason why you can't naively iterate over T.tupleof is that current tuple 
> foreach tries to look like normal foreach and thus iteration parameters can't 
> be  types. 

   void iterate(T)()
   {
   foreach (index, member; typeof(T.tupleof))
   {
   pragma(msg, __traits(identifier, T.tupleof[index]));
   }
   }

artur


Re: copying memory in phobos

2014-04-08 Thread Artur Skawina
On 04/08/14 14:35, Mike wrote:
> On Tuesday, 8 April 2014 at 11:56:43 UTC, ketmar wrote:
>>> I understand that.  But why is dest[] = src[] not good enough for run-time?
>> 'cause some compilers (gcc, for example) has memcpy() as 'intrinsic' and 
>> generates better inline code for it sometimes. it's just a small hint for 
>> compiler backend, and faster code is good, isn't it? ;-)
> 
> a[] = b[] causes the compiler to generate a call to _d_arraycopy, and 
> _d_arraycopy calls, you guessed it, memcpy!  (verified with GDC 4.8.2)  So, 
> there is no performance benefit calling memcpy directly.  It's going to be 
> called anyway.

'memcoy' being a built-in compiler intrinsic means that when the compiler
sees a 'memcpy' call, it does some checks (eg is the length statically
known and small enough?) and then can generated the copy instructions
directly, instead of calling the lib function.

artur


Re: Manually-allocated memory and maximum array capacity

2014-04-08 Thread Artur Skawina
On 04/07/14 22:58, Joseph Rushton Wakeling wrote:
> On 05/04/14 02:18, Artur Skawina wrote:
>> Not portably, as it will be libc and/or allocator specific.
> 
> I think that's fine.  I would be using it in circumstances where it's nice to 
> have if I can get it, not a problem if I can't.  As long as I make 
> appropriate use of version statements to ensure it's only used where 
> available, it should be OK and not affect usability.
> 
>> For example, for glibc this would work:
>>
>> /* static if (using_glibc) */
>> size_t capacity(const void* p) @property @safe {
>>return malloc_usable_size(p);
>> }
> 
> Thanks! :-)

Just be careful; I used the name 'capacity' because it fit
into your example, but 'capacity' shouldn't be overloaded like
that - it works very differently from the magic built-in property.

The only safe way to use it would be:

   E[] aalloc(E)(size_t l) @trusted {
  if (l

Re: They are not the same

2014-04-05 Thread Artur Skawina
On 04/05/14 21:51, Timon Gehr wrote:
> On 04/05/2014 11:53 AM, bearophile wrote:
>> John Colvin:
>>
>>> I think there's an argument that this should work, on the grounds that
>>> the context pointer is just another argument and therefore the lambda
>>> can be weakly pure.
>>
>> Was this discussed in the forum?
> 
> I've been bringing this up time and time again, but it is usually ignored.
> 
>> Do you think you can ask for an enhancement in Bugzilla?
>> ...
> 
> It's a plain bug. In fact, you have commented on it:
> 
> https://d.puremagic.com/issues/show_bug.cgi?id=9148

You're asking for bypassing immutability there (The first 'bar'.
That second 'bar' does not make sense w/o properly typed delegates;
the second 'foo' should indeed work).

artur


Re: Manually-allocated memory and maximum array capacity

2014-04-04 Thread Artur Skawina
On 04/05/14 00:54, Joseph Rushton Wakeling wrote:
> Hello all,
> 
> If we change the length of a dynamic array using the normal GC-based methods, 
> e.g. by setting the array's .length property, we find that the array's 
> capacity typically does not simply equal the length, but some greater value; 
> there is excess allocation.
> 
> Question: is there a comparable phenomenon for memory that is manually 
> allocated using malloc?  That is, that if we specify a particular number of 
> bytes to allocate, it may be rounded up to a particular larger number?
> 
> And, if so -- is there any way of guaranteeing what that larger number will 
> be?
> 
> The reason I ask is because, suppose that I use a dynamic array as a 
> fixed-size buffer, and that its minimum size must be n.  So, I can do:
> 
> arr.length = n;
> if (arr.capacity > arr.length)
> {
> arr.length = arr.capacity;
> }
> 
> ... and get the largest possible buffer that is at least size n, but does not 
> allocate any more memory than setting length = n.
> 
> I'm wondering if I can do something similar with manual memory allocation.

Not portably, as it will be libc and/or allocator specific.

For example, for glibc this would work:

   /* static if (using_glibc) */
   size_t capacity(const void* p) @property @safe { 
  return malloc_usable_size(p);
   }

artur


Re: Template magic exercise

2014-03-30 Thread Artur Skawina
On 03/30/14 15:36, Jack Applegame wrote:
> Wraper structure again. Is there solution without it?

No. D only allows op overloading in structs/unions/classes, so
one of those will be necessary. The simpliest solution would be
something like:

   class C {
  int elementsAccessor(size_t index) { ... }

  @property ref elements() {
 struct Elements(O) {
auto opIndex(size_t i) {
   auto o = *cast(O*)&this;
   return o.elementsAccessor(i);
}
@disable this(this);
 }
 return *cast(Elements!(typeof(this))*)&this;
  }
   }

and if you need that code to be @safe:

 auto opIndex(size_t i) @safe {
auto o = (f) @trusted { return *cast(O*)f; }(&this);
return o.elementsAccessor(i);
 }
 // etc

artur


Re: Wrapping C code?

2014-03-29 Thread Artur Skawina
On 03/29/14 20:01, CJS wrote:
> I've been using a medium-sized C library. Most of the library calls look 
> something like
> 
> action(context, arg1, arg2)
> 
> Where  is the name of the library, action is the action to take, and 
> context is an opaque pointer defined by the library to keep all the state 
> related to these actions.
> 
> Is there a simple way to wrap this library so I could make calls that look 
> like
> 
> context.action(arg1, arg2)?
> 
> I'm hoping for something with less manual work than having to wrap each 
> individual function call. Especially since the types involved in the library 
> can be somewhat complex and require trawling through multiple header files to 
> find out the true definition.
> 

The problem description is a little vague, at least w/o more context. If
you control D's view of that opaque structure then the simpliest solution
would be something like:

   struct Context {
  auto ref opDispatch(string NAME, Args...)(Args args) {
 return mixin(""~NAME~"(&this, args)");
  }
   }

artur


Re: Choice ranges?

2014-03-29 Thread Artur Skawina
On 03/29/14 18:30, Timon Gehr wrote:
> 
> I'm stuck with 2.060 myself, but there's always http://dpaste.dzfl.pl/.

For the examples, I used a gdc that claims __VERSION__==2062L.

(for /real/ code I'm still using a 2.057 based one...)

artur


Re: Choice ranges?

2014-03-29 Thread Artur Skawina
On 03/29/14 16:31, Timon Gehr wrote:
> On 03/29/2014 01:37 AM, Artur Skawina wrote:
>> You can wrap the range in a common one. When the above approach isn't
>> enough, there's always the next level:
> 
> (Note that your code does not actually compile.)

Of course it compiles -- with the compiler version I happen to use...

The compiler situation is one of the main reasons I gave up on D 
about a year ago. Every release introduces a new dialect. This may
not be such a big problem for trivial toy programs, but for anything
else it means that the only practical approach is locking the toolchain
down and never looking forward.
Sometimes this means that the examples I post won't work -- I don't
have any newer D compiler to check with, sorry.

The reason I'm still around here is that while D has tons of problems,
there is no better alternative available, for now.

I decided to revisit that DynRange implementation today, to see just how
concise and readable it could be made, while still resulting in absolutely
optimal codegen. The result was this:

   struct DynRange(R, F...) {
  size_t n;
  union { mixin(fmtStmts!(q{ typeof(F[$d](R.init)) r$d; }, F)); }

  this(R r, size_t n) {
 this.n = n;
 mixin(fmtSwitch!("n", q{ $d: r$d = F[$d](r); break; }, F));
  }

  mixin switchDispatch!("n", q{ $d: return r$d.$member $args; }, F);
   }

   // [1]

artur


[1] // The generic helpers used:

   template evalExpMap(string C, string F, A...) {
  enum evalExpMap = {
 import std.array, std.conv;
 string s, l, t;
 static if (is(typeof(A))) alias B = typeof(A);
else   alias B = A;
 foreach (I, _; B) {
auto r = replace(replace(F, "$s", A[I].stringof),
"$d", to!string(I));
l ~= (I?", ":"") ~ r;
s ~=   r ~ ";\n";
t ~=   r ~ " ";
 }
 return replace(replace(replace(C, "$...;", s), "$...,", l), "$...", t);
  }();
   }
   template fmtStmts(string FMT, A...) { alias fmtStmts = evalExpMap!("$...", 
FMT, A); }
   template fmtSwitch(string EXP, string FMT, A...) {
  alias fmtSwitch = evalExpMap!("switch ("~EXP~") { $... default: 
assert(0); }", "case "~FMT, A);
   }

   // fmtDispatch: A helper that keeps all the @property boilerplate in one 
place.
   mixin template switchDispatch(string EXPR, string CODE, T...) {
  template opDispatch(string M) {
 import std.array;
 enum C = replace(CODE, "$member", M);
 @property auto ref opDispatch()()
  if (is(typeof(function { mixin(fmtSwitch!(EXPR, replace(C, "$args", 
""), T)); }))) {
mixin(fmtSwitch!(EXPR, replace(C, "$args", ""), T));
 }
 @property auto ref opDispatch(A...)(A a)
  if (is(typeof(function { mixin(fmtSwitch!(EXPR, replace(C, "$args", 
"=a"), T)); }))) {
mixin(fmtSwitch!(EXPR, replace(C, "$args", "=a"), T));
 }
 auto ref opDispatch(A...)(A a)
  if (is(typeof(function { mixin(fmtSwitch!(EXPR, replace(C, "$args", 
"(a)"), T)); }))) {
mixin(fmtSwitch!(EXPR, replace(C, "$args", "(a)"), T));
 }
  }
   }



Re: Choice ranges?

2014-03-28 Thread Artur Skawina
On 03/28/14 23:10, H. S. Teoh wrote:
> On Fri, Mar 28, 2014 at 10:44:11PM +0100, Artur Skawina wrote:
>> On 03/28/14 20:00, H. S. Teoh wrote:
>>> Today I ran into an interesting situation where I have a function f
>>> that needs to return ranges of different types (but identical
>>> element types):
>>>
>>> auto f(A...)(A args) {
>>> ...
>>> if (someCondition)
>>> return cartesianProduct(x, y)
>>> .joiner;
>>> else
>>> return cartesianProduct(x, y)
>>> .joiner
>>> .filter!someFilter;
>>> }
>>>
>>> This obviously can't compile, because the return types are not the
>>> same.  (Note that someCondition is only known at runtime.) But
>>> abstractly speaking, it *should* work, because the element type of
>>> the returned range is identical.
>>>
>>> So how would I implement something like this?
>>
>> eg
>>  auto f(A...)(A args) {
>>  ...
>>  return cartesianProduct(x, y)
>>  .joiner
>>  .filter!(a=>somecondition?true:somefilter(a));
>>  }
> [...]
> 
> It's not that simple, though.  I guess I gave a bad example. In the
> actual code, someCondition decides whether or not a cartesian product is
> even used. So the return range needs to somehow switch between a
> cartesianProduct filtered by some filters, vs. an alternative algorithm
> filtered by some other filters.

D is statically typed -- there is no way for one function to return
different types that are selected by a runtime condition.
The fact that the produced elements have the same type is irrelevant.

You can wrap the range in a common one. When the above approach isn't
enough, there's always the next level:

   struct DynRange(R, F...) {
  R r;
  /*immutable*/ size_t n;

  static _ugh() { string r; foreach (N, _; F) 
r~="typeof(F["~N.stringof~"](r)) f"~N.stringof~";"; return r; }
  union U { mixin(_ugh()); }
  U u;

  this(R r, size_t n) {
 this.r = r; this.n = n;
 foreach (N, _; typeof(F)) if (N==n) u.tupleof[N] = F[N](r);
  }

  auto ref front() @property { foreach (N, _; typeof(F)) if (N==n) return 
u.tupleof[N].front; assert(0); }
  bool empty() @property { foreach (N, _; typeof(F)) if (N==n) return 
u.tupleof[N].empty; assert(0); }
  void popFront(){ foreach (N, _; typeof(F)) if (N==n) 
u.tupleof[N].popFront(); }

   }

   import std.array;

   auto f(R)(R r, bool somecondition) {
  import std.algorithm, std.conv;
  return DynRange!(R,
map!"a*a",
r=>filter!"a%2"((map!(a=>to!string(a^^a).length)(r)))
 )(r, somecondition);
   }

   void main() {
  import std.stdio;

  auto r = [1,2,3,4,5].f(false);
  writeln(r);
  r = [1,2,3,4,5].f(true);
  writeln(r);
   }

[Optimizing DynRange is left as an exercise for the reader. ;) In practice,
 when used with just two chains, the gain would be minimal anyway. Adding
 a level of indirection for the range primitives would prevent inlining.] 

artur


Re: Choice ranges?

2014-03-28 Thread Artur Skawina
On 03/28/14 20:00, H. S. Teoh wrote:
> Today I ran into an interesting situation where I have a function f that
> needs to return ranges of different types (but identical element types):
> 
>   auto f(A...)(A args) {
>   ...
>   if (someCondition)
>   return cartesianProduct(x, y)
>   .joiner;
>   else
>   return cartesianProduct(x, y)
>   .joiner
>   .filter!someFilter;
>   }
> 
> This obviously can't compile, because the return types are not the same.
> (Note that someCondition is only known at runtime.) But abstractly
> speaking, it *should* work, because the element type of the returned
> range is identical.
> 
> So how would I implement something like this?

eg
auto f(A...)(A args) {
...
return cartesianProduct(x, y)
.joiner
.filter!(a=>somecondition?true:somefilter(a));
}

artur


Re: Bug with references (no casting used)

2014-02-22 Thread Artur Skawina
On 02/22/14 18:22, andrea9940 wrote:
> I was trying to get my vector struct to use extensively references for 
> passing parameters and I found a subtle bug which make me lose a few hour.
> 
> A sample code that shows the bug is here http://pastebin.com/rvcNdjAE (fails 
> with dmd 2.064 on linux)
> I think that the code is wrong and dmd does not recognize it:
> opBinary() allocates a struct on the stack which is then accepted by 
> reference in opOpAssign.

That is ok; the problem is that opBinary returns a local stack-allocated
object by reference. Make it return by value, and with some help from RVO
you should get only one copy (which is necessary because you create a new
Vector instance).

IOW:

   Vector opBinary(string op)(T rhs) const;
   ref Vector opOpAssign(string op)(T rhs);
   ref Vector opOpAssign(string op)(auto ref const Vector rhs);

artur


Re: Is there kind of "associative tuple" - like syntax in D?

2014-02-22 Thread Artur Skawina
On 02/21/14 18:57, Uranuz wrote:
> In my template functions, classes it's necessary to write variadic template 
> parameter list, where elements are options to this class/function  changing 
> it's behaviour. But they are optional and may be not set at all. These 
> options may be folowed by variadic template parameter list that will be 
> processed in static foreach loop. What I'm thinking about is creating some 
> sort of key-value tuple syntax like in associative arrays. For example I 
> could set components or options of my template in easy-to-read manner.

You could wrap all the options in special types, as already suggested. If you 
don't
want to do that, and only need them to affect /local/ behavior, something like 
this
will work:

   class Foo(string OPTS, A...) {
  private static {
 auto _getOpts() {
struct O {
   byte opt1;
   string opt2 = "def";
   bool b;
   string[string] extra;
}
struct ON { mixin("enum "~OPTS~";"); }
O o;
foreach (N; __traits(allMembers, ON))
   mixin("o. "~N~" = ON. "~N~";");
return o;
 }
 enum opts = _getOpts();
 auto _getExtra(K)(K k) { if (auto p = k in opts.extra) return *p; 
return null; }
  }

  static if (opts.opt1>9)
 { /*...*/ pragma(msg, opts.opt1); }
  static if (opts.b && opts.opt2!="def")
 { /*...*/ pragma(msg, opts.opt2); }
  static if (_getExtra("b"))
 { /*...*/ pragma(msg, opts.extra["b"]); }

  /* handle 'A'... */
  /*...*/
   }

   void main() {
  alias MyFoo1 =
 Foo!q{opt1 = 42, opt2 = "blah", b = true, extra = ["a":"b", "b":"c"]};
 
  alias MyFoo2 = Foo!(q{b = false}, MyFoo1, 3.14, "etc");
   }


Not ideal, but right now I can't think of a simpler solution, using today's D.

artur


Re: Generating an enum from a tuple of Types?

2014-01-25 Thread Artur Skawina
On 01/25/14 16:38, Johannes Pfau wrote:
> Is it possible to generate a enum from a tuple of types without string
> mixins?
> 
> struct S(Types...)
> {
> enum Tag
> {
> //?
> }
> }
> 
> 
> where the tag enum should have Types.length members. The exact names of
> the enum members don't matter and could be numbered, for example:
> Tag._1, Tag._2, ...

Well, if you don't need names then just use the index directly.

Eg, see 'DiscUnion.type' in 

http://forum.dlang.org/thread/mtkzbwfgwsstndxbe...@forum.dlang.org#post-mailman.555.1377703234.1719.digitalmars-d-learn:40puremagic.com

(A newer compiler may allow for that offset-of calculation at CT)

artur


Re: Is it possible to handle 'magic' property assignments a'la PHP?

2014-01-05 Thread Artur Skawina
On 01/05/14 15:36, TheFlyingFiddle wrote:
> Another simple example that have helped me tremendously when debugging OpenGL 
> calls. A simple dispatcher that checks glGetError after every call.
> 
> struct GL
> {
> auto opDispatch(string name, Args...)(Args args)
> {
> enum glName = "gl" ~ name;
> mixin(format("
> static if(is(ReturnType!%1$s == void))
> {
> %1$s(args);
> checkGLError();
> }
> else
> {
> auto r = %1$s(args);
> checkGLError();
> return r;
>  }", glName));
> 
> }
> }
> GL gl;
> 
> I simply use gl.funcName instead of glFuncName. opDispatch rules!.

While 'void' is not a first class type in D, there /is/ a special
case for returning 'void' from functions - so all of the above can
simply be written as:

   struct gl {
  static auto ref opDispatch(string name, Args...)(Args args) {
 scope (exit) checkGLError();
 return mixin("gl"~name~"(args)");
  }
   }

artur


Re: inotify and recursion

2013-12-27 Thread Artur Skawina
On 12/27/13 15:13, Artur Skawina wrote:
>struct MyInotifyEvent(size_t BS) {
>   inotify_event event;
>   char[BS] buffer;
>   alias event this;
>}
>[...]
>enum bufsiz = inotify_event.sizeof + PATH_MAX + 1;
>auto event = cast(MyInotifyEvent!bufsiz*)malloc(bufsiz);
>[...]
>writeln("Name:", event.buffer[0..event.len-1]); // 2do: strip any extra 
> trailing \0s.

Well, that could get awkward, as the inotify api doesn't really support 
disabling
event batching. A saner design would be something like the code below.

artur

struct INotify {
   Fd fd;
   
   import std.exception;
   import core.sys.posix.unistd;
   
   this(cint flags) {
  fd = inotify_init(flags);
  errnoEnforce(fd!=-1);
   }
   ~this() {
  close(fd);
   }
   
   Wd add(const char* name, uint mask) { return inotify_add_watch(fd, name, 
mask); }
   Fd remove(Wd wd){ return inotify_rm_watch(fd, wd); }
   
   bool get(CB)(CB cb) {
  void[4*1024] buffer = void;
  
  auto got = read(fd, &buffer, buffer.sizeof);
  
  if (got<=inotify_event.sizeof)
 return false;
 
  size_t off = 0;
 
  while (off<=got-inotify_event.sizeof) {
 auto evp = cast(inotify_event*)&buffer[off];
 auto namebuf = evp.len ? (cast(char*)&evp.name)[0..evp.len-1] : null;

 while (namebuf.length && !namebuf[namebuf.length-1])
--namebuf.length;

 cb(evp, namebuf);
 
 off += inotify_event.sizeof + evp.len;
  }
  
  assert(off==got);
  return true;
   }
}

void main(string argv[]) {
   import std.string;
   auto ntf = INotify(0);
   
   foreach (arg; argv[1..$])
  ntf.add(toStringz(arg), IN_MODIFY);
   
   void myCallback(/*scope*/ const inotify_event* ev, /*scope*/ char[] name) {
  /* Don't even think about escaping any of the args. Dup if necessary. */
  import std.stdio;
  writeln(*ev, " \"", name, "\"");
   }
   
   while (1)
  ntf.get(&myCallback);
}


// libc i/f follows:

alias uint32_t = uint;
alias cint = int;
alias Fd = cint;

extern(C) {
   Fd inotify_init();
   Fd inotify_init1(cint flags);
   Wd inotify_add_watch(Fd fd, const char* pathname, uint mask);
   Fd inotify_rm_watch(Fd fd, Wd wd);
}

Fd inotify_init(cint flags) { return inotify_init1(flags); }

enum IN_MODIFY = 0x0002; /* DEFINEME */

struct Wd { Fd fd; alias fd this; }

struct inotify_event {
   Wd   wd;   /* Watch descriptor */
   uint32_t mask; /* Mask of events */
   uint32_t cookie;   /* Unique cookie associating related events (for 
rename(2)) */
   uint32_t len;  /* Size of name field */
   char name[0];   /* Optional null-terminated name */
   
   void toString(DG, FT)(scope DG sink, FT fmt) const @trusted {
  import std.format;
  foreach (I, E; this.tupleof)
 static if (I

Re: inotify and recursion

2013-12-27 Thread Artur Skawina
On 12/27/13 14:28, David Eagen wrote:
> I had trouble getting the file name from the event. I think it's because the 
> inotify module has name defined as char[0]. So I did this, which prints the 
> name by using the extra data beyond the inotify_event struct itself:
> 
> 
> void* buf = GC.malloc(bufsiz);
> 
> /* wait for an event to occur */
> size_t readlen = read(inotfd, buf, bufsiz);
> inotify_event* event = cast(inotify_event*) (buf);
> 
> /* process event struct here */
> writeln("Received inotify event:");
> writeln("Bytes read: ", readlen);
> writeln("Length: ", event.len);
> writeln("Name:", cast(char[])(buf[event.len..readlen]));

   writeln("Name:", (cast(char*)&event.name)[0..event.len-1]); // 2do: strip 
any extra trailing \0s.

It's probably easier (and safer) if you do it like this:

   struct MyInotifyEvent(size_t BS) {
  inotify_event event;
  char[BS] buffer;
  alias event this;
   }
   [...]
   enum bufsiz = inotify_event.sizeof + PATH_MAX + 1;
   auto event = cast(MyInotifyEvent!bufsiz*)malloc(bufsiz);
   [...]
   writeln("Name:", event.buffer[0..event.len-1]); // 2do: strip any extra 
trailing \0s.
  
artur


Re: inotify and recursion

2013-12-27 Thread Artur Skawina
On 12/27/13 04:23, David Eagen wrote:
> void main()
> {
> string filename="aaa";
> 
> int inotfd = inotify_init();
> int watch_desc = inotify_add_watch(inotfd, toStringz(filename), 
> IN_MODIFY);
> 
> size_t bufsiz = inotify_event.sizeof + PATH_MAX + 1;
> inotify_event* event = cast(inotify_event *) malloc(bufsiz);
> 
> /* wait for an event to occur */
> read(inotfd, event, event.sizeof);

You probably meant

   read(inotfd, event, (*event).sizeof);

but in this case the inotify_event structure contains an optional
trailing buffer, so it should be

   read(inotfd, event, bufsiz);

artur


Re: My first D module - Critiques welcome.

2013-12-25 Thread Artur Skawina
On 12/25/13 15:07, Dejan Lekic wrote:
>> You could also do some neat stuff with opDispatch.  Someone
>> actually
>> wrote an article about using it with roman numerals:
>> http://idorobots.org/2012/03/04/romans-rubies-and-the-d/
> 
> The idea is actually brilliant. :)
> I think I may use it in the future when I need to deal with roman numbers.

Note that the "D’s version has no runtime overhead at all" part is not true -
- there still is the overhead of a function call (which he admits to later).

A truly overhead-less version would be:

   struct Roman {
  template opDispatch(string number) {
 enum num = number.replace("IV", "")
  .replace("IX", "V")
  .replace("XL", "")
  .replace("XC", "L");

 enum opDispatch = num.count('I')
+ num.count('V') * 5
+ num.count('X') * 10
+ num.count('L') * 50
+ num.count('C') * 100;
  }
   }

artur


Re: Dub and GtkD

2013-12-24 Thread Artur Skawina
On 12/23/13 19:30, Mike Wey wrote:
> On 12/22/2013 10:00 PM, Artur Skawina wrote:
>> On 12/22/13 20:21, Mike Wey wrote:
>>> On 12/22/2013 03:36 PM, Russel Winder wrote:
>>>>
>>>> Python now uses the reflection approach to providing a Python binding to
>>>> the API: PyGTK has given way to PyGobject. Has the PyGobject approach
>>>> been rejected for GtkD staying with the PyGtk approach?
>>>
>>> I don't think that would be a good approach with D, you either need a whole 
>>> lot of compile time magic, or loose type safety and do everything at 
>>> runtime.
>>
>> It's not that bad; no compile time magic and zero runtime overhead is
>> possible: http://repo.or.cz/w/girtod.git/tree/gtk2:/gtk2
>>
>> While I haven't updated those bindings  in ~ two years, they should
>> still work; may just need some tweaks, to deal with recent d language
>> changes and to support newer lib features. The biggest remaining issue
>> is lack of integrated Cairo bindings.
> 
> Those are generated from the gir files beforehand like GtkD is generated from 
> the documentation (Moving to a gir based generator is on the TODO list, but 
> time currently doesn't permit it). While with the PyGobject approach the 
> bindings aren't generated beforehand but everything is done at runtime.

Didn't realize that. It kind of makes sense for a scripting language which
does not care about performance at all[1]. It doesn't for a compiled 
language like D, where the equivalent would be to extract the gi/typelib
data at /compile-time/. Which could be done via CTFE and mixins. But, as the
lib i/f is very stable, it's much better to pay the conversion cost once and
use a cached, pre-built version.

The only advantage of parsing the introspection data at run-time would be
that you could use a compiled D binary to access libs that it didn't know
about at build time. Writing programs that use dlls w/o having any idea about
the interface that those libs provide isn't exactly common. All checks would
have to be done at runtime, which is what "loose type safety" meant, i guess.
It didn't occur to me that somebody might want this functionality in a
compiled statically typed language.

Something that /was/ on my to-do list is a binary gtk-server like approach,
that would allow decoupling the gui parts from the "core" application. In D
this could be done transparently, with full type safety and negligible runtime
cost (might still be cheaper than using gtkd).

artur

[1] If it did, it could just build (and cache) a bindings-dll on first use,
avoiding ffi etc. Probably only matters in practice if you're already
JITting the code anyway, as dealing with the args will be expensive.


Re: Dub and GtkD

2013-12-22 Thread Artur Skawina
On 12/22/13 20:21, Mike Wey wrote:
> On 12/22/2013 03:36 PM, Russel Winder wrote:
>>
>> Python now uses the reflection approach to providing a Python binding to
>> the API: PyGTK has given way to PyGobject. Has the PyGobject approach
>> been rejected for GtkD staying with the PyGtk approach?
> 
> I don't think that would be a good approach with D, you either need a whole 
> lot of compile time magic, or loose type safety and do everything at runtime.

It's not that bad; no compile time magic and zero runtime overhead is
possible: http://repo.or.cz/w/girtod.git/tree/gtk2:/gtk2

While I haven't updated those bindings  in ~2 two years, they should
still work; may just need some tweaks, to deal with recent d language
changes and to support newer lib features. The biggest remaining issue
is lack of integrated Cairo bindings.

artur


Re: Problem: Cannot create class out of nothing using witchcraft

2013-10-15 Thread Artur Skawina
On 10/15/13 10:03, DoctorCaptain wrote:
> If what I am asking is unclear, I will be more than happy to
> explain in a different way. I tried to be simultaneously as
> succinct and as comprehensive as possible with what the issue is.
 
I'm not sure what exactly you're trying to do, but...

The issue is just that you are trying to access types that are
not available inside the GrabBagT template. With /built-in/ types
this of course works, as 'int' etc are always known.
One way to deal with that would be:

   template GrabBagT(string className, T...)
if (allSatisfy!(isChildOrBaseClass, T))
   {
mixin(genClassStr!(T.length)(className));
   }

   string genClassStr(size_t TL)(string className)
   {
string classStr = "";
classStr ~= `static class ` ~ className ~ ` : BaseClass`;
classStr ~= `{`;
// Demonstrate that the template itself is not the problem
classStr ~= `ChildT!("BestChild").BestChild t1000;`;
// Add arbitrary data members
foreach (i; 0..TL)
classStr ~= "T["~ to!(string)(i) ~ `] t` ~ to!(string)(i) ~ `;`;
classStr ~= `void printAttempts() {`;
foreach (i; 0..TL)
classStr ~= `writeln(` ~ to!string(i) ~ `);`;
classStr ~= `}`;
classStr ~= `}`;
return classStr;
   }

artur


Re: Call a function with a function pointer

2013-10-13 Thread Artur Skawina
On 10/13/13 16:43, Benjamin Thaut wrote:
> Am 10.10.2013 17:45, schrieb Namespace:
>> On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:
>>> Namespace:
>>>
 You mean like this?
 
 void foo(T)(extern(C) void function(T*) func) {

 }
 

 That prints: Error: basic type expected, not extern
>>>
>>> In theory that's correct, in practice the compiler refuses that, it's
>>> in Bugzilla, so try to define the type outside the signature (untested):
>>>
>>> alias TF = extern(C) void function(T*);
>>>
>>> void foo(T)(TF func) {}
>>>
>>> Bye,
>>> bearophile
>>
>> /d917/f732.d(8): Error: basic type expected, not extern
>> /d917/f732.d(8): Error: semicolon expected to close alias declaration
>> /d917/f732.d(8): Error: no identifier for declarator void function(T*)
> 
> I found a possible workaround. Its ugly as hell, but at least it works until 
> the bugs are fixed. 

There's no need for such ugly workarounds -- this is just a problem with
the *new* alias syntax. The old one accepts it (unless this changed recently):

alias extern(C) static void function(int*) Func_t;

artur


Re: Traits

2013-10-13 Thread Artur Skawina
On 10/13/13 02:25, luminousone wrote:
> On Saturday, 12 October 2013 at 23:48:56 UTC, Artur Skawina wrote:
>>template isBaseOf(BASE, C) {
>>   enum isBaseOf = {
>>  static if (is(C S == super))
>> foreach (A; S)
>>static if (isBaseOf!(BASE, A))
>>   return true;
>>  return is(C==BASE);
>>   }();
>>}
>>
>> Sorry, didn't test this properly; going to blame the dlang is-expression 
>> docs.
>> It's not like D has multiple inheritance, so using "base classes" (plural)
>> is very misleading...

> yea "is" can be a lil confusing, especially that "is( C S == super)" 
> expression.
> 
> I take it that "is( C S == super)" is only the bases directly listed for 
> inheritance by the class and not the bases bases as well? which is the reason 
> for the change you made their?

Yes, D supports only single inheritance, so there can never be more than
one "super" class (plus interfaces). I'm not using classes in D often and
when I looked up that is-expr syntax, the wrong doc confused me. It should
say "base class" (or "super class"), not "base classes".

artur


  1   2   3   >