Re: Efficient way to pass struct as parameter

2018-01-28 Thread Marco Leise via Digitalmars-d-learn
Am Wed, 3 Jan 2018 10:57:13 -0800
schrieb Ali Çehreli :

> On 01/03/2018 10:40 AM, Patrick Schluter wrote:
>  > On Tuesday, 2 January 2018 at 23:27:22 UTC, H. S. Teoh wrote:  
>  >>
>  >> When it comes to optimization, there are 3 rules: profile, profile,
>  >> profile.  I used to heavily hand-"optimize" my code a lot (I come from
>  >> a strong C/C++ background -- premature optimization seems to be a
>  >> common malady among us in that crowd).  
>  >
>  > That's why I always tell that C++ is premature optimization oriented
>  > programming, aka as POOP.  
> 
> […]
>
> That's why I like producer functions that return values:
> 
> vector makeInts(some param) {
>  // ...
> }
> 
> And if they can be 'pure', D allows them to be used to initialize 
> immutable variables as well. Pretty cool! :)
> 
> Ali

May I add, this is also optimal performance-wise. The result
variable will be allocated on the caller stack and the
callee writes directly to it. So even POOPs like me, do it.

-- 
Marco



Re: __dtor vs __xdtor

2017-08-12 Thread Marco Leise via Digitalmars-d-learn
Am Fri, 11 Aug 2017 17:10:14 +
schrieb bitwise :

> Ok thanks.
> 
> I don't understand why you would ever want to call __dtor 
> then...is it possible to have only __dtor without also having 
> __xdtor? Like, if I want to call a struct's destructor, do I have 
> to check for both, or can I just always check for, and call 
> __xdtor?

I think it was simply that all the special methods needed a
symbol name, so this() was called __ctor and ~this() was
called __dtor. It was never supposed to cover field
destruction, mixed in destructors or inheritance in classes.
User code was not expected to call these directly anyways.
Not very long ago __xdtor and __xpostblit were introduced
that wrap up the entire finalization and copy operation.
__dtor will remain as the 1:1 representation of the ~this()
method.

-- 
Marco



Re: readText with added null-terminator that enables sentinel-based search

2017-08-09 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 08 Aug 2017 20:48:39 +
schrieb Nordlöw :

> Has anybody written a wrapper around `std.file.readText` (or 
> similar) that appends a final zero-byte terminator in order to 
> realize sentinel-based search in textual parsers.

What do you mean by similar? There are many ways to load a file
into memory before appending \0. In fast.json I used a memory
mapped file. On some OSs you can read past the end of such
mappings safely to generate extra \0 bytes. 16 zero-bytes is a
good amount if you want to use the SSE4.2 string instruction.

https://github.com/mleise/fast/blob/master/source/fast/json.d#L1464

-- 
Marco



Re: returning D string from C++?

2017-08-05 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 05 Aug 2017 20:17:23 +
schrieb bitwise :

>  virtual DString getTitle() const {
>  DString ret;
>  ret.length = GetWindowTextLength(_hwnd) + 1;
>  ret.ptr = (const char*)gc_malloc(ret.length, 0xA, NULL);
>  GetWindowText(_hwnd, (char*)ret.ptr, ret.length);
>  return ret;
>  }

In due diligence, you are casting an ANSI string into a UTF-8
string which will result in broken Unicode for non-ASCII window
titles. In any case it is better to use the wide-character
versions of Windows-API functions nowadays. (Those ending in
'W' instead of 'A'). Starting with Windows 2000, the core was
upgraded to UTF-16[1], which means you don't have to
implement the lossy conversion to ANSI code pages and end up
like this ...

[information loss]
   UTF-8 <-> Windows codepage <-> UTF-16
  ||
  in your code inside Windows

... but instead directly pass and get Unicode strings like
this ...

   UTF-8 <-> UTF-16
  |
  in your code

string to zero terminated UTF-16:
http://dlang.org/phobos/std_utf.html#toUTF16z
zero terminated UTF-16 to string:
ptr.to!string() or just ptr[0..len] if known

Second I'd like to mention that you should have set
ret.length = GetWindowText(_hwnd, (char*)ret.ptr, ret.length);
Currently your length is anything from 1 to N bytes longer
than the actual string[2], which is not obvious because any
debug printing or display of the string stops at the embedded
\0 terminator.

[1] https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows
[2]
https://msdn.microsoft.com/de-de/library/windows/desktop/ms633521(v=vs.85).aspx

-- 
Marco



Re: Compile Time versus Run Time

2017-07-31 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 31 Jul 2017 15:43:21 +
schrieb Martin Tschierschke :

> As a rookie in D programming I try to understand the power of 
> templated functions with compile time parameters. With DMD 2.074 
> a compile time format
> (auto output = format!("Print this %s")(var);)
> 
> was introduced, now we all know that very many of this format 
> strings are immutable, so wouldn't it be cool to automatically 
> detect this and use the compile time version?
> 
> Without the need to think about it and to use an other syntax?
> Is this theoretically possible?

I see no way to accomplish this. For the compiler to see the
contents of the format string it needs to be a template
argument and as soon as you want to also allow runtime values
to be accepted there, you need to use an alias, which in turn
precludes the use of function results or concatenation.
Believe me I've spent quite some time on trying something like
this for format strings.
 
> Regards mt.

As far as using template arguments for code optimizations go, I
know that at least GCC will turn runtime arguments into
template arguments of sorts internally, thereby creating
duplicates of the function with one or more arguments
optimized out.
On the other hand, you don't want to drive this too far. While
it is nice to have compile-time checks, templates are actually
troublesome on some levels. For example, the duplicated code
makes it hard to cache the formatting function in the CPU and
when writing libraries you always have to provide the full
implementation that will get linked into the host application,
which is a concern under certain licensing schemes.
The benefits of shared libraries, like loading the code into
memory once and use it by multiple processes or fixing
security issues in one central place and have all programs use
the new code without recompilation are also void. I.e. without
template arguments, `format()` and all its dependencies
(templates as well as regular functions) are compiled right
into the Phobos shared library for all programs to use. If
there is a security issue, it can be replaced with a patched
version. Now with template arguments, `format!()` is compiled
into each Dlang application multiple times for each format
string and security fixes cannot be applied without
recompiling them all.

-- 
Marco



Re: Error 1: Previous Definition Different : _D3gtk3All12__ModuleInfoZ (gtk.All.__ModuleInfo)

2017-07-29 Thread Marco Leise via Digitalmars-d-learn
Am Fri, 28 Jul 2017 22:53:52 +
schrieb FoxyBrown :

> After upgrading to latest dmd and having to rebuild gtk, I now 
> get the following error
> 
>   Error 1: Previous Definition Different : 
> _D3gtk3All12__ModuleInfoZ (gtk.All.__ModuleInfo)
>
>
> in my apps that were previously working(no changes, opened up old 
> app and tried to build it and it didn't work). All I did was 
> upgrade dmd2.

Expect potential changes to the ABI in every Dlang version.
After a compiler upgrade you have to rebuild all libraries.
That's why for the Gentoo Linux packages I maintain, there is
a separate library path for each Dlang version, compiler
vendor and architecture (i.e. 32-bit/64-bit). That way an
upgrade doesn't affect existing apps at the cost of manually
maintaining the list of compilers (and versions) you want to
install GtkD for.

> So tired of D and it's crap ;/ So unstable in so many ways. About 
> 10% as productive overall than other languages I've used.  It's 
> error messages are about as helpful as a rock.

Error messages did get better, but generic functions will
always end up looking more verbose than e.g. errors for C
function calls.

-- 
Marco



Re: GtkD nothing

2017-07-06 Thread Marco Leise via Digitalmars-d-learn
Am Thu, 06 Jul 2017 03:49:04 +
schrieb FoxyBrown :

> Unfortunately, importing that module seems to throw an error for 
> some insane reason.
> 
> Error 42: Symbol Undefined _D3gtk6All12__ModuleInfoZ 
> (gtk.AllGTK.__ModuleInfo)
> 
> without importing it in to the project(but directly importing all 
> the other modules works fine, e.g., copying and pasting).
> 

Sounds like there is no compiled version of gtk.All in the
GtkD lib. You could compile it together with your application
as a workaround.

-- 
Marco



Re: avoid extra variable during void pointer cast

2017-05-17 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 15 May 2017 19:30:00 +
schrieb Bauss :

> pragma(inline, true); doesn't actually do what you think it does. 
> In lining is always done whenever possible and that only tells 
> the compiler to spit out an error if it can't inline it.
 
A compiler doesn't simply inline whenever it can. A big
function that's called often would lead to massive code
duplication in that case. What I meant pragma(inline, true) to
do is overrule this cost calculation. Since the OP asked for no
extra function calls, the error on failure to inline seemed
appropriate. Cross-module inlining may fail for example on
some compiler(s) or with separate compilation.

-- 
Marco



Re: D on AArch64 CPU

2017-05-14 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 14 May 2017 15:11:09 +
schrieb Richard Delorme :

> Or should I wait for an offcial support of this architecture?

You ARE the official support now. :)

-- 
Marco



Re: avoid extra variable during void pointer cast

2017-05-14 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 14 May 2017 20:18:24 +
schrieb Kevin Brogan :

> I have a piece of code that takes a callback function.
> 
> The callback has the signature void callback(void* state, void* 
> data)
> 
> There are several of these functions. All of them use state and 
> data as differing types.
> 
> As an example, let's look at one that uses both of them as int*.
> 
> addInt(void* state, void* data)
> {
>  *cast(int*)state += *cast(int*)data;
> }
> 
> Is it not possible to specify the cast as an alias so that I can 
> declare the cast once at the beginning of the function?
> 
> Something like this?
> 
> addInt(void* state, void* data)
> {
>  alias _state = cast(int*)state; // Error: basic type 
> expected, not cast
>  alias _data = cast(int*)data; // Error: basic type expected, 
> not cast
> 
>  *_state += *_data;
> }

No, that is not possible. An alias can only be assigned a
symbol.

> I can always do this:
> 
> addInt(void* state, void* data)
> {
>  int* _state = cast(int*)state;
>  int* _data = cast(int*)data;
> 
>  *_state += *_data;
> }
> 
> But I don't want to create a new variable and assign it everytime 
> I call the function. The examples I'm using are contrived, but in 
> the c code I am porting this from, the callback gets called 
> thousands of times a second, every optimization matters, and the 
> variables are used many times per function. I don't want to 
> riddle the code with casts if i can avoid it and I don't want to 
> create and destroy useless proxy variables every time the 
> function is called.

Let the compiler optimize the assignment away and don't worry
much about it. Inlining also works well within the same module.
In this case here I would probably use "consume" functions as
I dub them:

import std.traits;
pragma(inline, true) /* Not really needed I hope ;) */
ref T consume(T)(ref void* data) if (!hasIndirections!T)
{
T* ptr = cast(T*)data;
data += T.sizeof;
return *ptr;
}

You can then rewrite your addInt function like this:

void add(T)(void* state, void* data) if (isNumeric!T)
{
state.consume!T += data.consume!T;
}

-- 
Marco



Re: Easy sockets - don't exist yet?

2016-09-27 Thread Marco Leise via Digitalmars-d-learn
Just in case, here are the relevant docs:
http://dlang.org/phobos/std_net_curl.html


Re: Easy sockets - don't exist yet?

2016-09-27 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 26 Sep 2016 23:40:10 +
schrieb Vincent :

> 1. Easy to use. No more stupid "UNIX sockets", "TCP types" and so 
> on. Just simple as this:
> 
> // Client side
> auto sock = new ClientSocket("google.com", 80);
> sock.WriteLine("GET / HTTP/1.0");
> sock.WriteLine("Host: google.com");
> sock.WriteLine();// empty line sent

Haha, this is not how I learned network layers at school.
You seem to want on the ...

Network Layer (3): A connection based socket using the Internet
Protocol

Transport Layer (4): A stateful connection using TCP

Application Layer (6): HTTP

Just that you don't ask for HTTP directly, but shoehorn a
packet based socket into sending microscopic strings. In this
case I recommend cURL, which you can feed with all the header
data at once and sends your complete request in one packet.
That'll also handle most of the HTTP specialties.

