Re: Comparison of Enumerations with base type of String?

2017-08-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, August 27, 2017 03:47:58 Michael Reiland via Digitalmars-d-learn 
wrote:
> You can randomly assign a string to an enum?  Or am I
> misunderstanding that last bit of code?

No, you can't directly assign a string to an enum of type string. That's
part of why they don't pass isInputRange. This code fails to compile

enum S : string
{
a = "foo",
b = "bar"
}

void main()
{
S s = "baz";
}

though you can force it with a cast, e.g.

S s = cast(S)"baz";

Unfortunately however, enums in D really aren't very strongly typed. So,
while direct assignment will fail, stuff like

S s = S.a;
s ~= "blah";

will compile. And enums of base type int have the same problem - e.g.

E e = E.a | E.b;

In both cases, you trivially end up with a value that is not valid for that
enum type and will likely cause problems with final switch (which will
result in an Error being thrown when not compiling with -release but will do
who-knows-what when -release is used, because there is no check with
-release).

The result is that a variable of an enum type does not entirely act like the
base type even when you're not considering stuff like using is expressions
or std.traits to test something based on its type. It's implicitly
convertible to its base type but is not its base type. However, a bunch of
operations that IMHO really should not be legal on an enum are (e.g.
appending), and some which could be legal but should result in the base type
rather than the enum type (e.g concatenation or |ing) result in the enum
type, making it trivial to create enum variables with values that aren't in
the enum if you're not careful. Discussions have been had on this in the
past, and I'm firmly of the belief that the current design is a mistake in
this regard, but some (Andrei included) have argued that it's perfectly
legitimate to have an enum variable which is not one of the listed enum
values with the idea that you're defining a general type that has a few
known constants but the constants aren't all of the values. I think this
violates the idea of what an enum is (I think that an enum should always
define all valid values for that enum and no other values should be legal),
and it definitely doesn't play nicely with final switch, but for the moment,
we're stuck.

> Also it sounds to me like string enums are going to be slower
> performance wise than integer enums.

I expect so. How efficient an enum is depends entirely on what its base type
is and what you're doing with it. However, if all you're really looking for
is to have a string representation of the name of an enum, then you can have
the base type be int, and to!string and writeln will give you the string
representation of the name of the enum without the enum needing to be a
string. Whether it makes sense to use string as the base type of an enum
depends entirely on what you're trying to do with the enum, just like
whether you use a struct as the base type of an enum makes sense depends on
what you're doing. Sometimes, it can be very useful, but that doesn't mean
that it's always the best solution.

- Jonathan M Davis



Re: Comparison of Enumerations with base type of String?

2017-08-26 Thread Michael Reiland via Digitalmars-d-learn
You can randomly assign a string to an enum?  Or am I 
misunderstanding that last bit of code?


Also it sounds to me like string enums are going to be slower 
performance wise than integer enums.


Re: ATTN: Andrej Mitrovic: Port Audio

2017-08-26 Thread Johnson via Digitalmars-d-learn

On Sunday, 27 August 2017 at 02:23:32 UTC, Johnson wrote:

On Sunday, 27 August 2017 at 02:00:22 UTC, Johnson wrote:
You wrote a thread a while back about your callbacks not being 
called and you had a fix.


[...]


After going through the code a bit, seems there are some bugs 
with  Only OpenStream seems to take a ** so the other 
functions are getting passed junk.


At least, I got sound! Scared the shit out of me too!


I should mention that the callback is still not being called, but 
I used the sawtooth to modify a buffer and used Pa_WriteStream. 
Pa_SetStreamFinishedCallback is working.


PaStreamFlags.PrimeOutputBuffersUsingStreamCallback still causes 
an access violation.


Seems like the callback address is not being correctly 
transmitted to PA.




Re: ATTN: Andrej Mitrovic: Port Audio

2017-08-26 Thread Johnson via Digitalmars-d-learn

On Sunday, 27 August 2017 at 02:00:22 UTC, Johnson wrote:
You wrote a thread a while back about your callbacks not being 
called and you had a fix.


[...]


After going through the code a bit, seems there are some bugs 
with  Only OpenStream seems to take a ** so the other 
functions are getting passed junk.


At least, I got sound! Scared the shit out of me too!


Re: Comparison of Enumerations with base type of String?

2017-08-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, August 27, 2017 01:43:14 Michael Reiland via Digitalmars-d-learn 
wrote:
> Hey guys,
>
> I was running through a tutorial and I noticed that enums can
> have a base type of string.  Which is interesting, but I'm
> wondering about comparisons.
>
> I'm guessing the comparison boils down to a pointer comparison,
> but I thought I'd confirm.

No, it'll do the normal string comparison, just like enums that are ints do
a normal integer comparison. The fact the strings are enums doesn't really
change much except for stuff that's specifically doing something differently
for enums. It just means that instead of having separate constants which are
strings, you have them grouped together, and final switch statements will
require that the cases cover all of them. Some stuff like std.conv.to!string
or writeln will end up using the names of the enums rather than their values
like they do with other enums even though they're strings, but in general,
having

enum S : string
{
foo = "yes",
bar = "no",
}

isn't all that different from just doing

enum foo = "yes";
enum bar = "no";

except that declaring the enum S essentially puts them in a namespace called
S. It does create a new type S, which affects some stuff (e.g. S is not a
range, whereas string is), so operating an an S is not completely identical
to operating on a string, but S doesn't magically end up implementing
operations differently than occurs with string. It's just that some of the
operations on S are more restricted than a naked string, and since they
implicitly convert to string rather than being a string, some functions that
looks at the type will operate on an S differently than they would for a
naked string.

- Jonathan M Davis



ATTN: Andrej Mitrovic: Port Audio

2017-08-26 Thread Johnson via Digitalmars-d-learn
You wrote a thread a while back about your callbacks not being 
called and you had a fix.


http://www.digitalmars.com/d/archives/digitalmars/D/learn/Anyone_using_Portaudio_22343.html

I'm trying to get portAudio to work on my machine and it seems 
everything passes yet my callbacks are not being called.



I do not know if it is the same issue you had or what. Could you 
describe your fixes, if you remember? You said it was alias 
issues, my source uses alias, so maybe I have the updated one.


