c++ stdlib and utils for D with noGC
D's standard library isn't really noGC friendly, so, why not make somewhat of a noGC compatible runtime.
And why it's called clib? Because it's a betterCLibrary. But, despite the name it's mainly noGC library.
TODO: a Wiki or something like it.I consider those features to be most essential. C++11 features will probably come after base features. Same for later C++ versions.
- algorithm
- complex
- [-] exception (partially implemented, but more as release-compatible asserts)
- fstream
- functional
- iomanip
- ios
- iosfwd
- iostream
- istream
- iterator
- limits
- locale
- [-] memory (partially implemented, has Mallocator,
_new
and_free
) - numeric
- ostream
- sstream
- stdexcept
- streambuf
- strstream
- typeinfo (used only for extern(C++) classes)
- utility
- bitset
- optional
- [-] deque (do not plan to implement it, not sure how to be completely honest, PR's are welcome though)
- list
- map
- queue
- set
- stack
- string (technically is an alias to
vector!char
with static if shenanigans. WIP) - [-] valarray (same as deque)
- vector
- [-] format (exists in C++20 specs, but my version currently is for emulating c's format function)
- [-] conv (just your normal type conversion)
D's keyword new
can't be used with noGC and to "fix" that there's two functions: _new
and _free
in clib.memory
which can be used to create classes with noGC.
clib.memory._new
can be used to construct class and allocate memory for it and _free
can be used to forcefully free class.
import clib.memory;
class Class {}
void main() @nogc {
Class c = _new!Class();
_free(c);
}
To enable add versions "CLIB_USE_TYPEINFO"
to dub.sdl
or -version=CLIB_USE_TYPEINFO
as compiler flag.
If you want some alternative to D's typeid
and TypeInfo
on extern(C++)
classes 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;
// D way:
class DClass {}
class DChild: DClass{}
DChild dprt;
if (typeid(dprt) != typeid(DClass)) printf("Not same\n");
if (typeid(DClass).isBaseOf(typeid(DChild))) printf("Is child\n");
// Clib way:
class CClass: CppObject {
// No need to do it for CppObject!
// mixin RTTI!CppObject;
}
class CChild: CClass{
// Must be done for each parent, including interfaces
// but excluding CppObject
mixin RTTI!CClass;
}
CChild cprt;
if (_typeid(cprt) != _typeid!CClass) printf("Not same\n");
if (_typeid!CClass().isBaseOf(cprt)) printf("Is child\n");
clib.typeinfo.reinterpret_cast
can be used to work around known bug.
import core.stdc.stdio;
import clib.typecast;
import clib.memory;
extern(C++) class ICpp: CppObject {
void baseFunc() @nogc nothrow { printf("ICpp func\n"); }
}
extern(C++) class CppClass: ICpp {
mixin RTTI!ICpp;
override void baseFunc() @nogc nothrow { printf("CppClass func\n"); }
}
extern(C) int main() @nogc nothrow {
CppClass c = _new!CppClass();
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(c)); // must be a cast
reinterpret_cast!ICpp(c).testBaseFunc(); // or treat it as member
}
- dmd / ldc / gdc - D compiler
- dub - D package manager
- just - Make system
- valgrind - Memory checker
- reuse - See License
See CONTRIBUTING.md.
- Copy of used licenses can be found in
LICENSES
folder. Main license can be found in LICENSE file. - List of authors can be found in AUTHORS.md.
This project is REUSE compliant.