https://wiki.dlang.org/api.php?action=feedcontributions&user=Superstar64&feedformat=atomD Wiki - User contributions [en]2024-03-28T10:04:04ZUser contributionsMediaWiki 1.31.2https://wiki.dlang.org/?title=D_binding_for_C&diff=6671D binding for C2015-09-22T00:27:50Z<p>Superstar64: const -> enum</p>
<hr />
<div>== Introduction ==<br />
While D cannot directly compile C source code, it can easily interface to C code, be linked with C object files, and call C functions in DLLs. <br />
<br />
The interface to C code is normally found in C '''.h''' files. So, the trick to connecting with C code is in converting C .h files to D modules. This turns out to be difficult to do mechanically since inevitably some human judgement must be applied. This is a guide to doing such conversions.<br />
<br />
<br />
== Preprocessor ==<br />
'''.h''' files can sometimes be a bewildering morass of layers of macros, '''#include''' files, '''#ifdef''''s, etc. D doesn't include a text preprocessor like the C preprocessor, so the first step is to remove the need for it by taking the preprocessed output. For DMC (the Digital Mars C/C++ compiler), the command:<br />
<br />
<syntaxhighlight lang="bash"><br />
dmc -c program.h -e -l<br />
</syntaxhighlight><br />
<br />
will create a file '''program.lst''' which is the source file after all text preprocessing.<br />
<br />
For gcc (GNU Compiler Collection), use the command:<br />
<syntaxhighlight lang="bash"><br />
gcc -E -P program.h > program.lst<br />
</syntaxhighlight><br />
<br />
<br />
Remove all the '''#if''', '''#ifdef''', '''#include''', etc. statements.<br />
<br />
== Linkage ==<br />
Generally, surround the entire module with:<br />
<br />
<syntaxhighlight lang="D"><br />
extern (C)<br />
{<br />
/* ...file contents... */<br />
}<br />
</syntaxhighlight><br />
<br />
to give it C linkage.<br />
<br />
=== Global variables ===<br />
<br />
Global variables need to have an extra <code>extern</code> and the <code>__gshared</code> storage.<br />
<br />
''The C Way''<br />
<br />
int a;<br />
<br />
''The D Way''<br />
<br />
extern (C) extern __gshared int a;<br />
<br />
For TLS variables __gshared is not used.<br />
<br />
<br />
== Types ==<br />
<br />
A little global search and replace will take care of renaming the C types to D types. The following tables show typical mappings for 32 bit and 64 bit C code.<br />
Note that there is a difference between them according to the type long. For convencience D offers the type alias '''core.stdc.config.c_ulong''' and '''core.stdc.config.c_long'''. <br />
<br />
Also note that the following lists sometimes show the implicit C variant, e.g., '''long long''' instead of its equivalent explicit variant '''long long int'''.<br />
<br />
For 32 bit systems:<br />
<br />
{| class="wikitable"<br />
|+Mapping C type to D type <br />
!C type <br />
!D type<br />
|-<br />
|long double <br />
|real<br />
|-<br />
|unsigned long long <br />
|ulong<br />
|-<br />
|long long <br />
|long<br />
|-<br />
|unsigned long <br />
|uint<br />
|-<br />
|long <br />
|int<br />
|-<br />
|unsigned int <br />
|uint<br />
|-<br />
|int <br />
|int<br />
|-<br />
|unsigned short <br />
|ushort<br />
|-<br />
|signed char <br />
|byte<br />
|-<br />
|unsigned char <br />
|ubyte<br />
|-<br />
|wchar_t <br />
|wchar or dchar<br />
|-<br />
|bool <br />
|bool, byte, int<br />
|-<br />
|size_t <br />
|size_t<br />
|-<br />
|ptrdiff_t <br />
|ptrdiff_t <br />
<br />
|}<br />
<br />
For 64 bit systems:<br />
<br />
{| class="wikitable"<br />
|+Mapping C type to D type <br />
!C type <br />
!D type<br />
|-<br />
|long double <br />
|real<br />
|-<br />
|unsigned long long <br />
|ulong<br />
|-<br />
|long long <br />
|long<br />
|-<br />
|unsigned long <br />
|uint (Windows) / ulong (Unix)<br />
|-<br />
|long <br />
|int (Windows) / long (Unix) <br />
|-<br />
|unsigned <br />
|uint<br />
|-<br />
|unsigned int <br />
|int<br />
|-<br />
|unsigned short <br />
|ushort<br />
|-<br />
|signed char <br />
|byte<br />
|-<br />
|unsigned char <br />
|ubyte<br />
|-<br />
|wchar_t <br />
|wchar or dchar<br />
|-<br />
|bool <br />
|bool, byte, int<br />
|-<br />
|size_t <br />
|size_t<br />
|-<br />
|ptrdiff_t <br />
|ptrdiff_t <br />
<br />
|}<br />
<br />
== NULL ==<br />
'''NULL''' and '''((void*)0)''' should be replaced with '''null'''.<br />
Numeric Literals<br />
Any ‘L’ or ‘l’ numeric literal suffixes should be removed, as a C '''long''' is (usually) the same size as a D '''int'''. Similarly, ‘LL’ suffixes should be replaced with a single ‘L’. Any ‘u’ suffix will work the same in D.<br />
<br />
== String Literals == <br />
In most cases, any ‘L’ prefix to a string can just be dropped, as D will implicitly convert strings to wide characters if necessary. <br />
<br />
However, one can also replace:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
L"string"<br />
</syntaxhighlight><br />
<br />
with:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
"string"w // for 16 bit wide characters<br />
"string"d // for 32 bit wide characters<br />
</syntaxhighlight><br />
<br />
== Macros ==<br />
Lists of macros like:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
#define FOO 1<br />
#define BAR 2<br />
#define ABC 3<br />
#define DEF 40<br />
</syntaxhighlight><br />
<br />
can be replaced with:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
enum<br />
{ FOO = 1,<br />
BAR = 2,<br />
ABC = 3,<br />
DEF = 40<br />
}<br />
</syntaxhighlight><br />
<br />
or with:<br />
<br />
<syntaxhighlight lang="D"><br />
enum int FOO = 1;<br />
enum int BAR = 2;<br />
enum int ABC = 3;<br />
enum int DEF = 40;<br />
</syntaxhighlight><br />
<br />
Function style macros, such as:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
#define MAX(a,b) ((a) < (b) ? (b) : (a))<br />
</syntaxhighlight><br />
<br />
can be replaced with functions:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
int MAX(int a, int b) { return (a < b) ? b : a; }<br />
</syntaxhighlight><br />
<br />
The functions, however, won't work if they appear inside static initializers that must be evaluated at compile time rather than runtime. To do it at compile time, a template can be used:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
#define GT_DEPTH_SHIFT (0)<br />
#define GT_SIZE_SHIFT (8)<br />
#define GT_SCHEME_SHIFT (24)<br />
#define GT_DEPTH_MASK (0xffU << GT_DEPTH_SHIFT)<br />
#define GT_TEXT ((0x01) << GT_SCHEME_SHIFT)<br />
<br />
/* Macro that constructs a graphtype */<br />
#define GT_CONSTRUCT(depth,scheme,size) \<br />
((depth) | (scheme) | ((size) << GT_SIZE_SHIFT))<br />
<br />
/* Common graphtypes */<br />
#define GT_TEXT16 GT_CONSTRUCT(4, GT_TEXT, 16)<br />
</syntaxhighlight><br />
<br />
The corresponding D version would be:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
enum uint GT_DEPTH_SHIFT = 0;<br />
enum uint GT_SIZE_SHIFT = 8;<br />
enum uint GT_SCHEME_SHIFT = 24;<br />
enum uint GT_DEPTH_MASK = 0xffU << GT_DEPTH_SHIFT;<br />
enum uint GT_TEXT = 0x01 << GT_SCHEME_SHIFT;<br />
<br />
// Template that constructs a graphtype<br />
template GT_CONSTRUCT(uint depth, uint scheme, uint size)<br />
{<br />
// notice the name of the const is the same as that of the template<br />
enum uint GT_CONSTRUCT = (depth | scheme | (size << GT_SIZE_SHIFT));<br />
}<br />
<br />
// Common graphtypes<br />
enum uint GT_TEXT16 = GT_CONSTRUCT!(4, GT_TEXT, 16);<br />
</syntaxhighlight><br />
<br />
== Declaration Lists ==<br />
D doesn't allow declaration lists to change the type. Hence:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
int *p, q, t[3], *s;<br />
</syntaxhighlight><br />
<br />
should be written as:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
int* p, s;<br />
int q;<br />
int[3] t;<br />
</syntaxhighlight><br />
<br />
== Void Parameter Lists ==<br />
Functions that take no parameters:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
int foo(void);<br />
</syntaxhighlight><br />
<br />
are in D:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
int foo();<br />
</syntaxhighlight><br />
<br />
== Extern Global C Variables ==<br />
Whenever a global variable is declared in D, it is also defined. But if it's also defined by the C object file being linked in, there will be a multiple definition error. To fix this problem, use the extern storage class. For example, given a C header file named foo.h:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
struct Foo { };<br />
struct Foo bar;<br />
</syntaxhighlight><br />
<br />
It can be replaced with the D modules, foo.d:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct Foo { }<br />
extern (C)<br />
{<br />
extern Foo bar;<br />
}<br />
</syntaxhighlight><br />
<br />
== Typedef ==<br />
<code>alias</code> is the D equivalent to the C typedef:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
typedef int foo;<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
alias foo = int;<br />
</syntaxhighlight><br />
<br />
== Function pointers ==<br />
<br />
With function pointers there are (at least) two cases where an alias have to be used, instead of a function pointer. <br />
<br />
* When declaring function parameters with a specific linkage.<br />
* When using a cast with a specific linkage. You won't see this in a binding, if you're not converting inline functions.<br />
<br />
=== Function parameters ===<br />
The following is syntactically invalid in D:<br />
<br />
''The C Way''<br />
void foo (extern(C) void function () callback);<br />
<br />
Use an alias:<br />
<br />
''The D Way''<br />
alias Callback = extern (C) void function(); <br />
void foo (Callback callback);<br />
<br />
=== Cast ===<br />
<br />
You won't see this in a binding, if you're not converting inline functions.<br />
<br />
This is invalid in D as well:<br />
<br />
void* foo;<br />
...<br />
auto bar = cast(extern (C) void function ()) foo;<br />
<br />
Use the same approach as above:<br />
<br />
alias Callback = extern (C) void function(); <br />
...<br />
auto bar = cast(Callback) foo;<br />
<br />
== Structs ==<br />
Replace declarations like:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
typedef struct Foo<br />
{ int a;<br />
int b;<br />
} Foo, *pFoo, *lpFoo;<br />
</syntaxhighlight><br />
<br />
with:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct Foo<br />
{ int a;<br />
int b;<br />
}<br />
alias pFoo = Foo*;<br />
alias lpFoo = Foo*;<br />
</syntaxhighlight><br />
<br />
== Anonymous structs ==<br />
If an anonymous struct is used directly to declare a variable you're forced to invent a name for the struct in D, since D doesn't support anonymous structs. <br />
<br />
''The C Way''<br />
<syntaxhighlight lang="D"><br />
struct<br />
{<br />
int a;<br />
int b;<br />
} c; <br />
</syntaxhighlight><br />
Translate to:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct _AnonymousStruct1<br />
{<br />
int a;<br />
int b;<br />
}<br />
<br />
_AnonymousStruct1 c;<br />
</syntaxhighlight><br />
<br />
Any name can be used in this case.<br />
<br />
== Struct Member Alignment ==<br />
A good D implementation by default will align struct members the same way as the C compiler it was designed to work with. But if the .h file has some <code>#pragma</code>'s to control alignment, they can be duplicated with the D align attribute:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
#pragma pack(1)<br />
struct Foo<br />
{<br />
int a;<br />
int b;<br />
};<br />
#pragma pack()<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct Foo<br />
{<br />
align (1):<br />
int a;<br />
int b;<br />
}<br />
</syntaxhighlight><br />
<br />
== Nested Structs ==<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
struct Foo<br />
{<br />
int a;<br />
struct Bar<br />
{<br />
int c;<br />
} bar;<br />
};<br />
<br />
struct Abc<br />
{<br />
int a;<br />
struct<br />
{<br />
int c;<br />
} bar;<br />
};<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct Foo<br />
{<br />
int a;<br />
struct Bar<br />
{<br />
int c;<br />
}<br />
Bar bar;<br />
}<br />
<br />
struct Abc<br />
{<br />
int a;<br />
struct<br />
{<br />
int c;<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
== __cdecl, __pascal, __stdcall ==<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
int __cdecl x;<br />
int __cdecl foo(int a);<br />
int __pascal bar(int b);<br />
int __stdcall abc(int c);<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
extern (C) int x;<br />
extern (C) int foo(int a);<br />
extern (Pascal) int bar(int b);<br />
extern (Windows) int abc(int c);<br />
</syntaxhighlight><br />
<br />
== __declspec(dllimport) ==<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
__declspec(dllimport) int __stdcall foo(int a);<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
export extern (Windows) int foo(int a);<br />
</syntaxhighlight><br />
<br />
== __fastcall ==<br />
Unfortunately, D doesn't support the '''__fastcall''' convention. Therefore, a shim will be needed, either written in C:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
int __fastcall foo(int a);<br />
<br />
int myfoo(int a)<br />
{<br />
return foo(int a);<br />
}<br />
</syntaxhighlight><br />
<br />
and compiled with a C compiler that supports '''__fastcall''' and linked in, or compile the above, disassemble it with [http://www.digitalmars.com/ctg/obj2asm.html obj2asm] and insert it in a D '''myfoo''' shim with [http://dlang.org/iasm.html inline assembler].<br />
<br />
<br />
== See also ==<br />
<br />
* [[Bind D to C]] Obsolete<br />
* [[Binding generators]] Tools which can perform such conversions automatically<br />
* [http://p0nce.github.io/d-idioms/#Porting-from-C-gotchas Porting from C gotchas]<br />
<br />
[[Category:Binding]]<br />
[[Category:HowTo]]</div>Superstar64https://wiki.dlang.org/?title=D_binding_for_C&diff=6670D binding for C2015-09-22T00:24:34Z<p>Superstar64: const globals can have thier addresses taken, c macros and enums can't</p>
<hr />
<div>== Introduction ==<br />
While D cannot directly compile C source code, it can easily interface to C code, be linked with C object files, and call C functions in DLLs. <br />
<br />
The interface to C code is normally found in C '''.h''' files. So, the trick to connecting with C code is in converting C .h files to D modules. This turns out to be difficult to do mechanically since inevitably some human judgement must be applied. This is a guide to doing such conversions.<br />
<br />
<br />
== Preprocessor ==<br />
'''.h''' files can sometimes be a bewildering morass of layers of macros, '''#include''' files, '''#ifdef''''s, etc. D doesn't include a text preprocessor like the C preprocessor, so the first step is to remove the need for it by taking the preprocessed output. For DMC (the Digital Mars C/C++ compiler), the command:<br />
<br />
<syntaxhighlight lang="bash"><br />
dmc -c program.h -e -l<br />
</syntaxhighlight><br />
<br />
will create a file '''program.lst''' which is the source file after all text preprocessing.<br />
<br />
For gcc (GNU Compiler Collection), use the command:<br />
<syntaxhighlight lang="bash"><br />
gcc -E -P program.h > program.lst<br />
</syntaxhighlight><br />
<br />
<br />
Remove all the '''#if''', '''#ifdef''', '''#include''', etc. statements.<br />
<br />
== Linkage ==<br />
Generally, surround the entire module with:<br />
<br />
<syntaxhighlight lang="D"><br />
extern (C)<br />
{<br />
/* ...file contents... */<br />
}<br />
</syntaxhighlight><br />
<br />
to give it C linkage.<br />
<br />
=== Global variables ===<br />
<br />
Global variables need to have an extra <code>extern</code> and the <code>__gshared</code> storage.<br />
<br />
''The C Way''<br />
<br />
int a;<br />
<br />
''The D Way''<br />
<br />
extern (C) extern __gshared int a;<br />
<br />
For TLS variables __gshared is not used.<br />
<br />
<br />
== Types ==<br />
<br />
A little global search and replace will take care of renaming the C types to D types. The following tables show typical mappings for 32 bit and 64 bit C code.<br />
Note that there is a difference between them according to the type long. For convencience D offers the type alias '''core.stdc.config.c_ulong''' and '''core.stdc.config.c_long'''. <br />
<br />
Also note that the following lists sometimes show the implicit C variant, e.g., '''long long''' instead of its equivalent explicit variant '''long long int'''.<br />
<br />
For 32 bit systems:<br />
<br />
{| class="wikitable"<br />
|+Mapping C type to D type <br />
!C type <br />
!D type<br />
|-<br />
|long double <br />
|real<br />
|-<br />
|unsigned long long <br />
|ulong<br />
|-<br />
|long long <br />
|long<br />
|-<br />
|unsigned long <br />
|uint<br />
|-<br />
|long <br />
|int<br />
|-<br />
|unsigned int <br />
|uint<br />
|-<br />
|int <br />
|int<br />
|-<br />
|unsigned short <br />
|ushort<br />
|-<br />
|signed char <br />
|byte<br />
|-<br />
|unsigned char <br />
|ubyte<br />
|-<br />
|wchar_t <br />
|wchar or dchar<br />
|-<br />
|bool <br />
|bool, byte, int<br />
|-<br />
|size_t <br />
|size_t<br />
|-<br />
|ptrdiff_t <br />
|ptrdiff_t <br />
<br />
|}<br />
<br />
For 64 bit systems:<br />
<br />
{| class="wikitable"<br />
|+Mapping C type to D type <br />
!C type <br />
!D type<br />
|-<br />
|long double <br />
|real<br />
|-<br />
|unsigned long long <br />
|ulong<br />
|-<br />
|long long <br />
|long<br />
|-<br />
|unsigned long <br />
|uint (Windows) / ulong (Unix)<br />
|-<br />
|long <br />
|int (Windows) / long (Unix) <br />
|-<br />
|unsigned <br />
|uint<br />
|-<br />
|unsigned int <br />
|int<br />
|-<br />
|unsigned short <br />
|ushort<br />
|-<br />
|signed char <br />
|byte<br />
|-<br />
|unsigned char <br />
|ubyte<br />
|-<br />
|wchar_t <br />
|wchar or dchar<br />
|-<br />
|bool <br />
|bool, byte, int<br />
|-<br />
|size_t <br />
|size_t<br />
|-<br />
|ptrdiff_t <br />
|ptrdiff_t <br />
<br />
|}<br />
<br />
== NULL ==<br />
'''NULL''' and '''((void*)0)''' should be replaced with '''null'''.<br />
Numeric Literals<br />
Any ‘L’ or ‘l’ numeric literal suffixes should be removed, as a C '''long''' is (usually) the same size as a D '''int'''. Similarly, ‘LL’ suffixes should be replaced with a single ‘L’. Any ‘u’ suffix will work the same in D.<br />
<br />
== String Literals == <br />
In most cases, any ‘L’ prefix to a string can just be dropped, as D will implicitly convert strings to wide characters if necessary. <br />
<br />
However, one can also replace:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
L"string"<br />
</syntaxhighlight><br />
<br />
with:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
"string"w // for 16 bit wide characters<br />
"string"d // for 32 bit wide characters<br />
</syntaxhighlight><br />
<br />
== Macros ==<br />
Lists of macros like:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
#define FOO 1<br />
#define BAR 2<br />
#define ABC 3<br />
#define DEF 40<br />
</syntaxhighlight><br />
<br />
can be replaced with:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
enum<br />
{ FOO = 1,<br />
BAR = 2,<br />
ABC = 3,<br />
DEF = 40<br />
}<br />
</syntaxhighlight><br />
<br />
or with:<br />
<br />
<syntaxhighlight lang="D"><br />
enum int FOO = 1;<br />
enum int BAR = 2;<br />
enum int ABC = 3;<br />
enum int DEF = 40;<br />
</syntaxhighlight><br />
<br />
Function style macros, such as:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
#define MAX(a,b) ((a) < (b) ? (b) : (a))<br />
</syntaxhighlight><br />
<br />
can be replaced with functions:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
int MAX(int a, int b) { return (a < b) ? b : a; }<br />
</syntaxhighlight><br />
<br />
The functions, however, won't work if they appear inside static initializers that must be evaluated at compile time rather than runtime. To do it at compile time, a template can be used:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
#define GT_DEPTH_SHIFT (0)<br />
#define GT_SIZE_SHIFT (8)<br />
#define GT_SCHEME_SHIFT (24)<br />
#define GT_DEPTH_MASK (0xffU << GT_DEPTH_SHIFT)<br />
#define GT_TEXT ((0x01) << GT_SCHEME_SHIFT)<br />
<br />
/* Macro that constructs a graphtype */<br />
#define GT_CONSTRUCT(depth,scheme,size) \<br />
((depth) | (scheme) | ((size) << GT_SIZE_SHIFT))<br />
<br />
/* Common graphtypes */<br />
#define GT_TEXT16 GT_CONSTRUCT(4, GT_TEXT, 16)<br />
</syntaxhighlight><br />
<br />
The corresponding D version would be:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
const uint GT_DEPTH_SHIFT = 0;<br />
const uint GT_SIZE_SHIFT = 8;<br />
const uint GT_SCHEME_SHIFT = 24;<br />
const uint GT_DEPTH_MASK = 0xffU << GT_DEPTH_SHIFT;<br />
const uint GT_TEXT = 0x01 << GT_SCHEME_SHIFT;<br />
<br />
// Template that constructs a graphtype<br />
template GT_CONSTRUCT(uint depth, uint scheme, uint size)<br />
{<br />
// notice the name of the const is the same as that of the template<br />
const uint GT_CONSTRUCT = (depth | scheme | (size << GT_SIZE_SHIFT));<br />
}<br />
<br />
// Common graphtypes<br />
const uint GT_TEXT16 = GT_CONSTRUCT!(4, GT_TEXT, 16);<br />
</syntaxhighlight><br />
<br />
== Declaration Lists ==<br />
D doesn't allow declaration lists to change the type. Hence:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
int *p, q, t[3], *s;<br />
</syntaxhighlight><br />
<br />
should be written as:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
int* p, s;<br />
int q;<br />
int[3] t;<br />
</syntaxhighlight><br />
<br />
== Void Parameter Lists ==<br />
Functions that take no parameters:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
int foo(void);<br />
</syntaxhighlight><br />
<br />
are in D:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
int foo();<br />
</syntaxhighlight><br />
<br />
== Extern Global C Variables ==<br />
Whenever a global variable is declared in D, it is also defined. But if it's also defined by the C object file being linked in, there will be a multiple definition error. To fix this problem, use the extern storage class. For example, given a C header file named foo.h:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
struct Foo { };<br />
struct Foo bar;<br />
</syntaxhighlight><br />
<br />
It can be replaced with the D modules, foo.d:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct Foo { }<br />
extern (C)<br />
{<br />
extern Foo bar;<br />
}<br />
</syntaxhighlight><br />
<br />
== Typedef ==<br />
<code>alias</code> is the D equivalent to the C typedef:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
typedef int foo;<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
alias foo = int;<br />
</syntaxhighlight><br />
<br />
== Function pointers ==<br />
<br />
With function pointers there are (at least) two cases where an alias have to be used, instead of a function pointer. <br />
<br />
* When declaring function parameters with a specific linkage.<br />
* When using a cast with a specific linkage. You won't see this in a binding, if you're not converting inline functions.<br />
<br />
=== Function parameters ===<br />
The following is syntactically invalid in D:<br />
<br />
''The C Way''<br />
void foo (extern(C) void function () callback);<br />
<br />
Use an alias:<br />
<br />
''The D Way''<br />
alias Callback = extern (C) void function(); <br />
void foo (Callback callback);<br />
<br />
=== Cast ===<br />
<br />
You won't see this in a binding, if you're not converting inline functions.<br />
<br />
This is invalid in D as well:<br />
<br />
void* foo;<br />
...<br />
auto bar = cast(extern (C) void function ()) foo;<br />
<br />
Use the same approach as above:<br />
<br />
alias Callback = extern (C) void function(); <br />
...<br />
auto bar = cast(Callback) foo;<br />
<br />
== Structs ==<br />
Replace declarations like:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
typedef struct Foo<br />
{ int a;<br />
int b;<br />
} Foo, *pFoo, *lpFoo;<br />
</syntaxhighlight><br />
<br />
with:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct Foo<br />
{ int a;<br />
int b;<br />
}<br />
alias pFoo = Foo*;<br />
alias lpFoo = Foo*;<br />
</syntaxhighlight><br />
<br />
== Anonymous structs ==<br />
If an anonymous struct is used directly to declare a variable you're forced to invent a name for the struct in D, since D doesn't support anonymous structs. <br />
<br />
''The C Way''<br />
<syntaxhighlight lang="D"><br />
struct<br />
{<br />
int a;<br />
int b;<br />
} c; <br />
</syntaxhighlight><br />
Translate to:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct _AnonymousStruct1<br />
{<br />
int a;<br />
int b;<br />
}<br />
<br />
_AnonymousStruct1 c;<br />
</syntaxhighlight><br />
<br />
Any name can be used in this case.<br />
<br />
== Struct Member Alignment ==<br />
A good D implementation by default will align struct members the same way as the C compiler it was designed to work with. But if the .h file has some <code>#pragma</code>'s to control alignment, they can be duplicated with the D align attribute:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
#pragma pack(1)<br />
struct Foo<br />
{<br />
int a;<br />
int b;<br />
};<br />
#pragma pack()<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct Foo<br />
{<br />
align (1):<br />
int a;<br />
int b;<br />
}<br />
</syntaxhighlight><br />
<br />
== Nested Structs ==<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
struct Foo<br />
{<br />
int a;<br />
struct Bar<br />
{<br />
int c;<br />
} bar;<br />
};<br />
<br />
struct Abc<br />
{<br />
int a;<br />
struct<br />
{<br />
int c;<br />
} bar;<br />
};<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
struct Foo<br />
{<br />
int a;<br />
struct Bar<br />
{<br />
int c;<br />
}<br />
Bar bar;<br />
}<br />
<br />
struct Abc<br />
{<br />
int a;<br />
struct<br />
{<br />
int c;<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
== __cdecl, __pascal, __stdcall ==<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
int __cdecl x;<br />
int __cdecl foo(int a);<br />
int __pascal bar(int b);<br />
int __stdcall abc(int c);<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
extern (C) int x;<br />
extern (C) int foo(int a);<br />
extern (Pascal) int bar(int b);<br />
extern (Windows) int abc(int c);<br />
</syntaxhighlight><br />
<br />
== __declspec(dllimport) ==<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
__declspec(dllimport) int __stdcall foo(int a);<br />
</syntaxhighlight><br />
<br />
becomes:<br />
<br />
''The D Way''<br />
<syntaxhighlight lang="D"><br />
export extern (Windows) int foo(int a);<br />
</syntaxhighlight><br />
<br />
== __fastcall ==<br />
Unfortunately, D doesn't support the '''__fastcall''' convention. Therefore, a shim will be needed, either written in C:<br />
<br />
''The C Way''<br />
<syntaxhighlight lang="C"><br />
int __fastcall foo(int a);<br />
<br />
int myfoo(int a)<br />
{<br />
return foo(int a);<br />
}<br />
</syntaxhighlight><br />
<br />
and compiled with a C compiler that supports '''__fastcall''' and linked in, or compile the above, disassemble it with [http://www.digitalmars.com/ctg/obj2asm.html obj2asm] and insert it in a D '''myfoo''' shim with [http://dlang.org/iasm.html inline assembler].<br />
<br />
<br />
== See also ==<br />
<br />
* [[Bind D to C]] Obsolete<br />
* [[Binding generators]] Tools which can perform such conversions automatically<br />
* [http://p0nce.github.io/d-idioms/#Porting-from-C-gotchas Porting from C gotchas]<br />
<br />
[[Category:Binding]]<br />
[[Category:HowTo]]</div>Superstar64https://wiki.dlang.org/?title=DIP67&diff=4940DIP672014-10-31T23:27:26Z<p>Superstar64: </p>
<hr />
<div>{| class="wikitable"<br />
!Title:<br />
!'''Associative Ranges'''<br />
|-<br />
|DIP:<br />
|67<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|'''Rejected'''<br />
|-<br />
|Created:<br />
|2014-10-28<br />
|-<br />
|Last Modified:<br />
|2014-10-31<br />
|-<br />
|Author:<br />
|Freddy "superstar64" Cubas<br />
|-<br />
|Links:<br />
|<br />
[https://github.com/D-Programming-Language/phobos/pull/2646 Pull request for phobos]<br />
|}<br />
<br />
== Abstract ==<br />
Introduce Associative ranges and lazy associative ranges to phobos.<br />
A associative range is a user defined container that has all the features of a build-in associative array.<br />
A lazy associative range is a sub set of a associative with only a index operator(of any type)<br />
== Rationale ==<br />
Allow abtraction of hashmaps with ranges.<br />
<br />
== Description ==<br />
An associative range must have:<br />
A '''byKey''' attribute that returns an input range of keys,<br />
A '''byValue''' attribute that returns an input range of values,<br />
'''byKey''' and '''byValue''' must be align to the same Pair when iterating.<br />
An index operator that takes a key and returns a value.<br />
An in operator that takes a key and returns a value pointer(or a user defined type that acts like one) or null if it doesn't exist.<br />
<br />
A lazy associative range must have:<br />
An alias to the key type "'''KeyType'''"<br />
An alias to the value type "'''ValueType'''"<br />
An index operator that takes a key type and returns value.<br />
<br />
== Usage ==<br />
<syntaxhighlight lang="d"><br />
import std.range;<br />
struct AssociativeRange<br />
{<br />
InputRange!float byKey;<br />
InputRange!uint byValue;<br />
uint opIndex(float);<br />
const (uint)* opBinaryRight(string op)(float) if(op=="in");<br />
}<br />
static assert(isAssociativeRange!AssociativeRange);<br />
alias K=ElementKeyType!AssociativeRange;<br />
alias V=ElementValueType!AssociativeRange;<br />
</syntaxhighlight><br />
<syntaxhighlight lang="d"><br />
import std.range;<br />
struct LazyAssociativeRange<br />
{<br />
alias KeyType=double;<br />
alias ValueType=float;<br />
float opIndex(double);<br />
}<br />
static assert(isLazyAssociativeRange!LazyAssociativeRange);<br />
alias K=ElementKeyType!LazyAssociativeRange;<br />
alias V=ElementValueType!LazyAssociativeRange;<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.<br />
<br />
[[Category: DIP]]</div>Superstar64https://wiki.dlang.org/?title=DIPs&diff=4939DIPs2014-10-31T23:23:39Z<p>Superstar64: </p>
<hr />
<div>{| class="wikitable sortable"<br />
! ID<br />
! Title<br />
! Status<br />
! Description<br />
|-<br />
| [[DIP1]]<br />
| Template DIP<br />
| Draft<br />
| This is a DIP template that can be used as a model to start a new proposal.<br />
|-<br />
| [[DIP2]]<br />
| Const code bloat<br />
| '''Approved'''<br />
| proposed solution for [http://d.puremagic.com/issues/show_bug.cgi?id=1961 bug 1961].<br />
|-<br />
| [[DIP3]]<br />
| Remove inheritance protection<br />
| '''Approved'''<br />
| non-public inheritance in a single inheritance language that has a single root object hierarchy makes little sense.<br />
|-<br />
| [[DIP4]]<br />
| Properties<br />
| [[DIP6|Superseded by DIP6]]<br />
| an alternate usage/definition syntax for properties.<br />
|-<br />
| [[DIP5]]<br />
| Properties 2<br />
| [[DIP6|Superseded by DIP6]]<br />
| a variant of DIP4.<br />
|-<br />
| [[DIP6]]<br />
| Annotations<br />
| '''Approved'''<br />
| extend the D programming language with annotations.<br />
|-<br />
| [[DIP7]]<br />
| Operator overloading<br />
| '''Approved'''<br />
| Revamped operator overloading.<br />
|-<br />
| [[DIP8]]<br />
| Improving Runtime Type Info<br />
| Draft<br />
| Templating RTTI.<br />
|-<br />
| [[DIP9]]<br />
| Redo toString API<br />
| Draft<br />
| Replace inefficient aggregate toString API with efficient delegate-based version that supports formatting.<br />
|-<br />
| [[DIP10]]<br />
| Qualified constructors and destructors for structs<br />
| Draft<br />
|<br />
|-<br />
| [[DIP11]]<br />
| Automatic downloading of imports<br />
| Draft<br />
| Support automatically downloading imported files via new import path specifications or pragmas.<br />
|-<br />
| [[DIP12]]<br />
| C API Headers<br />
| '''Approved'''<br />
| Collection of D headers for common C libraries.<br />
|-<br />
| [[DIP13]]<br />
| Import path binding<br />
| Draft<br />
| Allow to bind an import path to a package.<br />
|-<br />
| [[DIP14]]<br />
| Import path binding in source code<br />
| Draft<br />
| Allow to bind an import path to a package from within sources.<br />
|-<br />
| [[DIP15]]<br />
| Import of packages<br />
| [[DIP37|Superseded by DIP37]]<br />
| Improve imports of packages with submodules.<br />
|-<br />
| [[DIP16]]<br />
| Transparently substitute module with package<br />
| [[DIP37|Superseded by DIP37]]<br />
|<br />
|-<br />
| [[DIP17]]<br />
| Sane volatile statement<br />
| [[DIP20|Superseded by DIP20]]<br />
|<br />
|-<br />
| [[DIP18]]<br />
| Non-GC Threads<br />
| Draft<br />
|<br />
|-<br />
| [[DIP20]]<br />
| Volatile read/write intrinsics<br />
| Draft<br />
| Intrinsics to perform C-style volatile loads/stores from/to memory.<br />
|-<br />
| [[DIP21]]<br />
| Fixing property<br />
| Draft<br />
|<br />
|-<br />
| [[DIP22]]<br />
| Private symbol visibility<br />
| Draft<br />
| Modification of private & Co symbol rules to reduce name clashes. Add internal linkage storage class.<br />
|-<br />
| [[DIP23]]<br />
| Fixing property redux<br />
| Draft<br />
| Initial<br />
|-<br />
| [[DIP24]]<br />
| Fixing properties and optional parens.<br />
| Draft<br />
| Fixing properties and optional parens. Only those. In a general and straightforward way. (counter proposal to DIP23)<br />
|-<br />
| [[DIP25]]<br />
| Sealed references<br />
| Draft<br />
|<br />
|-<br />
| [[DIP26]]<br />
| Properties the other way round<br />
| Draft<br />
|<br />
|-<br />
| [[DIP27]]<br />
| Function definition<br />
| Draft<br />
|<br />
|-<br />
| [[DIP28]]<br />
| Property definition<br />
| Draft<br />
|<br />
|-<br />
| [[DIP29]]<br />
| Unique pointers<br />
| Draft<br />
| Unique pointers can be implicitly cast to/from immutable and shared.<br />
|-<br />
| [[DIP30]]<br />
| Delegate definition<br />
| Draft<br />
|<br />
|-<br />
| [[DIP31]]<br />
| Defined compile time paradox resolution<br />
| Draft<br />
|<br />
|-<br />
| [[DIP32]]<br />
| Uniform tuple syntax<br />
| Draft<br />
|<br />
|-<br />
| [[DIP33]]<br />
| A standard exception hierarchy<br />
| Draft<br />
|<br />
|-<br />
| [[DIP34]]<br />
| Static array literals<br />
| Draft<br />
|<br />
|-<br />
| [[DIP35]]<br />
| [[DIP25|Sealed References]] Amendment<br />
| Draft<br />
|<br />
|-<br />
| [[DIP36]]<br />
| Rvalue References<br />
| Rejected<br />
|<br />
|-<br />
| [[DIP37]]<br />
| Importing Packages as if They Were Modules<br />
| '''Implemented'''<br />
| Allow for packages to be imported as if they were modules by providing a ''package.d'' file.<br />
|<br />
|-<br />
| [[DIP38]]<br />
| Safe references without runtime checks<br />
| Draft<br />
|<br />
|-<br />
| [[DIP39]]<br />
| Safe rvalue references: backwards compatible, safe against ref/nonref code evolution, compatible with UFCS and DIP38.<br />
| Draft<br />
|<br />
|-<br />
| [[DIP40]]<br />
| Template parameter deduction for constructors.<br />
| Draft<br />
|<br />
|-<br />
| [[DIP41]]<br />
| dmd/rdmd command line overhaul.<br />
| Draft<br />
|<br />
|-<br />
| [[DIP42]]<br />
| Support enum E(T) = expression; for manifest constants<br />
| '''Implemented'''<br />
|<br />
|-<br />
| [[DIP43]]<br />
| D/Objective-C<br />
| Draft<br />
| Adds language extensions to make D ABI compatible with Objective-C.<br />
|-<br />
| [[DIP44]]<br />
| scope(this)<br />
| Draft<br />
| Extends scope guards to class / struct lifetime.<br />
|-<br />
| [[DIP45]]<br />
| making export an attribute<br />
| Draft<br />
| Turn export into an attribute and fix various shortcomings of its current implementation.<br />
|-<br />
| [[DIP46]]<br />
| region based storage allocation<br />
| Draft<br />
| Library addition to GC to allow for region based allocation strategies<br />
|-<br />
| [[DIP47]]<br />
| Outline Member Functions of Aggregates<br />
| Draft<br />
| Allow class/struct member function definitions to be placed outside of the class/struct declaration.<br />
|-<br />
| [[DIP48]]<br />
| Interface specifications for aggregate types<br />
| Draft<br />
|<br />
|-<br />
| [[DIP49]]<br />
| Define qualified postblit<br />
| Draft<br />
| Fix D2 type-system hole.<br />
|-<br />
| [[DIP50]]<br />
| AST Macros<br />
| Draft<br />
| Abstract Syntax Tree macros. A general solution for language extensions.<br />
|-<br />
| [[DIP51]]<br />
| not-virtual-by-default<br />
| Draft<br />
| Change the behaviour of class methods so they are not virtual by default.<br />
|-<br />
| [[DIP52]]<br />
| Implicit conversions<br />
| Draft<br />
| Add more implicit conversion options for user-defined types.<br />
|-<br />
| [[DIP53]]<br />
| Qualified constructor revisited<br />
| Draft<br />
| Make qualified constructor definition more simple and understandable.<br />
|-<br />
| [[DIP54]]<br />
| Revamp of Phobos tuple types<br />
| Draft<br />
| Address frequent informational confusion around std.typetuple & friends, initiate transition to std.meta.* package<br />
|-<br />
| [[DIP55]]<br />
| Access Data Items In Ancestor Stack Frames<br />
| Draft<br />
| Support for *caller pointer in functions and adding class features to functions<br />
|-<br />
| [[DIP56]]<br />
| Provide Pragma to control function inlining<br />
| Draft<br />
| Add pragma(inline,true); and pragma(inline,false);<br />
|-<br />
| [[DIP57]]<br />
| static foreach<br />
| Draft<br />
|<br />
|-<br />
| [[DIP58]]<br />
| Make ".." a binary operator<br />
| Draft<br />
|<br />
|-<br />
| [[DIP59]]<br />
| ??<br />
| Draft<br />
|<br />
|-<br />
| [[DIP60]]<br />
| Add @nogc function attribute<br />
| '''Implemented'''<br />
|<br />
|-<br />
| [[DIP61]]<br />
| Add namespace scopes to support calling external C++ functions in C++ namespaces<br />
| Draft<br />
|<br />
|-<br />
| [[DIP62]]<br />
| Volatile type qualifier for unoptimizable variables in embedded programming<br />
| '''Rejected'''<br />
|<br />
|-<br />
| [[DIP63]]<br />
| Operator overloading for raw templates<br />
| Draft<br />
|<br />
|-<br />
| [[DIP64]]<br />
| Attribute Cleanup<br />
| Draft<br />
|<br />
|-<br />
| [[DIP65]]<br />
| Exception handling syntax cleanup<br />
| '''Rejected'''<br />
|<br />
|-<br />
| [[DIP66]]<br />
| (Multiple) alias this<br />
| Draft<br />
|-<br />
| [[DIP67]]<br />
| Associative Ranges<br />
| '''Rejected'''<br />
|}<br />
<br />
----<br />
[[Category:DIP]]</div>Superstar64https://wiki.dlang.org/?title=DIP67&diff=4938DIP672014-10-31T23:23:34Z<p>Superstar64: </p>
<hr />
<div>{| class="wikitable"<br />
!Title:<br />
!'''Associative Ranges'''<br />
|-<br />
|DIP:<br />
|67<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|'''Rejected'''<br />
|-<br />
|Created:<br />
|2014-10-28<br />
|-<br />
|Last Modified:<br />
|2014-10-28<br />
|-<br />
|Author:<br />
|Freddy "superstar64" Cubas<br />
|-<br />
|Links:<br />
|<br />
[https://github.com/D-Programming-Language/phobos/pull/2646 Pull request for phobos]<br />
|}<br />
<br />
== Abstract ==<br />
Introduce Associative ranges and lazy associative ranges to phobos.<br />
A associative range is a user defined container that has all the features of a build-in associative array.<br />
A lazy associative range is a sub set of a associative with only a index operator(of any type)<br />
== Rationale ==<br />
Allow abtraction of hashmaps with ranges.<br />
<br />
== Description ==<br />
An associative range must have:<br />
A '''byKey''' attribute that returns an input range of keys,<br />
A '''byValue''' attribute that returns an input range of values,<br />
'''byKey''' and '''byValue''' must be align to the same Pair when iterating.<br />
An index operator that takes a key and returns a value.<br />
An in operator that takes a key and returns a value pointer(or a user defined type that acts like one) or null if it doesn't exist.<br />
<br />
A lazy associative range must have:<br />
An alias to the key type "'''KeyType'''"<br />
An alias to the value type "'''ValueType'''"<br />
An index operator that takes a key type and returns value.<br />
<br />
== Usage ==<br />
<syntaxhighlight lang="d"><br />
import std.range;<br />
struct AssociativeRange<br />
{<br />
InputRange!float byKey;<br />
InputRange!uint byValue;<br />
uint opIndex(float);<br />
const (uint)* opBinaryRight(string op)(float) if(op=="in");<br />
}<br />
static assert(isAssociativeRange!AssociativeRange);<br />
alias K=ElementKeyType!AssociativeRange;<br />
alias V=ElementValueType!AssociativeRange;<br />
</syntaxhighlight><br />
<syntaxhighlight lang="d"><br />
import std.range;<br />
struct LazyAssociativeRange<br />
{<br />
alias KeyType=double;<br />
alias ValueType=float;<br />
float opIndex(double);<br />
}<br />
static assert(isLazyAssociativeRange!LazyAssociativeRange);<br />
alias K=ElementKeyType!LazyAssociativeRange;<br />
alias V=ElementValueType!LazyAssociativeRange;<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.<br />
<br />
[[Category: DIP]]</div>Superstar64https://wiki.dlang.org/?title=DIP67&diff=4936DIP672014-10-28T22:51:13Z<p>Superstar64: /* Usage */</p>
<hr />
<div>{| class="wikitable"<br />
!Title:<br />
!'''Associative Ranges'''<br />
|-<br />
|DIP:<br />
|67<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Draft<br />
|-<br />
|Created:<br />
|2014-10-28<br />
|-<br />
|Last Modified:<br />
|2014-10-28<br />
|-<br />
|Author:<br />
|Freddy "superstar64" Cubas<br />
|-<br />
|Links:<br />
|<br />
[https://github.com/D-Programming-Language/phobos/pull/2646 Pull request for phobos]<br />
|}<br />
<br />
== Abstract ==<br />
Introduce Associative ranges and lazy associative ranges to phobos.<br />
A associative range is a user defined container that has all the features of a build-in associative array.<br />
A lazy associative range is a sub set of a associative with only a index operator(of any type)<br />
== Rationale ==<br />
Allow abtraction of hashmaps with ranges.<br />
<br />
== Description ==<br />
An associative range must have:<br />
A '''byKey''' attribute that returns an input range of keys,<br />
A '''byValue''' attribute that returns an input range of values,<br />
'''byKey''' and '''byValue''' must be align to the same Pair when iterating.<br />
An index operator that takes a key and returns a value.<br />
An in operator that takes a key and returns a value pointer(or a user defined type that acts like one) or null if it doesn't exist.<br />
<br />
A lazy associative range must have:<br />
An alias to the key type "'''KeyType'''"<br />
An alias to the value type "'''ValueType'''"<br />
An index operator that takes a key type and returns value.<br />
<br />
== Usage ==<br />
<syntaxhighlight lang="d"><br />
import std.range;<br />
struct AssociativeRange<br />
{<br />
InputRange!float byKey;<br />
InputRange!uint byValue;<br />
uint opIndex(float);<br />
const (uint)* opBinaryRight(string op)(float) if(op=="in");<br />
}<br />
static assert(isAssociativeRange!AssociativeRange);<br />
alias K=ElementKeyType!AssociativeRange;<br />
alias V=ElementValueType!AssociativeRange;<br />
</syntaxhighlight><br />
<syntaxhighlight lang="d"><br />
import std.range;<br />
struct LazyAssociativeRange<br />
{<br />
alias KeyType=double;<br />
alias ValueType=float;<br />
float opIndex(double);<br />
}<br />
static assert(isLazyAssociativeRange!LazyAssociativeRange);<br />
alias K=ElementKeyType!LazyAssociativeRange;<br />
alias V=ElementValueType!LazyAssociativeRange;<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.<br />
<br />
[[Category: DIP]]</div>Superstar64https://wiki.dlang.org/?title=DIP67&diff=4935DIP672014-10-28T22:49:00Z<p>Superstar64: /* Usage */</p>
<hr />
<div>{| class="wikitable"<br />
!Title:<br />
!'''Associative Ranges'''<br />
|-<br />
|DIP:<br />
|67<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Draft<br />
|-<br />
|Created:<br />
|2014-10-28<br />
|-<br />
|Last Modified:<br />
|2014-10-28<br />
|-<br />
|Author:<br />
|Freddy "superstar64" Cubas<br />
|-<br />
|Links:<br />
|<br />
[https://github.com/D-Programming-Language/phobos/pull/2646 Pull request for phobos]<br />
|}<br />
<br />
== Abstract ==<br />
Introduce Associative ranges and lazy associative ranges to phobos.<br />
A associative range is a user defined container that has all the features of a build-in associative array.<br />
A lazy associative range is a sub set of a associative with only a index operator(of any type)<br />
== Rationale ==<br />
Allow abtraction of hashmaps with ranges.<br />
<br />
== Description ==<br />
An associative range must have:<br />
A '''byKey''' attribute that returns an input range of keys,<br />
A '''byValue''' attribute that returns an input range of values,<br />
'''byKey''' and '''byValue''' must be align to the same Pair when iterating.<br />
An index operator that takes a key and returns a value.<br />
An in operator that takes a key and returns a value pointer(or a user defined type that acts like one) or null if it doesn't exist.<br />
<br />
A lazy associative range must have:<br />
An alias to the key type "'''KeyType'''"<br />
An alias to the value type "'''ValueType'''"<br />
An index operator that takes a key type and returns value.<br />
<br />
== Usage ==<br />
<syntaxhighlight lang="d"><br />
import std.range;<br />
struct AssociativeRange<br />
{<br />
float[] byKey;<br />
uint[] byValue;<br />
uint opIndex(float);<br />
const (uint)* opBinaryRight(string op)(float) if(op=="in");<br />
}<br />
static assert(isAssociativeRange!AssociativeRange);<br />
alias K=ElementKeyType!AssociativeRange;<br />
alias V=ElementValueType!AssociativeRange;<br />
</syntaxhighlight><br />
<syntaxhighlight lang="d"><br />
import std.range;<br />
struct LazyAssociativeRange<br />
{<br />
alias KeyType=double;<br />
alias ValueType=float;<br />
float opIndex(double);<br />
}<br />
static assert(isLazyAssociativeRange!LazyAssociativeRange);<br />
alias K=ElementKeyType!LazyAssociativeRange;<br />
alias V=ElementValueType!LazyAssociativeRange;<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.<br />
<br />
[[Category: DIP]]</div>Superstar64https://wiki.dlang.org/?title=DIP67&diff=4934DIP672014-10-28T22:43:29Z<p>Superstar64: </p>
<hr />
<div>{| class="wikitable"<br />
!Title:<br />
!'''Associative Ranges'''<br />
|-<br />
|DIP:<br />
|67<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Draft<br />
|-<br />
|Created:<br />
|2014-10-28<br />
|-<br />
|Last Modified:<br />
|2014-10-28<br />
|-<br />
|Author:<br />
|Freddy "superstar64" Cubas<br />
|-<br />
|Links:<br />
|<br />
[https://github.com/D-Programming-Language/phobos/pull/2646 Pull request for phobos]<br />
|}<br />
<br />
== Abstract ==<br />
Introduce Associative ranges and lazy associative ranges to phobos.<br />
A associative range is a user defined container that has all the features of a build-in associative array.<br />
A lazy associative range is a sub set of a associative with only a index operator(of any type)<br />
== Rationale ==<br />
Allow abtraction of hashmaps with ranges.<br />
<br />
== Description ==<br />
An associative range must have:<br />
A '''byKey''' attribute that returns an input range of keys,<br />
A '''byValue''' attribute that returns an input range of values,<br />
'''byKey''' and '''byValue''' must be align to the same Pair when iterating.<br />
An index operator that takes a key and returns a value.<br />
An in operator that takes a key and returns a value pointer(or a user defined type that acts like one) or null if it doesn't exist.<br />
<br />
A lazy associative range must have:<br />
An alias to the key type "'''KeyType'''"<br />
An alias to the value type "'''ValueType'''"<br />
An index operator that takes a key type and returns value.<br />
<br />
== Usage ==<br />
<syntaxhighlight lang="d"><br />
struct AssociativeRange<br />
{<br />
float[] byKey;<br />
uint[] byValue;<br />
uint opIndex(float);<br />
const (uint)* opBinaryRight(string op)(float) if(op=="in");<br />
}<br />
static assert(isAssociativeRange!AssociativeRange);<br />
alias K=ElementKeyType!AssociativeRange;<br />
alias V=ElementValueType!AssociativeRange;<br />
</syntaxhighlight><br />
<syntaxhighlight lang="d"><br />
struct LazyAssociativeRange<br />
{<br />
alias KeyType=double;<br />
alias ValueType=float;<br />
float opIndex(double);<br />
}<br />
static assert(isLazyAssociativeRange!LazyAssociativeRange);<br />
alias K=ElementKeyType!LazyAssociativeRange;<br />
alias V=ElementValueType!LazyAssociativeRange;<br />
</syntaxhighlight><br />
== Copyright ==<br />
This document has been placed in the Public Domain.<br />
<br />
[[Category: DIP]]</div>Superstar64https://wiki.dlang.org/?title=DIPs&diff=4933DIPs2014-10-28T22:40:19Z<p>Superstar64: </p>
<hr />
<div>{| class="wikitable sortable"<br />
! ID<br />
! Title<br />
! Status<br />
! Description<br />
|-<br />
| [[DIP1]]<br />
| Template DIP<br />
| Draft<br />
| This is a DIP template that can be used as a model to start a new proposal.<br />
|-<br />
| [[DIP2]]<br />
| Const code bloat<br />
| '''Approved'''<br />
| proposed solution for [http://d.puremagic.com/issues/show_bug.cgi?id=1961 bug 1961].<br />
|-<br />
| [[DIP3]]<br />
| Remove inheritance protection<br />
| '''Approved'''<br />
| non-public inheritance in a single inheritance language that has a single root object hierarchy makes little sense.<br />
|-<br />
| [[DIP4]]<br />
| Properties<br />
| [[DIP6|Superseded by DIP6]]<br />
| an alternate usage/definition syntax for properties.<br />
|-<br />
| [[DIP5]]<br />
| Properties 2<br />
| [[DIP6|Superseded by DIP6]]<br />
| a variant of DIP4.<br />
|-<br />
| [[DIP6]]<br />
| Annotations<br />
| '''Approved'''<br />
| extend the D programming language with annotations.<br />
|-<br />
| [[DIP7]]<br />
| Operator overloading<br />
| '''Approved'''<br />
| Revamped operator overloading.<br />
|-<br />
| [[DIP8]]<br />
| Improving Runtime Type Info<br />
| Draft<br />
| Templating RTTI.<br />
|-<br />
| [[DIP9]]<br />
| Redo toString API<br />
| Draft<br />
| Replace inefficient aggregate toString API with efficient delegate-based version that supports formatting.<br />
|-<br />
| [[DIP10]]<br />
| Qualified constructors and destructors for structs<br />
| Draft<br />
|<br />
|-<br />
| [[DIP11]]<br />
| Automatic downloading of imports<br />
| Draft<br />
| Support automatically downloading imported files via new import path specifications or pragmas.<br />
|-<br />
| [[DIP12]]<br />
| C API Headers<br />
| '''Approved'''<br />
| Collection of D headers for common C libraries.<br />
|-<br />
| [[DIP13]]<br />
| Import path binding<br />
| Draft<br />
| Allow to bind an import path to a package.<br />
|-<br />
| [[DIP14]]<br />
| Import path binding in source code<br />
| Draft<br />
| Allow to bind an import path to a package from within sources.<br />
|-<br />
| [[DIP15]]<br />
| Import of packages<br />
| [[DIP37|Superseded by DIP37]]<br />
| Improve imports of packages with submodules.<br />
|-<br />
| [[DIP16]]<br />
| Transparently substitute module with package<br />
| [[DIP37|Superseded by DIP37]]<br />
|<br />
|-<br />
| [[DIP17]]<br />
| Sane volatile statement<br />
| [[DIP20|Superseded by DIP20]]<br />
|<br />
|-<br />
| [[DIP18]]<br />
| Non-GC Threads<br />
| Draft<br />
|<br />
|-<br />
| [[DIP20]]<br />
| Volatile read/write intrinsics<br />
| Draft<br />
| Intrinsics to perform C-style volatile loads/stores from/to memory.<br />
|-<br />
| [[DIP21]]<br />
| Fixing property<br />
| Draft<br />
|<br />
|-<br />
| [[DIP22]]<br />
| Private symbol visibility<br />
| Draft<br />
| Modification of private & Co symbol rules to reduce name clashes. Add internal linkage storage class.<br />
|-<br />
| [[DIP23]]<br />
| Fixing property redux<br />
| Draft<br />
| Initial<br />
|-<br />
| [[DIP24]]<br />
| Fixing properties and optional parens.<br />
| Draft<br />
| Fixing properties and optional parens. Only those. In a general and straightforward way. (counter proposal to DIP23)<br />
|-<br />
| [[DIP25]]<br />
| Sealed references<br />
| Draft<br />
|<br />
|-<br />
| [[DIP26]]<br />
| Properties the other way round<br />
| Draft<br />
|<br />
|-<br />
| [[DIP27]]<br />
| Function definition<br />
| Draft<br />
|<br />
|-<br />
| [[DIP28]]<br />
| Property definition<br />
| Draft<br />
|<br />
|-<br />
| [[DIP29]]<br />
| Unique pointers<br />
| Draft<br />
| Unique pointers can be implicitly cast to/from immutable and shared.<br />
|-<br />
| [[DIP30]]<br />
| Delegate definition<br />
| Draft<br />
|<br />
|-<br />
| [[DIP31]]<br />
| Defined compile time paradox resolution<br />
| Draft<br />
|<br />
|-<br />
| [[DIP32]]<br />
| Uniform tuple syntax<br />
| Draft<br />
|<br />
|-<br />
| [[DIP33]]<br />
| A standard exception hierarchy<br />
| Draft<br />
|<br />
|-<br />
| [[DIP34]]<br />
| Static array literals<br />
| Draft<br />
|<br />
|-<br />
| [[DIP35]]<br />
| [[DIP25|Sealed References]] Amendment<br />
| Draft<br />
|<br />
|-<br />
| [[DIP36]]<br />
| Rvalue References<br />
| Rejected<br />
|<br />
|-<br />
| [[DIP37]]<br />
| Importing Packages as if They Were Modules<br />
| '''Implemented'''<br />
| Allow for packages to be imported as if they were modules by providing a ''package.d'' file.<br />
|<br />
|-<br />
| [[DIP38]]<br />
| Safe references without runtime checks<br />
| Draft<br />
|<br />
|-<br />
| [[DIP39]]<br />
| Safe rvalue references: backwards compatible, safe against ref/nonref code evolution, compatible with UFCS and DIP38.<br />
| Draft<br />
|<br />
|-<br />
| [[DIP40]]<br />
| Template parameter deduction for constructors.<br />
| Draft<br />
|<br />
|-<br />
| [[DIP41]]<br />
| dmd/rdmd command line overhaul.<br />
| Draft<br />
|<br />
|-<br />
| [[DIP42]]<br />
| Support enum E(T) = expression; for manifest constants<br />
| '''Implemented'''<br />
|<br />
|-<br />
| [[DIP43]]<br />
| D/Objective-C<br />
| Draft<br />
| Adds language extensions to make D ABI compatible with Objective-C.<br />
|-<br />
| [[DIP44]]<br />
| scope(this)<br />
| Draft<br />
| Extends scope guards to class / struct lifetime.<br />
|-<br />
| [[DIP45]]<br />
| making export an attribute<br />
| Draft<br />
| Turn export into an attribute and fix various shortcomings of its current implementation.<br />
|-<br />
| [[DIP46]]<br />
| region based storage allocation<br />
| Draft<br />
| Library addition to GC to allow for region based allocation strategies<br />
|-<br />
| [[DIP47]]<br />
| Outline Member Functions of Aggregates<br />
| Draft<br />
| Allow class/struct member function definitions to be placed outside of the class/struct declaration.<br />
|-<br />
| [[DIP48]]<br />
| Interface specifications for aggregate types<br />
| Draft<br />
|<br />
|-<br />
| [[DIP49]]<br />
| Define qualified postblit<br />
| Draft<br />
| Fix D2 type-system hole.<br />
|-<br />
| [[DIP50]]<br />
| AST Macros<br />
| Draft<br />
| Abstract Syntax Tree macros. A general solution for language extensions.<br />
|-<br />
| [[DIP51]]<br />
| not-virtual-by-default<br />
| Draft<br />
| Change the behaviour of class methods so they are not virtual by default.<br />
|-<br />
| [[DIP52]]<br />
| Implicit conversions<br />
| Draft<br />
| Add more implicit conversion options for user-defined types.<br />
|-<br />
| [[DIP53]]<br />
| Qualified constructor revisited<br />
| Draft<br />
| Make qualified constructor definition more simple and understandable.<br />
|-<br />
| [[DIP54]]<br />
| Revamp of Phobos tuple types<br />
| Draft<br />
| Address frequent informational confusion around std.typetuple & friends, initiate transition to std.meta.* package<br />
|-<br />
| [[DIP55]]<br />
| Access Data Items In Ancestor Stack Frames<br />
| Draft<br />
| Support for *caller pointer in functions and adding class features to functions<br />
|-<br />
| [[DIP56]]<br />
| Provide Pragma to control function inlining<br />
| Draft<br />
| Add pragma(inline,true); and pragma(inline,false);<br />
|-<br />
| [[DIP57]]<br />
| static foreach<br />
| Draft<br />
|<br />
|-<br />
| [[DIP58]]<br />
| Make ".." a binary operator<br />
| Draft<br />
|<br />
|-<br />
| [[DIP59]]<br />
| ??<br />
| Draft<br />
|<br />
|-<br />
| [[DIP60]]<br />
| Add @nogc function attribute<br />
| '''Implemented'''<br />
|<br />
|-<br />
| [[DIP61]]<br />
| Add namespace scopes to support calling external C++ functions in C++ namespaces<br />
| Draft<br />
|<br />
|-<br />
| [[DIP62]]<br />
| Volatile type qualifier for unoptimizable variables in embedded programming<br />
| '''Rejected'''<br />
|<br />
|-<br />
| [[DIP63]]<br />
| Operator overloading for raw templates<br />
| Draft<br />
|<br />
|-<br />
| [[DIP64]]<br />
| Attribute Cleanup<br />
| Draft<br />
|<br />
|-<br />
| [[DIP65]]<br />
| Exception handling syntax cleanup<br />
| '''Rejected'''<br />
|<br />
|-<br />
| [[DIP66]]<br />
| (Multiple) alias this<br />
| Draft<br />
|-<br />
| [[DIP67]]<br />
| Associative Ranges<br />
| Draft<br />
|}<br />
<br />
----<br />
[[Category:DIP]]</div>Superstar64https://wiki.dlang.org/?title=DIP67&diff=4932DIP672014-10-28T22:39:24Z<p>Superstar64: Created page with "{| class="wikitable" !Title: !'''Associative Ranges''' |- |DIP: |67 |- |Version: |1 |- |Status: |Draft |- |Created: |2014-10-28 |- |Last Modified: |2009-11-15 |- |Author: |Fre..."</p>
<hr />
<div>{| class="wikitable"<br />
!Title:<br />
!'''Associative Ranges'''<br />
|-<br />
|DIP:<br />
|67<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Draft<br />
|-<br />
|Created:<br />
|2014-10-28<br />
|-<br />
|Last Modified:<br />
|2009-11-15<br />
|-<br />
|Author:<br />
|Freddy "superstar64" Cubas<br />
|-<br />
|Links:<br />
|<br />
[https://github.com/D-Programming-Language/phobos/pull/2646 Pull request for phobos]<br />
|}<br />
<br />
== Abstract ==<br />
Introduce Associative ranges and lazy associative ranges to phobos.<br />
A associative range is a user defined container that has all the features of a build-in associative array.<br />
A lazy associative range is a sub set of a associative with only a index operator(of any type)<br />
== Rationale ==<br />
Allow abtraction of hashmaps with ranges.<br />
<br />
== Description ==<br />
An associative range must have:<br />
A '''byKey''' attribute that returns an input range of keys,<br />
A '''byValue''' attribute that returns an input range of values,<br />
'''byKey''' and '''byValue''' must be align to the same Pair when iterating.<br />
An index operator that takes a key and returns a value.<br />
An in operator that takes a key and returns a value pointer(or a user defined type that acts like one) or null if it doesn't exist.<br />
<br />
A lazy associative range must have:<br />
An alias to the key type "'''KeyType'''"<br />
An alias to the value type "'''ValueType'''"<br />
An index operator that takes a key type and returns value.<br />
<br />
== Usage ==<br />
<syntaxhighlight lang="d"><br />
struct AssociativeRange<br />
{<br />
float[] byKey;<br />
uint[] byValue;<br />
uint opIndex(float);<br />
const (uint)* opBinaryRight(string op)(float) if(op=="in");<br />
}<br />
static assert(isAssociativeRange!AssociativeRange);<br />
alias K=ElementKeyType!AssociativeRange;<br />
alias V=ElementValueType!AssociativeRange;<br />
</syntaxhighlight><br />
<syntaxhighlight lang="d"><br />
struct LazyAssociativeRange<br />
{<br />
alias KeyType=double;<br />
alias ValueType=float;<br />
float opIndex(double);<br />
}<br />
static assert(isLazyAssociativeRange!LazyAssociativeRange);<br />
alias K=ElementKeyType!LazyAssociativeRange;<br />
alias V=ElementValueType!LazyAssociativeRange;<br />
</syntaxhighlight><br />
== Copyright ==<br />
This document has been placed in the Public Domain.<br />
<br />
[[Category: DIP]]</div>Superstar64