Also, using paPrimeOutputBuffersUsingStreamCallback causes an 
access violation ;/


Here are some dll's I'm using

https://github.com/spatialaudio/portaudio-binaries



I'm including the two files needed to compile what I have in case 
you(or anyone else) decide to help figure this out:


Make sure to change the dll location in the DLL_PortAudio struct 
and set the appropriate audio interface to use(I have it set to 
12, but have tried every value on my system with no luck).



module mPortAudio;
import std.stdio, std.conv;


enum PaError : int
{   
NoError = 0,
NotInitialized = -1,
UnanticipatedHostError,
InvalidChannelCount,
InvalidSampleRate,
InvalidDevice,
InvalidFlag,
SampleFormatNotSupported,
BadIODeviceCombination,
InsufficientMemory,
BufferTooBig,
BufferTooSmall,
NullCallback,
BadStreamPtr,
TimedOut,
InternalError,
DeviceUnavailable,
IncompatibleHostApiSpecificStreamInfo,
StreamIsStopped,
StreamIsNotStopped,
InputOverflowed,
OutputUnderflowed,
HostApiNotFound,
InvalidHostApi,
CanNotReadFromACallbackStream,
CanNotWriteToACallbackStream,
CanNotReadFromAnOutputOnlyStream,
CanNotWriteToAnInputOnlyStream,
IncompatibleStreamHostApi,
BadBufferPtr,
FormatIsSupported = 0,
};

enum PaSampleFormat : ulong
{
Float32  = 0x0001,
Int32= 0x0002,
Int24= 0x0004,
Int16= 0x0008,
Int8 = 0x0010,
UInt8= 0x0020,
CustomFormat = 0x0001,
NonInterleaved = 0x8000
}

enum PaHostApiTypeId : int
{
InDevelopment=0,
DirectSound=1,
MME=2,
ASIO=3,
SoundManager=4,
CoreAudio=5,
OSS=7,
ALSA=8,
AL=9,
BeOS=10,
WDMKS=11,
JACK=12,
WASAPI=13,
AudioScienceHPI=14
};


enum PaStreamCallbackResult : int
{
paContinue=0,   /**< Signal that the stream should continue 
invoking the callback and processing audio. */
paComplete=1,   /**< Signal that the stream should stop 
invoking the callback and finish once all output samples have 
played. */
paAbort=2   /**< Signal that the stream should stop 
invoking the callback and finish as soon as possible. */

};





enum PaStreamFlags : ulong
{
NoFlag = 0,
ClipOff = 0x0001,
DitherOff = 0x0002,
NeverDropInput = 0x0004,
PrimeOutputBuffersUsingStreamCallback = 0x0008,
PlatformSpecificFlags = 0x,
}

alias void PaStream;
enum paFramesPerBufferUnspecified = 0;
enum PaStreamCallbackFlags : ulong
{
InputUnderflow = 0x0001,
InputOverflow = 0x0002,
OutputUnderflow = 0x0004,
OutputOverflow = 0x0008,
PrimingOutput = 0x0010,
}



alias extern(C) int function(const(void) *input, void *output, 
ulong frameCount, const(PaStreamCallbackTimeInfo)* timeInfo, 
PaStreamCallbackFlags statusFlags, void *userData ) 
PaStreamCallback;

alias void function( void *userData ) PaStreamFinishedCallback;

alias int PaDeviceIndex;
enum paNoDevice = cast(PaDeviceIndex)-1;
enum paUseHostApiSpecificDeviceSpecification =  
cast(PaDeviceIndex)-2;

alias int PaHostApiIndex;
alias double PaTime;


struct PaHostApiInfo
{
int structVersion;
PaHostApiTypeId type;
const(char) *name;
int deviceCount;
PaDeviceIndex defaultInputDevice;
PaDeviceIndex defaultOutputDevice;
};

struct PaDeviceInfo
{
int structVersion;
const(char) *name;
PaHostApiIndex hostApi;
int maxInputChannels;
int maxOutputChannels;
PaTime defaultLowInputLatency;
PaTime defaultLowOutputLatency;
PaTime defaultHighInputLatency;
PaTime defaultHighOutputLatency;
double defaultSampleRate;
};

struct PaStreamCallbackTimeInfo
{
PaTime inputBufferAdcTime;
PaTime currentTime;
PaTime outputBufferDacTime;
};

struct PaStreamInfo
{
int structVersion;
PaTime inputLatency;
PaTime outputLatency;
double sampleRate;
};


struct PaHostErrorInfo
{
PaHostApiTypeId hostApiType;
long errorCode;
const(char) *errorText;
};

struct PaStreamParameters
{
PaDeviceIndex device;
int channelCount;
PaSampleFormat sampleFormat;
PaTime suggestedLatency;
void *hostApiSpecificStreamInfo;
};
