Not all data transmissions via IP are TCP either. A good bunch
is sent via stateless UDP. That would not be considered a
stream though. I'm just getting at the name "ClientSocket"
here, which can entail more than TCP/IP streams.

-- 
Marco



Re: How to debug (potential) GC bugs?

2016-09-27 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 25 Sep 2016 16:23:11 +
schrieb Matthias Klumpp :

> So, I would like to know the following things:
> 
> 1) Is there any caveat when linking to C libraries and using the 
> GC in a project? So far, it seems to be working well, but there 
> have been a few cases where I was suspicious about the GC 
> actually doing something to malloc'ed stuff or C structs present 
> in the bindings.

If you pass callbacks into the C code, make sure they never
throw. Stack unwinding and exception handling generally
doesn't work across language boundaries.

A tracing garbage collector starts with the assumption that
all the memory that it allocated is no longer reachable and
then starts scanning the known memory for any pointers to
allocations that falsify this assumption.
What you malloc'ed is unknown to the GC and wont be scanned.
Should you ever have GC memory pointers in your malloc'ed
stuff, then you need to call GC.addRange() to make those
pointers keep the allocations alive. Otherwise you will get a
"used after free" error: data corruption or access violations.
A simple case would be a string that you constructed in D and
store in C as a pointer. The GC can automatically scan the
stack and any globals/statics on the D side, but that's about
it.

I know of no tools similar to valgrind specially designed to
debug the D GC. You can plug into the GC API and keep track of
the allocation sizes. I.e. write a proxy GC.

-- 
Marco



Re: Cannot compare object.opEquals is not nogc

2016-07-23 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 23 Jul 2016 13:18:03 +
schrieb Rufus Smith :

> Trying to compare a *ptr value with a value in nogc code results 
> in the error:
> 
> Error: @nogc function '...' cannot call non-@nogc function 
> 'object.opEquals' 
> 
> Shouldn't object opEquals be marked?

The only situation that you can work around is if the 'object'
is actually known to be one of your @nogc objects. Then you
can simply downcast before calling opEquals.

It's certainly limiting, but just an artifact of OOP and I can
assure you that making D usable without GC has been high on
the priority list (for an community driven open-source project
anyways). Phobos got reworked to get rid of unnecessary GC
allocations and Andrei Alexandrescu contemplated making
object's methods @nogc at one point.

If you need a restricted object hierarchy, you'll have to
write a new "NoGcObject" base class. opEquals would still take
"object", though you can avoid a dynamic cast by writing:

  (cast(NoGcObject)cast(void*)obj).someMethod();

The cast to void* prior to the downcast drops the class type
information and a dynamic cast becomes a static cast.

-- 
Marco



Re: asm woes...

2016-05-31 Thread Marco Leise via Digitalmars-d-learn
Am Fri, 27 May 2016 10:16:48 +
schrieb Era Scarecrow :

> On Friday, 27 May 2016 at 10:14:31 UTC, Era Scarecrow wrote:
> >   inc dword ptr [EAX+Foo.x.offsetof];  
> 
> 
>   So just tested it, and it didn't hang, meaning all unittests 
> also passed.
> 
>   Final solution is:
> 
>asm pure @nogc nothrow {
>  mov EAX, this;
>  add dword ptr [EAX+wideIntImpl.lo.offsetof], 1;
>  adc dword ptr [EAX+wideIntImpl.lo.offsetof+4], 0;
>  adc dword ptr [EAX+wideIntImpl.hi.offsetof], 0;
>  adc dword ptr [EAX+wideIntImpl.hi.offsetof+4], 0;
>}

The 'this' pointer is usually in some register already. On
Linux 32-bit for example it is in EAX, on Linux 64-bit is in
RDI. What DMD does when it encounters an asm block is, it
stores every parameter (including the implicit this) on the
stack and when you do "mov EAX, this;" it loads it back from
there using EBP as the base pointer to the stack variables. The
boilerplate will look like this on 32-bit Linux:

   push   EBP // Save what's currently in EBP
   movEBP,ESP // Remember current stack pointer as base for 
variables
   push   EAX // Save implicit 'this' parameter on the stack
   movEAX,DWORD PTR [EBP-0x4] // Load 'this' into EAX as you requested
   
   movESP,EBP // Restore stack to what it was before saving parameters 
and variables
   popEBP // Restore EBP register
   ret// Return from function

Remember that this works only for x86 32-bit in DMD and LDC.
GDC passes inline asm right through to an arbitrary external
assembler after doing some template replacements. It will not
understand any of the asm you feed it, but forward the
external assemblers error messages.

On the other hand GDC's and LDC's extended assemblers free you
from manually loading stuff into registers. You just use a
placeholder and tell the compiler to put 'this' into some
register. The compiler will realize it is already in EAX or
RDI and do nothing but use that register instead of EAX in
your code above. Sometimes that has the additional benefit that
the same asm code works on both 32-bit and 64-bit.
Also, extended asm is transparent to the optimizer. The code
can be inlined and already loaded variables reused.

By the way, you are right that 32-bit does not have access to
64-bit machine words (actually kind of obvious), but your idea
wasn't far fetched, since there is the X32 architecture at
least for Linux. It uses 64-bit machine words, but 32-bit
pointers and allows for compact and fast programs.

-- 
Marco



Re: asm woes...

2016-05-31 Thread Marco Leise via Digitalmars-d-learn
Am Fri, 27 May 2016 10:06:28 +
schrieb Guillaume Piolat :

> Referencing EBP or ESP yourself is indeed dangerous. Not sure why 
> the documentation would advise that. Using "this", names of 
> parameters/locals/field offset is much safer.

DMD makes sure that the EBP relative access of parameters and
stack variables works by copying everything to the stack
that's in registers when you have an asm block in the
function. Using var[EBP] or just plain var will then
dereference that memory location.

-- 
Marco



Re: Is there an easy way to convert a pointer to malloc'd memory to an array?

2016-05-25 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 24 May 2016 20:58:14 +
schrieb Gary Willoughby :

> On Tuesday, 24 May 2016 at 18:43:22 UTC, Adam D. Ruppe wrote:
> > On Tuesday, 24 May 2016 at 18:42:41 UTC, Gary Willoughby wrote:  
> >> I have a T* pointer to the start of a malloc'd chunk of 
> >> memory, the type T and the number of T's stored in the chunk.
> >>
> >> Is there an efficient way of converting this information to a 
> >> D array of type T[] or even T[n]?  
> >
> > Slice it:
> >
> > T[] = t[0 .. n];  
> 
> That! ...is amazing!

How did you _ever_ read structs from files without this
knowledge?

-- 
Marco



Re: Formatted Output: Exact number of Decimal Places

2016-05-16 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 16 May 2016 20:24:51 +
schrieb Q. Schroll :

> Lets say I want to print a table with floats. How can it be 
> formatted like that:
> |  2.4   |
> | 12.2   |
> |  8.131 |
> | 17.44  |
> Also acceptable is
> |  2.400 |
> | 12.200 |
> |  8.131 |
> | 17.440 |

Use %#6.3f to get the above output.

> but not
> | 02.4   |
> | 12.2   |
> | 08.131 |
> | 17.44  |
> or any other solutions with leading zeros.

-- 
Marco



Re: inferred size for static array initialization

2016-05-02 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 2 May 2016 18:52:11 +0200
schrieb ag0aep6g <anonym...@example.com>:

