Skip to content

Commit 889c00d

Browse files
authored
Merge pull request #2789 from thewilsonator/cppns
add methods for dealing with C++ namespaces merged-on-behalf-of: Petar Kirov <PetarKirov@users.noreply.github.com>
2 parents 6023d7b + d99790a commit 889c00d

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

spec/cpp_interface.dd

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,88 @@ void main()
178178
}
179179
------
180180

181+
$(P C++ can open the same namespace in the same file and multiple files.
182+
In D, this can be done as follows:)
183+
184+
---
185+
module ns;
186+
extern (C++, `ns`)
187+
{
188+
int foo() { return 1; }
189+
int bar() { return 2; }
190+
}
191+
---
192+
193+
$(P or in multiple files, by organizing them in a package consisting of several modules:)
194+
---
195+
ns/
196+
|-- a.d
197+
|-- b.d
198+
|-- package.d
199+
---
200+
201+
$(P File `ns/a.d`:)
202+
---
203+
module a; extern (C++, `ns`) { int foo() { return 1; } }
204+
---
205+
206+
$(P File `ns/b.d`:)
207+
---
208+
module b; extern (C++, `ns`) { int bar() { return 2; } }
209+
---
210+
211+
$(P File `ns/package.d`:)
212+
---
213+
module ns;
214+
public import a, b;
215+
---
216+
$(P Then you can import the package containing the extern C++ declarations as follows:)
217+
218+
---
219+
import ns;
220+
static assert(foo() == 1 && bar() == 2);
221+
---
222+
223+
$(P Note that the `extern (C++, `ns`)` linkage attribute affects only the ABI (name mangling and calling convention) of
224+
these declarations. Importing them follows the usual
225+
$(LINK2 spec/module, D module import semantics).)
226+
227+
$(P Alternatively, the non-string form can be used to introduce a scope. Note that the
228+
enclosing module already provides a scope for the symbols declared in the namespace.
229+
This form does not allow closing and reopening the same namespace with in the same module. That is:)
230+
---
231+
module a; extern (C++, ns1) { int foo() { return 1; } }
232+
---
233+
---
234+
module b; extern (C++, ns1) { int bar() { return 2; } }
235+
---
236+
---
237+
import a, b;
238+
static assert(foo() == 1 && bar() == 2);
239+
---
240+
$(P works, but:)
241+
---
242+
extern (C++, ns1) { int foo() { return 1; } }
243+
extern (C++, ns1) { int bar() { return 2; } }
244+
---
245+
$(P does not. Additionally, aliases can be used to avoid collision of symbols:)
246+
---
247+
module a; extern (C++, ns) { int foo() { return 1; } }
248+
---
249+
---
250+
module b; extern (C++, ns) { int bar() { return 2; } }
251+
---
252+
---
253+
module ns;
254+
import a, b;
255+
alias foo = a.ns.foo;
256+
alias bar = b.ns.bar;
257+
---
258+
---
259+
import ns;
260+
static assert(foo() == 1 && bar() == 2);
261+
---
262+
181263
$(H2 $(LNAME2 classes, Classes))
182264

183265
$(P C++ classes can be declared in D by using the $(CODE extern (C++))

0 commit comments

Comments
 (0)