Re: Library design

2014-06-13 Thread Rutger via Digitalmars-d-learn

On Friday, 13 June 2014 at 05:54:02 UTC, TheFlyingFiddle wrote:

On Friday, 13 June 2014 at 04:11:38 UTC, Rutger wrote:
I'm trying to create a minimal tweening library in D based on 
the

commonly used easing equations by Robert Penner
(http://www.robertpenner.com/easing/).
One of the goals with the design of the library is that any
numeric type should be tweenable.(The user of the library
shouldn't have to do any casting of their own etc) Now how do I
go about and design a data structure that can take either 
floats,

ints or doubles, store them and modify them?

This is what I hacked together earlier today:


abstract class TweenWrapper{

}


class Tween(T) : TweenWrapper{

T owner;

string[] members;

/** Duration in milliseconds */
int duration;

/** Elapsed time in milliseconds */
int elapsedTime;

bool isComplete;

/** Type of easing */
EasingType easingType;

}

TweenWrapper is just what it sounds like, a wrapper so I don't
have to specify any type for the container holding the Tween
objects(DList!TweenWrapper).

__traits(getMember, owner, members[0]) =
valueReturnedFromEasingFunction;
Was How I planned to use this class.. but you know, compile 
time

only.


Let me know if this isn't enough to go on.
Is what I'm asking even possible(the easy way) in D?


TL;DR
Help me make D Dynamic!



From what i can tell you want something similar to this.

interface ITween
{
   void update(int elapsedTime);
}

class Tween(T, string member) : ITween
{
   //Expands to
   //|alias memberType = typeof(T.memberName);|

   mixin("alias memberType = typeof("
  ~ T.stringof ~ "." ~ member ~ ");");

   memberType from;
   memberType to;
   EasingType type;

   int duration;
   int elapsedTime;

   T owner;

   @property bool isComplete()
   {
  return elapsedTime >= duration;
   }

   void update(int time)
   {
  elapsedTime = min(elapsedTime + time, duration);
  double amount = elapsedTime / cast(double)duration;
  auto tweened = ease(type, from, to, amount);
  __traits(getMember, owner, member) = tweened;
   }
}

Where ease is a method that will look something like this:

T ease(T)(EasingType type, T from, T to, double amount) 
if(isNumeric!T)

{
   double result;
   if(type == EasingType.linear)
 result = linearEase(amount);
   else
  assert(0, "Not yet implemented");

   return cast(T)((to - from) * result + from));
}

double linearEase(double amount)
{
   return amount;
}

This will work for all number types.

Hope this was helpful.



Gonna try this later, thanks a lot!





Re: Working on a library: request for code review

2014-06-13 Thread Mike via Digitalmars-d-learn

On Thursday, 12 June 2014 at 19:30:06 UTC, Rene Zwanenburg wrote:
I need to go. Please don't mind any typo's and untested code 
;). Didn't take a look at writers yet, readers and util need 
some more scrutiny, but the main theme is: eliminate 
unnecessary temporary GC allocations.


Thank you for feedback, hoping for more! I will apply the 
suggestions tonight.




Re: Cannot alias null

2014-06-13 Thread via Digitalmars-d-learn
On Thursday, 12 June 2014 at 21:07:47 UTC, Tom Browder via 
Digitalmars-d-learn wrote:
What I was really trying to do was D'ify C expressions like 
this:


  typedef ((struct t*)0) blah;


This doesn't compile for me with GCC, and I don't know what it's 
supposed to mean. ((struct t*) 0) is a value, not a type...


Where does it come from?


Re: Cannot alias null

2014-06-13 Thread monarch_dodra via Digitalmars-d-learn

On Thursday, 12 June 2014 at 22:54:20 UTC, Ali Çehreli wrote:

On 06/12/2014 03:38 PM, monarch_dodra wrote:
> So there's something special about "null".

The difference is that null is an expression. It is the same 
limitation as not being able to alias a literal.


alias zero = 0;
alias blah = null;


Oh! Right. That makes sense.

So you should use enum instead:
enum zero = 0;
enum blah = null;

Thanks.


Re: Cannot alias null

2014-06-13 Thread Tom Browder via Digitalmars-d-learn
On Fri, Jun 13, 2014 at 7:59 AM, via Digitalmars-d-learn
 wrote:
> On Thursday, 12 June 2014 at 21:07:47 UTC, Tom Browder via
> Digitalmars-d-learn wrote:
>>
>> What I was really trying to do was D'ify C expressions like this:
>>
>>   typedef ((struct t*)0) blah;
>
>
> This doesn't compile for me with GCC, and I don't know what it's supposed to
> mean. ((struct t*) 0) is a value, not a type...

