Re: What is a concise way to test if floating point value is integral?

2013-08-28 Thread Paul Jurczak
On Thursday, 29 August 2013 at 06:23:18 UTC, Jonathan M Davis 
wrote:

On Thursday, August 29, 2013 07:47:16 Paul Jurczak wrote:

I'm writing this rather ugly:

sqrt(cast(float)D) != round(sqrt(cast(float)D)

line and I'm looking for more concise notation without
introducing a meaningless variable to hold expression being
tested. Is there an equivalent of std.math.trunc(), which would
return fractional portion instead, maybe frac()?


There may be something in std.math which makes it cleaner, but 
I would have
thought that the to test whether a floating point value is an 
integral value,
you'd just cast it to an integral type and then compare that 
against the

original. e.g.

auto isIntegral = cast(int)my_float == my_float;

- Jonathan M Davis


Isn't type conversion:

auto isIntegral = to!int(my_float) == my_float;

more recommended/idiomatic D way to deal with built-in types?


Re: UFCS in template function

2013-08-28 Thread Jacob Carlborg

On 2013-08-28 23:28, ixid wrote:

UFCS does not work in this template where the normal function call
syntax will work:

template test(alias fun) {
 auto test(T)(T n) {
 return n.fun;
 }
}

Is this the same as the inability to use UFCS with functions declared in
the same scope as the call? Is there no way to address this issue
without messing with calling class members (that is what I understand to
be the reason for the limitation on UFCS, I may have misunderstood). It
also prevents the use of function literals in UFCS chains which seems
like a great pity and the loss of what should be a very natural part of
the language.


UFCS only works for module level functions.

--
/Jacob Carlborg


Re: Question about garbage collector

2013-08-28 Thread Jacob Carlborg

On 2013-08-28 23:28, bioinfornatics wrote:

Hi everyone,

yesterday i read an article into a french linux journal that in some
years garbage collector will disapear.

Why ? he explain in very very short as:
--
- Moore's law will be not anymore true
so only memory will continue to increase ( static and volatil )
- Garbage Collector are not efficient in big memory for some technical
reason
- Data to manage will continue to grow big data ant full memory stategy
will the rule

So Develloper will move to a language where they are no garbage collector.
--

In bioinformatic we work with big data or full memory stategy often and
that will not stop. So what think D garbage cllector's dev about this ?


There has been some discussion about implementing ARC (Automatic 
Reference Counting) in the compiler.


--
/Jacob Carlborg


Re: What is a concise way to test if floating point value is integral?

2013-08-28 Thread Jonathan M Davis
On Thursday, August 29, 2013 07:47:16 Paul Jurczak wrote:
> I'm writing this rather ugly:
> 
> sqrt(cast(float)D) != round(sqrt(cast(float)D)
> 
> line and I'm looking for more concise notation without
> introducing a meaningless variable to hold expression being
> tested. Is there an equivalent of std.math.trunc(), which would
> return fractional portion instead, maybe frac()?

There may be something in std.math which makes it cleaner, but I would have 
thought that the to test whether a floating point value is an integral value, 
you'd just cast it to an integral type and then compare that against the 
original. e.g.

auto isIntegral = cast(int)my_float == my_float;

- Jonathan M Davis


Re: What is a concise way to test if floating point value is integral?

2013-08-28 Thread Paul Jurczak

On Thursday, 29 August 2013 at 05:47:43 UTC, Paul Jurczak wrote:

I'm writing this rather ugly:

sqrt(cast(float)D) != round(sqrt(cast(float)D)

line and I'm looking for more concise notation without 
introducing a meaningless variable to hold expression being 
tested. Is there an equivalent of std.math.trunc(), which would 
return fractional portion instead, maybe frac()?


I defined a helper function:

bool isIntegral(T)(T x) {return x == round(x);}

but is there something in D libraries to give me this 
functionality?


What is a concise way to test if floating point value is integral?

2013-08-28 Thread Paul Jurczak

I'm writing this rather ugly:

sqrt(cast(float)D) != round(sqrt(cast(float)D)

line and I'm looking for more concise notation without 
introducing a meaningless variable to hold expression being 
tested. Is there an equivalent of std.math.trunc(), which would 
return fractional portion instead, maybe frac()?


Re: dmd memory usage/static lib/algorithm bug?

2013-08-28 Thread Marek Janukowicz
H. S. Teoh wrote:

> On Thu, Aug 29, 2013 at 12:45:05AM +0200, Marek Janukowicz wrote:
>> H. S. Teoh wrote:
> [...]
>> > Oh, and BTW, are you on Linux 32-bit or 64-bit? Don't know if that
>> > makes a difference, but just in case.
>> 
>> 64-bit
> [...]
> 
> Maybe try compiling with -m32 and see if it makes a difference? If so,
> it may be a 64-bit related dmd bug. I'm also having trouble building a
> working compiler toolchain with a purely 64-bit environment.

Yeah, it makes a difference :)

./main(_D4core7runtime18runModuleUnitTestsUZb19unittestSegvHandlerUiPS4core3sys5posix6signal9siginfo_tPvZv+0x2c)
[0x80a8c64]
linux-gate.so.1(__kernel_rt_sigreturn+0x0)[0xe410]
./main(_D6sorter14__unittestL9_3FZv101__T13quickSortImplS65_D6sorter14__unittestL9_3FZv2dgPFNaNbNfS6sorter3ValS6sorter3ValZbTAS6sorter3ValZ13quickSortImplMFAS6sorter3ValZv+0x1a7)
[0x80a1b53]
./main(_D6sorter14__unittestL9_3FZv122__T4sortS65_D6sorter14__unittestL9_3FZv2dgPFNaNbNfS6sorter3ValS6sorter3ValZbVE3std9algorithm12SwapStrategy0TAS6sorter3ValZ4sortMFAS6sorter3ValZS6sorter14__unittestL9_3FZv99__T11SortedRangeTAS6sorter3ValS65_D6sorter14__unittestL9_3FZv2dgPFNaNbNfS6sorter3ValS6sorter3ValZbZ11SortedRange+0x17)
[0x80a20cb]
./main(_D6sorter14__unittestL9_3FZv+0x6d)[0x80a2079]
./main(_D6sorter9__modtestFZv+0x8)[0x80a21ac]
./main(_D4core7runtime18runModuleUnitTestsUZb16__foreachbody352MFKPS6object10ModuleInfoZi+0x24)
[0x80a8ccc]
./main(_D2rt5minfo17moduleinfos_applyFMDFKPS6object10ModuleInfoZiZi16__foreachbody541MFKS2rt14sections_linux3DSOZi+0x37)
[0x80a5f47]
./main(_D2rt14sections_linux3DSO7opApplyFMDFKS2rt14sections_linux3DSOZiZi+0x2c)
[0x80a619c]
./main(_D2rt5minfo17moduleinfos_applyFMDFKPS6object10ModuleInfoZiZi+0x14)
[0x80a5ef4]
./main(runModuleUnitTests+0x87)[0x80a8bd7]
./main(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi6runAllMFZv+0x25)[0x80a4a55]
./main(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi7tryExecMFMDFZvZv+0x18)
[0x80a46c0]
./main(_d_run_main+0x121)[0x80a4691]
./main(main+0x14)[0x80a4564]
/lib32/libc.so.6(__libc_start_main+0xf3)[0xf74d4943]
Segmentation fault (core dumped)

This stacktrace did not show in 64-bit version, but the problem persists.

-- 
Marek Janukowicz


Re: dmd memory usage/static lib/algorithm bug?

2013-08-28 Thread H. S. Teoh
On Thu, Aug 29, 2013 at 12:45:05AM +0200, Marek Janukowicz wrote:
> H. S. Teoh wrote:
[...]
> > Oh, and BTW, are you on Linux 32-bit or 64-bit? Don't know if that
> > makes a difference, but just in case.
> 
> 64-bit
[...]

Maybe try compiling with -m32 and see if it makes a difference? If so,
it may be a 64-bit related dmd bug. I'm also having trouble building a
working compiler toolchain with a purely 64-bit environment.


T

-- 
Fact is stranger than fiction.


Re: dmd memory usage/static lib/algorithm bug?

2013-08-28 Thread Marek Janukowicz
H. S. Teoh wrote:

> On Wed, Aug 28, 2013 at 11:02:17PM +0200, Marek Janukowicz wrote:
>> I was finally able to create simple test case that probably reproduces
>> the bug (probably, because the stack trace is completely different,
>> but the code that is there is similar). This requires 2 source code
>> files:
> [...]
>> Run with:
>> 
>> dmd -unittest main.d sorter.d && ./main
>> 
>> For me this results in a segfault. Changing one of many seemingly
>> unrelated details (eg. moving offending code directly to main,
>> commenting out std.stdio import in main.d) makes the problem
>> disappear.
>> 
>> Can anyone try to reproduce that? Again, I'm on DMD 2.063.2.
> 
> It doesn't seem to happen on git HEAD. I'm going to try 2.063.2 and see
> what happens.
> 
> Oh, and BTW, are you on Linux 32-bit or 64-bit? Don't know if that makes
> a difference, but just in case.

64-bit


-- 
Marek Janukowicz


Re: dmd memory usage/static lib/algorithm bug?

2013-08-28 Thread H. S. Teoh
On Wed, Aug 28, 2013 at 02:10:34PM -0700, H. S. Teoh wrote:
> On Wed, Aug 28, 2013 at 11:02:17PM +0200, Marek Janukowicz wrote:
> > I was finally able to create simple test case that probably
> > reproduces the bug (probably, because the stack trace is completely
> > different, but the code that is there is similar). This requires 2
> > source code files:
> [...]
> > Run with: 
> > 
> > dmd -unittest main.d sorter.d && ./main
> > 
> > For me this results in a segfault. Changing one of many seemingly
> > unrelated details (eg. moving offending code directly to main,
> > commenting out std.stdio import in main.d) makes the problem
> > disappear.
> > 
> > Can anyone try to reproduce that? Again, I'm on DMD 2.063.2.
> 
> It doesn't seem to happen on git HEAD. I'm going to try 2.063.2 and
> see what happens.
[...]

Update: I've reproduced this problem on 2.063.2, but while trying to
track down the problem, I discovered that building 2.063.2 from source
doesn't produce a working toolchain. :-( I've spent an hour trying to
figure out what's wrong with 2.063.2, but with no success. So, you
*could* be right that something may be wrong with libphobos2.a.

I'll try to download the tarball from dlang.org again and see if that
helps, or if I've messed up my system somehow. :-P


T

-- 
There are two ways to write error-free programs; only the third one works.


Question about garbage collector

2013-08-28 Thread bioinfornatics

Hi everyone,

yesterday i read an article into a french linux journal that in 
some years garbage collector will disapear.


Why ? he explain in very very short as:
--
- Moore's law will be not anymore true
so only memory will continue to increase ( static and volatil )
- Garbage Collector are not efficient in big memory for some 
technical reason
- Data to manage will continue to grow big data ant full memory 
stategy will the rule


So Develloper will move to a language where they are no garbage 
collector.

--

In bioinformatic we work with big data or full memory stategy 
often and that will not stop. So what think D garbage cllector's 
dev about this ?





UFCS in template function

2013-08-28 Thread ixid
UFCS does not work in this template where the normal function 
call syntax will work:


template test(alias fun) {
auto test(T)(T n) {
return n.fun;
}
}

Is this the same as the inability to use UFCS with functions 
declared in the same scope as the call? Is there no way to 
address this issue without messing with calling class members 
(that is what I understand to be the reason for the limitation on 
UFCS, I may have misunderstood). It also prevents the use of 
function literals in UFCS chains which seems like a great pity 
and the loss of what should be a very natural part of the 
language.


Re: Limited Semi-PolyMorphic (LSP) structs?

2013-08-28 Thread Era Scarecrow

On Wednesday, 28 August 2013 at 15:20:34 UTC, Artur Skawina wrote:
It's hard to tell what your actual requirements are; this 
discriminated union might help. It does a bit more than what 
you ask for, as it also gives access to /data/, not just 
methods; this shouldn't be a problem.


 Requirements, I don't have any written down but I have it in my 
head. I want to replace specific functions, I don't want to use a 
vTable (or pointer or anything like that). They are replaced 
based on fixed criteria of what the changed behavior is/needs to 
be.


 I want to use OO and inheritance to split it into logical 
portions (after sorta implementing inheritance/semi-polymorphism 
in pure C functions the code got ugly fast and is difficult to 
navigate through).



The data access parts could be even more efficient, but I 
failed to figure out a way to check for perfectly overlapping 
fields at CT - offsetof doesn't work after an alias-this 
conversion takes place, CTFE does not allow the pointer 
arithmetic required, and when ctfe does, the result can be 
false negatives. Maybe someone else has an idea how to 
correctly implement the 'atSameOff' function below (which would 
make accesses to compatible data members free; right now the 
type check is never omitted. It could also be done using manual 
annotations, but those shouldn't be necessary...)


 It looks like I'll have to read this in more detail when I can 
wrap my head around it. I'll give it a look.


Re: dmd memory usage/static lib/algorithm bug?

2013-08-28 Thread H. S. Teoh
On Wed, Aug 28, 2013 at 11:02:17PM +0200, Marek Janukowicz wrote:
> I was finally able to create simple test case that probably reproduces
> the bug (probably, because the stack trace is completely different,
> but the code that is there is similar). This requires 2 source code
> files:
[...]
> Run with: 
> 
> dmd -unittest main.d sorter.d && ./main
> 
> For me this results in a segfault. Changing one of many seemingly
> unrelated details (eg. moving offending code directly to main,
> commenting out std.stdio import in main.d) makes the problem
> disappear.
> 
> Can anyone try to reproduce that? Again, I'm on DMD 2.063.2.

It doesn't seem to happen on git HEAD. I'm going to try 2.063.2 and see
what happens.

Oh, and BTW, are you on Linux 32-bit or 64-bit? Don't know if that makes
a difference, but just in case.


> H. S. Teoh - thanks for your detailed description, but this test case
> probably sheds some more light and invalidates some of your
> hyphotheses. As for building static library - I thought it would be
> easier, so if the bug remains unresolved I'll probably just rebuild
> the whole phobos. The problem is definitely not some old version of
> libphobos2.a stuck around, because the problem could be reproduced
> exactly the same way on 3 machines I tried.
[...]

I'll give it a try on 2.063.2 to see if I can reproduce the problem.


T

-- 
Ruby is essentially Perl minus Wall.


Re: dmd memory usage/static lib/algorithm bug?

2013-08-28 Thread Marek Janukowicz
I was finally able to create simple test case that probably reproduces the 
bug (probably, because the stack trace is completely different, but the code 
that is there is similar). This requires 2 source code files:

main.d:

module main;

// This line must be there - import any module from std causes is necessary 
to
// reproduce the bug
import std.stdio;

import sorter;

void main () {
} 

---

sorter.d:

module sorter;

import std.algorithm;

  struct Val {
int i;
  }

unittest {
  Val [] arr;
  arr ~= Val( 2 );
  arr ~= Val( 1 );

  // This works
  arr.sort!((Val a, Val b) { return a.i < b.i; });

  // This segfaults when sorting
  auto dg = (Val a, Val b) { return a.i < b.i; };
  arr.sort!(dg);

}

--

Run with: 

dmd -unittest main.d sorter.d && ./main

For me this results in a segfault. Changing one of many seemingly unrelated 
details (eg. moving offending code directly to main, commenting out 
std.stdio import in main.d) makes the problem disappear.

Can anyone try to reproduce that? Again, I'm on DMD 2.063.2.

H. S. Teoh - thanks for your detailed description, but this test case 
probably sheds some more light and invalidates some of your hyphotheses. As 
for building static library - I thought it would be easier, so if the bug 
remains unresolved I'll probably just rebuild the whole phobos. The problem 
is definitely not some old version of libphobos2.a stuck around, because the 
problem could be reproduced exactly the same way on 3 machines I tried.

-- 
Marek Janukowicz


Re: repeating random number sequences.

2013-08-28 Thread H. S. Teoh
On Wed, Aug 28, 2013 at 06:18:01PM +0200, Jesse Phillips wrote:
> On Tuesday, 27 August 2013 at 12:59:19 UTC, Jason den Dulk wrote:
> >Hi
> >
> >This code
> >
> >  foreach (j; 0..5)
> >writeln(rndGen().take(5));
> >  writeln(uniform(0, 1024));
> >  foreach (j; 0..5)
> >writeln(rndGen().take(5));
> 
> What monarch said, though std.range.refRange() may be of interest:
> 
> http://dlang.org/phobos/std_range.html#.refRange

That currently doesn't work too well if you use any RNG members other
than the standard range API, due to:

http://d.puremagic.com/issues/show_bug.cgi?id=10888


T

-- 
Ignorance is bliss... until you suffer the consequences!


Re: dmd memory usage/static lib/algorithm bug?

2013-08-28 Thread H. S. Teoh
On Wed, Aug 28, 2013 at 05:29:40PM +0200, Marek Janukowicz wrote:
> This is really a cross-domain issue, but I didn't feel like splitting
> it into separate posts would make sense.
> 
> I use DMD 2.063.2 on Linux 64-bit.
> 
> I have some code in my (non-trivial) application that basically
> corresponds to this:
> 
> import std.stdio, std.algorithm, std.array;
> 
> void main () {
>   struct Val {
> int i;
>   }
>   Val[] arr;
>   arr ~= Val( 3 );
>   arr ~= Val( 1 );
>   arr ~= Val( 2 );
>   auto sorter = (Val a, Val b) { return a.i < b.i; };
>   writefln( "sorted: %s", arr.sort!(sorter));
> }
> 
> While this simple example works, I'm getting segfaults with
> corresponding code in thisi bigger project. Those segfaults can be
> traced down to algorithm.d line 8315 or another line (8358?) that use
> this "sorter" lambda I passed to "sort!" - suggesting it is a bad
> memory reference.

Possible causes that I can think of are:

1) You have a struct somewhere and your lambda closes over it (or one of
its members), but later on you return this struct to another scope and
invoke the lambda. But since structs can get moved around when passed
between different functions, the lambda's context pointer is invalid and
so it crashes. On simple programs this problem may be hidden because you
don't use the stack as much, so the old copy of the struct may still be
intact even though that part of the stack is technically no longer
valid, so the lambda may still *appear* to work.

2) There is a compiler bug that generates wrong code for a lambda.
There have been some such bugs before where it fails to recognize a
lambda, or fails to notice that a local variable is closed over, so it
doesn't move the local variable to the heap but leaves it on the stack,
where it gets invalidated afterwards, causing the lambda to crash.


> I tried to create a simple test case that would fail similarly, but to
> no avail. I can't make the code for my whole project available, so
> let's just say it's either some bug in DMD or something caused by my
> limited knowledge of D.

If you have a reliable way of reproducing the problem and can
encapsulate it into a shell script / batch file, you can use Vladimir
Panteleev's DustMite to automatically reduce your code to the minimum
for reproducing the bug. See:

https://github.com/D-Programming-Language/tools/tree/master/DustMite


> Now the funny things begin: I copied algorithm.d to my project in an
> attempt to make some modifications to it (hopefully to fix the problem
> or at least get some insight into its nature), but things miraculously
> started working!  This leads me to the suspicion there is something
> wrong with libphobos2.a file provided with DMD tarball.

This is another possibility. :)  Did you check whether DMD is linking
the correct version of libphobos2.a into your program? Sometimes strange
things can happen when you have stale copies of older versions of
libphobos2.a lying around your system, and DMD accidentally picks those
up instead of the correct version.

But it could also be, that this is merely masking the problem. Invalid
pointers are notorious for causing heisenbugs that appear/disappear when
you move unrelated code around.


> Next problem in the line is that compilation of my project with
> algorithm.d included takes almost 4GB of RAM. While I'm aware of the
> fact DMD deliberately doesn't free the memory for performance
> purposes, this makes the compilation fail due to insufficient memory
> on machines with 4GB RAM (and some taken).

You could try splitting it up. :) Well, we're planning to split it up at
some point, now that DMD supports package.d. Here's roughly how you
might do it:

