class
struct
ref
const
nothrow
+ agora |- dub.json |- source/agora |- source/scpd |- source/scpp
"preGenerateCommands": [ "$DUB --verbose --single scripts/build_scpp.d" ], "sourceFiles-posix": [ "source/scpp/build/*.o" ], "sourceFiles-windows": [ "source/scpp/build/*.obj" ], "versions": [ "_GLIBCXX_USE_CXX98_ABI" ], "dflags": [ "-extern-std=c++17" ], "lflags-posix": [ "-lstdc++" ],
CppRuntime_Clang
CppRuntime_Gcc
CppRuntime_Microsoft
extern(C++) struct Foo { int a; } extern(C++) void func1 (ref const(Foo) f); extern(C++) void func2 (const(Foo*) f); extern(C++) void func3 (const(Foo**) f);
struct Foo { int a; }; void func1 (Foo const& f); void func2 (Foo const* f); // void func2 (Foo const* const f); void func3 (Foo const* const* f);
extern(C++, "dlang", "awesome", "app") void awesomeFunc (); // Don't do this: extern(C++, dlang.awesome.app) void lessAwesome (); static assert( lessAwesome.mangleof == dlang.awesome.app.lessAwesome.mangleof);
version (CppRuntime_Clang) enum StdNamespace = AliasSeq!("std", "__1"); else enum StdNamespace = "std"; // Mind the parenthesis! public extern(C++, (StdNamespace)) struct equal_to (T = void) {}
public extern(C++, (StdNamespace)) struct pair (T1, T2) { T1 first; T2 second; }
pragma(mangle, str)
static foreach (Type; GlueTypes) extern(C++) ulong cppSizeOf (ref Type); /// size checks unittest { foreach (Type; GlueTypes) { Type object = Type.init; assert(Type.sizeof == cppSizeOf(object), format("Type '%s' size mismatch: %s (D) != %s (C++)", Type.stringof, Type.sizeof, cppSizeOf(object))); } }
/// Contains the size and offset of a field within a struct extern(C++) struct FieldInfo { long size, offset; } static foreach (Type; GlueTypes) extern(C++) FieldInfo cppFieldInfo (ref Type, const(char)*);
/// size & layout checks for C++ structs / objects unittest { foreach (Type; TypesWithLayout) foreach (idx, field; Type.init.tupleof) { auto object = Type.init; auto field_info = cppFieldInfo(object, Type.tupleof[idx].stringof.toStringz); assert(typeof(field).sizeof == field_info.size, format("Field '%s' of '%s' size mismatch: %s (D) != %s (C++)", Type.tupleof[idx].stringof, Type.stringof, typeof(field).sizeof, field_info.size)); assert(Type.tupleof[idx].offsetof == field_info.offset, format("Field '%s' of '%s' offset mismatch: %s (D) != %s (C++)", Type.tupleof[idx].stringof, Type.stringof, Type.tupleof[idx].offsetof, field_info.offset)); } }
#include <map> template<typename K, typename V> class Map { static Map<K,V>* make () { return new Map<K,V>(); } V& operator[] (K const& key) { return this->map[key]; } void insertOrAssign(const K& key, const V& value) { this->map.insert_or_assign(key, value); } std::map<K, V> map; }; // Explicit instantiation template struct Map<char const*, int>;
extern(C++, class): struct Map (Key, Value) { extern(D) void opIndexAssign (Value value, const Key key) { this.insertOrAssign(key, value); } static Map* make (); ref Value opIndex (ref const Key key); private void insertOrAssign(const ref Key, const ref Value); }
#include <map> template class std::map<char const*, int>;
import core.stdcpp.map; alias MyMap = map!(const(char)*, int);
std
core.stdcpp
allocator
array
vector
string
exception
memory
string_view
map
throw
extern(C++, [class|struct])
extern(C++, ident|expression)
core.attributes : gnuAbiTag
pragma(mangle, str_or_decl, [str])
std::string
__traits(getTargetInfo, "something")
-preview=in
const T&
Slide 5
Disclaimer: POSIX only (MacOS / Windows)
Slide 10
Slide 15
Slide 20
Slide 23