Difference between revisions of "Calypso/TipsAndTricks"
(→Constructing C++ classes or structs on malloc'd memory) |
|||
(4 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
− | == Constructing C++ classes or structs | + | == Constructing C++ classes or structs inside malloc'd memory == |
− | When a C++ library expects to be granted ownership | + | When a C++ library expects to be granted ownership of a piece of memory, the allocation shouldn't be done by the GC unless you always keep a reference to the allocated memory, which is pointless additional work and not always possible. |
− | Calypso provides a small runtime library which contains some | + | Calypso provides a small runtime library which contains some commonplace utility functions, such as <code>cppNew</code> and <code>cppDelete</code> to bypass the GC while constructing C++ class/struct objects: |
<syntaxhighlight lang="D"> | <syntaxhighlight lang="D"> | ||
Line 9: | Line 9: | ||
import (C++) std.unique_ptr; | import (C++) std.unique_ptr; | ||
− | auto testClass = cppNew!MyCppClass(); // malloc then ctor call | + | auto testClass = cppNew!MyCppClass(...); // malloc then ctor call |
unique_ptr!MyCppClass owner; | unique_ptr!MyCppClass owner; | ||
owner.reset(testClass); | owner.reset(testClass); | ||
Line 15: | Line 15: | ||
// testClass will be free'd by the owner's dtor | // testClass will be free'd by the owner's dtor | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | == New traits == | ||
+ | |||
+ | Calypso provides a few new traits (some of them were needed for the implementation of C++ member function pointers, most of which is in the small Calypso runtime library): | ||
+ | |||
+ | ==== isCpp ==== | ||
+ | <syntaxhighlight lang="D"> | ||
+ | static assert (__traits(isCpp, MyCppClass) == true); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==== getBaseOffset ==== | ||
+ | <syntaxhighlight lang="Cpp"> | ||
+ | struct Base { int n; }; | ||
+ | struct Base2 { int o; }; | ||
+ | |||
+ | class Derived : public Base, public Base2 {}; | ||
+ | </syntaxhighlight> | ||
+ | <syntaxhighlight lang="D"> | ||
+ | static assert (__traits(getBaseOffset, Derived, Base2) == int.sizeof); | ||
+ | </syntaxhighlight> | ||
+ | Works with C++ structs and classes, and D classes. | ||
+ | |||
+ | ==== getCppVirtualIndex ==== | ||
+ | Returns the <strong>C++</strong> virtual table offset (in bytes) of the function, or -1 if it's not a C++ virtual function or a D function overriding one. Remember that an "hybrid" D class deriving from a C++ class usually has two or more virtual tables, the D one and a C++ one. | ||
+ | |||
+ | <syntaxhighlight lang="Cpp"> | ||
+ | class MyCppClass { | ||
+ | virtual int foo(); | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | <syntaxhighlight lang="D"> | ||
+ | class DplusCpp { | ||
+ | override int foo() { return 123; } | ||
+ | } | ||
+ | |||
+ | void main() { | ||
+ | writeln(__traits(getCppVirtualIndex, DplusCpp.foo)); // should prints sizeof(void*)*2 according to the Itanium ABI | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | This trait was added for the library-side implementation of Itanium member function pointers. | ||
+ | |||
+ | [[Category:Experimental compilers]] |
Latest revision as of 05:01, 27 March 2018
Contents
Constructing C++ classes or structs inside malloc'd memory
When a C++ library expects to be granted ownership of a piece of memory, the allocation shouldn't be done by the GC unless you always keep a reference to the allocated memory, which is pointless additional work and not always possible.
Calypso provides a small runtime library which contains some commonplace utility functions, such as cppNew
and cppDelete
to bypass the GC while constructing C++ class/struct objects:
import cpp.memory; // cppNew and cppDelete
import (C++) std.unique_ptr;
auto testClass = cppNew!MyCppClass(...); // malloc then ctor call
unique_ptr!MyCppClass owner;
owner.reset(testClass);
// testClass will be free'd by the owner's dtor
New traits
Calypso provides a few new traits (some of them were needed for the implementation of C++ member function pointers, most of which is in the small Calypso runtime library):
isCpp
static assert (__traits(isCpp, MyCppClass) == true);
getBaseOffset
struct Base { int n; };
struct Base2 { int o; };
class Derived : public Base, public Base2 {};
static assert (__traits(getBaseOffset, Derived, Base2) == int.sizeof);
Works with C++ structs and classes, and D classes.
getCppVirtualIndex
Returns the C++ virtual table offset (in bytes) of the function, or -1 if it's not a C++ virtual function or a D function overriding one. Remember that an "hybrid" D class deriving from a C++ class usually has two or more virtual tables, the D one and a C++ one.
class MyCppClass {
virtual int foo();
};
class DplusCpp {
override int foo() { return 123; }
}
void main() {
writeln(__traits(getCppVirtualIndex, DplusCpp.foo)); // should prints sizeof(void*)*2 according to the Itanium ABI
}
This trait was added for the library-side implementation of Itanium member function pointers.