- Temporarily rename std/algorithm.d into another file.
- Create a directory called std/algorithm/
- Create the file std/algorithm/package.d containing something like this:

module std.algorithm;
public import std.algorithm.search;
public import std.algorithm.sort;
public import std.algorithm.set;
public import std.algorithm.mutation;
...

- Split up algorithm.d into the above parts (std/algorithm/search.d,
  std/algorithm/sort.d, ... etc.). You probably don't really need to
  follow exactly the above division; any partitioning of std.algorithm
  into mutually-independent parts will do. Probably splitting into just
  two parts will to cut down memory usage enough to make it compilable
  on your system.

Or, if this is too much work for your purposes, you could make a copy of
std.algorithm, rename it to my.algorithm, say, update all your imports
accordingly, and then just edit the file and delete the parts you don't
use. For example, if you don't use any of the set functions (merge,
cartesianProduct, etc.), just delete them from the file along with all
their unittests. This should reduce the amount of memory needed to
compile it.


> So my questions are:
> - how can I limit DMD memory usage?

I'll let others answer, since I'm not

Re: repeating random number sequences.

2013-08-28 Thread Jesse Phillips

On Tuesday, 27 August 2013 at 12:59:19 UTC, Jason den Dulk wrote:

Hi

This code

  foreach (j; 0..5)