struct DLL_PortAudio
{
@("DLLImport") public static 

Re: How to store data when using parallel processing

2017-08-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, August 27, 2017 00:26:33 Andrew Chapman via Digitalmars-d-learn 
wrote:
> Hi all, just wanting some advice on parallel processing and
> specifically how to deal with access violations.
>
> I am reading a list of words from a file like this:
>
> auto fileHandle = File("wordlist.txt", "r");
>
> string word;
> string[] words;
> string[ulong] hashMap;
>
> while ((word = fileHandle.readln()) !is null) {
>   words ~= word;
> }
>
> Then I'm doing some processing on the words.  I want to make this
> run as quickly as possible so I am doing the processing across
> the cores of my CPU like this:
>
> foreach (thisWord; parallel(words)) {
>   string wordLower = thisWord.strip().toLower();
>   ulong key = keyMaker.createKeyForWord(wordLower);
>
>  // hashMap[key] = wordLower;
> }
>
> The question is, in the above loop, how can I make the commented
> out line work without having an access violation.  Do I need to
> use a different data structure?  Or rethink what I'm doing?

std.parallelism is designed to work on stuff that's truly parallel, whereas
adding a value to an AA is not. For multiple threads to be able to access
it, it needs to be protected by a mutex or a synchronized block, in which
case the assignment is no longer parallel. Whether that matters much depends
on how expensive the rest of what the loop is doing is. If it's cheap
enough, then the threads will all just end up blocking on the mutex,
effectively making the code serial and making the parallelism pointless,
whereas if it's expensive enough that the threads will spend most of their
time doing the rest of the loop, then you can get an increase in performance
over just doing it in one thread. It wouldn't surprise me if simply doing
all of the work in the first loop and not creating the words array in the
first place would be faster than trying to parallelize the second loop, but
I don't know. You'd have to test it and see.

But std.parallelism cheats with regards to shared (which is part of why it's
@system). hiding the fact that you're dealing with multiple threads, but all
of the issues when using shared data remain (e.g. needing to use mutexes to
protect against data races). std.parallelism just normally manages to avoid
that problem by operating on separate pieces of data simultaneously rather
than operating on the same data on multiple threads at the same time,
whereas what you're doing with regards to the result involves operating on
the same data from multiple threads at the same time, which doesn't work
without mutexes.

An alternative would be to have a separate AA per thread, and then you
combine them after the loop, but that requires checking which thread you're
on so that you grab the correct one in a particular iteration of the loop. I
assume that std.parallelism provides a reasonably easy way to do that, but I
haven't done much with it, so I don't know. Worst case, you can probably go
off of the thread ID using core.thread.

std.parallelism may offer other ways to accomplish this, but I'd have to
study it to be sure. Either way, fundamentally, you're either going to have
to protect the hash table with a mutex, and the writes will be synchronous
even if the data creation is parallelized, or you have to store the data
from each thread separately while the threads are running and then combine
the data when the threads are done.

- Jonathan M Davis



Comparison of Enumerations with base type of String?

2017-08-26 Thread Michael Reiland via Digitalmars-d-learn

Hey guys,

I was running through a tutorial and I noticed that enums can 
have a base type of string.  Which is interesting, but I'm 
wondering about comparisons.


I'm guessing the comparison boils down to a pointer comparison, 
but I thought I'd confirm.




How to store data when using parallel processing

2017-08-26 Thread Andrew Chapman via Digitalmars-d-learn
Hi all, just wanting some advice on parallel processing and 
specifically how to deal with access violations.


I am reading a list of words from a file like this:

auto fileHandle = File("wordlist.txt", "r");

string word;
string[] words;
string[ulong] hashMap;

while ((word = fileHandle.readln()) !is null) {
words ~= word;
}

Then I'm doing some processing on the words.  I want to make this 
run as quickly as possible so I am doing the processing across 
the cores of my CPU like this:


foreach (thisWord; parallel(words)) {
string wordLower = thisWord.strip().toLower();
ulong key = keyMaker.createKeyForWord(wordLower);

// hashMap[key] = wordLower;
}

The question is, in the above loop, how can I make the commented 
out line work without having an access violation.  Do I need to 
use a different data structure?  Or rethink what I'm doing?


Thanks in advance.
Andrew.


Re: No CTFE of function

2017-08-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, August 26, 2017 23:53:36 Cecil Ward via Digitalmars-d-learn 
wrote:
> On Saturday, 26 August 2017 at 23:49:30 UTC, Cecil Ward wrote:
> > On Saturday, 26 August 2017 at 18:16:07 UTC, ag0aep6g wrote:
> >> On Saturday, 26 August 2017 at 16:52:36 UTC, Cecil Ward wrote:
> >>> Any ideas as to why GDC might just refuse to do CTFE on
> >>> compile-time-known inputs in a truly pure situation?
> >>
> >> That's not how CTFE works. CTFE only kicks in when the
> >> *result* is required at compile time. For example, when you
> >> assign it to an enum. The inputs must be known at compile
> >> time, and the interpreter will refuse to go on when you try
> >> something impure. But those things don't trigger CTFE.
> >>
> >> The compiler may choose to precompute any constant expression,
> >> but that's an optimization (constant folding), not CTFE.
> >
> > I think I understand, but I'm not sure. I should have explained
> > properly. I suspect what I should have said was that I was
> > expecting an _optimisation_ and I didn't see it. I thought that
> > a specific instance of a call to my pure function that has all
> > compile-time-known arguments would just produce generated code
> > that returned an explicit constant that is worked out by CTFE
> > calculation, replacing the actual code for the general function
> > entirely. So for example
> >
> > auto foo() { return bar( 2, 3 ); }
> >
> > (where bar is strongly pure and completely CTFE-able) should
> > have been replaced by generated x64 code looking exactly
> > literally like
> >
> > auto foo() { return 5; }
> >
> > expect that the returned result would be a fixed-length literal
> > array of 32-but numbers in my case (no dynamic arrays anywhere,
> > these I believe potentially involve RTL calls and the allocator
> > internally).
>
> I was expecting this optimisation to 'return literal constant
> only' because I have seen it before in other cases with GDC.
> Obviously generating a call that involves running the algorithm
> at runtime is a performance disaster when it certainly could have
> all been thrown away in the particular case in point and been
> replaced by a return of a precomputed value with zero runtime
> cost. So this is actually an issue with specific compilers, but I
> was wondering if I have missed anything about any D general rules
> that make CTFE evaluation practically impossible?

I don't know what you've seen before, but CTFE _only_ happens when the
result must be known at compile time - e.g. it's used to directly initialize
an enum or static variable. You will _never_ see CTFE done simply because
you called the function with literals. It's quite possible that GDC's
optimizer could inline the function and do constant folding and
significantly reduce the code that you actually end up with (maybe even
optimize it out entirely in some cases), but it would not be CTFE. It would
simply be the compiler backend optimizing the code. CTFE is done by the
frontend, and it's the same across dmd, ldc, and gdc so long as they have
the same version of the frontend (though the current version of gdc is quite
old, so if anything, it's behind on what it can do). So, if you want CTFE to
occur, then you _must_ assign the result to something that must have its
value known at compile time, and that will be the same across the various
compilers so long as the frontend version is the same. Any optimizations
which might optimize out function calls would be highly dependent on the
compiler backend and could easily differ across compiler versions.

My guess is that you previously saw your code optimized down such that you
thought that the compiler used CTFE when it didn't and that you're not
seeing such an optimization now, because your function is too large. If you
want to guarantee that the call is made at compile time and not worry about
whether the optimizer will do what you want, just assign the result to an
enum and then use the enum rather than hoping that the optimizer will
optimize the call out for you.

- Jonathan M Davis



Re: No CTFE of function

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 26 August 2017 at 23:53:36 UTC, Cecil Ward wrote:

On Saturday, 26 August 2017 at 23:49:30 UTC, Cecil Ward wrote:

[...]


I was expecting this optimisation to 'return literal constant 
only' because I have seen it before in other cases with GDC. 
Obviously generating a call that involves running the algorithm 
at runtime is a performance disaster when it certainly could 
have all been thrown away in the particular case in point and 
been replaced by a return of a precomputed value with zero 
runtime cost. So this is actually an issue with specific 
compilers, but I was wondering if I have missed anything about 
any D general rules that make CTFE evaluation practically 
impossible?


I suspect I posted this in the wrong category completely, should 
have been under GDC (poss applies to LDC too, will test that)


Re: No CTFE of function

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 26 August 2017 at 23:49:30 UTC, Cecil Ward wrote:

On Saturday, 26 August 2017 at 18:16:07 UTC, ag0aep6g wrote:

On Saturday, 26 August 2017 at 16:52:36 UTC, Cecil Ward wrote:
Any ideas as to why GDC might just refuse to do CTFE on 
compile-time-known inputs in a truly pure situation?


That's not how CTFE works. CTFE only kicks in when the 
*result* is required at compile time. For example, when you 
assign it to an enum. The inputs must be known at compile 
time, and the interpreter will refuse to go on when you try 
something impure. But those things don't trigger CTFE.


The compiler may choose to precompute any constant expression, 
but that's an optimization (constant folding), not CTFE.


I think I understand, but I'm not sure. I should have explained 
properly. I suspect what I should have said was that I was 
expecting an _optimisation_ and I didn't see it. I thought that 
a specific instance of a call to my pure function that has all 
compile-time-known arguments would just produce generated code 
that returned an explicit constant that is worked out by CTFE 
calculation, replacing the actual code for the general function 
entirely. So for example


auto foo() { return bar( 2, 3 ); }

(where bar is strongly pure and completely CTFE-able) should 
have been replaced by generated x64 code looking exactly 
literally like

auto foo() { return 5; }
expect that the returned result would be a fixed-length literal 
array of 32-but numbers in my case (no dynamic arrays anywhere, 
these I believe potentially involve RTL calls and the allocator 
internally).


I was expecting this optimisation to 'return literal constant 
only' because I have seen it before in other cases with GDC. 
Obviously generating a call that involves running the algorithm 
at runtime is a performance disaster when it certainly could have 
all been thrown away in the particular case in point and been 
replaced by a return of a precomputed value with zero runtime 
cost. So this is actually an issue with specific compilers, but I 
was wondering if I have missed anything about any D general rules 
that make CTFE evaluation practically impossible?


Re: No CTFE of function

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 26 August 2017 at 18:16:07 UTC, ag0aep6g wrote:

On Saturday, 26 August 2017 at 16:52:36 UTC, Cecil Ward wrote:
Any ideas as to why GDC might just refuse to do CTFE on 
compile-time-known inputs in a truly pure situation?


That's not how CTFE works. CTFE only kicks in when the *result* 
is required at compile time. For example, when you assign it to 
an enum. The inputs must be known at compile time, and the 
interpreter will refuse to go on when you try something impure. 
But those things don't trigger CTFE.


The compiler may choose to precompute any constant expression, 
but that's an optimization (constant folding), not CTFE.


I think I understand, but I'm not sure. I should have explained 
properly. I suspect what I should have said was that I was 
expecting an _optimisation_ and I didn't see it. I thought that a 
specific instance of a call to my pure function that has all 
compile-time-known arguments would just produce generated code 
that returned an explicit constant that is worked out by CTFE 
calculation, replacing the actual code for the general function 
entirely. So for example


auto foo() { return bar( 2, 3 ); }

(where bar is strongly pure and completely CTFE-able) should have 
been replaced by generated x64 code looking exactly literally like

auto foo() { return 5; }
expect that the returned result would be a fixed-length literal 
array of 32-but numbers in my case (no dynamic arrays anywhere, 
these I believe potentially involve RTL calls and the allocator 
internally).


Re: wrapping a C style delegate

2017-08-26 Thread Ali Çehreli via Digitalmars-d-learn

On 08/25/2017 05:49 PM, Nicholas Wilson wrote:

> I was thinking of something along those lines: but what about the
> lifetime of the passed delegate (the address of a local variable)? How
> can I ensure that it won't segfault when callback goes out of scope?
> I could new it with the GC but
> a) I'd rather have the wrapper be @nogc and
> b) i'd have to hold a reference to it or pin it because
> SomeAPIaddCallback will be in a driver somewhere and wouldn't get
> scanned by the GC.