Sorry, you're correct.  It is from a C macro and would be used for an
rvalue.  Something like this:

$ cat chdr.h
struct t;
#define t_nullptr ((struct t*)0)
struct t* t_ptr = t_nullptr;

After pre-processing with "gcc -E -P" that should read:

$ cat chdr.h.i
struct t;
struct t* t_ptr = ((struct t*)0);

which does compile.

So I'm not sure how to translate that into D.   I do know my first
attempt here doesn't work, even with it being surrounded by extern (C)
{}:

$ cat chdr.d
struct t;
struct t* t_ptr = null;

> Where does it come from?

The usage comes from many of the C API headers in the BRL-CAD package
(http://brlcad.org).

Best,

-Tom


Re: Dub. Mercurial (bitbucket.org). Projects deployment

2014-06-13 Thread Uranuz via Digitalmars-d-learn

Thanks for all the answers)

8. I have another more simple question about rdmd utility. It 
takes one *.d file and searches for all dependencies. What if I 
need to pass independent *.d file or *.ddoc file directly to dmd 
compiler? How could I do that using dmd? I have no idea how I 
could include *.ddoc file with set of DDOC macroses. I have tried 
to use string mixin.


mixin(import("mysettings.ddoc"));

But I haven't succeed. My be compiler strips all the comments 
before mixing in or I doing something wrong. Another way is to 
use dmd.conf but I don't like this, because it's brutal way of 
doing so and as I think it's not compiler independent.


Re: Cannot alias null

2014-06-13 Thread Philpax via Digitalmars-d-learn
On Friday, 13 June 2014 at 15:05:49 UTC, Tom Browder via 
Digitalmars-d-learn wrote:

On Fri, Jun 13, 2014 at 7:59 AM, via Digitalmars-d-learn
 wrote:

On Thursday, 12 June 2014 at 21:07:47 UTC, Tom Browder via
Digitalmars-d-learn wrote:


What I was really trying to do was D'ify C expressions like 
this:


  typedef ((struct t*)0) blah;



This doesn't compile for me with GCC, and I don't know what 
it's supposed to

mean. ((struct t*) 0) is a value, not a type...


Sorry, you're correct.  It is from a C macro and would be used 
for an

rvalue.  Something like this:

$ cat chdr.h
struct t;
#define t_nullptr ((struct t*)0)
struct t* t_ptr = t_nullptr;

After pre-processing with "gcc -E -P" that should read:

$ cat chdr.h.i
struct t;
struct t* t_ptr = ((struct t*)0);

which does compile.

So I'm not sure how to translate that into D.   I do know my 
first
attempt here doesn't work, even with it being surrounded by 
extern (C)

{}:

$ cat chdr.d
struct t;
struct t* t_ptr = null;


Where does it come from?


The usage comes from many of the C API headers in the BRL-CAD 
package

