Re: endsWith - for a string vs an array of strings

2015-01-11 Thread Mengu via Digitalmars-d-learn

On Saturday, 10 January 2015 at 23:32:47 UTC, bearophile wrote:

Laeeth Isharc:

In D there is a feature that allows a function to accept both 
an array of items and items,


yes - it is funny there is not an overloading that accepts 
arrays


I meant this D feature:


void foo(T)(T[] items...) {
import std.stdio;
items.writeln;
}
void main() {
foo("red", "green", "blue");
foo(["red", "green", "blue"]);
auto a = ["red", "green", "blue"];
foo(a);
}


Bye,
bearophile


for the curious, expanding tuples and typetuples on ali's book is 
explained at 
http://ddili.org/ders/d.en/tuples.html#ix_tuples..expand and at 
http://ddili.org/ders/d.en/tuples.html#ix_tuples.TypeTuple, 
std.typetuple.


Re: Sqlite

2015-01-11 Thread Paul via Digitalmars-d-learn

On Sunday, 11 January 2015 at 22:19:28 UTC, Tobias Pankrath wrote:
Hint: Put the SQL in a file create_people.sql and import it 
into your code via the import statement:


string sql = import("create_people.sql"); // you'll need a 
correct -J compiler switch


That way you can easily test if it's correct on the 
commandline. It's .read  in the sqlite3 shell.


Neat, thank you!


Re: How to interface with C++ code or dll?

2015-01-11 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 11 January 2015 at 12:56:40 UTC, Suliman wrote:

I had read about using C++ libs from D, and understood that 
there is 2 ways:
1. Make binding - convert .H to .d (I still do not fully 
understand what is it)

2. Use directly C++ lib (.dll)


No, there are not two ways. There is one way. In order to use any 
library from C or C++, you *have* to create a binding. The 
binding tells the compiler the function signatures and types that 
are available to be used. It allows you to compile your code 
without error. Then, the C or C++ library can be linked with the 
final executable just like a D library, or (in the case of shared 
libraries) loaded at runtime (as Derelict does) with system calls.





I decided to start from simple example 
http://www.gdal.org/warptut.html


For compiling it's need #include "gdalwarper.h", so I maked 
gdalwarper.d with tool htod.
I know that it's not recommended for usage more, but other 
tools look too complex for me (I even do not understand how to 
sun them on Windows).


After I had add import gdalwarper.d to my test project. But 
during compilation it's asked me about other d files, that I 
included one ny other in App.d file. In the result I got error 
that:
"source\cpl_port.d(147): Error: module ctype is in file 
'std\c\ctype.d' which can not be read"


You've imported std.c.ctype, which doesn't exist. You need to 
import core.stdc.ctype instead. All of the C stuff is in 
core.stdc in DRuntime.




I have got a question. Files that I include is only header 
files. They do not include any code. How App would run? I 
should specify C++ source location or what?