writeln(rndGen().take(5));
  writeln(uniform(0, 1024));
  foreach (j; 0..5)
writeln(rndGen().take(5));


What monarch said, though std.range.refRange() may be of interest:

http://dlang.org/phobos/std_range.html#.refRange


dmd memory usage/static lib/algorithm bug?

2013-08-28 Thread Marek Janukowicz
This is really a cross-domain issue, but I didn't feel like splitting it 
into separate posts would make sense.

I use DMD 2.063.2 on Linux 64-bit.

I have some code in my (non-trivial) application that basically corresponds 
to this:

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

void main () {
  struct Val {
int i;
  }
  Val[] arr;
  arr ~= Val( 3 );
  arr ~= Val( 1 );
  arr ~= Val( 2 );
  auto sorter = (Val a, Val b) { return a.i < b.i; };
  writefln( "sorted: %s", arr.sort!(sorter));
}

While this simple example works, I'm getting segfaults with corresponding 
code in thisi bigger project. Those segfaults can be traced down to 
algorithm.d line 8315 or another line (8358?) that use this "sorter" lambda 
I passed to "sort!" - suggesting it is a bad memory reference.

I tried to create a simple test case that would fail similarly, but to no 
avail. I can't make the code for my whole project available, so let's just 
say it's either some bug in DMD or something caused by my limited knowledge 
of D.

