c++ stdlib and utils for D with betterC
D's standard library isn't really noGC and betterC friendly, so, why not make somewhat of a -betterC compatible runtime.
And why it's called clib? Because it's a betterCLibrary. But, despite the name it's mainly noGC library with small amount betterC utilities.
- algorithm
- complex
- exception
- fstream
- functional
- iomanip
- ios
- iosfwd
- iostream
- istream
- iterator
- limits
- locale
- memory (""partially implemented"" with ""allocator"")
- numeric
- ostream
- sstream
- stdexcept
- streambuf
- strstream
- typeinfo (requires hacks due to angry TypeInfo)
- utility
- bitset
- optional
- deque
- list
- map
- queue
- set
- stack
- string (technically is an alias to
vector!char
with static if shenanigans. WIP) - valarray
- vector
Can be enabled when using clib:betterc
as dependency instead of clib
. Everything is same with exception of that clib:betterc
compiles with -betterC
flag, which will prevent linkage errors.
D's keyword new
can't be used with -betterC since it uses TypeInfo and to "fix" that there's a module named classes
. As of now it contains three functions: _new
, _free
and _cast
which can be used to use classes with -betterC.
There's a way to use classes without classes
module. Instantiate your classes as:
__gshared CppClass c = new CppClass();
If you want some alternative to D's typeid
and TypeInfo
then import clib.typeinfo
and derive all your classes from cppObject
. Albeit type_info
can't provide with everything that TypeInfo
provides since D does not provide any RTTI for C++ classes. Example of usage:
import clib.typeinfo;
class CppRTTI: cppObject {
mixin RTTI!cppObject;
}
class ChildCppRTTI: CppRTTI {
mixin RTTI!CppRTTI;
}
ChildCppRTTI cprt;
if (_typeid(cprt) != _typeid!CppRTTI) printf("Not same\n");
if (_typeid!CppRTTI().isBaseOf(cprt)) printf("Is child\n");
_new
can be used to construct class and allocate memory for it
extern(C++) interface ICpp { }
extern(C++) class CppClass: ICpp { }
CppClass c = _new!CppClass();
_free
can be used to forcefully free class
/// Any of those will work
_free(c);
c._free();
clib.typecast
can be used to work around known bug
import clib.typecast;
reinterpret_cast!ICpp(t).icppFunc();
somefunc( t.reinterpret_cast!ICpp );
It is important to know that -betterC places a lot of contraints. Most important ones are new
keyword and no dynamic casts. new
can be easily replaced with _new!
or __gshared ...
, but for dynamic casts you have to work around it unless #21690
will be fixed
void testBaseFunc(ICpp base) {
base.baseFunc();
reinterpret_cast!ICpp(base).baseFunc(); // doesn't matter as it's already ICpp
}
testBaseFunc(c); // will case segfault!!!
testBaseFunc(reinterpret_cast!ICpp(base)); // must be a reinterpret cast
reinterpret_cast!ICpp(base).testBaseFunc(); // or treat it as member