Imports are only used at compile time to determine which types 
and functions are available to use. We don't need the code for 
the C or C++ stuff because everything is already compiled in the 
library that you are linking to or loading. Even in D, you don't 
need the code for modules you import -- only their function 
signatures and type declarations. D is designed such that you 
don't need to separate the interface from the implementation, but 
you can if you want to (that's what .di files are for).


To be clear, let's say you have module a.d and another module 
b.d. Module a has a function sayHello. You compile module a and 
the code for say hello, which prints hello to the screen, is 
translated and saved in a library. Later, you compile b.d. Since 
module b imports a, then the compiler has to load a into memory 
and parse the signature for the function sayHello -- but it 
doesn't *need* the code for say hello. All it needs is this part:


void sayHello( string str );

It doesn't care what the implementation of the function looks 
like, because now it isn't compiling a.d, it's compiling b.d. It 
only needs to know how to call the function and what it returns 
so it can throw an error if b.d calls sayHello with an int or a 
float or anything that isn't a string. Then, when the executable 
is generated, the linker will match up the call to sayHello in b 
with the implementation of sayHello in a.


There are some exceptions to this. You need the implementation of 
templates and anything you want to use at compile time, but for 
code that is runtime only you don't.




=

Then I decided to look how to use ready dll. As far as I know D 
have directive pragma(), that allow to import any lib.
Also afaik that it support inly import of dll in format of lib. 
Am I right?


No. This is not a feature of D. D has a "lib" pragma that allows 
you to link to a library without passing the library on the 
command line. THat is:


pragma( lib, "MyLib.lib" );

This will cause the compiler to automatically link MyLib.lib to 
your app. It's the same as passing MyLib.lib on the command line. 
The compiler still needs to know the path where the library can 
be found.


However, this does *not* allow you to automatically use any 
library in D without importing the library's source modules. So 
for a C or C++ library, you still need a binding to import.





Re: Sqlite

2015-01-11 Thread Tobias Pankrath via Digitalmars-d-learn

On Sunday, 11 January 2015 at 20:30:41 UTC, Paul wrote:
On Sunday, 11 January 2015 at 20:20:21 UTC, ketmar via 
Digitalmars-d-learn wrote:
note the single quotes in your code: that is where it all goes 
wrong. i
don't know where you got that quotes from, but this is not a 
valid SQL

syntax for `CREATE TABLE`. ;-)


Thank you, I thought it might be something obvious - that will 
teach me to cut and paste code! :D


Hint: Put the SQL in a file create_people.sql and import it into 
your code via the import statement:


string sql = import("create_people.sql"); // you'll need a 
correct -J compiler switch


That way you can easily test if it's correct on the commandline. 
It's .read  in the sqlite3 shell.




Re: Build all combinations of strings

2015-01-11 Thread bearophile via Digitalmars-d-learn

Nordlöw:

Couldn't we do a first pass and check that if elements of T are 
distinct and if so set doCopy to false otherwise true?


The algorithm you have seen in Rosettacode doesn't care if and 
what items of the input sequence are duplicated, it handles them 
as they are all distinct. And them being distinct (or not 
distinct) doesn't change the desire to use something like doCopy 
to have dup-ped output arrays, so I don't understand what you are 
trying to say.


The purpose of doCopy is similar of the difference between 
File.byLine and File.byLineCopy (originally I suggested to give a 
doCopy argiment to byLine too, for safety. Andrei said no. Later 
experience has shown I was right and we have added byLineCopy, 
but now the default line iteration is the non-copying one, that 
is less safe).


Bye,
bearophile


Re: Build all combinations of strings

2015-01-11 Thread Nordlöw

On Sunday, 11 January 2015 at 18:01:09 UTC, bearophile wrote:

Is doCopy really needed as an argument here?

Couldn't this be inferred from the mutability of T instead?


doCopy is useful, if it's true all the permutation arrays are 
distinct and dup-ped, otherwise they are all different. It's 
true by default, so casual users of that generator will avoid 
bugs. You can set it to false to speed up your code.


Couldn't we do a first pass and check that if elements of T are 
distinct and if so set doCopy to false otherwise true?


Re: Sqlite

2015-01-11 Thread Paul via Digitalmars-d-learn
On Sunday, 11 January 2015 at 20:20:21 UTC, ketmar via 
Digitalmars-d-learn wrote:
note the single quotes in your code: that is where it all goes 
wrong. i
don't know where you got that quotes from, but this is not a 
valid SQL

syntax for `CREATE TABLE`. ;-)


Thank you, I thought it might be something obvious - that will 
teach me to cut and paste code! :D




Re: Build all combinations of strings

2015-01-11 Thread Nordlöw

On Sunday, 11 January 2015 at 18:01:09 UTC, bearophile wrote:

Nordlöw:


Is doCopy really needed as an argument here?

Couldn't this be inferred from the mutability of T instead?


doCopy is useful, if it's true all the permutation arrays are 
distinct and dup-ped, otherwise they are all different. It's 
true by default, so casual users of that generator will avoid 
bugs. You can set it to false to speed up your code.



Later I have refined the idea, you can see it here, that allows 
true @nogc code when needed:


struct CartesianPower(bool doCopy=true, T) {
T[] items;
uint repeat;
T[] row;
uint i, maxN;

this(T[] items_, in uint repeat_, T[] buffer) pure nothrow 
@safe @nogc {

this.items = items_;
this.repeat = repeat_;
row = buffer[0 .. repeat];
row[] = items[0];
maxN = items.length ^^ repeat;
}

static if (doCopy) {
@property T[] front() pure nothrow @safe @nogc {
return row.dup;
}
} else {
@property T[] front() pure nothrow @safe @nogc {
return row;
}
}

@property bool empty() pure nothrow @safe @nogc {
return i >= maxN;
}

void popFront() pure nothrow @safe @nogc {
i++;
if (empty)
return;
uint n = i;
size_t count = repeat - 1;
while (n) {
row[count] = items[n % items.length];
count--;
n /= items.length;
}
}
}

auto cartesianPower(bool doCopy=true, T)(T[] items, in uint 
repeat)

pure nothrow @safe {
return CartesianPower!(doCopy, T)(items, repeat, new 
T[repeat]);

}

auto cartesianPower(bool doCopy=true, T)(T[] items, in uint 
repeat, T[] buffer)

pure nothrow @safe @nogc {
if (buffer.length >= repeat) {
return CartesianPower!(doCopy, T)(items, repeat, 
buffer);

} else {
// Is this correct in presence of chaining?
static immutable err = new Error("buffer.length < 
repeat");

throw err;
}
}

void main() @nogc {
import core.stdc.stdio;
int[3] items = [10, 20, 30];
int[4] buf;
foreach (p; cartesianPower!false(items, 4, buf))
printf("(%d, %d, %d, %d)\n", p[0], p[1], p[2], p[3]);
}


Bye,
bearophile


Nice! PR anyone?


Re: Sqlite

2015-01-11 Thread ketmar via Digitalmars-d-learn
On Sun, 11 Jan 2015 20:00:03 +
Paul via Digitalmars-d-learn  wrote:

> Can someone please tell me what I'm doing wrong here, the sql 
> INSERT statement fails for some reason. I don't fully understand 
> the callback function yet (I borrowed this from a C tutorial on 
> the subject), maybe that is the source of the problem?
> 
> 
> import etc.c.sqlite3;
> import std.stdio;
> 
> //stub
> extern(C) int aCallback(void *n, int c, char **v, char **col)
> {
>return 0;
> }
> 
> void main(){
>   
>   sqlite3 *db;
>   int result = sqlite3_open("myDatabase.db", &db);
>   
>   if (result) {   
>   writeln("Failed to open database");
>   return; 
>   }
>   
>   //create table  
>   char *msg = null;
>   result = sqlite3_exec(db, "CREATE TABLE people('id INT PRIMARY 
> KEY NOT NULL, surname TEXT NOT NULL');", &aCallback, null, &msg);
>   if (result) {   
>   writeln("Failed to create table");
>   
>   //tidy up on exit
>   sqlite3_close(db);
>   return; 
>   }
>   
>   //insert record
>   msg = null;
>   result = sqlite3_exec(db, "INSERT INTO people (id, surname) 
> VALUES (1, 'Smith');", &aCallback, null, &msg);
>   if (result) {   
>   writeln("Failed to insert record");
>   
>   //tidy up on exit
>   sqlite3_close(db);  
>   return; 
>   
>   }   
> 
>   sqlite3_free(msg);
>   sqlite3_close(db);  
> 
> }
> 
> Many thanks
> 
> Paul
if you'll output the error message, you'll see something unusual here:

  if (result) {
import std.conv : to;
writeln("Failed to insert record: ", to!string(msg));
//tidy up on exit
sqlite3_close(db);  
return; 
  } 

"Failed to insert record: table people has no column named id"

wow! but it has! or isn't it? yep, it hasn't. the error is here:
>   result = sqlite3_exec(db, "CREATE TABLE people('id INT PRIMARY 
> KEY NOT NULL, surname TEXT NOT NULL');", &aCallback, null, &msg);

`CREATE TABLE people('...')` is not the syntax you want. i don't know
why sqlite is not rejecting it, but the correct one is this:

  result = sqlite3_exec(db, "CREATE TABLE people(id INT PRIMARY "~
"KEY NOT NULL, surname TEXT NOT NULL);", &aCallback, null, &msg);

note the single quotes in your code: that is where it all goes wrong. i
don't know where you got that quotes from, but this is not a valid SQL
syntax for `CREATE TABLE`. ;-)


signature.asc
Description: PGP signature


Sqlite

2015-01-11 Thread Paul via Digitalmars-d-learn
Can someone please tell me what I'm doing wrong here, the sql 
INSERT statement fails for some reason. I don't fully understand 
the callback function yet (I borrowed this from a C tutorial on 
the subject), maybe that is the source of the problem?



import etc.c.sqlite3;
import std.stdio;

//stub
extern(C) int aCallback(void *n, int c, char **v, char **col)
{
  return 0;
}

void main(){

sqlite3 *db;
int result = sqlite3_open("myDatabase.db", &db);

if (result) {   
writeln("Failed to open database");
return; 
}

//create table  
char *msg = null;
	result = sqlite3_exec(db, "CREATE TABLE people('id INT PRIMARY 
KEY NOT NULL, surname TEXT NOT NULL');", &aCallback, null, &msg);

if (result) {   
writeln("Failed to create table");

//tidy up on exit
sqlite3_close(db);
return; 
}

//insert record
msg = null;
	result = sqlite3_exec(db, "INSERT INTO people (id, surname) 
VALUES (1, 'Smith');", &aCallback, null, &msg);

if (result) {   
writeln("Failed to insert record");

//tidy up on exit
sqlite3_close(db);  
return; 

}   

sqlite3_free(msg);
sqlite3_close(db);  

}

Many thanks

Paul


Re: Build all combinations of strings

2015-01-11 Thread bearophile via Digitalmars-d-learn

Nordlöw:


Is doCopy really needed as an argument here?

Couldn't this be inferred from the mutability of T instead?


doCopy is useful, if it's true all the permutation arrays are 
distinct and dup-ped, otherwise they are all different. It's true 
by default, so casual users of that generator will avoid bugs. 
You can set it to false to speed up your code.



Later I have refined the idea, you can see it here, that allows 
true @nogc code when needed:


struct CartesianPower(bool doCopy=true, T) {
T[] items;
uint repeat;
T[] row;
uint i, maxN;

this(T[] items_, in uint repeat_, T[] buffer) pure nothrow 
@safe @nogc {

this.items = items_;
this.repeat = repeat_;
row = buffer[0 .. repeat];
row[] = items[0];
maxN = items.length ^^ repeat;
}

static if (doCopy) {
@property T[] front() pure nothrow @safe @nogc {
return row.dup;
}
} else {
@property T[] front() pure nothrow @safe @nogc {
return row;
}
}

@property bool empty() pure nothrow @safe @nogc {
return i >= maxN;
}

void popFront() pure nothrow @safe @nogc {
i++;
if (empty)
return;
uint n = i;
size_t count = repeat - 1;
while (n) {
row[count] = items[n % items.length];
count--;
n /= items.length;
}
}
}

auto cartesianPower(bool doCopy=true, T)(T[] items, in uint 
repeat)

pure nothrow @safe {
return CartesianPower!(doCopy, T)(items, repeat, new 
T[repeat]);

}

auto cartesianPower(bool doCopy=true, T)(T[] items, in uint 
repeat, T[] buffer)

pure nothrow @safe @nogc {
if (buffer.length >= repeat) {
return CartesianPower!(doCopy, T)(items, repeat, buffer);
} else {
// Is this correct in presence of chaining?
static immutable err = new Error("buffer.length < 
repeat");

throw err;
}
}

void main() @nogc {
import core.stdc.stdio;
int[3] items = [10, 20, 30];
int[4] buf;
foreach (p; cartesianPower!false(items, 4, buf))
printf("(%d, %d, %d, %d)\n", p[0], p[1], p[2], p[3]);
}


Bye,
bearophile


Re: Build all combinations of strings

2015-01-11 Thread Nordlöw

On Monday, 11 June 2012 at 19:52:38 UTC, bearophile wrote:

Using that the code is:

import std.string, std.stdio, std.array;
void main() {
auto words = "foo bar doo".split();
auto res = permutations!false(words).map!(p => p.join(" 
"))().array();

writeln(res);
}


Is doCopy really needed as an argument here?

Couldn't this be inferred from the mutability of T instead?


How to interface with C++ code or dll?

2015-01-11 Thread Suliman via Digitalmars-d-learn

I am trying to understand how to use C++ lib from D.
For my App I need http://www.gdal.org

I had read about using C++ libs from D, and understood that there 
is 2 ways:
1. Make binding - convert .H to .d (I still do not fully 
understand what is it)

2. Use directly C++ lib (.dll)

I decided to start from simple example 
http://www.gdal.org/warptut.html


For compiling it's need #include "gdalwarper.h", so I maked 
gdalwarper.d with tool htod.
I know that it's not recommended for usage more, but other tools 
look too complex for me (I even do not understand how to sun them 
on Windows).


After I had add import gdalwarper.d to my test project. But 
during compilation it's asked me about other d files, that I 
included one ny other in App.d file. In the result I got error 
that:
"source\cpl_port.d(147): Error: module ctype is in file 
'std\c\ctype.d' which can not be read"


I have got a question. Files that I include is only header files. 
They do not include any code. How App would run? I should specify 
C++ source location or what?


=

Then I decided to look how to use ready dll. As far as I know D 
have directive pragma(), that allow to import any lib.
Also afaik that it support inly import of dll in format of lib. 
Am I right?


And next. How I can understand which lib do I need. All 
documentation of GDAL assume that programmer will use source 
code, but not libs. And what I should to do? I download gdal 
bins, and there is a lot of dlls and I even can't understand 
which of them I need.


Re: Tuple/Typedef question

2015-01-11 Thread Dicebot via Digitalmars-d-learn

I use this Typedef implementation instead:

/// one with non-default initializer
template Typedef(T, istring name, T initval)
{
static assert (name.length, "Can't create Typedef with an 
empty identifier");


enum Typedef =
("struct " ~ name ~
"{ " ~
T.stringof ~ " value = " ~ initval.stringof ~ ";" 
~

"alias value this;" ~
" }");
}

/// basic overload
template Typedef(T, istring name)
{
static assert (name.length, "Can't create Typedef with an 
empty identifier");


enum Typedef =
("struct " ~ name ~
"{ " ~
T.stringof ~ " value; " ~
"alias value this;" ~
" }");
}

unittest
{
mixin(Typedef!(int, "MyInt1"));
mixin(Typedef!(int, "MyInt2"));

static assert (!is(MyInt1 : MyInt2));
}


Re: Tuple/Typedef question

2015-01-11 Thread ketmar via Digitalmars-d-learn
On Sun, 11 Jan 2015 12:00:19 +
Martin via Digitalmars-d-learn 
wrote:

> > as for `Typedef!` -- you can use it's third arg, "cookie":
> >
> >   import std.typecons;
> >
> >   alias T1 = Tuple!(int, int);
> >   alias T2 = Tuple!(int, int);
> >
> >   alias T1New = Typedef!(T1, T1.init, "t0");
> >   alias T2New = Typedef!(T2, T2.init, "t1");
> >
> >   pragma(msg, __traits(isSame, T1New, T2New)); // false
> >
> > there was a heated discussion about `std.typecons.Typedef`, 
> > built-in
> > `typedef` and other related things, but the decision was to 
> > keep the
> > status quo.
> 
> I can't believe I missed the cookie part. Thanks!
this part deserves a better explanation in docs, 'cause it's easy to
miss the details, especially for those who assumed that each `Typedef!`
creates a distinct type. too bad that my writing skills sux (and i'm
really biased against the current `Typedef!`).


signature.asc
Description: PGP signature


Re: Tuple/Typedef question

2015-01-11 Thread Martin via Digitalmars-d-learn
On Sunday, 11 January 2015 at 11:52:42 UTC, ketmar via 
Digitalmars-d-learn wrote:

On Sun, 11 Jan 2015 11:41:08 +
Martin via Digitalmars-d-learn 


wrote:


Is there a way to get Tuple (and Typedef) from the std.typecons
module to generate a new type that is unique on every
instantiation? What I mean is:

alias T1 = Tuple!(int, int);
alias T2 = Tuple!(int, int);

writeln(__traits(isSame, T1, T2)); // prints true

When using Typedef, the types are still the same:

alias T1New = Typedef!(T1);
alias T2New = Typedef!(T2);

writeln(__traits(isSame, T1New, T2New)); // still prints true

The documentation of Typedef says:
"Typedef allows the creation of a unique type which is based on
an existing type. Unlike the alias feature, Typedef ensures the
two types are not considered as equals."

Shouldn't the second part at least print false then?

as for `Typedef!` -- you can use it's third arg, "cookie":

  import std.typecons;

  alias T1 = Tuple!(int, int);
  alias T2 = Tuple!(int, int);

  alias T1New = Typedef!(T1, T1.init, "t0");
  alias T2New = Typedef!(T2, T2.init, "t1");

  pragma(msg, __traits(isSame, T1New, T2New)); // false

there was a heated discussion about `std.typecons.Typedef`, 
built-in
`typedef` and other related things, but the decision was to 
keep the

status quo.


I can't believe I missed the cookie part. Thanks!


Re: Tuple/Typedef question

2015-01-11 Thread ketmar via Digitalmars-d-learn
On Sun, 11 Jan 2015 11:41:08 +
Martin via Digitalmars-d-learn 
wrote:

> Is there a way to get Tuple (and Typedef) from the std.typecons
> module to generate a new type that is unique on every
> instantiation? What I mean is:
> 
> alias T1 = Tuple!(int, int);
> alias T2 = Tuple!(int, int);
> 
> writeln(__traits(isSame, T1, T2)); // prints true
> 
> When using Typedef, the types are still the same:
> 
> alias T1New = Typedef!(T1);
> alias T2New = Typedef!(T2);
> 
> writeln(__traits(isSame, T1New, T2New)); // still prints true
> 
> The documentation of Typedef says:
> "Typedef allows the creation of a unique type which is based on
> an existing type. Unlike the alias feature, Typedef ensures the
> two types are not considered as equals."
> 
> Shouldn't the second part at least print false then?
as for `Typedef!` -- you can use it's third arg, "cookie":

  import std.typecons;

  alias T1 = Tuple!(int, int);
  alias T2 = Tuple!(int, int);

  alias T1New = Typedef!(T1, T1.init, "t0");
  alias T2New = Typedef!(T2, T2.init, "t1");

  pragma(msg, __traits(isSame, T1New, T2New)); // false

there was a heated discussion about `std.typecons.Typedef`, built-in
`typedef` and other related things, but the decision was to keep the
status quo.


signature.asc
Description: PGP signature


Tuple/Typedef question

2015-01-11 Thread Martin via Digitalmars-d-learn

Is there a way to get Tuple (and Typedef) from the std.typecons
module to generate a new type that is unique on every
instantiation? What I mean is:

alias T1 = Tuple!(int, int);
alias T2 = Tuple!(int, int);

writeln(__traits(isSame, T1, T2)); // prints true

When using Typedef, the types are still the same:

alias T1New = Typedef!(T1);
alias T2New = Typedef!(T2);

writeln(__traits(isSame, T1New, T2New)); // still prints true

The documentation of Typedef says:
"Typedef allows the creation of a unique type which is based on
an existing type. Unlike the alias feature, Typedef ensures the
two types are not considered as equals."

Shouldn't the second part at least print false then?