Now the funny things begin: I copied algorithm.d to my project in an attempt 
to make some modifications to it (hopefully to fix the problem or at least 
get some insight into its nature), but things miraculously started working! 
This leads me to the suspicion there is something wrong with libphobos2.a 
file provided with DMD tarball.

Next problem in the line is that compilation of my project with algorithm.d 
included takes almost 4GB of RAM. While I'm aware of the fact DMD 
deliberately doesn't free the memory for performance purposes, this makes 
the compilation fail due to insufficient memory on machines with 4GB RAM 
(and some taken).

So my questions are:
- how can I limit DMD memory usage?
- how can I include a static library with my project? I can compile 
algorithm.d to a static lib, but how do I include this one explicitly with 
my project while the rest of Phobos should be taken from the stock 
libphobos2.a ?
- any other ideas how to solve my problems on any level?

-- 
Marek Janukowicz


Re: Limited Semi-PolyMorphic (LSP) structs?

2013-08-28 Thread Artur Skawina
On 08/28/13 06:45, Era Scarecrow wrote:
> On Wednesday, 28 August 2013 at 03:45:06 UTC, Andre Artus wrote:
>> Era,
>>
>> I haven't had time to go through your everything you wrote here but are you 
>> looking to create some form of discriminated union (AKA tagged union) using 
>> D structs?
>>
>> Do you have a specific problem you need to solve, or are you just exploring 
>> the language?
> 
>  The tagged union struct does sorta match the basic idea. What i have is a 
> structure that basically is just a single struct, however it's 
> semi-polymorphic. (I guess that's obvious by the subject). What changes is 
> only really behavior and rarely would it actually add more data, so 
> inheriting and OOP fits it fairly well, however since structs can't inherit 
> it becomes an issue. I can either inherit, or i can make the function(s) 
> large and clunky and basically do it as C.
> 
> ie:
> 
> struct AB {
>   char type;
> 
>   void A() {
> if (type == 'A') {
> }
> if (type == 'B') {
> }
>   }
> }
> 
>  Etc. One of the biggest reasons to modify the behavior is for the 
> records/subrecords i'm working on they need to build their identifiers based 
> on what they are. Locations give X,Y, if it's an NPC, their name, if it's a 
> texture the texture name, if it's a Dialog it needs to create a hash and 
> append it to the ID afterwards. These are just a few. If i can inherit all 
> the individual creations shorten to less than 10 lines per, otherwise i have 
> a massive function.

It's hard to tell what your actual requirements are; this discriminated union
might help. It does a bit more than what you ask for, as it also gives access
to /data/, not just methods; this shouldn't be a problem.

The data access parts could be even more efficient, but I failed to figure
out a way to check for perfectly overlapping fields at CT - offsetof doesn't
work after an alias-this conversion takes place, CTFE does not allow the
pointer arithmetic required, and when ctfe does, the result can be false
negatives. Maybe someone else has an idea how to correctly implement the 
`atSameOff` function below (which would make accesses to compatible data
members free; right now the type check is never omitted. It could also be
done using manual annotations, but those shouldn't be necessary...)

artur


   struct B { int x, y, z; auto a() { return 0; } }

   struct S1 { B super_; alias super_ this; auto a() { return x; } }
   struct S2 { B super_; alias super_ this; auto a() { return x+y; } }
   struct S3 { B super_; alias super_ this; auto a() { return x+y*z; } }
   struct S3x { int gg; B super_; alias super_ this; auto a() { return 
x+y*z+gg; } }

   struct DiscUnion(UE...) {
  union { UE members; }
  int type;

  mixin(evalExpMap!("%...;", q{
   this(B:UE[%d])(B b) { this = b; }
   void opAssign(B:UE[%d])(B b) {
  scope (failure) type = 0;
  members[%d] = b;
  type = %d+1;
   };
}, UE));

  ref DT as(DT)() @property {
 foreach (I, _; UE)
static if(is(DT==UE[I])) if (type==I+1)
   return members[I];
 assert(0, "Invalid DiscUnion extraction");
  }

  template opDispatch(string M) {
 auto ref opDispatch(A...)(A a) {
foreach (I, _; UE)
   if (type==I+1)
  return mixin("members[I]."~M~"(a)");
assert(0, "Invalid DiscUnion state");
 }
 
 auto ref opDispatch()() @property if (isFieldOf!(M, UE[0]) && 
!sameRep!(M, UE)) {
foreach (I, _; UE)
   if (type==I+1)
  return mixin("members[I]."~M);
assert(0, "Invalid DiscUnion state");
 }
 
 ref opDispatch()() @property if (isFieldOf!(M, UE[0]) && sameRep!(M, 
UE)) {
return mixin("members[0]."~M);
 }
  }
   }

   alias S = DiscUnion!(S1, S2, S3);
   alias SX = DiscUnion!(S3, S3x);

   void main() {
  S s = S1(B(2,3,4));
  assert (s.a()==2);
  s = S2(B(2,3,4));
  assert (s.a()==5);
  s = S3(s.super_);
  assert (s.a()==14);
  assert (s.x==2);

  auto t = s.as!S3;
  static assert (is(S3==typeof(t)));
  assert (t.y==3);
  
  SX sx = S3x(42, B(2,3,4));
  assert (sx.a()==14+42);
  assert (sx.x==2);
  sx = S3(B(2,3,4));
  assert (sx.x==2);
   }

   template isFieldOf(string M, T) {
   enum isFieldOf = is(typeof(function(T t) { return mixin("t."~M); }));
   }
   
   // XXX `offsetof` returns bogus results after an implicit conversion.
   // XXX Should be possible to fix `atSameOff`, to pass the two asserts below
   // XXX using CTFE - but that is too limited, does not allow pointer
   // XXX substraction even when both point to fields of the same object, and
   // XXX introduces other problems (like incorrect pointer equality 
evaluation).
   bool atSameOff(string M, A, B)() @property {
  ret

Re: Regarding std.collection.Array

2013-08-28 Thread Tobias Pankrath

On Wednesday, 28 August 2013 at 00:45:48 UTC, bearophile wrote:
Is it a good idea to add to std.collection.Array a method 
similar to:


T[] unsafeRelease() pure nothrow {
return this._data._payload;
}


It's meant to be used as an unsafe hack to call some some 
functions that require a built-in array as input.


Bye,
bearophile


It could be useful. Although I currently wouldn't have any use 
cases in my projects.


It should return this._data._payload[0 .. length].








Re: Limited Semi-PolyMorphic (LSP) structs?

2013-08-28 Thread Era Scarecrow
 K got a prototype working, I know there's issues with it but for 
now it looks simple and acts the way it is suppose to (at least 
to the unittest) so... Had to use templates through all the 
functions in order for auto ref to work right (hopefully forwards 
what it needs...)



/*
  //the only thing i would need to update, wish i didn't have to 
though...

  enum entries = ["iA:A,C",
  "iB:A,B"];

  //AB as the base struct. 'real_' defaulted for the real 
functions.

  mixin(LSPS("AB", entries));
*/

//generated output - start
struct AB {
  LSPS_Type type;
  auto ref A(T...)(auto ref T t) {
void* ptr = &this;
with(LSPS_Type) { switch(type) {
  case LSPS_iB: return (cast(iB*) ptr).real_A(t);
  default: return (cast(iA*) ptr).real_A(t);
}}
}

  auto ref B(T...)(auto ref T t) {
void* ptr = &this;
with(LSPS_Type) { switch(type) {
  case LSPS_iB: return (cast(iB*) ptr).real_B(t);
  default: throw new Exception("Function 'B' not 
avaliable for subtype of "~to!string(type)~"");

}}
  }

  auto ref C(T...)(auto ref T t) {
void* ptr = &this;
return (cast(iA*) ptr).real_C(t);
  }

  enum LSPS_Type {LSPS_iA, LSPS_iB, }
}
//generated - end

//the two structs that are inherited.
struct iA {
  AB lsps; alias lsps this;
  string real_A(){ return "iA_A";}
  string real_C(){ return "iA_C";}
}
struct iB {
  AB lsps; alias lsps this;
  string real_A(){ return "iB_A";}
  string real_B(){ return "iB_B";}
}

  //Doesn't matter if it's iA, iB or AB, it should act the same
  iA ab;
  assert(ab.A() == "iA_A");
  assertThrown(ab.B());
  assert(ab.C() == "iA_C");

  ab.type = AB.LSPS_Type.LSPS_iB;
  assert(ab.A() == "iB_A");
  assert(ab.B() == "iB_B");
  assert(ab.C() == "iA_C");


Re: Variant[Variant]

2013-08-28 Thread Jason den Dulk

On Tuesday, 27 August 2013 at 18:32:46 UTC, Ali Çehreli wrote:

May I ask you or somebody else to create a bug about 
VariantN.toHash not being considered at all. Thank you! :)


I have filed a bug report for this, and I have placed a work 
around in my code, so that's it for now, I suppose. Thanks again.