Good points. I think you have to store a copy of the delegate in 
MyStruct and pass e.g. the array index of it as userData to 
intermediateCallback(). I think a Mallocator-based array would make the 
wrapper nogc.


Ali



Getting error in dmd testsuite

2017-08-26 Thread Thomas Mader via Digitalmars-d-learn

Hello,

I am building ldc on Nix (https://nixos.org/nix/) but keep 
getting an error while running the cppa.d test from the dmd 
testsuite (https://github.com/ldc-developers/dmd-testsuite).


1588:  ... runnable/cppa.d -L-lstdc++ (-g) -O
1588: Test failed.  The logged output:
1588: /tmp/nix-build-ldc-1.3.0.drv-0/build/bin/ldmd2 -conf= -m64 
-Irunnable  -L-lstdc++  
-od/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable 
-of/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0 runnable/cppa.d /tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppb.cpp.o
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o: In function `_Dmain':
1588: runnable/cppa.d:(.text._Dmain[_Dmain]+0x49f): undefined 
reference to `int foo15372(int)'
1588: runnable/cppa.d:(.text._Dmain[_Dmain]+0x4b2): undefined 
reference to `Foo15802::boo(int)'
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o:(.data.rel.ro._D4cppa6C131616__vtblZ[_D4cppa6C131616__vtblZ]+0x0): undefined reference to `C13161::dummyfunc()'
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o:(.data.rel.ro._D4cppa4Test6__vtblZ[_D4cppa4Test6__vtblZ]+0x0): undefined reference to `C13161::dummyfunc()'
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o:(.data.rel.ro._D4cppa7C13161a6__vtblZ[_D4cppa7C13161a6__vtblZ]+0x0): undefined reference to `C13161a::dummyfunc()'
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o:(.data.rel.ro._D4cppa5Testa6__vtblZ[_D4cppa5Testa6__vtblZ]+0x0): undefined reference to `C13161a::dummyfunc()'

1588: collect2: error: ld returned 1 exit status
1588: Error: 
/nix/store/df84hkmhrhx1c2zpvrhmk6aprhlzkasx-gcc-wrapper-6.4.0/bin/gcc failed with status: 1

1588:
1588:
1588: ==
1588: Test failed: expected rc == 0, exited with rc == 1
1588:
1588: make[2]: *** [Makefile:335: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa.d.out] Error 1


Apart from that all other tests pass.
Any ideas?

It's running on Linux with gcc 6.4.0.


Re: Retrieve the data of all the threads together once all threads are completed in a task pool

2017-08-26 Thread vino via Digitalmars-d-learn

On Saturday, 26 August 2017 at 17:38:37 UTC, Vino.B wrote:

Hi,

  Can some one provide me an example of how to wait for all the 
threads to be completed in a taskPool and then retrieve the 
data of all the threads together instead of getting the data of 
each threads(after successfully executed). For example, the 
below test program outputs only one string "Welcome" but not 
the string "Home".


import std.stdio;
import std.parallelism;

string Data;
auto Textarr = [ "Welcome", "Home" ];

string fn (string text)
{ return text; }

string Submain ()
{
 foreach ( i; taskPool.parallel(Textarr[0 .. $], 1))
   {
auto Task = task(, i);
Task.executeInNewThread();
auto TaskData = Task.workForce;
Data ~= TaskData;
  }
  return Data;
}

void main ()
{
 Submain;
 writeln(Data[0 .. $]);
}

From,
Vino.B


Hi All,

  Was able to find a solution, but the output writes additional 
empty lines., request your help on how to print without the empty 
lines.


Program:
import std.stdio;
import std.parallelism;
import std.algorithm;
import std.string;
string Data;
auto Textarr = [ "Welcome", "Home" ];
string endresult;
string fn (string text)
{ return text; }

void main ()
{
 string text;
 auto endresult = taskPool.workerLocalStorage(text);
 foreach ( i; parallel(Textarr[0 .. $], 1))
   {
auto Task = task(, i);
Task.executeInNewThread();
auto TaskData = Task.workForce;
endresult.get ~= TaskData;
  }
  foreach (i; sums.toRange)
   { writeln(i); }
}

Output:
C:\Users\admin\Desktop\Script>rdmd test.d
Welcome
Home







C:\Users\admin\Desktop\Script>


Re: How do I send a message to a struct member function?

2017-08-26 Thread Enjoys Math via Digitalmars-d-learn

On Saturday, 26 August 2017 at 10:05:31 UTC, drug wrote:

26.08.2017 09:49, Enjoys Math пишет:


I have a series of structs each of which needs to spawn a 
worker thread on initialization.  There seems to be no way to 
send a message back to the struct for instance to cause a 
member function call on /that/ structs data.


Please advise me.
If it is appropriate for you the better way would be to send 
/that/ structs to the corresponding worker thread and then it 
can call any method.
Another way is you can during worker thread spawning pass 
thread id and then pass messages back to parent thread.


I can't do the second approach because the parent thread creates 
many instances of the struct, each of which need a call back to a 
method.


How do I do the first method (in code) because I've tried 20 
different ways already.


Re: No CTFE of function

2017-08-26 Thread ag0aep6g via Digitalmars-d-learn

On Saturday, 26 August 2017 at 16:52:36 UTC, Cecil Ward wrote:
Any ideas as to why GDC might just refuse to do CTFE on 
compile-time-known inputs in a truly pure situation?


That's not how CTFE works. CTFE only kicks in when the *result* 
is required at compile time. For example, when you assign it to 
an enum. The inputs must be known at compile time, and the 
interpreter will refuse to go on when you try something impure. 
But those things don't trigger CTFE.


The compiler may choose to precompute any constant expression, 
but that's an optimization (constant folding), not CTFE.


No CTFE of function

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn
I have a pure function that has constant inputs, known at 
compile-time, contains no funny stuff internally - looked at the 
generated code, and no RTL calls at all. But in a test call with 
constant literal values (arrays initialised to literal) passed to 
the pure routine GDC refuses to CTFE the whole thing, as I would 
expect it (based on previous experience with d and GDC) to simply 
generate a trivial function that puts out a block of 
CTFE-evaluated constant data corresponding to the input.


Unfortunately it's a bit too long to post in here. I've tried 
lots of variations. Function is marked nogc safe pure nothrow


Any ideas as to why GDC might just refuse to do CTFE on 
compile-time-known inputs in a truly pure situation? Haven't 
tried DMD yet. Can try LDC. Am using d.godbolt.org to look at the 
result, as I don't have a machine here to run a d compiler on.


Other things I can think of. Contains function-in-a-function 
calls, which are all unlined out in the generated code nicely, 
and not the first time I've done that with GDC either.


Switches: Am using -Os or -O2 or -O3 - tried all. Tuning to 
presume + enable the latest x86-64 instructions. release build, 
no bounds-checks.


Re: Building (and including libraries) without dub

2017-08-26 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 26 August 2017 at 09:03:03 UTC, Hasen Judy wrote:
Building simple programs without dub is easy, just pass a list 
of .d source files to `dmd` or `ldc2`.


What if I want to include a 3rd party library?


It is also easy, just pass the list of its d source files to the 
compiler as well. Quite trivial, really.


Re: Building (and including libraries) without dub

2017-08-26 Thread Mike Wey via Digitalmars-d-learn

On 26-08-17 12:02, drug wrote:

26.08.2017 12:03, Hasen Judy пишет:
Building simple programs without dub is easy, just pass a list of .d 
source files to `dmd` or `ldc2`.


What if I want to include a 3rd party library? Surely before dub 
existed, people were incorporating other libraries in their projects.


I want to learn how this works from first principles. I've been 
working with dynamic/interpreted languages for too long, I forgot what 
it's like to build native programs without a dependency manager.


Any help would be appreciated!


It's like C++. If you use Linux then:
```
dmd  -L/path/to/lib 
-llibrarynamewithoutlibprefix

```
or example
```
dmd myapp.d -L../otherproject/lib -lcool
```
line above compiles `myapp.d` file and links it with library `libcool` 
that is place in directory `../otherproject/lib`


You will need an extra `-L` to pass things to the linker with dmd.

```
dmd myapp.d -L-L../otherproject/lib -L-lcool
```

--
Mike Wey


Re: 2 Dimensional Array Sorting

2017-08-26 Thread Vino.B via Digitalmars-d-learn

On Saturday, 26 August 2017 at 10:45:13 UTC, Vino.B wrote:

On Saturday, 26 August 2017 at 10:07:53 UTC, user1234 wrote:

[...]


Hi,

 Now there is no duplicate , but the sequence is still not 
correct


[...]


Hi,

  If I execute the script several time's i still get the 
duplicate entries.


From,
Vino.B


Re: 2 Dimensional Array Sorting

2017-08-26 Thread Vino.B via Digitalmars-d-learn

On Saturday, 26 August 2017 at 10:07:53 UTC, user1234 wrote:

On Saturday, 26 August 2017 at 09:53:44 UTC, Vino.B wrote:

On Saturday, 26 August 2017 at 06:12:57 UTC, user1234 wrote:

[...]


Hi,
  I tired you logic, but doesn't seem to be working, as every 
time i execute the order of the file list is different as in 
the below program i have used the sort based on the file name.


[...]


Try with (a,b) => a[1].to!int < b[1].to!int as predicate. T


Hi,

 Now there is no duplicate , but the sequence is still not correct

Output: the File C:\Temp\TEAM2\PROD_TEAM\dir1 is after 
C:\Temp\TEAM3\EXPORT\dir2

C:\Users\admin\Desktop\Script\D>rdmd Ftest.d
C:\Temp\TEAM2\BACKUP\dir1 
35732

C:\Temp\TEAM2\TEAM\DIR1   40
C:\Temp\TEAM2\TEAM\DIR2   2228
C:\Temp\TEAM2\EXPORT\dir2 30
C:\Temp\TEAM3\BACKUP\dir1 
71465

C:\Temp\TEAM3\EXPORT\dir2 61
C:\Temp\TEAM2\PROD_TEAM\dir1  
35772


Required output
C:\Temp\TEAM2\BACKUP\dir1 
35732

C:\Temp\TEAM2\TEAM\DIR1   40
C:\Temp\TEAM2\TEAM\DIR2   2228
C:\Temp\TEAM2\EXPORT\dir2 30
C:\Temp\TEAM2\PROD_TEAM\dir1  
35772
C:\Temp\TEAM3\BACKUP\dir1 
71465

C:\Temp\TEAM3\EXPORT\dir2 61

From,
Vino.B


Re: 2 Dimensional Array Sorting

2017-08-26 Thread user1234 via Digitalmars-d-learn

On Saturday, 26 August 2017 at 09:53:44 UTC, Vino.B wrote:

On Saturday, 26 August 2017 at 06:12:57 UTC, user1234 wrote:

[...]


Hi,
  I tired you logic, but doesn't seem to be working, as every 
time i execute the order of the file list is different as in 
the below program i have used the sort based on the file name.


[...]


Try with (a,b) => a[1].to!int < b[1].to!int as predicate. T


Re: How do I send a message to a struct member function?

2017-08-26 Thread drug via Digitalmars-d-learn

26.08.2017 09:49, Enjoys Math пишет:


I have a series of structs each of which needs to spawn a worker thread 
on initialization.  There seems to be no way to send a message back to 
the struct for instance to cause a member function call on /that/ 
structs data.


Please advise me.
If it is appropriate for you the better way would be to send /that/ 
structs to the corresponding worker thread and then it can call any method.
Another way is you can during worker thread spawning pass thread id and 
then pass messages back to parent thread.


Re: Building (and including libraries) without dub

2017-08-26 Thread Hasen Judy via Digitalmars-d-learn

On Saturday, 26 August 2017 at 10:02:03 UTC, drug wrote:

It's like C++. If you use Linux then:
```
dmd  -L/path/to/lib 
-llibrarynamewithoutlibprefix

```
or example
```
dmd myapp.d -L../otherproject/lib -lcool
```
line above compiles `myapp.d` file and links it with library 
`libcool` that is place in directory `../otherproject/lib`


Thanks for your response!

So if I may make a guess, when you include a dependency in a dub 
project, what it ends up doing is compiling the dependency 
separately into a lib file then statically link the lib with your 
project?


Re: Building (and including libraries) without dub

2017-08-26 Thread drug via Digitalmars-d-learn

26.08.2017 12:03, Hasen Judy пишет:
Building simple programs without dub is easy, just pass a list of .d 
source files to `dmd` or `ldc2`.


What if I want to include a 3rd party library? Surely before dub 
existed, people were incorporating other libraries in their projects.


I want to learn how this works from first principles. I've been working 
with dynamic/interpreted languages for too long, I forgot what it's like 
to build native programs without a dependency manager.


Any help would be appreciated!


It's like C++. If you use Linux then:
```
dmd  -L/path/to/lib 
-llibrarynamewithoutlibprefix

```
or example
```
dmd myapp.d -L../otherproject/lib -lcool
```
line above compiles `myapp.d` file and links it with library `libcool` 
that is place in directory `../otherproject/lib`


Re: 2 Dimensional Array Sorting

2017-08-26 Thread Vino.B via Digitalmars-d-learn

On Saturday, 26 August 2017 at 06:12:57 UTC, user1234 wrote:

On Saturday, 26 August 2017 at 06:11:37 UTC, user1234 wrote:

On Saturday, 26 August 2017 at 06:01:15 UTC, Vino.B wrote:

Hi,

 Can someone provide me a example of sorting 2 Dimensional 
Array containing Filename and Size, and should be sorted by 
Size.


From,
Vino.B


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

string[2][] nameAndSize = [["b", "2"], ["a", "1"]];
auto s = nameAndSize.sort!((a,b) => a[0] < b[0] && a[1] < 
b[1]);

writeln(s);
}


I missed the "by Size" directive. So it's just:

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

string[2][] nameAndSize = [["b", "2"], ["a", "1"]];
auto s = nameAndSize.sort!((a,b) => a[1] < b[1]);
writeln(s);
}


Hi,
  I tired you logic, but doesn't seem to be working, as every 
time i execute the order of the file list is different as in the 
below program i have used the sort based on the file name.


Program:
import std.file: dirEntries, isFile, SpanMode;
import std.stdio: writeln, writefln;
import std.algorithm: filter, map, sort;
import std.path: globMatch, baseName;
import std.array: array, replace;
import std.typecons: tuple;
import std.parallelism;
import std.conv;
int SizeDir = 10;
string[][] Subdata;

auto Dirlst = [ "C:\\Temp\\TEAM2\\TEAM", 
"C:\\Temp\\TEAM2\\PROD_TEAM", "C:\\Temp\\TEAM3\\BACKUP", 
"C:\\Temp\\TEAM3\\EXPORT"];

string[][] SizeDirList (string Fs)
{
ulong subdirTotal = 0;
auto unc = "?\\"~Fs;
auto dFiles = dirEntries(unc, SpanMode.shallow).filter!(a => 
a.isDir && !globMatch(a.baseName, "*DND*")).map!(a => 
tuple(a.name, a.size)).array;

  foreach (d; dFiles)
{
auto SdFiles = dirEntries(d[0], SpanMode.depth).map!(a => 
tuple(a.size)).array;

foreach (f; parallel(SdFiles,1))
{ subdirTotal += f[0]; }
   ulong subdirTotalGB = (subdirTotal/1024);
   if (subdirTotalGB > SizeDir)
		{ Subdata ~= [d[0].replace("?\\", ""), 
to!string(subdirTotalGB)]; }

subdirTotal = 0;
}
return Subdata;
}
void main ()
{
 foreach (string Fs; parallel(Dirlst[0 .. $],1))
{
auto SizeDirListTask = task(, Fs);
SizeDirListTask.executeInNewThread();
auto SizeDirListTaskData = SizeDirListTask.yieldForce;
		auto sortedresult = SizeDirListTaskData.sort!((a,b) => a[0] < 
b[0]);

foreach(i; sortedresult[0 .. $])
writefln("%-(%-63s %)", i);
}

}

Output :The sequence is not correct and there are duplicates.

C:\Users\admin\Desktop\Script\D>rdmd Ftest.d
C:\Temp\TEAM2\TEAM\DIR1   40
C:\Temp\TEAM2\TEAM\DIR2   2228
C:\Temp\TEAM2\TEAM\DIR2   2228
C:\Temp\TEAM2\PROD_TEAM\dir1  
35772

C:\Temp\TEAM2\TEAM\DIR2   2228
C:\Temp\TEAM2\PROD_TEAM\dir1  
35772
C:\Temp\TEAM3\BACKUP\dir1 
71465

C:\Temp\TEAM3\EXPORT\dir2 61

C:\Users\admin\Desktop\Script\D>rdmd Ftest.d
C:\Temp\TEAM2\TEAM\DIR1   40
C:\Temp\TEAM2\TEAM\DIR2   2228
C:\Temp\TEAM2\PROD_TEAM\dir1  
35772
C:\Temp\TEAM3\BACKUP\dir1 
71465

C:\Temp\TEAM3\EXPORT\dir2 61

C:\Users\admin\Desktop\Script\D>rdmd Ftest.d
C:\Temp\TEAM2\TEAM\DIR1   40
C:\Temp\TEAM2\TEAM\DIR2   2228
C:\Temp\TEAM3\BACKUP\dir1 
71465

C:\Temp\TEAM3\EXPORT\dir2 61
C:\Temp\TEAM2\PROD_TEAM\dir1  
35772


Required Output :C:\Temp\TEAM2\..., C:\Temp\TEAM3...

C:\Temp\TEAM2\TEAM\DIR1   40
C:\Temp\TEAM2\TEAM\DIR2   2228
C:\Temp\TEAM2\PROD_TEAM\dir1  
35772
C:\Temp\TEAM3\BACKUP\dir1 
71465

C:\Temp\TEAM3\EXPORT\dir2 61

From,
Vino.B



Building (and including libraries) without dub

2017-08-26 Thread Hasen Judy via Digitalmars-d-learn
Building simple programs without dub is easy, just pass a list of 
.d source files to `dmd` or `ldc2`.


What if I want to include a 3rd party library? Surely before dub 
existed, people were incorporating other libraries in their 
projects.


I want to learn how this works from first principles. I've been 
working with dynamic/interpreted languages for too long, I forgot 
what it's like to build native programs without a dependency 
manager.


Any help would be appreciated!


Re: spawnProcess: Exit parent process without terminating child process

2017-08-26 Thread FreeSlave via Digitalmars-d-learn

On Friday, 25 August 2017 at 19:55:09 UTC, timvol wrote:

Hi guys,

I want execute a process. I know, I can execute a process using 
"spawnProcess" or "executeShell". But I want exit the parent.


My code for testing purposes is the following:

int main(string[] asArgs_p)
{
if ( (asArgs_p.length >= 2) && asArgs_p[1].isDir() )
{
while(1) {}
}
else
{
import std.process;
spawnProcess([asArgs_p[0], "test"]);
}
return 0;
}

So, starting the application without any parameter, it calls 
"spawnProcess" with an parameter. Now, I want that the parent 
process (the process started without parameter) terminates, 
while the created process remains running.


At the moment, the parent process creates the child and remains 
open (because of the while(1)-loop).


Any ideas how I can exit the parent and keep the child process 
running?


Note that in your particular case the spawnProcess as used now 
should work too. It should run in parallel with its parent. 
Parent will exit and child process will remain. I'm not sure why 
the parent does not exit in your case. When starting this program 
without parameters it will not run into while(1) branch at all.


Re: spawnProcess: Exit parent process without terminating child process

2017-08-26 Thread FreeSlave via Digitalmars-d-learn

On Friday, 25 August 2017 at 19:55:09 UTC, timvol wrote:

Hi guys,

I want execute a process. I know, I can execute a process using 
"spawnProcess" or "executeShell". But I want exit the parent.


My code for testing purposes is the following:

int main(string[] asArgs_p)
{
if ( (asArgs_p.length >= 2) && asArgs_p[1].isDir() )
{
while(1) {}
}
else
{
import std.process;
spawnProcess([asArgs_p[0], "test"]);
}
return 0;
}

So, starting the application without any parameter, it calls 
"spawnProcess" with an parameter. Now, I want that the parent 
process (the process started without parameter) terminates, 
while the created process remains running.


At the moment, the parent process creates the child and remains 
open (because of the while(1)-loop).


Any ideas how I can exit the parent and keep the child process 
running?


Running process in detached state will be available in the future 
versions of Phobos. This functionality has been already merged in 
master https://github.com/dlang/phobos/pull/5483


Until then you may consider to use a third-party library 
https://github.com/FreeSlave/detached


Re: pipeProcess not returning immediately

2017-08-26 Thread FoxyBrown via Digitalmars-d-learn

On Saturday, 26 August 2017 at 06:24:26 UTC, user1234 wrote:
On Saturday, 26 August 2017 at 01:13:35 UTC, Johnson Jones 
wrote:
I am running ffplay.exe and my application does not return 
immediately from pipeProcess. I have to close ffplay for my 
program to continue execution.


No process is asynchronous in std.process.

If you don't want to block your program then wrap it in a 
thread that checks periodically for termination.


Either you are wrong or the docks are wrong:

https://dlang.org/phobos/std_process.html

pipeProcess also spawns a child process which runs in 
**parallel** with its parent. However, instead of taking 
arbitrary streams, it automatically creates a set of pipes that 
allow the parent to communicate with the child through the 
child's standard input, output, and/or error streams. This 
function corresponds roughly to C's popen function.





Re: testing for deprecation

2017-08-26 Thread user1234 via Digitalmars-d-learn

On Friday, 25 August 2017 at 20:35:52 UTC, jmh530 wrote:
On Thursday, 1 September 2016 at 11:13:42 UTC, rikki cattermole 
wrote:


That is a first that somebody wanted it.
Bug report please!


I just ran across this with

deprecated {
void foo();
}
void main() {
pragma(msg, __traits(getAttributes, foo));
}

producing just tuple().


getAttributes is made for UDAs only.


How do I send a message to a struct member function?

2017-08-26 Thread Enjoys Math via Digitalmars-d-learn


I have a series of structs each of which needs to spawn a worker 
thread on initialization.  There seems to be no way to send a 
message back to the struct for instance to cause a member 
function call on /that/ structs data.


Please advise me.


Re: Best syntax for a diagonal and vertical slice

2017-08-26 Thread Ilya Yaroshenko via Digitalmars-d-learn

On Saturday, 22 July 2017 at 20:55:06 UTC, kerdemdemir wrote:

We have awesome way for creating slices like:

a = new int[5];
int[] b = a[0..2];

But what about if I have 2D array and I don't want to go 
vertical. Something like :


int[3][3] matrix = [
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
];

I believe I can use std.range function "RoundRobin"(or maybe it 
won't work with 2D array directly) for having a good looking 
vertical slice which will have 1,4,7 or 2,5,8 or 3,6,9 in my 
example above.


And what if I want to go diagonal like 1,5,9 or 3,5,7 in the 
example above. Is there a good solution in std without using 
for loops?


I have one more requirement for fulfilling the task that I 
working on. This slices do not have to be the same size as the 
array. For example in the example above slice size could have 2 
instead of 3. In this case I need to have slices like 
1,5;2,6;4,8;5,9 ... and so on for diagonal case.


Erdem

Ps: Converting the 2D array to 1D array is possible in my case.


Hello Erdem,

You may want to use mir-algorithm DUB package. It is a D tensor 
library.

https://github.com/libmir/mir-algorithm

import mir.ndslice;

auto slice = matrix[0].ptr.sliced(3, 3);
auto row = matrix[0];
auto col = matrix[0 .. $, 0];

A lot of examples with diagonal and sub-diagonals can be found 
here

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

Best,
Ilya


Re: pipeProcess not returning immediately

2017-08-26 Thread user1234 via Digitalmars-d-learn

On Saturday, 26 August 2017 at 01:13:35 UTC, Johnson Jones wrote:
I am running ffplay.exe and my application does not return 
immediately from pipeProcess. I have to close ffplay for my 
program to continue execution.


No process is asynchronous in std.process.

If you don't want to block your program then wrap it in a thread 
that checks periodically for termination.


Re: 2 Dimensional Array Sorting

2017-08-26 Thread user1234 via Digitalmars-d-learn

On Saturday, 26 August 2017 at 06:11:37 UTC, user1234 wrote:

On Saturday, 26 August 2017 at 06:01:15 UTC, Vino.B wrote:

Hi,

 Can someone provide me a example of sorting 2 Dimensional 
Array containing Filename and Size, and should be sorted by 
Size.


From,
Vino.B


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

string[2][] nameAndSize = [["b", "2"], ["a", "1"]];
auto s = nameAndSize.sort!((a,b) => a[0] < b[0] && a[1] < 
b[1]);

writeln(s);
}


I missed the "by Size" directive. So it's just:

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

string[2][] nameAndSize = [["b", "2"], ["a", "1"]];
auto s = nameAndSize.sort!((a,b) => a[1] < b[1]);
writeln(s);
}


Re: 2 Dimensional Array Sorting

2017-08-26 Thread user1234 via Digitalmars-d-learn

On Saturday, 26 August 2017 at 06:01:15 UTC, Vino.B wrote:

Hi,

 Can someone provide me a example of sorting 2 Dimensional 
Array containing Filename and Size, and should be sorted by 
Size.


From,
Vino.B


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

string[2][] nameAndSize = [["b", "2"], ["a", "1"]];
auto s = nameAndSize.sort!((a,b) => a[0] < b[0] && a[1] < 
b[1]);

writeln(s);
}


2 Dimensional Array Sorting

2017-08-26 Thread Vino.B via Digitalmars-d-learn

Hi,

 Can someone provide me a example of sorting 2 Dimensional Array 
containing Filename and Size, and should be sorted by Size.


From,
Vino.B