> On 02.05.2016 15:53, Marco Leise wrote:
> >immutable tab = { static enum S[] s = [  
> 
> `static enum`? What kind of black magic is this?

I don't know, but it works, haha.

-- 
Marco



Re: inferred size for static array initialization

2016-05-02 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 02 May 2016 13:00:27 +
schrieb Erik Smith :

> Is there a way to initialize a static array and have it's size 
> inferred (and that works for arrays of structs using braced 
> literals)?  This would make it easier to maintain longer static 
> array definitions.  The code below doesn't work when removing the 
> array size even though the array is declared as static immutable.
> 
>  import std.traits;
>  static immutable int[] a  = [1,2,3];
>  static assert(isStaticArray!(typeof(a)));  // fails
> 

Sure,

  struct S { int a, b; }

  immutable tab = { static enum S[] s = [
  {1,2},
  {3,4},
  ]; return cast(typeof(s[0])[s.length])s; }();

  static assert(isStaticArray!(typeof(tab)));  // succeeds

-- 
Marco



Re: Garbage Collector : Ignoring a reference

2016-04-26 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 26 Apr 2016 13:35:37 +
schrieb Begah :

> When the screen switches to another screen ie from menu to the 
> game,
> I want that the "button.png" texture is automaticly destroyed by 
> the gc.

My ideological point of view is that you must not use
non-deterministic garbage collection for resources. Neither
for files, GUI widgets or textures. The garbage collector
cannot look past its own confined environment (heap memory
allocated by the D program and loaded D libraries) and will
not have enough information to tell if the process is running
out of file handles, backing buffer for widgets or texture
memory on the graphics card. It only takes action, when its own
heap is filling up or when you manually call GC.collect().
All the convenient 100% GC languages from Java to Python
require the user to call ".close()" for files,
".dispose()/.Destroy()" for widgets, etc.
Reference counting is the correct approach. It makes using
external resources safe and convenient by removing the need
for manual lifetime management. Cyclic references cannot
exist in the D code in this scenario.

The texture constructor:
- sets ref count to 1
- adds texture to hash map
The copy constructor:
- increments the ref count
The destructor:
- decrements the ref count
- if ref count reaches 0:
  - removes the texture from the hash table
  - destroys the texture data

-- 
Marco



Re: Adding a float with all four elements of a float4

2016-04-21 Thread Marco Leise via Digitalmars-d-learn
Am Thu, 21 Apr 2016 00:14:53 +
schrieb Straivers :

> Hi,
> 
> I want to make a utility wrapper around a core.simd.float4, and 
> have been trying to make the following code work, but have been 
> met with no success.
> 
> auto add(float rhs)
> {
>  return __simd(XMM.ADDPS, lhs, rhs);
> }

It seems like your are duplicating std.simd:
https://github.com/TurkeyMan/simd

-- 
Marco



Re: char array weirdness

2016-03-29 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 28 Mar 2016 16:29:50 -0700
schrieb "H. S. Teoh via Digitalmars-d-learn"
:

> […] your diacritics may get randomly reattached to
> stuff they weren't originally attached to, or you may end up with wrong
> sequences of Unicode code points (e.g. diacritics not attached to any
> grapheme). Using filter() on Korean text, even with autodecoding, will
> pretty much produce garbage. And so on.

I'm on the same page here. If it ain't ASCII parsable, you
*have* to make a conscious decision about whether you need
code units or graphemes. I've yet to find out about the use
cases for auto-decoded code-points though.

> So in short, we're paying a performance cost for something that's only
> arguably better but still not quite there, and this cost is attached to
> almost *everything* you do with strings, regardless of whether you need
> to (e.g., when you know you're dealing with pure ASCII data).

An unconscious decision made by the library that yields the
least likely intended and expected result? Let me think ...
mhhh ... that's worse than iterating by char. No talking
back :p.

-- 
Marco



Re: How to be more careful about null pointers?

2016-03-29 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 29 Mar 2016 06:00:32 +
schrieb cy :

> struct Database {
>string derp;
>Statement prepare(string s) {
>   return Statement(1234);
>}
> }
> 
> struct Statement {
>int member;
>void bind(int column, int value) {
>   import std.stdio;
>   writeln("derp",member);
>}
> 
> }
> 
> 
> class Wrapper {
>Database something;
>Statement prep;
>this() {
>  something = Database("...");
>  prep = something.prepare("...");
>}
> }
> 
> Wrapper oops;
> void initialize() {
>oops = new Wrapper();
> }
> 
> class Entry {
>Wrapper parent;
>this(Wrapper parent) {
>  //this.parent = parent;
>  //oops
>  parent = parent;
>}
>void usefulmethod() {
>  parent.prep.bind(1,42);
>  //parent.prep.execute();
>  //parent.prep.reset();
>}
> }
> 
> void main() {
>initialize();
>auto entry = new Entry(oops);
>entry.usefulmethod();
> }
> 
> That program causes a segmentation fault on my machine. Somehow 
> despite never initializing Entry.parent, a class object (whose 
> default init is a null pointer), I can still call methods on it, 
> access members on it, and call methods on those members. No 
> warnings or errors. The segfault doesn't happen until the bind() 
> method.

Dlang aborts programs that run into invalid states. Common
invalid states are failing contract assertions, out of memory
conditions or in this case a null-pointer dereference.

When designing Dlang, Walter decided that null pointers don't
require checks as the operating system will eventually abort
the program and debuggers are designed to assist you in this
situation.

Some people with a different programming background feel that
a modern language should wrap every pointer access in a check
and possibly throw a recoverable Exception here or make
null-pointer opt-in to begin with. The topic is still open for
discussion:
http://wiki.dlang.org/Language_issues#Null_References

-- 
Marco



Re: I need some help benchmarking SoA vs AoS

2016-03-26 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 26 Mar 2016 17:43:48 +
schrieb maik klein :

> On Saturday, 26 March 2016 at 17:06:39 UTC, ag0aep6g wrote:
> > On 26.03.2016 18:04, ag0aep6g wrote:
> >> https://gist.github.com/aG0aep6G/a1b87df1ac5930870ffe/revisions
> >
> > PS: Those enforces are for a size of 100_000 not 1_000_000, 
> > because I'm impatient.
> 
> Thanks, okay that gives me more more reliable results.
> for 1_000_000
> 
> benchmarking complete access
> AoS: 1 sec, 87 ms, 266 μs, and 4 hnsecs
> SoA: 1 sec, 491 ms, 186 μs, and 6 hnsecs
> benchmarking partial access
> AoS: 7 secs, 167 ms, 635 μs, and 8 hnsecs
> SoA: 1 sec, 20 ms, 573 μs, and 1 hnsec
> 
> This is sort of what I expected. I will do a few more benchmarks 
> now. I probably also randomize the inputs.

That looks more like it. :) There is a few things to keep in
mind. When you use constant data and don't use the result
compilers can:

- Const-fold computations away.
- Specialize functions on compile-time known arguments. That
  works mostly as if the argument was a template argument. A
  new instance of the function is created for each invokation
  with a compile-time known value. (Disabling inlining wont
  prevent this.)
- Call pure functions with the same argument only once in a
  loop of 1_000_000.
- Replace 1_000_000 additions of the number X in a loop with
  the expression 1_000_000*X.

In addition to these real-world optimizations, when you don't
accumulate the result of the function call and print it or
store it in some global variable, the whole computation may be
removed as "no side-effect", as others have pointed out. When
inlining is used the compiler may also see through attempts to
only use a part of the result and remove instructions that
lead to the rest of it. For example when you return a struct
with two fields - a and b - and store the sum of a, but ignore
b, then the compiler may remove computations that are only
needed for b!

Try to generate input from random number generators or
external files. Disable inlining for the benchmarked function
via attribute or pragma(inline, false) or otherwise make sure
that the compiler cannot guess what any of the arguments are
and perform const-folding after inlining. When the result is
returned, make sure you use so much of it, that the
compiler cannot elide instructions after inlining. It is
often enough to just store it in a global variable.

-- 
Marco



Re: If stdout is __gshared, why does this throw / crash?

2016-03-05 Thread Marco Leise via Digitalmars-d-learn
Got it now: https://issues.dlang.org/show_bug.cgi?id=15768

writeln() creates a copy of the stdout struct in a non
thread-safe way. If stdout has been assigned a File struct
created from a file name this copy includes a "racy"
increment/decrement of a reference count to the underlying
C-library FILE*. In the case that the reference count is
erroneously reaching 0, the file is closed prematurely and
when Glibc tries to access internal data it results in the
observable SIGSEGV.

-- 
Marco



Re: If stdout is __gshared, why does this throw / crash?

2016-03-05 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 05 Mar 2016 14:18:31 +
schrieb Atila Neves :

> void main() {
>  stdout = File("/dev/null", "w");
>  foreach(t; 1000.iota.parallel) {
>  writeln("Oops");
>  }
> }

First thing I tried:

void main() {
 stdout = File("/dev/null", "w");
 foreach(t; 1000.iota.parallel) {
 stdout.writeln("Oops");
 }
}

That does NOT segfault ... hmm.

-- 
Marco



Re: Backslash escaping weirdness

2016-03-05 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 01 Mar 2016 05:14:13 +
schrieb Nicholas Wilson :

> On Tuesday, 1 March 2016 at 04:48:01 UTC, Adam D. Ruppe wrote:
> > On Tuesday, 1 March 2016 at 04:18:11 UTC, Nicholas Wilson wrote:
> >> What is causing these errors? I'm using \t and \n in string 
> >> all over the place and they work.
> >
> > I don't think there's enough context to know for sure... but my 
> > guess is you forgot to close one of the quotes a couple lines 
> > above.
> >
> > So look up for an unpaired "
> 
> It was. Thanks.

And then God created syntax highlighting and He saw that it
was good. ;)

-- 
Marco



Re: Is this a bug in std.typecons.Tuple.slice?

2016-02-08 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 09 Feb 2016 00:38:10 +
schrieb tsbockman <thomas.bock...@gmail.com>:

> On Sunday, 7 February 2016 at 02:11:15 UTC, Marco Leise wrote:
> > What I like most about your proposal is that it doesn't break 
> > any existing code that wasn't broken before. That can't be 
> > emphasized enough.
> 
> Although I wish more than 3 people had voted in my poll, two of 
> them did claim to need the `ref`-ness of `Tuple.slice`, so I 
> don't think we can just ditch it. (I did not vote.)
> 
> If you guys want to add a return-by-value version, it should be 
> treated as an enhancement, not a bug fix in my opinion.

As mentioned I never used the feature myself and wont vote
for one or the other. Three people with no source code to
exemplify current use of .slice! is indeed not much to base
decisions on and both fixes yield unexpected results in
different contexts that warrant bug reports.

-- 
Marco



Re: Is this a bug in std.typecons.Tuple.slice?

2016-02-06 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 06 Feb 2016 11:02:37 +
schrieb tsbockman :

> On Saturday, 6 February 2016 at 08:47:01 UTC, Saurabh Das wrote:
> > I think we should add a static assert to slice to ensure that 
> > the current implementation is not used in a case where the 
> > alignment doesn't match. This is better than failing without 
> > any warning.
> 
> If we pursue the deprecation route, I agree that this is a 
> necessary step.

That would hurt the least, yes. It's more like a .dup with
start and end parameter then.

> > We could add new (differently named) functions for slicing 
> > non-aligned tuples.
> >
> > I agree that my approach of removing the ref may break existing 
> > code, so if introduced, it should be named differently.
> >
> > I am not comfortable with tuple(42, true, "abc").slice(1, 3) 
> > being different in type from tuple(true, " abc").
> 
> Why? What practical problem does this cause?

For me it is mostly a gut feeling. Historically types
mimicking other types have often evoked trouble for example in
generic functions or concretely - if you look at my other post
- in D's AA implementation.

-- 
Marco



Re: Things that keep D from evolving?

2016-02-06 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 06 Feb 2016 11:47:02 +
schrieb Ola Fosheim Grøstad
:

> Of course, Swift does not aim for very high performance, but for 
> convenient application/gui development. And frankly JavaScript is 
> fast enough for that kind of programming.

My code would not see much ref counting in performance critical
loops. There is no point in ref counting every single point in
a complex 3D scene.
I could imagine it used on bigger items. Textures for example
since they may be used by several objects. Or - a prime
example - any outside resource that is potentially scarce and
benefits from deterministic release: file handles, audio
buffers, widgets, ...

-- 
Marco



Re: Things that keep D from evolving?

2016-02-06 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 06 Feb 2016 23:18:59 +
schrieb Ola Fosheim Grøstad
:

> Things that could speed up collection:
> - drop destructors so you don't track dead objects

Interesting, that would also finally force external resources
off the GC heap and into deterministic release. That needs a
solution to inheritance though. Think widget kits.

-- 
Marco



Re: Custom hash table key is const, how to call dtors?

2016-02-06 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 07 Feb 2016 01:05:28 +
schrieb cy <dl...@verge.info.tm>:

> On Saturday, 6 February 2016 at 03:57:16 UTC, Marco Leise wrote:
> 
> > No, but they could have dtors because they contain malloc'd 
> > data. E.g. string literals that don't live on the GC heap.
> 
> Character arrays allocated with glibc malloc are immutable? News 
> to me...

err... well... you got a point there, but then new string(100)
is probably allocated with malloc, too deep down in druntime.

immutable really means that there is no mutable reference to
the data. At any point in your code you can cast something to
immutable when you that no mutable references will exist
thereafter. We do this all the time during construction of
immutable stuff, because when something is newly created,
there is only one unique reference that is turned immutable
after construction and you are set.

You can go the same route with other MM schemes such as
malloc, just that without a GC you are responsible for not
freeing the immutable data as long as there are references to
it. For example (and this applies to Ds GC'd AA, too) you must
not delete entries while you iterate over the keys. There is
no way to say "Hey I just borrowed the list of keys, please
disallow any writes to it."

For now, issues related to dtor-constness need to be fixed.
Then working with immutable data structures is a lot less of a
mine field.

-- 
Marco



Re: Is this a bug in std.typecons.Tuple.slice?

2016-02-06 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 06 Feb 2016 07:57:08 +
schrieb tsbockman <thomas.bock...@gmail.com>:

> On Saturday, 6 February 2016 at 06:34:05 UTC, Marco Leise wrote:
> > I don't want to sound dismissive, but when that thought came
> > to my mind I considered it unacceptable that the type of
> > Tuple!(int, bool, string).slice(1, 3) would be something
> > different than Tuple!(bool, string). In your case
> > Tuple!(TuplePad!4LU, bool, string). That's just a matter of
> > least surprise when comparing the types.
> >
> > I'll let others decide, since I never used tuple slices.
> 
> I'm not sure which approach is ultimately better, but aside from 
> the performance implications, your "needed change" could break a 
> lot of valid code in the wild - or it might break none; it really 
> just depends on whether anyone actually *uses* the `ref`-ness of 
> the `Tuple.slice` return type.

True.
 
> (It appears that Phobos, at least, does not. But there is no 
> guarantee that the rest of the world is using `Tuple` only in the 
> ways that Phobos does.)
> Leaving aside bizarre meta-programming stuff (because then 
> *anything* is a breaking change), my PR does not break any code, 
> except that which was already broken: the type of the slice is 
> only different in those cases where it *has* to be, for alignment 
> reasons; otherwise it remains the same as it was before.

I understand that. We just have a different perspective on the
problem. Your priorities:

- don't break what's not broken
- .slice! lends on opSlice and should return by ref

My priorities:

- type of .slice! should be as if constructing with same
  values from scratch
- keep code additions in Phobos to a minimum

Why do I insist on the return type? Because surprisingly
simple code breaks if it doesn't match. Not everything can be
covered by runtime conversions in D. It still took me a while
to come up with something obvious:

uint[Tuple!(uint, ulong)] hash;

auto tup = tuple(1u, 2u, 3UL);

hash[tup.slice!(1, 3)] = tup[0];

 compiles?  works?
original Tuple : yesno
Saurabh Das changes: yesyes
your changes   : no no

What I like most about your proposal is that it doesn't break
any existing code that wasn't broken before. That can't be
emphasized enough.

-- 
Marco



Re: Is this a bug in std.typecons.Tuple.slice?

2016-02-05 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 06 Feb 2016 04:28:17 +
schrieb tsbockman <thomas.bock...@gmail.com>:

> On Friday, 5 February 2016 at 19:16:11 UTC, Marco Leise wrote:
> >> > 1. Removing 'ref' from the return type
> >
> > Must happen. 'ref' only worked because of the reinterpreting 
> > cast which doesn't work in general. This will change the 
> > semantics. Now the caller of 'slice' will deal with a whole new 
> > copy of everything in the returned slice instead of a narrower 
> > view into the original data. But that's a needed change to fix 
> > the bug.
> 
> Actually, it's not: 
> https://github.com/D-Programming-Language/phobos/pull/3973
> 
> All that is required is to include a little padding at the 
> beginning of the slice struct to make the alignments match.

I don't want to sound dismissive, but when that thought came
to my mind I considered it unacceptable that the type of
Tuple!(int, bool, string).slice(1, 3) would be something
different than Tuple!(bool, string). In your case
Tuple!(TuplePad!4LU, bool, string). That's just a matter of
least surprise when comparing the types.

I'll let others decide, since I never used tuple slices.

-- 
Marco



Re: Template to create a type and instantiate it

2016-02-05 Thread Marco Leise via Digitalmars-d-learn
Mixin templates is the way to go if you want something new on
every use of the template. Otherwise using the template
multiple times with the same arguments will always give you
the first instance.

-- 
Marco



Re: Is this a bug in std.typecons.Tuple.slice?

2016-02-05 Thread Marco Leise via Digitalmars-d-learn
Am Fri, 05 Feb 2016 05:31:15 +
schrieb Saurabh Das :

> On Friday, 5 February 2016 at 05:18:01 UTC, Saurabh Das wrote:
> [...]
> 
> Apologies for spamming. This is an improved implementation:
> 
>  @property
>  Tuple!(sliceSpecs!(from, to)) slice(size_t from, size_t 
> to)() @safe const
>  if (from <= to && to <= Types.length)
>  {
>  return typeof(return)(field[from .. to]);
>  }
> 
>  ///
>  unittest
>  {
>  Tuple!(int, string, float, double) a;
>  a[1] = "abc";
>  a[2] = 4.5;
>  auto s = a.slice!(1, 3);
>  static assert(is(typeof(s) == Tuple!(string, float)));
>  assert(s[0] == "abc" && s[1] == 4.5);
> 
>  Tuple!(int, int, long) b;
>  b[1] = 42;
>  b[2] = 101;
>  auto t = b.slice!(1, 3);
>  static assert(is(typeof(t) == Tuple!(int, long)));
>  assert(t[0] == 42 && t[1] == 101);
>  }

That's quite concise. I like this. Though 'field' is now
called 'expand':
// backwards compatibility
alias field = expand;

> These questions still remain:
> > 1. Removing 'ref' from the return type

Must happen. 'ref' only worked because of the reinterpreting
cast which doesn't work in general. This will change the
semantics. Now the caller of 'slice' will deal with a whole
new copy of everything in the returned slice instead of a
narrower view into the original data. But that's a needed
change to fix the bug.

> > 2. Adding 'const' to the function signature

Hmm. Since const is transitive this may add const to stuff
that wasn't const, like in a Tuple!(Object). When you call
const slice on that, you would get a Tuple!(const(Object)).
I would use inout, making it so that the tuple's original
constness is propagated to the result.

I.e.: @property inout(Tuple!(sliceSpecs!(from, to)))
slice(size_t from, size_t to)() @safe inout

> > 3. Is the new implementation less efficient for correctly 
> > aligned tuples?

Yes, the previous one just added a compile-time known offset
to the "this"-pointer. That's _one_ assembly instruction after
inlining and optimization.
The new one makes a copy of every field. On struct fields this
can call the copy constructor "this(this)" which is used for
example in reference counting to preform an increment for the
copy.
On "plain old data" it would simply copy the bit patterns. But
that's obviously still less efficient than adding an offset to
the pointer.
You need two methods if you want to offer the best of both
worlds. As soon as your function does not return a pointer or
has 'ref' on it, the compiler will provide memory on the stack
to hold the result and a copy will occur.
That said, sufficiently smart compilers can analyze what's
happening and come to the conclusion that when after the copy,
the original is no longer used, they can be merged.

> 4. @trusted -> @safe?

Sounds good, but be aware of the mentioned implications with
"this(this)". Copy constructors often need to do unsafe
things, so @safe here would disallow them in Tuples.
On the other hand recent versions of the front-end should
infer attributes for templates, so you can generally omit them
and "let the Tuple decide". This mechanism also already adds
@nogc, pure, nothrow as possible in both the original and your
implementation.
(The original code only had @trusted on it because the
compiler would always infer the safety as @system due to the
pointer casts and @system is close to intolerable for a
"high-level" functional programming feature such as tuples.
The other attributes should have been inferred correctly.)

-- 
Marco



Custom hash table key is const, how to call dtors?

2016-02-05 Thread Marco Leise via Digitalmars-d-learn
Usually I want the keys to be declared "immutable" to signal
that their content must not change in order to provide stable
hashes. But when you remove items from the table you need to
call a const/immutable dtor that needs to be written for
everything that can be a hash table key.

What do you put into such a const/immutable dtor?
How do others deal with this?

-- 
Marco



Re: Custom hash table key is const, how to call dtors?

2016-02-05 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 06 Feb 2016 03:38:54 +
schrieb cy <dl...@verge.info.tm>:

> On Friday, 5 February 2016 at 22:18:50 UTC, Marco Leise wrote:
> > But when you remove items from the table you need to call a 
> > const/immutable dtor that needs to be written for everything 
> > that can be a hash table key.
> 
> You need to write destructors for hash keys? How would you use 
> string literals as keys then? Could you provide an example 
> maybe...?

No, but they could have dtors because they contain malloc'd
data. E.g. string literals that don't live on the GC heap.

-- 
Marco



Re: Is this a bug in std.typecons.Tuple.slice?

2016-02-04 Thread Marco Leise via Digitalmars-d-learn
https://issues.dlang.org/show_bug.cgi?id=15645


Re: Octree implementation?

2016-02-04 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 01 Feb 2016 02:56:06 +
schrieb Tofu Ninja :

> Just out of curiosity, does anyone have an octree implementation 
> for D laying around? Just looking to save some time.

I have one written in Delphi that you could prune till it fits.

-- 
Marco



Re: Is this a bug in std.typecons.Tuple.slice?

2016-02-04 Thread Marco Leise via Digitalmars-d-learn
Am Thu, 04 Feb 2016 15:17:54 +
schrieb Saurabh Das :

> On Thursday, 4 February 2016 at 12:28:39 UTC, Saurabh Das wrote:
> > This code:
> > [...]
> 
> Update: Simplified, this also doesn't work:
> 
> void main()
> {
>  import std.typecons;
>  auto tp = tuple(10, false, "hello");
> 
>  auto u0 = tp.slice!(0, tp.length);
>  auto u1 = tp.slice!(1, tp.length);
>  auto u2 = tp.slice!(2, tp.length);
> 
>  static assert(is(typeof(u0) == Tuple!(int, bool, string)));
>  static assert(is(typeof(u1) == Tuple!(bool, string)));
>  static assert(is(typeof(u2) == Tuple!(string)));
> 
>  assert(u2[0] == "hello");
>  assert(u0[2] == "hello");
>  assert(u1[1] == "hello");// This fails
> }
> 
> rdmd erasetype.d
> core.exception.AssertError@erasetype.d(16): Assertion failure
> 
> Any ideas?

Yes this is a clear bug, I'll report a bug and post the issue
number later.

-- 
Marco



Re: Something about Chinese Disorder Code

2015-11-24 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 24 Nov 2015 17:08:33 +
schrieb BLM768 :

> On Tuesday, 24 November 2015 at 09:48:45 UTC, magicdmer wrote:
> > I display chinese string like:
> >
> > auto str = "你好,世界"
> > writeln(str)
> >
> > and The display is garbled。
> >
> > some windows api like MessageBoxA ,if string is chinese, it 
> > displays disorder code too
> >
> > i think i must use WideCharToMultiByte to convert it , is there 
> > any other answer to solve this question simplely
> 
> You can also try using a wide string literal, i.e. "你好,世界"w. The 
> suffix forces the string to use 16-bit characters.
> 
> The garbled display from writeln might be related to your console 
> settings. If you aren't using the UTF-8 codepage in cmd.exe, that 
> would explain why the text appears garbled. Unfortunately, 
> Windows has some significant bugs with UTF-8 in the console.

This is really our problem. We pretend the output terminal is
UTF-8 without providing any means to configure the terminal or
converting the output to the terminal's encoding. All OSs
provide conversion API that works for the most part (assuming
normalization form D for example), but we just don't use them.
Most contributers were on Linux or English Windows system
where the issue is not obvious. But even in Europe łáö will
come out garbled.

Now this is mostly not an issue with modern Linux and OS X as
the default is UTF-8, but some people refuse to change to
variable length encodings and Windows has always been
preferring fixed length encodings.

The proper way to solve this for the OP in a cross-platform
way is to replace writeln with something that detects whether
the output is a terminal and then converts the string to
something that will display correctly, which can be a simple
wchar[] on Windows or the use of iconv on Linux. Ketmar is
currently using iconv to print D string on his Linux set up
for Cyrillic KIO-8U and I think I used it in some code as
well. It is not perfect, but will make most printable strings
readable. ICU I think is the only library that gets it 100%
correct with regards to normalization and offering you
different error concealment methods.

-- 
Marco



Re: Implicit conversion rules

2015-10-21 Thread Marco Leise via Digitalmars-d-learn
Am Wed, 21 Oct 2015 12:49:35 -0700
schrieb Ali Çehreli :

> On 10/21/2015 12:37 PM, Sigg wrote:
> 
>  > cause at least few more "fun" side effects.
> 
> One of those side effects would be function calls binding silently to 
> another overload:
> 
> void foo(bool){/* ... */}
> void foo(int) {/* ... */}
> 
>auto a = 0;  // If the type were deduced by the value,
>foo(a);  // then this would be a call to foo(bool)...
> // until someone changed the value to 2. :)
> 
> Ali

God forbid anyone implement such nonsense into D !
That would be the last thing we need that we cannot rely on
the overload resolution any more. It would be as if making 'a'
const would change the overload resolution when none of the
overloads deal with constness...

import std.format;
import std.stdio;

string foo(bool b) { return format("That's a boolean %s!", b); }
string foo(uint u) { return format("Thats an integral %s!", u); }

void main()
{
  int a = 2497420, b = 2497419;
const int c = 2497420, d = 2497419;
writeln(foo(a-b));
writeln(foo(c-d));
writeln("WAT?!");
}

-- 
Marco



Re: [sdc] linker problems when building programs with sdc

2015-10-18 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 18 Oct 2015 11:35:16 +0200
schrieb Joseph Rushton Wakeling via Digitalmars-d-learn
:

> Hello all,
> 
> I recently decided to have another play with sdc to see how it's doing.  
> Since 
> my dmd is installed in /opt/dmd/ I had to do a couple of tricks to get sdc 
> itself to build:
> 
> (i) put a dlang.conf in /etc/ld.so.conf.d/ containing the /opt/dmd/lib64 path;
> 
> (ii) call 'make LD_PATH=/opt/dmd/lib64' when building sdc
> 
> sdc itself then builds successfully, and I wind up with a bin/ directory 
> containing sdc and sdc.conf (which contains includePath and libPath options) 
> and 
> a lib/ directory containing libd.a, libd-llvm.a, libphobos.a and libsdrt.a.
> 
> However, when I try to build any program, even a simple hello-world, I get a 
> linker error:
> 
> $ ./sdc hello.d
> hello.o: In function `_D5hello4mainFMZv':
> hello.d:(.text+0x1c): undefined reference to `_D3std5stdio7writelnFMAyaZv'
> collect2: error: ld returned 1 exit status
> 
> To solve this, I tried adding in a library-path flag, but this simply 
> resulted 
> in an exception being thrown by sdc's options parsing:
> 
> $ ./sdc -L$MYHOMEDIR/code/D/sdc/lib hello.d
> std.getopt.GetOptException@/opt/dmd/bin/../import/std/getopt.d(604): 
> Unrecognized option -L$MYHOMEDIR/code/D/sdc/lib
> 
> [cut great big backtrace]
> 
> Can anyone advise what's missing in my setup?  I did also try adding 
> $MYHOMEDIR/code/D/sdc/lib to the /etc/ld.so.conf.d/dlang.conf file, and 
> re-running ldconfig, but that didn't seem to make any difference.
> 
> Thanks & best wishes,
> 
>  -- Joe

Maybe you should have started with `return 42;`? :D
writeln is not a light-weight in terms of exercised compiler
features. I didn't even know that it compiles yet. Last time I
heard it was not usable.

-- 
Marco



Re: How to check if JSONValue of type object has a key?

2015-10-06 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 06 Oct 2015 21:39:28 +
schrieb Fusxfaranto :

> Additionally, just like associative arrays, if you need to access 
> the value, you can get a pointer to it with the in operator (and 
> if the key doesn't exist, it will return a null pointer).
> 
> const(JSONValue)* p = "key" in root;
> if (p)
> {
>  // key exists, do something with p or *p
> }
> else
> {
>  // key does not exist
> }

And you could go further and write

if (auto p = "key" in root)
{
 // key exists, do something with p or *p
}
else
{
 // key does not exist
}

-- 
Marco



Re: __simd_sto confusion

2015-10-03 Thread Marco Leise via Digitalmars-d-learn
This is a bug in overload resolution when __vector(void[16])
is involved. You can go around it by changing float4 to void16,
only to run into an internal compiler error:
  backend/gother.c 988
So file a bug for both @ issues.dlang.org
Also it looks like DMD wants you to use the return value of
the intrinsic, is that expected?

-- 
Marco



Re: __simd_sto confusion

2015-10-03 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 03 Oct 2015 23:42:22 +
schrieb Nachtraaf :

> I changed the type of result to void16 like this:
> 
> float dot_simd1(float4  a, float4 b)
> {
>  void16 result = __simd(XMM.DPPS, a, b, 0xFF);
>  float value;
>  __simd_sto(XMM.STOSS, value, result);
>  return value;
> }
> 
> and for me this code compiles and runs without any errors now.
> I'm using DMD64 D Compiler v2.068 on Linux. If you got an 
> internal compiler error that means that it's a compiler bug 
> though I have no clue what. Did you try the same thing I did or 
> casting the variable?
> I guess I should file a bugreport for overload resolution if it's 
> not a duplicate for now?

Yes. At some point the intrinsics will need a more thorough
rework. Currently none of those that return void, int or set
flags work as they should.

-- 
Marco



Re: Mac IDE with Intellisense

2015-10-01 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 26 Sep 2015 10:38:25 +
schrieb Gary Willoughby :

> Auto-complete in D is tricky because of this feature and no-one 
> has invested any time to figure out a nice way to provide 
> auto-complete for this.

Mono-D does have UFCS auto-complete. The plugin is going to
bit-rot though, since its only developer is done studying.

-- 
Marco



Re: WTF does "Enforcement failed" actually mean?

2015-10-01 Thread Marco Leise via Digitalmars-d-learn
Am Thu, 01 Oct 2015 08:52:43 +
schrieb John Colvin :

> On Thursday, 1 October 2015 at 07:08:00 UTC, Russel Winder wrote:
> > On Wed, 2015-09-30 at 23:35 -0700, Ali Çehreli via 
> > Digitalmars-d-learn wrote:
> >> On 09/30/2015 10:46 PM, Russel Winder via Digitalmars-d-learn 
> >> wrote:
> >> > [...]
> >> 
> >> It's coming from the following no-message enforce():
> >> 
> >>  enforce(!r.empty);
> >> 
> >> 
> >> https://github.com/D-Programming-Language/phobos/blob/master/std/algo
> >> rithm/iteration.d#L2481
> >> 
> >> You are using the no-seed version of reduce(), which uses the 
> >> first element as seed, which means that the range cannot be 
> >> empty.
> >
> > Well that explanation (*) makes it abundantly clear that the 
> > error reporting from this part of Phobos is distinctly 
> > substandard, let alone below par.
> >
> >
> > (*) Which is clear and informative!
> 
> Bug report? Then it'll get fixed.

The problem is that in out minds addition has an implicit seed
value of 0 and multiplication has 1, so a potentially empty
range doesn't immediately raise a red flag.

The correct thing to use, following this train of thought, is
http://dlang.org/phobos/std_algorithm_iteration.html#.sum
(Additionally it provides better accuracy when summing up
floating-point values.)

-- 
Marco



Re: Interval Arithmetic

2015-10-01 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 29 Sep 2015 21:04:00 +
schrieb Wulfrick :

> Is there an interval arithmetic library in D? I couldn’t find one.
> 
> In case I had to write my own, I understand that the IEEE 
> standard floating point arithmetic provides operations for 
> rounding up or down certain operations like summing, subtracting, 
> etc. (thus overriding the default behavior of rounding to nearest 
> representable).
> 
> How do I access this functionality in D? At first I thought that 
> std.math.nextDown and nextUp is what I needed, but not so. 
> Apparently these functions return the previous or next 
> representable *after* the calculation has been done.
> 
> For example, I would like the value of x+y rounded in the 
> arithmetic towards -\infty, which may or may not be nextDown(x+y).
> 
> Any luck?
> Thanks for reading!

Yes, Phobos provides you with this thing:
http://dlang.org/phobos/std_math.html#.FloatingPointControl
Read the help carefully. End of the scope generally means "}".

You can also use the C standard library from D and use:
http://www.cplusplus.com/reference/cfenv/fesetround/

  import core.stdc.fenv;
  fesetround( FE_DOWNWARD );
  auto z = x + y;

And if all that still isn't enough you can write it in inline
assembler using the `fldcw` mnemonic.

Note that the FP control word is per thread and any external
code you call or even buggy interrupt handlers could change or
reset it to defaults. Known cases include a faulty printer
driver and Delphi's runtime, which enables FP exceptions to
throw exceptions on division by 0. Just saying this so if it
ever happens you have it in the back of your mind. Against
interrupt handlers you probably cannot protect, but when
calling other people's code it would be best not depend on
what the FP control word is set to on return.
`FloatingPointControl` is nice here, because you can
temporarily set the rounding mode directly for a block of FP
instructions where no external libraries are involved.

-- 
Marco



Re: Interval Arithmetic

2015-10-01 Thread Marco Leise via Digitalmars-d-learn
Am Thu, 01 Oct 2015 12:03:10 +
schrieb ponce :

> I have a RAII struct to save/restore the FP control word.
> It also handle the SSE control word which unfortunately exist.
> 
> https://github.com/p0nce/dplug/blob/master/plugin/dplug/plugin/fpcontrol.d

Nice to have in Phobos. I assume you have to set the correct
control word depending on whether you perform math on the FPU
or via SSE (as is standard for x86_64)? And I assume further
that DMD always uses FPU math and other compilers provide
flags to switch between FPU and SSE?

-- 
Marco


Re: final class & final methods

2015-09-25 Thread Marco Leise via Digitalmars-d-learn
Am Fri, 25 Sep 2015 10:28:54 +
schrieb ref2401 :

> If I declare a class as `final` do I  have to mark all methods of 
> the class as `final` too?

No.

-- 
Marco



Re: Why does reverse also flips my other dynamic array?

2015-09-14 Thread Marco Leise via Digitalmars-d-learn
Thanks for the clarification.


Re: Why does reverse also flips my other dynamic array?

2015-09-12 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 12 Sep 2015 10:55:50 +
schrieb "Namal" :

> > Why is also b flipped here? This doesn't happen if I use static 
> > arrays.
> 
> nvm. I need to .dup that.

Correct, static arrays are value types and copied on
assignment. Dynamic arrays on the other hand are generally
slices of memory on the garbage collected heap represented by
just a pointer to the first element and a length. When you
assign those you only get a second reference to the same data.

Note that often the original dynamic array has additional
capacity beyond its length. This can be used to ~= additional
items without causing a reallocation, but is lost when you
do the assignment "b = a". (This is so you can't accidentally
append different items to both a and b and have them overwrite
each other.) You can query the actual capacity with a.capacity.

Just felt like writing down some knowledge you might need
along the way. :)

-- 
Marco



Re: Utf8 to Utf32 cast cost

2015-06-10 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 8 Jun 2015 12:59:31 +0200
schrieb Daniel Kozák via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com:

 
 On Mon, 08 Jun 2015 10:41:59 +
 Kadir Erdem Demir via Digitalmars-d-learn
 digitalmars-d-learn@puremagic.com wrote:
 
  I want to use my char array with awesome, cool std.algorithm 
  functions. Since many of this algorithms requires like slicing 
  etc.. I prefer to create my string with Utf32 chars. But by 
  default all strings literals are Utf8 for performance.
  
  With my current knowledge I use to!dhar to convert Utf8[](or 
  char[]) to Utf32[](or dchar[])
  
  dchar[] range = to!dchar(erdem.dup)
  
  How costly is this?
 
 import std.conv;
 import std.utf;
 import std.datetime;
 import std.stdio;
 
 void f0() {
 string somestr = some not so long utf8 string forbenchmarking;
 dstring str = to!dstring(somestr);
 }
 
 
 void f1() {
 string somestr = some not so long utf8 string forbenchmarking;
 dstring str = toUTF32(somestr);
 }
 
 void main() {
 auto r = benchmark!(f0,f1)(1_000_000);
 auto f0Result = to!Duration(r[0]);
 auto f1Result = to!Duration(r[1]);
 writeln(f0 time: ,f0Result);
 writeln(f1 time: ,f1Result);
 }
 
 
 /// output ///
 f0 time: 2 secs, 281 ms, 933 μs, and 8 hnsecs
 f1 time: 600 ms, 979 μs, and 8 hnsecs
 

Please have the result of the transcode influence the program
output. E.g. Add the first character of the UTF32 string to
some global variable and print it out. At the moment - at
least in theory - you allow the compiler to deduce f0/f1 as
pure, return-nothing functions and you will benchmark anything
from your written code to an empty loop. I'm talking out of
experience here:
https://github.com/mleise/fast/blob/master/source/fast/internal.d#L99

-- 
Marco



Re: Utf8 to Utf32 cast cost

2015-06-10 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 08 Jun 2015 11:13:25 +
schrieb Daniel Kozak kozz...@gmail.com:

 BTW on ldc(ldc -O3 -singleobj -release -boundscheck=off) 
 transcode is the fastest:
 
 f0 time: 1 sec, 115 ms, 48 μs, and 7 hnsecs // to!dstring
 f1 time: 449 ms and 329 μs // toUTF32
 f2 time: 272 ms, 969 μs, and 1 hnsec // transcode

Three functions, each twice as fast and twice as hidden as the
one before. :)

-- 
Marco



Re: Convert C array pointer to a D slice without data copy

2015-05-18 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 18 May 2015 09:51:48 +
schrieb John Colvin john.loughran.col...@gmail.com:

 No need to worry about the GC here, it only scans the stack and 
 its own heap (unless you specifically add a new root).

And even if you add a root it wont free anything it did not
allocate itself! You could even append to your C array. It
will check how much capacity the slice still has on the GC
heap and after realizing the .ptr is not even in one of its
pools, allocate a GC copy of the C array right away.

-- 
Marco



Re: 'const' and 'in' parameter storage classes

2015-05-18 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 18 May 2015 09:05:51 -0400
schrieb Steven Schveighoffer schvei...@yahoo.com:

 On 5/15/15 2:19 PM, ref2401 wrote:
  On Friday, 15 May 2015 at 16:30:29 UTC, Steven Schveighoffer wrote:
  On 5/15/15 12:04 PM, ref2401 wrote:
  What is the difference between 'const' and 'in' parameter storage
  classes?
  When should I use 'const' or 'in'?
 
  The documentation says 'in' is the same as 'const scope' but I can't
  write 'const scope ref' though it's legal to write 'in ref'.
 
  scope ref const
 
 
  still getting the error: Error: scope cannot be ref or out
 
 interesting. Seems you would be right then.
 
 The only other possibility could be ref scope const, but that doesn't 
 seem right, I'll try it.
 
 Nope, so basically there is no way to do in by expanding to scope const. 
 This is something that should be considered if we ever want to modify 
 what 'in' means.
 
 I am not sure yet whether in ref should be valid or scope ref should 
 be valid either. It doesn't seem to me that it should trigger an error.
 
 -Steve

Issue 8121 - scope ref is perfectly OK
https://issues.dlang.org/show_bug.cgi?id=8121

-- 
Marco



Re: Function name from function pointer

2015-04-11 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 11 Apr 2015 18:28:35 +
schrieb Paul D Anderson claude.re...@msnmail.com:

 Is there a way to return the name of a function (a string) from a 
 pointer to that function?
 
 Function pointer example from D Reference:
 ---
 int function() fp;
 
 void test()
 {
  static int a = 7;
  static int foo() { return a + 3; }
 
  fp = foo;
 }
 
 void bar()
 {
  test();
  int i = fp();   // i is set to 10
 }
 ---
 
 Can I get foo from fp?
 
 Paul
 
 

Nope, that would require that fp not only contains a pointer
to the function but also a pointer to the name. That's not how
it works. But continuing that thought, you could add the
function's name as an additional variable and set that every
time you set fp.

-- 
Marco



Re: Is it any faster to read array slices than just elements of an array?

2015-04-09 Thread Marco Leise via Digitalmars-d-learn
Am Wed, 08 Apr 2015 17:01:43 +
schrieb ZILtoid1991 ziltoidtheomnic...@gmail.com:

 While I technically finished the 0.2 version of my graphics 
 engine which has a reasonable speed at low internal resolutions 
 and with only a couple of sprites, but it still gets bottlenecked 
 a lot. First I'll throw out the top-down determination 
 algorhythm as it requires constant memory paging (alrought it 
 made much more sense when the engine was full OO and even slower).
 
 Instead I'll use a overwriting (bottom-up) method. It still 
 needs constant updates and I have to remove the per sprite 
 transparency key and use a per layer key, however it requires 
 much less paging, and still have the ability of unbound layer 
 numbers and sprite count with unbound sizes.
 
 I also came up with the idea of reading slices out from the 
 graphical elements to potentially speed up the process a bit, 
 especially as the custom bitmaps it uses are 16bit for palette 
 operations, so per pixel read operations would waste a portion of 
 memory bus. So should I write a method for the bitmap class which 
 gets a line from it? (an array slice as it contains the data in a 
 single 1D array to avoid jagged arrays on a future expansion for 
 a scaler) And can I write an array slice at a position of an 
 array? (to reduce writeback calls)

I don't get the whole picture, but an array slice is just a
pointer and a length, so it doesn't access the pixels at all.
If you know you will be going over the whole scanline, by all
means get an array slice (or a C style raw pointer) and
process it in as big chunks as possible. For example
copying with 128-bit SSE registers will be much faster than
16-bit ushorts. (SSE4 also offers a table lookup function.)
Beyond that - since it is a gfx engine - why not use OpenGL
and drop the palette lookup altogether ?

-- 
Marco



Re: naked popcnt function

2014-11-22 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 22 Nov 2014 18:30:05 +
schrieb Ad a...@fakmail.fg:

 Hello, I would like to write a popcnt function. This works fine
 
 ulong popcnt(ulong x)
 {
 asm { mov RAX, x ; popcnt RAX, RAX ; }
 }
 
 However, if I add the naked keyword ( which should improve 
 performance? ) it doesn't work anymore and I can't figure out 
 what change I am supposed to make ( aside from x[RBP] instead of 
 x )
 This function is going to be *heavily* used.
 
 Thanks for any help.

It is long ago that I tried naked, but IIRC it strips all
compiler generated code from the function and I see no 'ret'
in your function. So it probably runs into whatever code lies
behind that function in the executable.
I would use a tool like obj2asm or objdump to check what the
generated code looks like, or use a debugger that can
disassemble on the fly.

-- 
Marco



Re: Question about Vectors

2014-11-21 Thread Marco Leise via Digitalmars-d-learn
Am Thu, 20 Nov 2014 20:17:31 +
schrieb Charles csmith.ku2...@gmail.com:

 So I was reading the documentation page: 
 http://dlang.org/simd.html and noticed what appears to be a typo:
 
 int4 v;
 (cast(int*)v)[3] = 2;   // set 3rd element of the 4 int vector
 (cast(int[4])v)[3] = 2;  // set 3rd element of the 4 int vector
 v.array[3] = 2;  // set 3rd element of the 4 int vector
 v.ptr[3] = 2;// set 3rd element of the 4 int vector
 
 v.array[3] = 2; and v.ptr[3] = 2; set the fourth element, and not 
 the third.
 
 As I was verifying this, I realized I had to compile it in 64 bit 
 code. The 32 bit code produced the error SIMD vector types not 
 supported on this platform.
 
 My test code is:
 
  void main() {
  import std.stdio;
  import core.simd;
 
  int4 v = 7;
  v.ptr[3] = 2;
  writeln(v.array[]);
  }
 
 
 Is that related to me compiling while using a 64 bit OS, or is 
 that true of any 32 bit OS, and thus, vectors can't be used in 
 programs intended to be run on 32 bit OSs?
 
 Thanks,
 Charles

DMD supports SIMD only on amd64, but you can use the GDC or
LDC2 compilers if you need 32-bit support for vector types.

-- 
Marco



Does the compiler always semantically analyze everything in a project?

2014-11-13 Thread Marco Leise via Digitalmars-d-learn
Specifically, when I put some code in a separately compiled
lib, does that save me anything in terms of files that have to
be analyzed or will dmd always go through every file that can
be reached through includes ? (.di files are out of question,
because they have issues)

-- 
Marco



Re: Does the compiler always semantically analyze everything in a project?

2014-11-13 Thread Marco Leise via Digitalmars-d-learn
Am Thu, 13 Nov 2014 16:54:45 +
schrieb Dicebot pub...@dicebot.lv:

 Apart from unused templates - yes. In abscence of .di files 
 separate compilation only affects generated object files

I thought so and wonder how that will scale with large code
bases. Lately I found so many bugs and shortcomings that the
ice is growing thin. There's bugs with .di files, with
separate compilation, with SIMD, static dtors inside
templates... and no the uncertainty how D projects will scale
if the module with main imports the world. It makes me want to
switch to C++. :p
I hope Walter's idea of full lazy evaluation can help here.

-- 
Marco



Re: Destructor order

2014-10-23 Thread Marco Leise via Digitalmars-d-learn
Am Thu, 23 Oct 2014 12:15:13 +
schrieb Marc Schütz schue...@gmx.net:

 Yet another use case for borrowing.

Cool, how does it keep the original struct alive though, if it
isn't stored anywhere? Or will it error out when you attempt
to use the dangling pointer to the object?

-- 
Marco



Re: m_condition.mutex cannot be used in shared method ?

2014-10-20 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 19 Oct 2014 17:09:22 +
schrieb Sean Kelly s...@invisibleduck.org:

 What really needs to happen is for everything in core.sync to be 
 made shared.  I got partway through this at one point and 
 stopped, because it was imposing a terrible design on the 
 classes--I had shared methods that were casting away shared and 
 then calling the non-shared methods to do the work.
 
 The reason for this was that the transitivity of shared was 
 preventing me from calling pthread_mutex_lock or whatever because 
 those functions didn't take a shared pthread_mutex_t.  And 
 attempting to rewrite core.sys.posix to make the logically shared 
 types explicitly shared had a cascading effect that made me 
 uncomfortable.
 
 Because of this, I remain unconvinced that the semantics of the 
 shared attribute are actually correct when applied to 
 user-defined types.  I want some kind of an I know what I'm 
 doing label, perhaps equivalent to the mutable attribute in 
 C++, but to exempt contained types from shared.

Thank you for that honest response. The situation is really
bizarre. I just tried to create a shared worker thread and
there is no ctor in Thread that creates a shared instance.

Is a shared constructor even meaningful? [1]
If yes, what do we need it for?

Can't we otherwise just implicitly and safely cast to shared
_after_ the constructor ran when we write `new shared(Foo)(...)`?

Casting away shared is not @safe. Since this is normal to
do in synchronized blocks, I figure the whole core.Thread and
core.sync.xxx family are @system functionality ?


[1]
(Note that I created a PR for DMD that disables shared
destruction:
https://github.com/D-Programming-Language/dmd/pull/4072)

-- 
Marco



Re: Runtime execution

2014-10-19 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 19 Oct 2014 06:55:17 +
schrieb Bauss jj_1...@live.dk:

 Is there anyway to pull of a runtime compilation of D code or at 
 the very least asm execution?

Sure. For runtime compilation you invoke any installed D
compiler and compile a conventional shared library that you
then load with:
http://dlang.org/library/core/runtime/Runtime.loadLibrary.html

For ASM execution you'd simply load the ASM into an executable
memory area (See virtual memory page protection attributes for
your OS) and call or jump into it through D's inline asm {}
blocks.

I hope that helps.

-- 
Marco



m_condition.mutex cannot be used in shared method ?

2014-10-19 Thread Marco Leise via Digitalmars-d-learn
I have a thread that is shared by
others, so I have a shared method, inside of which I wrote:

final void opOpAssign(string op : ~)(ref StreamingObject item) shared
{
synchronized (m_condition.mutex)
{
m_list.unshared ~= item;
m_condition.notify();
}
}

Error: non-shared method core.sync.condition.Condition.mutex is not callable 
using a shared object

Where exactly should my stuff stop to be shared so I can call .mutex ?

Btw.:
StreamingObject is a struct
unshared is a @property that casts away sharedness

-- 
Marco



Re: How do you get T from shared(T) ?

2014-10-01 Thread Marco Leise via Digitalmars-d-learn
Am Tue, 30 Sep 2014 14:48:03 +
schrieb John Colvin john.loughran.col...@gmail.com:

 On Sunday, 28 September 2014 at 09:11:07 UTC, Marco Leise wrote:
  For head-unshared there is `static if (is(T U : shared U))`.
  But how do you get the unshared type for anything from `shared
  void*` to `shared uint` ?
 
 template UnShared(T, bool removeAll = false)
 {
 static if(is(T : shared U, U))
 {
  static if(is(U : shared(V)*, V))
  {
  alias UnShared = UnShared!(V, true)*;
  }
  else
  {
  alias UnShared = U;
  }
  }
  else
  {
  static if(removeAll  is(T : U*, U))
  {
  alias UnShared = UnShared!(U, true)*;
  }
  else
  {
  alias UnShared = T;
  }
  }
 }
 
 unittest
 {
  static assert(is(UnShared!(shared int) == int));
  static assert(is(UnShared!(shared void*) == void*));
  static assert(is(UnShared!(shared(int**)*) == 
 shared(int**)*));
  static assert(is(UnShared!(shared(int**)**, true) == 
 int));
 }

Ah, thanks. That does the trick!

-- 
Marco



Re: A hash table implementation benchmark

2014-10-01 Thread Marco Leise via Digitalmars-d-learn
Am Wed, 01 Oct 2014 14:40:01 -0700
schrieb Ali Çehreli acehr...@yahoo.com:

 Found on Reddit:
 
  
 http://lonewolfer.wordpress.com/2014/03/13/benchmarking-hash-table-implementations-in-different-languages/
 
 Are you motivated enough to compare D's associative arrays with those 
 results? :)
 
 Ali

The question is ... do you dare with the current state of the
GC :D

-- 
Marco



Re: A hash table implementation benchmark

2014-10-01 Thread Marco Leise via Digitalmars-d-learn
Oh wit! It is a read-only benchmark.


How do you get T from shared(T) ?

2014-09-28 Thread Marco Leise via Digitalmars-d-learn
For head-unshared there is `static if (is(T U : shared U))`.
But how do you get the unshared type for anything from `shared
void*` to `shared uint` ?

-- 
Marco



Re: How do you get T from shared(T) ?

2014-09-28 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 28 Sep 2014 14:07:22 +
schrieb tcak t...@gmail.com:

 On Sunday, 28 September 2014 at 09:11:07 UTC, Marco Leise wrote:
  For head-unshared there is `static if (is(T U : shared U))`.
  But how do you get the unshared type for anything from `shared
  void*` to `shared uint` ?
 
 shared int a;
 
 int b = cast()a;

No, I mean for `shared void*`, too. But I special cased for
one level of pointer indirection now, so it works.

-- 
Marco



Re: Parsing

2014-03-31 Thread Marco Leise
Am Mon, 31 Mar 2014 04:06:38 +
schrieb Joel joel...@gmail.com:

 I've got a program that uses user input, but I'm having trouble 
 with it.
 
 Here's an example, the unenclosed numbers (1 2 3 in example) add 
 entries:
 
 0 Achievement
 1 2 3 cWon! st4 5 6 - user input
 
 (create 3 entries all with st4 5 6)
 
 0 Achievement
 1 house [4, 5, 6]
 2 rock [4, 5, 6]
 3 mouse [4, 5, 6]
 
 cmud - user input
 
 0 Achievement
 1 house [4, 5, 6] mud
 2 rock [4, 5, 6] mud
 3 mouse [4, 5, 6] mud
 
 So add the entries and while they are still hot, you can edit 
 them.
 
 I don't know if this an impossible ask for help, but I though I 
 might get some help. I'll keep going over my code to work it out.
 
 Thanks.

So what is the question?

-- 
Marco



Re: best D equivalent to C'stimeval

2014-03-31 Thread Marco Leise
Am Mon, 31 Mar 2014 05:09:22 +
schrieb ed sillymong...@gmail.com:

 Hi,
 
 Just wondering what the best replacement for C timeval is in D. 
 I'm looking at std.datetime.SysTime, but std.datetime is huge so 
 I'm not sure.
 
 Thanks,
 ed

If you just need to time something, TickDuration from
core.time is an efficient cross-platform timer.

auto t1 = TickDuration.currentSystemTick;
...
auto t2 = TickDuration.currentSystemTick;
writefln(Took %s ms, (t2-t1).msecs);

-- 
Marco



Re: Templates: generic return null;

2014-02-06 Thread Marco Leise
Am Mon, 03 Feb 2014 10:25:17 +
schrieb Chris wend...@tcd.ie:

 MyStruct(T) {
T[T] attributes;
// 
public auto getAttribute(T attr) {
if (!(attr in attributes)) {
  return null; // Doesn't work for numbers!
}
return attributes[attr];
  }
 }
 
 void main() {
auto myStr = MyStruct!int(0); // Error
 }

MyStruct(T) {
   T[T] attributes;
   // 
   public auto getAttribute(T attr) {
   return attr in attributes;
 }
}

There you go.

-- 
Marco



Re: 3d vector struct

2014-02-06 Thread Marco Leise
Am Mon, 03 Feb 2014 22:01:14 +
schrieb Stanislav Blinov stanislav.bli...@gmail.com:

 Return-by-value being optimized as a move might be one more 
 reason why you would like to use slices instead of variables to 
 store coordinates (since that would mean just moving a pointer 
 and a size_t), but that might have to wait until custom 
 allocators finally arrive.

3 doubles is only one machine word more than an array slice
and there are no indirections, allocations and length
attribute to deal with (which is always 3 here).

-- 
Marco



Re: Performant method for reading huge text files

2014-02-06 Thread Marco Leise
Am Tue, 04 Feb 2014 00:04:22 +
schrieb Rene Zwanenburg renezwanenb...@gmail.com:

 On Monday, 3 February 2014 at 23:50:54 UTC, bearophile wrote:
  Rene Zwanenburg:
 
  The problem is speed. I'm using LockingTextReader in 
  std.stdio, but it't not nearly fast enough. On my system it 
  only reads about 3 MB/s with one core spending all it's time 
  in IO calls.
 
  Are you reading the text by lines? In Bugzilla there is a 
  byLineFast:
  https://d.puremagic.com/issues/show_bug.cgi?id=11810
 
  Bye,
  bearophile
 
 Nope, I'm feeding it to csvReader which uses an input range of 
 characters. Come to think of it..
 
 Well this is embarassing, I've been sloppy with my profiling :). 
 It appears the time is actually spent converting strings to 
 doubles, done by csvReader to read a row into my Record struct. 
 No way to speed that up I suppose. Still I find it surprising 
 that parsing doubles is so slow.

Parsing textual representations of numbers is slow. The other
way around is faster. You have to check all kinds of stuff,
like preceding +/-, starts with a dot, are all characters '0'
to '9', is there an exponent? Is it NaN or nan?
Floating point math is slow, but when you store the
intermediate results while parsing inside an integer, you may
run out of digits if the number string is long. On the other
hand repeated floating point math will introduce some error
as you append digits.

Here is the ~400 lines version in Phobos:
https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L2250

-- 
Marco



Re: How to destroy a shared struct.

2014-01-28 Thread Marco Leise
Am Sun, 26 Jan 2014 21:36:58 +
schrieb Benjamin Thaut c...@benjamin-thaut.de:

 On Sunday, 26 January 2014 at 17:15:10 UTC, Marco Leise wrote:
  Since shared hasn't change much in the last years, I assume it
  is somewhat accepted in its current state. My understanding is
  that if something cannot be attributed to a single thread, it
  is shared. So far so good.
  Now I wrote an object pool struct with two properties: it can
  be used by multiple threads during its lifetime and this(this)
  is disabled. Logically the struct is both created and
  destroyed while only the creator thread (which holds the data)
  has access to it and there is no two ways about it. An
  object can only be destroyed when it is no longer shared.
 
  Yet the D compiler asks for a shared ~this(). This sounds as
  if it asks me to commit a logical error. So the question is,
  how do I define a shared struct without a shared ~this() which
  would be broken by definition?
 
 I ran into this issue some time ago too.
 https://d.puremagic.com/issues/show_bug.cgi?id=8295
 Walter stated in a discussion on the newsgroup that this is by
 design. It basically came down to, that shared structs should not
 be destroyed ...
 Although I really don't agree with this, it should be fixed. In
 my opinion it should not be neccessary to have a shared
 destructor, because as soon as it is destroyed, it is no longer
 shared. So no special shared destructor should be neccessary.

*nod*
But you must have misunderstood Walter. Keeping shared structs
alive forever certainly doesn't work. :p

-- 
Marco



How to destroy a shared struct.

2014-01-26 Thread Marco Leise
Since shared hasn't change much in the last years, I assume it
is somewhat accepted in its current state. My understanding is
that if something cannot be attributed to a single thread, it
is shared. So far so good.
Now I wrote an object pool struct with two properties: it can
be used by multiple threads during its lifetime and this(this)
is disabled. Logically the struct is both created and
destroyed while only the creator thread (which holds the data)
has access to it and there is no two ways about it. An
object can only be destroyed when it is no longer shared.

Yet the D compiler asks for a shared ~this(). This sounds as
if it asks me to commit a logical error. So the question is,
how do I define a shared struct without a shared ~this() which
would be broken by definition?

-- 
Marco



extern(C) function literals for stubs

2014-01-22 Thread Marco Leise
Can I define them somehow? The use case is defining extern C
functions that contain code to load the real thing from a
library.

  nothrow extern(C) void function(int) someFunc = ???

-- 
Marco



Re: extern(C) function literals for stubs

2014-01-22 Thread Marco Leise
Am Wed, 22 Jan 2014 17:52:03 +
schrieb bearophile bearophileh...@lycos.com:

 Marco Leise:
 
  Can I define them somehow? The use case is defining extern C
  functions that contain code to load the real thing from a
  library.
 
nothrow extern(C) void function(int) someFunc = ???
 
 Perhaps you want:
 
 extern(C) nothrow void someFunc(int someArg);
 
 Bye,
 bearophile

Thanks, but I want it to be a function pointer so I can swap
it from within the function literal in the fashion of 

  nothrow extern(C) void function(int) someFunc = (int arg) {
  someFunc = GetProcAddress(someFunc);
  someFunc(arg);
  }

-- 
Marco



Re: extern(C) function literals for stubs

2014-01-22 Thread Marco Leise
Am Wed, 22 Jan 2014 17:52:03 +
schrieb bearophile bearophileh...@lycos.com:

 Marco Leise:
 
  Can I define them somehow? The use case is defining extern C
  functions that contain code to load the real thing from a
  library.
 
nothrow extern(C) void function(int) someFunc = ???
 
 Perhaps you want:
 
 extern(C) nothrow void someFunc(int someArg);
 
 Bye,
 bearophile

Got it now. By declaring the literal stub function in a
template instead I can use the normal function declaration
syntax without introducing a new symbol at the definition site:

{
  ...
  nothrow extern(C) void function(int) someFunc = Stub!someFunc;
  ...
}

nothrow extern(C) auto Stub(alias func)(ParameterTypeTuple!func args)
{
debug printf(Loading %s...\n, func.stringof.ptr);
return (func = impl)(args);
}


-- 
Marco



Re: How do I choose the correct primative?

2014-01-01 Thread Marco Leise
C compilers like D compilers will pack a struct of two 16-bit
words into a 32-bit type if you don't force an alignment:
http://dlang.org/attribute.html#align
What you should avoid is having a data type start at an
address that is not a multiple of its size, especially when it
comes to SIMD.
Working with 16-bit values is not really supported in todays
x86 CPUs though, and integer math in D typically yields ints
even when you use smaller data types, reflecting what happens
on the hardware. Usually I use uint, size_t, real for things
that will go to CPU registers and the smallest data type that
will work for storage in memory.
Keep in mind that RAM access is slow compared to how fast CPUs
run. It can be beneficial to have slower data types if they
allow more data to fit into the CPU cache.

Typically you sort the fields of a struct by size with the
larger ones (e.g. pointers) at the top followed by ints,
shorts and finally bytes if you want to conserve memory. There
is even a template to do that for you, but I think it is more
of a toy, when you can easily do that manually without the
clutter:
http://dlang.org/phobos/std_typecons.html#.alignForSize



Re: Converting char to int

2014-01-01 Thread Marco Leise
Am Wed, 01 Jan 2014 07:27:54 +
schrieb Meta jared...@gmail.com:

 Your code is working correctly. D's chars, for all values up to 
 255, are the same as the ASCII character set.

UTF-8 reuses the ASCII mapping which is only defined from 0 to
127. Everything above is not ASCII and 255 is in fact not even
defined for UTF-8, which is why it was chosen as the
initializer for char in D.

-- 
Marco



Re: Custom binary operators

2013-12-29 Thread Marco Leise
Am Sat, 28 Dec 2013 15:24:31 +
schrieb Dicebot pub...@dicebot.lv:

 AFAIK it is intentionally banned to constrain operator 
 overloading abuse.

That and it makes the compiler faster.

-- 
Marco



Re: Reading file by line, weird result

2013-12-27 Thread Marco Leise
Am Fri, 27 Dec 2013 10:24:15 +
schrieb Dfr defle...@yandex.ru:

 On Friday, 27 December 2013 at 09:44:22 UTC, lomereiter wrote:
  The solution is to append `line.dup` instead of `line`.
 
  I guess this note in the documentation should be marked red:
  Each front will not persist after popFront is called, so the 
  caller must copy its contents (e.g. by calling to!string) if 
  retention is needed.
 
 Thank you, .dup helped.

To avoid allocating new memory for each line of text, byLine
reuses the buffer. You are supposed to make a duplicate if you
plan to keep it. It would be different if you had:

  string s;
  foreach (line; frange) {
  s ~= line
  }

in which case, the _contents_ of the line buffer, not the buffer
itself are appended to the string s.

-- 
Marco



Re: Which Libraries?

2013-12-27 Thread Marco Leise
Am Fri, 27 Dec 2013 07:00:29 +
schrieb Rikki Cattermole alphaglosi...@gmail.com:

 On Friday, 27 December 2013 at 05:00:30 UTC, Josh Phillips wrote:
  I was wondering if people could suggest which libraries may be
  best to use for building an application which would be a type of
  text editor with multiple documents and branches. I need
  something whereby I can create simple, custom windows and do
  simple text editing, but then i need it to also handle much more
  complicated graphics in a 3D viewport looking at lots of
  branching documents. I'm not quite sure if something like GtkD 
  or
  QtD can handle the more complicated graphics or not, or if it is
  possible to build it with windows, or perhaps trying to make a
  text editor with opengl. I've been looking into different ideas
  and thought i'd try and ask for some advice.
 
 GtkD and QtD are both bindings to my knowledge so they should 
 have the same power as the library itself.
 If you choose to go the route of making a gui lib yourself. Would 
 you be kind enough to look at mine (DOOGLE[1]). I could use some 
 help if you want to go that way.
 
 There is also DQuick and DWT.
 
 [1] https://github.com/rikkimax/DOOGLE/wiki/Roadmap

GtkD has OpenGL support

-- 
Marco



Re: Range of n lines from stdin

2013-12-27 Thread Marco Leise
Am Fri, 27 Dec 2013 14:26:59 +
schrieb Ivan Kazmenko ga...@mail.ru:

 Quick question.
 
 (1) I can do
 n.iota.map!(_ = readln)
 to get the next n lines from stdin.
 
 (2) However, when I do
 readln.repeat(n)
 it looks clearer but works differently: preserves front and reads 
 only one line.
 
 (3) In the particular case of readln, we can substitute it with
 stdin.byLine.take(n)
 but the question remains for other impure functions.
 
 So, what I ask for is some non-caching repeat for functions with 
 side effects.  More idiomatic than (1).  Is there something like 
 that in Phobos?  Is it an OK style to have an impure function in 
 an UFCS chain?
 
 If repeat could know whether its first argument is pure, it could 
 then enable or disable front caching depending on purity... no 
 way currently?

repeat() is only meant to repeat the same first element over
and over. I think it would be wrong if it changed its value
during iteration. A wrapper struct could be more ideomatic:

  FuncRange!readln.take(n)

 Ivan Kazmenko.

-- 
Marco



Re: getting __DIR__ and __TIME__ of compilation?

2013-12-27 Thread Marco Leise
Am Fri, 27 Dec 2013 12:43:15 +
schrieb Ravn ravnd...@gmail.com:

 On Friday, 27 December 2013 at 11:56:08 UTC, Ali Çehreli wrote:
  However, __FILE__ happens to be the current source file that is 
  being compiled but I think the OP wants the current compilation 
  directory. Being a C library file, getcwd() does not work at 
  compile time:
 
  import std.stdio;
 
  void main()
  {
  import std.path: dirName;
 
  enum compiledFile = __FILE__;
  writeln(compiledFile);
 
  static const compileTime = __DATE__ ~   ~ __TIME__;
  writeln(compileTime);
 
  /*
  import std.file: getcwd;
  static const compilationDir = getcwd();
  writeln(compilationDir);
 
  Error: getcwd cannot be interpreted at compile time, 
  because it has no available source code
  */
  }
 
  Ali
 
 Yes, just like what Ali said above,
 
 __FILE__, __DATE__ and __TIME__ do work for their respective 
 usages,
 but I'm also looking for a way to get the current compilation 
 directory during compile time, and getcwd() doesn't seem to be 
 working.
 
 Isn't there something like __DIR__ or __PATH__ that I can use to 
 get that information?
 
 -Ravn-

No, but if you just want the path where your sources are you
could use __FILE__ for any module and cut off the part of
it that belongs to the module path. A lot of Phobos works at
compile time, so you might be able to write a one-liner for
that.

-- 
Marco



Re: imports and a data structure (any critique welcome)

2013-12-27 Thread Marco Leise
Am Fri, 27 Dec 2013 13:45:10 +
schrieb bearophile bearophileh...@lycos.com:

 Timon Gehr:
 
  mixin ADT!q{ Term: Var char | Op char Term[] };
 
  void main(){
  const expr = Op('f', [Op('g',[Var('x'), Var('y')]), 
  Op('a',[]), Var('x')]);
  }
 
 Where is ADT defined? (And why isn't it a Phobos patch on GitHub?)
 
 
  convertNum could be written more compactly as:
  char convertNum(int x){
  return exyzfgh[x$?x:0];
 
 That's too much compact :-) Humans put a space around operators, 
 and sometimes some parentheses don't hurt:
 
 char convertNum(in int x) pure nothrow
 in {
  assert(x = 0);
 } body {
  return exyzfgh[(x  $) ? x : 0];
 }
 
 Bye,
 bearophile

Before you go _that_ far, just write:

  char convertNum(in size_t x) pure nothrow
  {
  return exyzfgh[(x  $) ? x : 0];
  }

:-)

-- 
Marco



Re: getting __DIR__ and __TIME__ of compilation?

2013-12-27 Thread Marco Leise
Am Fri, 27 Dec 2013 20:14:00 +
schrieb Ravn ravnd...@gmail.com:

 Tried enum path = dirName(__FILE__), compiles normally, no error 
 from the compiler, but it still returns a relative path instead 
 of a fullpath in my machine.

Too bad :-/
I hoped it would use absolute paths.

-- 
Marco



Re: Range of n lines from stdin

2013-12-27 Thread Marco Leise
Am Fri, 27 Dec 2013 20:34:02 +
schrieb Ivan Kazmenko ga...@mail.ru:

 Maybe the imperative should be repeat is a function, and 
 arguments of functions should be evaluated only once?  It does 
 make sense from a language point of view, but somewhat breaks the 
 abstraction for me.

The documentation is clear about it:

Repeats one value forever.

It has nothing to do with purity, whether the input range is
lazy or the element is fetched eagerly. If it was meant to do
what you expected it would read:

Constructs a range from lazily evaluating the expression
passed to it over and over.

This is not a limitation of the language either I think, since
arguments to functions can be declared lazy.

-- 
Marco



Re: Ultra-pure map()?

2013-12-27 Thread Marco Leise
Am Sat, 28 Dec 2013 01:54:26 +
schrieb John Colvin john.loughran.col...@gmail.com:

 On Saturday, 28 December 2013 at 01:41:35 UTC, David Held wrote:
  import std.algorithm;
  import std.stdio;
  import std.conv;
 
  class Trivial
  {
  int sideEffect() { return n++; }
  override string toString() pure { return to!string(n); }
  int n;
  }
 
  void main()
  {
  Trivial[] objs = [ new Trivial ];
  map!(o = o.sideEffect())(objs);
  writeln(objs);  // [0]
  foreach (o; objs) o.sideEffect();
  writeln(objs);  // [1]
  }
 
  Can someone explain to me why map() is not equivalent to 
  foreach in the code above?  From what I can tell, map() doesn't 
  do anything at all on objs, even though it is a perfectly 
  legitimate range (as far as I can tell).
 
  Dave
 
 Map is lazy and is never iterated over in your code, therefore no 
 side effects.

Yeah, this is kind of unintended usage. Typically with map you
take some input range, apply some algorithm to each element,
and return a range of the results.

Side effects and altering the input object itself makes me
want to pull out my crucifix. You shall not have impurity in
your functional style code!

-- 
Marco



Re: how to detect OS architecture?

2013-12-19 Thread Marco Leise
Am Wed, 18 Dec 2013 13:19:09 -
schrieb Regan Heath re...@netmail.co.nz:

 On Tue, 17 Dec 2013 15:13:20 -, Marco Leise marco.le...@gmx.de wrote:
 
  Am Tue, 17 Dec 2013 13:30:25 -
  schrieb Regan Heath re...@netmail.co.nz:
 
  On Mon, 16 Dec 2013 21:27:13 -, Hugo Florentino h...@acdam.cu  
  wrote:
 
   On Mon, 16 Dec 2013 20:23:00 +0100, Jacob Carlborg wrote:
   On 2013-12-16 17:46, Marco Leise wrote:
  
   Hehe, I guess the whole purpose of the launcher is to run in
   32-bit and detect at runtime if the 64-bit main executable can
   be run or the 32-bit version must be used.
  
   The only advantage of that is that only a 32bit launcher needs to be
   distributed. Perhaps that's the whole idea.
  
   It is. :)
 
  Process Explorer by sysinternals, now distributed by M$ does something
  similar.
  http://technet.microsoft.com/en-gb/sysinternals/bb896653.aspx
 
  It is a 32 bit exe, which detects the OS bit width and if it's 64 bit
  extracts a 64 exe from within itself to run.  When you quit that 64 bit
  exe, it deletes the file it extracted from disk.  It's quite a neat
  solution.
 
  R
 
 
  Only if your executable is self-contained. If you already have
  external DLLs or assets you can as well have a launcher and 2
  actual binaries.
 
 I don't see why that changes things?  Sure, you cannot extract your  
 *static* dependent dlls (those linked at compile time with libs), those  
 have to exist before you can execute your 32 bit launcher.  But, if you  
 really wanted to, you could extract and runtime load dlls no problem.
 
 R

That's my point. If you really wanted, you could do that but
you can as well have a launcher and 2 application binaries and
avoid this repeated file extraction/deletion and save
yourself some troubles at the end of the day.

-- 
Marco



Re: Unique IDs for each template instantiation at compile-time?

2013-12-19 Thread Marco Leise
Am Thu, 19 Dec 2013 00:01:03 +0100
schrieb Weasel weasel...@gmail.com:

 I was wondering if it was possible to generate unique(in order) 
 IDs for each template instantiation of a class at compile-time.
 
 A short example of what I'm trying to do:
 
 static int counter = 0;
 class A(T)
 {
  enum id = counter++;
 }
 class B : A!B
 {
 }
 
 Ofcourse, this doesn't compile because the counter variable 
 can't be read at compile-time.

Something like that cannot work. Imagine your template is in
a.d and you instantiate it in b.d and c.d. Now you compile:

  dmd -c b.d
  dmd -c c.d

Both times the counter imported from a.d would start at 0.

-- 
Marco



Re: Embed Windows Internet Explorer

2013-12-19 Thread Marco Leise
Am Wed, 18 Dec 2013 21:48:30 +0100
schrieb Andre an...@s-e-a-p.de:

 Am 16.12.2013 19:44, schrieb Andre:
  Hi,
 
  I try to embed Windows Internet Explorer into my application.
  Most of the coding should be availabe. During method navigate2
  I get an empty white screen. No errors is thrown but also the
  web page is not loaded. Do you have some ideas?
 
  = Is use the windows headers from DSource and the dgui forms library.
  I attached the source code.
 
  Kind regards
  André
 
 The issue was related to SysAllocString:
 
 VARIANT myURL;
 VariantInit(myURL);
 myURL.vt = cast(VARTYPE)VARENUM.VT_BSTR;
 = myURL.bstrVal = SysAllocString(cast(const(wchar*))url);
 webBrowser2.Navigate2( myURL, null, null, null, null);
 
 It only works with statement:
 myURL.bstrVal = cast(wchar*)http://www.google.de;;

Did you mean this?:
  myURL.bstrVal = http://www.google.dew.ptr;


-- 
Marco



Re: Embed Windows Internet Explorer

2013-12-19 Thread Marco Leise
Am Thu, 19 Dec 2013 17:36:57 +
schrieb Richard Webb richard.w...@boldonjames.com:

 On 18/12/2013 20:48, Andre wrote:
   = myURL.bstrVal = SysAllocString(cast(const(wchar*))url);
 
 
 Looks like the problem there is casting a string to a wchar* - I guess 
 the resulting BSTR will contain garbage instead of the intended value.
 
 
  
   It only works with statement:
   myURL.bstrVal = cast(wchar*)http://www.google.de;;
  
 
 
 Treating a wchar* as a BSTR might cause unexpected things to happen - 
 converting the string to a wchar* and then passing that to 
 SysAllocString would be safer.

Oh yes, you are right and I was totally ignorant of what a
BSTR is! It is a data structure for strings consisting of size
prefix for the character data (4 bytes), the character data as
wchars and a terminating zero wchar.

So your first approach was correct:

  string url = …;
  BSTR* bstrUrl = enforce(SysAllocString(toUTFz!(const(wchar)*)(url)),
  Out of memory or url is null);
  myURL.bstrVal = bstrUrl;

  …

  SysFreeString(bstrUrl);

-- 
Marco



Re: how to detect OS architecture?

2013-12-17 Thread Marco Leise
Am Tue, 17 Dec 2013 13:30:25 -
schrieb Regan Heath re...@netmail.co.nz:

 On Mon, 16 Dec 2013 21:27:13 -, Hugo Florentino h...@acdam.cu wrote:
 
  On Mon, 16 Dec 2013 20:23:00 +0100, Jacob Carlborg wrote:
  On 2013-12-16 17:46, Marco Leise wrote:
 
  Hehe, I guess the whole purpose of the launcher is to run in
  32-bit and detect at runtime if the 64-bit main executable can
  be run or the 32-bit version must be used.
 
  The only advantage of that is that only a 32bit launcher needs to be
  distributed. Perhaps that's the whole idea.
 
  It is. :)
 
 Process Explorer by sysinternals, now distributed by M$ does something  
 similar.
 http://technet.microsoft.com/en-gb/sysinternals/bb896653.aspx
 
 It is a 32 bit exe, which detects the OS bit width and if it's 64 bit  
 extracts a 64 exe from within itself to run.  When you quit that 64 bit  
 exe, it deletes the file it extracted from disk.  It's quite a neat  
 solution.
 
 R
 

Only if your executable is self-contained. If you already have
external DLLs or assets you can as well have a launcher and 2
actual binaries.

-- 
Marco



  1   2   3   >