(http://brlcad.org).

Best,

-Tom


Remove the struct from the pointer:

struct t;
t* t_ptr = null;


Re: Cannot alias null

2014-06-13 Thread monarch_dodra via Digitalmars-d-learn
On Friday, 13 June 2014 at 15:05:49 UTC, Tom Browder via 
Digitalmars-d-learn wrote:
So I'm not sure how to translate that into D.   I do know my 
first
attempt here doesn't work, even with it being surrounded by 
extern (C)

{}:

$ cat chdr.d
struct t;
struct t* t_ptr = null;


This seems to work fine for me. What's the problem?

Note this isn't *strictly* the same as what you have in C, as 
"null" is not strongly bindded to a single type. If you want a 
null pointer which is pre-emptivelly strongly, then you can use 
an eponymous template:


enum nullptr(T) = (T*).init;

auto p = nullptr!t;

Throw in an alias, and you got it working exactly like an C:


enum nullptr(T) = (T*).init;
alias t_nullptr = nullptr!t;
struct t* t_ptr = t_nullptr;

That said, I'd advise against this. Just use "null" and move on. 
It's idiomatic.


Re: Cannot alias null

2014-06-13 Thread Tom Browder via Digitalmars-d-learn
On Fri, Jun 13, 2014 at 10:15 AM, monarch_dodra via
Digitalmars-d-learn  wrote:
> On Friday, 13 June 2014 at 15:05:49 UTC, Tom Browder via Digitalmars-d-learn
> wrote:
>>
>> So I'm not sure how to translate that into D.   I do know my first
>> attempt here doesn't work, even with it being surrounded by extern (C)
>> {}:
>>
>> $ cat chdr.d
>> struct t;
>> struct t* t_ptr = null;
>
>
> This seems to work fine for me. What's the problem?

I use "dmd -c .d" (note file name change) and get:

t.d(2): Error: { } expected following aggregate declaration
t.d(2): Error: Declaration expected, not '*'

Taking Philpax's  suggestion I try

$ cat t.d
struct t;
t* t_ptr = null;

$ dmd -c t.d

and get a good build.

> Note this isn't *strictly* the same as what you have in C, as "null" is not
...
> strongly bindded to a single type. If you want a null pointer which is
> pre-emptivelly strongly, then you can use an eponymous template:
...
> That said, I'd advise against this. Just use "null" and move on. It's
> idiomatic.

So this is the correct (i.e., good enough) solution then:

$ cat t.d
struct t;
t* t_ptr = null;

Sounds good to me.

Thanks all.

Best,

-Tom


User defined forward range - foreach initializes f.r.

2014-06-13 Thread Andre via Digitalmars-d-learn

Hi,

I have a template class "List" which should provide generic list 
functionality. In my use case, using a class instead a struct

is more comfortable.

Following unittest fails, although the forward range
implements the save method.

unittest
{
auto intList = new List!int(1,2,3);
assert(intList.length == 3);
foreach(item; intList) {}
assert(intList.length == 3);
}


class List(T)
{
private T[] items;

this(T[] items...)
{
this.items = items;
}

bool empty() const
{
return items.length == 0;
}

@property int length() const
{
return items.length;
}

void popFront()
{
items = items[1..$];
}

@property List!T save() const
{
return new List!T( cast(T[]) items);
}

T front() const
{
return opIndex(0);
}

T opIndex(size_t index) const
{
return cast(T) items[index];
}
}

I already tried different thinks, like using dup or importing std.array.
But nothing helps, the unittest fails.
Why it fails?

Kind regards
André


Re: User defined forward range - foreach initializes f.r.

2014-06-13 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 13, 2014 at 08:14:11PM +0200, Andre via Digitalmars-d-learn wrote:
> Hi,
> 
> I have a template class "List" which should provide generic list
> functionality. In my use case, using a class instead a struct
> is more comfortable.
> 
> Following unittest fails, although the forward range
> implements the save method.
[...]

Generally, it's a bad idea to conflate a container with a range over its
contents. In this sense, built-in arrays are a very bad example, because
they show precisely this sort of conflation. But they get away with it
because of their hybrid value/reference semantics. Most containers,
however, don't have this sort of complex semantics, so they don't mix
very well with ranges directly.

It's much better to separate the container from a range over its
contents. So I wouldn't put the range API methods in the List class, but
implement an opSlice method that returns a struct that performs the list
iteration, that implements the range API. This allows you to write:

auto myList = new List(...);
foreach (item; myList[]) { // N.B., myList[] calls myList.opSlice()
...
}

Since the range struct returned by opSlice is separate from the
container itself, you don't have any risk of iteration also consuming
the container.


T

-- 
Let X be the set not defined by this sentence...


Re: User defined forward range - foreach initializes f.r.

2014-06-13 Thread Andre via Digitalmars-d-learn

Am 13.06.2014 20:22, schrieb H. S. Teoh via Digitalmars-d-learn:

[...]

Generally, it's a bad idea to conflate a container with a range over its
contents. In this sense, built-in arrays are a very bad example, because
they show precisely this sort of conflation. But they get away with it
because of their hybrid value/reference semantics. Most containers,
however, don't have this sort of complex semantics, so they don't mix
very well with ranges directly.

It's much better to separate the container from a range over its
contents. So I wouldn't put the range API methods in the List class, but
implement an opSlice method that returns a struct that performs the list
iteration, that implements the range API. This allows you to write:

auto myList = new List(...);
foreach (item; myList[]) { // N.B., myList[] calls myList.opSlice()
...
}

Since the range struct returned by opSlice is separate from the
container itself, you don't have any risk of iteration also consuming
the container.


T



Thank you, this information is really helpful.

Kind regards
André



Re: User defined forward range - foreach initializes f.r.

2014-06-13 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 13 June 2014 at 18:14:10 UTC, Andre wrote:

Hi,

I have a template class "List" which should provide generic 
list functionality. In my use case, using a class instead a 
struct

is more comfortable.

Following unittest fails, although the forward range
implements the save method.

unittest
{
auto intList = new List!int(1,2,3);
assert(intList.length == 3);
foreach(item; intList) {}
assert(intList.length == 3);
}

...

I already tried different thinks, like using dup or importing 
std.array.

But nothing helps, the unittest fails.
Why it fails?

Kind regards
André


To add to what H.S. Teoh said, which is good advice, but doesn't 
quite explain why your unittest failed: Foreach takes a copy of 
your range, and then "consumes it". This may or may not have an 
effect on the original range. If you plan to use your range again 
after a call, you are supposed to *save* it:


unittest
{
auto intList = new List!int(1,2,3);
assert(intList.length == 3);
foreach(item; intList.save) {} //HERE
assert(intList.length == 3);
}

There.


Initialization sequence of runtime environment

2014-06-13 Thread Tim via Digitalmars-d-learn
I recently posted another thread (regarding crt1.o: could not 
read symbols: Bad value - I'm creating a new thread because it's 
another problem) and I figured out that the following error:


stack_bottom = 7fc98804ae18 thread_stack 0x4
/usr/sbin/mysqld(my_print_stacktrace+0x35)[0x8cea15]
/usr/sbin/mysqld(handle_fatal_signal+0x4a4)[0x65e0d4]
/lib64/libpthread.so.0(+0xf710)[0x7fc98abcb710]
/usr/lib64/libphobos2.so.0.65(gc_malloc+0x29)[0x7fc951a70e05]

... occures when I never call rt_init()/rt_term() (or 
Runtime.initialize()/Runtime.terminate()). That solved the 
problem and I can successfully execute all my D-code.


I'm using the shared library as UDF in MySQL. My current code 
looks as follows:


export extern(C){
	my_bool mysql_d_udf_init(UDF_INIT *initid, UDF_ARGS *args, char 
*message)

{
return (rt_init() ? 0 : 1);
}

void mysql_d_udf_deinit(UDF_INIT *initid)
{
rt_term();
}

	char* mysql_d_udf(UDF_INIT* initid, UDF_ARGS* args, char* 
result, c_ulong *length, char* is_null, char* error)

{
string res = "Hello World!";
result = cast(char*) res.ptr;

*length = res.length;

return cast(char*) result;
}
}

When I register the function in MySQL and execute "select 
mysql_d_udf()" everything works fine. I'm receiving "Hello 
World!" and everything is fine. But when I try to restart the 
server, the server is not responding. I've to kill the server 
manually which is impracticable in productional environment.


I first thought that rt_term() throws an exception (or something 
else) that prevents the MySQL server from being restartet 
gracefully. So I removed rt_term() from my deinit()-function. But 
that didn't solve the problem. When I also remove rt_init() I'm 
getting the gc_malloc-exception as described above. So it seems 
that rt_init() registers/enables something I'm unable to release 
I don't know exactly. Fact is that I see no exception or log 
entry in my MySQL log and the server restarts successfully 
without my D-based UDF plugin. So something seems to be wrong...


I don't know if my initialization of the D-runtime environment is 
correct? I sometimes read something about gc_init() (but I 
thought rt_init()/Runtime.initialize() handles that for me...). 
Any suggestions how to initialize/terminate the runtime 
environment in shared libraries? Probably I'm doing something 
wrong...


If there's no solution, I've to write the UDF functions using C 
(I don't prefer that way because all other projects are D-based).


Re: User defined forward range - foreach initializes f.r.

2014-06-13 Thread Ali Çehreli via Digitalmars-d-learn
I am making the following comment to have others confirm, as well as 
remind others about a potential problem.


On 06/13/2014 11:14 AM, Andre wrote:

> unittest
> {
>  auto intList = new List!int(1,2,3);

[...]

> class List(T)
> {
>  private T[] items;
>
>  this(T[] items...)
>  {
>  this.items = items;
>  }

Unrelated to your question, I think that is a bug because you are 
keeping a reference to a temporary array. The compiler will generate a 
temporary array for 1, 2, and 3 and then that array will disappear.


Am I remembering correctly?

If so, I would recommend against 'T[] items...' but use an explicit slice:

this(T[] items)

The users will slightly be inconvenienced but the program will be correct.

Or, you can continue with 'T[] items...' and then have to take a copy of 
the argument:


this.items = items.dup;// copied

That is obviously slower when the user actually passed in a slice. 
That's why I think it is better to take an explicit slice as a parameter.


Ali



Re: User defined forward range - foreach initializes f.r.

2014-06-13 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 13 June 2014 at 19:03:12 UTC, Ali Çehreli wrote:
I am making the following comment to have others confirm, as 
well as remind others about a potential problem.


On 06/13/2014 11:14 AM, Andre wrote:

> unittest
> {
>  auto intList = new List!int(1,2,3);

[...]

> class List(T)
> {
>  private T[] items;
>
>  this(T[] items...)
>  {
>  this.items = items;
>  }

Unrelated to your question, I think that is a bug because you 
are keeping a reference to a temporary array. The compiler will 
generate a temporary array for 1, 2, and 3 and then that array 
will disappear.


Am I remembering correctly?

If so, I would recommend against 'T[] items...' but use an 
explicit slice:


this(T[] items)

The users will slightly be inconvenienced but the program will 
be correct.


Or, you can continue with 'T[] items...' and then have to take 
a copy of the argument:


this.items = items.dup;// copied

That is obviously slower when the user actually passed in a 
slice. That's why I think it is better to take an explicit 
slice as a parameter.


Ali


Yes.

`fun(T)(T[]...)` is just both `fun(T...)(T t)` and `fun(T)(T[] 
t)` both "conveniently" packaged into one, but with twice the 
pitfalls.


I'd suggest avoiding it altogether. It's a non-feature (IMO).


Why is stdin.byLine.writeln so slow?

2014-06-13 Thread Jyxent via Digitalmars-d-learn

I've been playing around with D and noticed that:

stdin.byLine.writeln

takes ~20 times as long as:

foreach(line; stdin.byLine) writeln(line);

I asked on IRC and this was suggested:

stdin.byLine(KeepTerminator.yes).copy(stdout.lockingTextWriter)

which is slightly faster than the foreach case.

It was suggested that there is something slow about writeln 
taking the input range, but I'm not sure I see why.  If I follow 
the code correctly, formatRange in std.format will eventually be 
called and iterate over the range.


Re: Why is stdin.byLine.writeln so slow?

2014-06-13 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 13 June 2014 at 20:48:16 UTC, Jyxent wrote:

I've been playing around with D and noticed that:

stdin.byLine.writeln

takes ~20 times as long as:

foreach(line; stdin.byLine) writeln(line);

I asked on IRC and this was suggested:

stdin.byLine(KeepTerminator.yes).copy(stdout.lockingTextWriter)

which is slightly faster than the foreach case.

It was suggested that there is something slow about writeln 
taking the input range, but I'm not sure I see why.  If I 
follow the code correctly, formatRange in std.format will 
eventually be called and iterate over the range.


Because:
stdin.byLine.writeln
and
foreach(line; stdin.byLine) writeln(line);
Don't produce the same output. One prints a range that contains 
strings, whereas the second repeatedly prints strings.


Given this input:
line 1
line2
Yo!

Then "stdin.byLine.writeln" will produce this string:
["line 1", "line\t2", "Yo!"]

So that's the extra overhead which is slowing you down, because 
*each* character needs to be individually parsed, and potentially 
escaped (eg: "\t").


The "copy" option is the same as the foreach one, since each 
string is individually passed to the writeln, which doesn't parse 
your string. The "lockingTextWriter" is just sugar to squeeze out 
extra speed.


Re: Working on a library: request for code review

2014-06-13 Thread Mike Wey via Digitalmars-d-learn

On 06/12/2014 09:30 PM, Rene Zwanenburg wrote:

I remember a function which does something like only only + canFind on
one go. It would look something like

header.colorMapDepth.among(16, 32);

but I can't find it right now.. Maybe it was only proposed but never added.


http://dlang.org/library/std/algorithm/among.html

--
Mike Wey


Re: Why is stdin.byLine.writeln so slow?

2014-06-13 Thread Ali Çehreli via Digitalmars-d-learn

On 06/13/2014 02:08 PM, monarch_dodra wrote:

> Given this input:
> line 1
> line2
> Yo!
>
> Then "stdin.byLine.writeln" will produce this string:
> ["line 1", "line\t2", "Yo!"]

Do you mean writeln() first generates an array and then prints that 
array? I've always imagined that it used the range interface and did 
similar to what copy() does.


Is there a good reason why the imagined-by-me-range-overload of 
writeln() behaves that way?


Ali



Re: Why is stdin.byLine.writeln so slow?

2014-06-13 Thread Jyxent via Digitalmars-d-learn

On Friday, 13 June 2014 at 21:08:08 UTC, monarch_dodra wrote:

On Friday, 13 June 2014 at 20:48:16 UTC, Jyxent wrote:

I've been playing around with D and noticed that:

stdin.byLine.writeln

takes ~20 times as long as:

foreach(line; stdin.byLine) writeln(line);

I asked on IRC and this was suggested:

stdin.byLine(KeepTerminator.yes).copy(stdout.lockingTextWriter)

which is slightly faster than the foreach case.

It was suggested that there is something slow about writeln 
taking the input range, but I'm not sure I see why.  If I 
follow the code correctly, formatRange in std.format will 
eventually be called and iterate over the range.


Because:
stdin.byLine.writeln
and
foreach(line; stdin.byLine) writeln(line);
Don't produce the same output. One prints a range that contains 
strings, whereas the second repeatedly prints strings.


Given this input:
line 1
line2
Yo!

Then "stdin.byLine.writeln" will produce this string:
["line 1", "line\t2", "Yo!"]

So that's the extra overhead which is slowing you down, because 
*each* character needs to be individually parsed, and 
potentially escaped (eg: "\t").


The "copy" option is the same as the foreach one, since each 
string is individually passed to the writeln, which doesn't 
parse your string. The "lockingTextWriter" is just sugar to 
squeeze out extra speed.


Hah.  You're right.  I had seen writeln being used this way and 
just assumed that it printed every line, without looking at the 
output too closely.


Thanks for clearing that up.


Re: Why is stdin.byLine.writeln so slow?

2014-06-13 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 13 June 2014 at 21:17:27 UTC, Ali Çehreli wrote:

On 06/13/2014 02:08 PM, monarch_dodra wrote:

> Given this input:
> line 1
> line2
> Yo!
>
> Then "stdin.byLine.writeln" will produce this string:
> ["line 1", "line\t2", "Yo!"]

Do you mean writeln() first generates an array and then prints 
that array?


No, it just receives a range, so it does range formating. eg:
"[" ~ Element ~ ", " ~ Element ... "]".

I've always imagined that it used the range interface and did 
similar to what copy() does.


That wouldn't make sense. Then, if I did "[1, 2, 3].writeln();", 
it would print:

123
instead of
[1, 2, 3]

Is there a good reason why the imagined-by-me-range-overload of 
writeln() behaves that way?


Ali


As I said, it's a range, so it prints a range. That's all there 
is to it.


That said, you can use one of D's most powerful formating 
abilities: Range formating:

writefln("%-(%s\n%)", stdin.byLine());

And BOOM. Does what you want. I freaking love range formatting.
More info here:
http://dlang.org/phobos/std_format.html#.formattedWrite

TLDR:
%( => range start
%) => range end
%-( => range start without element escape (for strings mostly).


Re: Why is stdin.byLine.writeln so slow?

2014-06-13 Thread Ali Çehreli via Digitalmars-d-learn

On 06/13/2014 03:02 PM, monarch_dodra wrote:

> No, it just receives a range, so it does range formating. eg:
> "[" ~ Element ~ ", " ~ Element ... "]".

It still looks like it could send the formatting characters as well as 
the elements separately to the output stream:


"["
Element
", "
...
"]"

I am assuming that the slowness in OP's example is due to constructing a 
long string.


Ali



Re: Why is stdin.byLine.writeln so slow?

2014-06-13 Thread monarch_dodra via Digitalmars-d-learn

On Friday, 13 June 2014 at 22:12:01 UTC, Ali Çehreli wrote:

On 06/13/2014 03:02 PM, monarch_dodra wrote:

> No, it just receives a range, so it does range formating. eg:
> "[" ~ Element ~ ", " ~ Element ... "]".

It still looks like it could send the formatting characters as 
well as the elements separately to the output stream:


"["
Element
", "
...
"]"

I am assuming that the slowness in OP's example is due to 
constructing a long string.


Ali


We'd have to check, but don't think that formatted write actually 
ever allocates anywhere, so there should be no "constructing a 
long string". The real issue (I think), is that when you ask 
formatted write to write a string, it just pipes the entire char 
array at once to the underlying stream.


If the characters are escaped though (which is the case when you 
print an array of strings), then formatedWrite needs to check 
each character individually, and then also pass each character 
individually to the underlying stream. And *that* could 
definitely justify the order of magnitude slowdown observed.


What's more this *may* trigger a per-character decode-encode 
loop. I'd have to check. But that shouldn't be observable next to 
the stream overhead anyways.


Re: Why is stdin.byLine.writeln so slow?

2014-06-13 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 13, 2014 at 10:02:49PM +, monarch_dodra via Digitalmars-d-learn 
wrote:
[...]
> That said, you can use one of D's most powerful formating abilities:
> Range formating:
> writefln("%-(%s\n%)", stdin.byLine());
> 
> And BOOM. Does what you want. I freaking love range formatting.
> More info here:
> http://dlang.org/phobos/std_format.html#.formattedWrite
> 
> TLDR:
> %( => range start
> %) => range end
> %-( => range start without element escape (for strings mostly).

I wrote part of that documentation, and my favorite example is matrix
formatting:

auto mat = [[1,2,3], [4,5,6], [7,8,9]];
writefln("[%([%(%d %)]%|\n %)]", mat);

Output:

[[1 2 3]
 [4 5 6]
 [7 8 9]]

D coolness at its finest!

Whoever invented %(, %|, %) is a genius. It takes C's printf formatting
from weak sauce to whole new levels of awesome. I remember debugging
some range-based code, and being able to write stuff like:

debug writefln("%(%(%s, %); %)", buggyNestedRange().take(10));

at strategic spots in the code is just pure win.  In C/C++, you'd have
to manually write nested loops to print out the data, which may involve
manually calling accessor methods, manually counting them, perhaps
storing intermediate output fragments in temporary buffers,
encapsulating all this jazz in a throwaway function so that you can use
it at multiple strategic points (in D you just copy-n-paste the single
line above), etc..  Pure lose.

(Speaking of which, this might be an awesome lightning talk topic at the
next DConf. ;-) Or did somebody already do it?)


T

-- 
Having a smoking section in a restaurant is like having a peeing section in a 
swimming pool. -- Edward Burr 


Re: Why is stdin.byLine.writeln so slow?

2014-06-13 Thread monarch_dodra via Digitalmars-d-learn
On Friday, 13 June 2014 at 22:25:25 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:

In C/C++,

you'd have
to manually write nested loops to print out the data, which may 
involve
manually calling accessor methods, manually counting them, 
perhaps

storing intermediate output fragments in temporary buffers,
encapsulating all this jazz in a throwaway function so that you 
can use
it at multiple strategic points (in D you just copy-n-paste the 
single

line above), etc..  Pure lose.

T


In C++, I usually use copy/transform:

*std::copy(begin(), end(), std::ostream_iterator(std::cout, 
"\n")) = "\n";

or
*std::tranform(begin(), end(), 
std::ostream_iterator(std::cout, "\n"), [](???){???}) = "\n";


It's a bit verbose, and looks like ass to the non-initiated, but 
once you are used to it, it's quite convenient. It's just 
something that grows on you. You can stack on a "foreach" if you 
need more "depth".


foreach(begin(), end(), [](R& r){
  *std::copy(r.begin(), r.end(), 
std::ostream_iterator(std::cout, "\n")) = "\n";

});

Though arguably, that's just a loop in disguise :)


does there exist a dimensional analysis library for D?

2014-06-13 Thread Vlad Levenfeld via Digitalmars-d-learn

something similar to boost/units?


Does __gshared have shared semantics?

2014-06-13 Thread Mike Franklin via Digitalmars-d-learn

In other words, is 'shared __gshared' redundant?


Re: Does __gshared have shared semantics?

2014-06-13 Thread Kapps via Digitalmars-d-learn

On Saturday, 14 June 2014 at 01:24:05 UTC, Mike Franklin wrote:

In other words, is 'shared __gshared' redundant?


All __gshared does is makes the variable not go into thread-local 
storage, nothing more. Shared does this, as well as modify the 
type to be shared(T) instead of just T. So yes, it's redundant.


DMD Fails with fPIC error

2014-06-13 Thread Reuben via Digitalmars-d-learn

Hi,
I'm new to D and am trying to compile a simple hello world 
program.

I get the following error when compiling it:


dmd test.d
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: 
/opt/dmd-2.065/lib64/libphobos2.a(lifetime_488_4cd.o): relocation 
R_X86_64_32 against `_D15TypeInfo_Shared7__ClassZ' can not be 
used when making a shared object; recompile with -fPIC
/opt/dmd-2.065/lib64/libphobos2.a: could not read symbols: Bad 
value

collect2: error: ld returned 1 exit status
--- errorlevel 1

This error occurs regardless of whether I use the -fPIC option or 
not.

Compiling DMD from source does not change anything.

I am using DMD 2.065.0 on Sabayon amd64, compiled from the dlang 
overlay with gcc (Gentoo Hardened 4.7.3-r1 p1.4, pie-0.5.5) 4.7.3.


Thanks in advance.


Casts and @trusted

2014-06-13 Thread Anonymous via Digitalmars-d-learn
This seems to work from quick testing, but it has casts in 
get_ref that I want to avoid.

cast(T*) refs[i] is obviously not @safe.
cast(T*) _buffer[read].ptr doesn't seem necessary, since 
_buffer[read] is conceivably a T so _buffer[read].ptr should be a 
T*. But without it I get "Error: cannot implicitly convert 
expression (&this._buffer[read]) of type const(char)* to char[5]*"
I do want to pass in a preallocated buffer to store some 
pointers, at least as one get option. I also want to disallow 
modification to the ring buffer through those pointers. How might 
I rework things to enable that usage while being @safe?


enum TakeStrategy { cyclic, once }
alias TS = TakeStrategy;
struct StaticRingBuffer(T, size_t cap) {
static assert (cap > 1);
private T[cap] _buffer;
private size_t _index = cap-1;
private size_t _fill = 0;
@property size_t extra() nothrow const {
return cap-fill;
}
@property size_t index() nothrow const {
return _index;
}
@property size_t fill() nothrow const {
return _fill;
}

@property const ref front() nothrow const {
return _buffer[index];
}

void put(T ele) pure nothrow {
if (index == cap-1) _index = 0;
else ++_index;
_buffer[index] = ele;

if (fill < cap) ++_fill;
}

void put(T[] eles) pure nothrow {
foreach(e; eles) put(e);
}

	@trusted void get_ref(TS strat=TS.cyclic)(size_t n, const(T*)[] 
refs) const nothrow

{
assert(refs.length == n);
static if (strat==TS.once) size_t numreads = fixNToFill(n);
else size_t numreads = n;

size_t read = index;
foreach(i;0..numreads) {
cast(T*) refs[i] = cast(T*) _buffer[read].ptr;
if (read == 0) read = fill-1;
else --read;
}

}

private size_t fixNToFill(size_t n) const nothrow {
return (n > fill) ? fill : n;
}
}


Re: Casts and @trusted

2014-06-13 Thread Ali Çehreli via Digitalmars-d-learn

On 06/13/2014 06:56 PM, Anonymous wrote:

>  @trusted void get_ref(TS strat=TS.cyclic)(size_t n, const(T*)[]
> refs) const nothrow
>  {
[...]
>  cast(T*) refs[i] = cast(T*) _buffer[read].ptr;

The left-hand side violates a promise: The function takes a slice where 
the elemenst are const. So, the function says that it will not modify 
the elements.


Also, _buffer[read] is an element, not a slice:

private T[cap] _buffer;

So, there is no .ptr property.

However, perhaps my test code fails to demonstrate your problem:

auto s = StaticRingBuffer!(int, 10)();

int i;
int*[] arr;
arr ~= &i;
s.get_ref(0, arr);

Please show us complete code. :)

Ali



Universal Construction Syntax for Pointers?

2014-06-13 Thread Meta via Digitalmars-d-learn
I thought this was possible, but DMD 2.065 doesn't allow it, 
saying "no constructor for int":


int* p = new int(3);

Is something like this planned for the future? I know we can 
already do:


int n = int(3);


Re: does there exist a dimensional analysis library for D?

2014-06-13 Thread Philippe Sigaud via Digitalmars-d-learn
Hi Vlad,

you can try David Nadlinger's std.units:

http://klickverbot.at/code/units/std_units.html

See the discussion at

http://forum.dlang.org/thread/io1vgo$1fnc$1...@digitalmars.com


>From what I deemly remember of Boost/units, it's a bit less complete,
but far easier to use.


Re: Universal Construction Syntax for Pointers?

2014-06-13 Thread Ali Çehreli via Digitalmars-d-learn

On 06/13/2014 10:29 PM, Meta wrote:

I thought this was possible, but DMD 2.065 doesn't allow it, saying "no
constructor for int":

int* p = new int(3);

Is something like this planned for the future? I know we can already do:

int n = int(3);


Those both compile with 2.066

Ali



Re: Universal Construction Syntax for Pointers?

2014-06-13 Thread Meta via Digitalmars-d-learn

On Saturday, 14 June 2014 at 06:39:56 UTC, Ali Çehreli wrote:

On 06/13/2014 10:29 PM, Meta wrote:
I thought this was possible, but DMD 2.065 doesn't allow it, 
saying "no

constructor for int":

int* p = new int(3);

Is something like this planned for the future? I know we can 
already do:


int n = int(3);


Those both compile with 2.066

Ali


Right, thanks. It's difficult to keep track of what's already 
released and what's in Git HEAD.