Add docs for %nspacemove

This commit is contained in:
William S Fulton 2024-05-31 19:04:51 +01:00
parent 946e4ccf18
commit 71e639bd13
6 changed files with 287 additions and 29 deletions

View File

@ -275,6 +275,11 @@
<li><a href="SWIGPlus.html#SWIGPlus_namespaces">Namespaces</a>
<ul>
<li><a href="SWIGPlus.html#SWIGPlus_nspace">The nspace feature for namespaces</a>
<ul>
<li><a href="SWIGPlus.html#SWIGPlus_nspace_feature_flag">%nspace for mirroring namespace hierarchies</a>
<li><a href="SWIGPlus.html#SWIGPlus_nspacemove">%nspacemove for modifying namespace hierarchies</a>
<li><a href="SWIGPlus.html#SWIGPlus_nspace_more">More about the nspace feature</a>
</ul>
</ul>
<li><a href="SWIGPlus.html#SWIGPlus_renaming_templated_types_namespaces">Renaming templated types in namespaces</a>
<li><a href="SWIGPlus.html#SWIGPlus_exception_specifications">Exception specifications</a>
@ -401,6 +406,10 @@
<li><a href="CPlusPlus20.html#CPlusPlus20_lambda_templates">Lambda templates</a>
<li><a href="CPlusPlus20.html#CPlusPlus20_constexpr_destructors">Constexpr destructors</a>
</ul>
<li><a href="CPlusPlus20.html#CPlusPlus20_preprocessor_changes">Preprocessor changes</a>
<ul>
<li><a href="CPlusPlus20.html#CPlusPlus20_va_opt">__VA_OPT__()</a>
</ul>
<li><a href="CPlusPlus20.html#CPlusPlus20_standard_library_changes">Standard library changes</a>
</ul>
</div>
@ -416,7 +425,7 @@
<li><a href="Preprocessor.html#Preprocessor_condition_compilation">Conditional Compilation</a>
<li><a href="Preprocessor.html#Preprocessor_nn5">Macro Expansion</a>
<li><a href="Preprocessor.html#Preprocessor_nn6">SWIG Macros</a>
<li><a href="Preprocessor.html#Preprocessor_nn7">C99 and GNU Extensions</a>
<li><a href="Preprocessor.html#Preprocessor_nn7">Variadic Macros</a>
<li><a href="Preprocessor.html#Preprocessor_delimiters">Preprocessing and delimiters</a>
<ul>
<li><a href="Preprocessor.html#Preprocessor_nn8">Preprocessing and %{ ... %} &amp; " ... " delimiters</a>

View File

@ -425,7 +425,11 @@ struct A {
<H3><a name="D_nspace">24.8.1 Extended namespace support (nspace)</a></H3>
<p>By default, SWIG flattens all C++ namespaces into a single target language namespace, but as for Java and C#, the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature is supported for D. If it is active, C++ namespaces are mapped to D packages/modules. Note, however, that like for the other languages, <em>free</em> variables and functions are not supported yet; currently, they are all allows written to the main proxy D module.</p>
<p>By default, SWIG flattens all C++ namespaces into a flattened D module hierarchy, but as for Java and C#, the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature is supported for D.
If the feature is active, C++ namespaces are mapped to D packages/modules.
This includes the <tt>nspace</tt> feature flag for mirroring the C++ namespaces into D namespaces as a scoped D module/package name.
It also includes <tt>%nspacemove</tt> for transforming a C++ namespace into a completely different scoped D module/package name.
Note, however, that like for the other languages, <em>free</em> variables and functions are not supported yet; currently, they are all available in the main proxy D module.</p>
<H3><a name="D_native_pointer_support">24.8.2 Native pointer support</a></H3>

View File

@ -1929,7 +1929,7 @@ Each SWIG module can be placed into a separate package.
<p>
The default behaviour described above can be improved via the <a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a>.
Note that it only works for classes, structs, unions and enums declared within a named C++ namespace.
When the nspace feature is used, the C++ namespaces are converted into Java packages of the same name.
When the nspace feature is used (either the <tt>nspace</tt> feature flag or <tt>%nspacemove</tt>), the C++ namespaces are converted into Java packages of the same name.
Proxy classes are thus declared within a package and this proxy makes numerous calls to the JNI intermediary class which is declared in the unnamed package by default.
As Java does not support types declared in a named package accessing types declared in an unnamed package, the <tt>-package</tt> commandline option described earlier generally should be used to provide a parent package.
So if SWIG is run using the <tt>-package com.myco</tt> option, a wrapped class, <tt>MyWorld::Material::Color</tt>, can then be accessed as <tt>com.myco.MyWorld.Material.Color</tt>.

View File

@ -1377,13 +1377,15 @@ add exception specification to functions or globally (respectively).
<p>
Since SWIG-3.0.0 C++ namespaces are supported via the %nspace feature.
C++ namespaces are supported via the %nspace feature.
</p>
<p> Namespaces are mapped into Lua tables. Each of those tables contains names that were defined within appropriate namespace. Namespaces structure (a.k.a nested namespaces) is preserved. Consider the following C++ code:
<p> Namespaces are mapped into Lua tables. Each of those tables contains names that were defined within an appropriate namespace. Namespace hierarchies (a.k.a nested namespaces) are preserved. Consider the following C++ code:
</p>
<div class="code"><pre>%module example
%nspace MyWorld::Nested::Dweller;
<div class="code"><pre>
%module example
%nspace MyWorld::World;
%nspace MyWorld::Nested::Dweller;
int module_function() { return 7; }
int module_variable = 9;
@ -1411,34 +1413,69 @@ Now, from Lua usage is as follows:
<div class="targetlang"><pre>
&gt; print(example.module_function())
7
7.0
&gt; print(example.module_variable)
9
9.0
&gt; print(example.MyWorld.World():create_world())
17
&gt; print(example.MyWorld.World.world_max_count)
9
17.0
&gt; print(example.MyWorld.World().world_max_count)
9.0
&gt; print(example.MyWorld.Nested.Dweller.MALE)
0
&gt; print(example.MyWorld.Nested.Dweller.count())
19
&gt;
19.0
</pre></div>
<p>
The hierarchies in Lua are the same as the C++ hierarchies when using <tt>%nspace</tt>,
however, we could instead completely change these hierarchies with <tt>%nspacemove</tt>.
Consider the code above with the two <tt>%nspace</tt> lines of code removed and replaced with the following:
</p>
<div class="code"><pre>
%nspacemove(DifferentWorld::SubSpace1::SubSpace2) MyWorld::World;
%nspacemove(DifferentWorld) MyWorld::Nested::Dweller;
</pre></div>
<p>
The Lua code uses the completely modified hierarchies:
</p>
<div class="targetlang"><pre>
&gt; print(example.module_function())
7.0
&gt; print(example.module_variable)
9.0
&gt; print(example.DifferentWorld.SubSpace1.SubSpace2.World():create_world())
17.0
&gt; print(example.DifferentWorld.SubSpace1.SubSpace2.World().world_max_count)
9.0
&gt; print(example.DifferentWorld.Dweller.MALE)
0
&gt; print(example.DifferentWorld.Dweller.count())
19.0
</pre></div>
<H4><a name="Lua_nn27">29.3.17.1 Compatibility Note </a></H4>
<p>
The nspace feature was first supported by the Lua module in SWIG-3.0.0
</p>
<p>
If SWIG is running in a backwards compatible way, i.e. without the <tt>-no-old-metatable-bindings</tt> option, then additional old-style names are generated (notice the underscore):
</p>
<div class="targetlang"><pre>
9
&gt; print(example.MyWorld.Nested.Dweller_MALE)
0
&gt; print(example.MyWorld.Nested.Dweller_count())
11
&gt;
19.0
</pre></div>
<p>
The ability to move symbols into different namespaces via <tt>%nspacemove</tt> was introduced in SWIG-4.3.0.
</p>
<H4><a name="Lua_nn29">29.3.17.2 Names </a></H4>

View File

@ -72,6 +72,11 @@
<li><a href="#SWIGPlus_namespaces">Namespaces</a>
<ul>
<li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
<ul>
<li><a href="#SWIGPlus_nspace_feature_flag">%nspace for mirroring namespace hierarchies</a>
<li><a href="#SWIGPlus_nspacemove">%nspacemove for modifying namespace hierarchies</a>
<li><a href="#SWIGPlus_nspace_more">More about the nspace feature</a>
</ul>
</ul>
<li><a href="#SWIGPlus_renaming_templated_types_namespaces">Renaming templated types in namespaces</a>
<li><a href="#SWIGPlus_exception_specifications">Exception specifications</a>
@ -4763,15 +4768,31 @@ More advanced handling of namespaces is discussed next.
<p>
Some target languages provide support for the <tt>nspace</tt> <a href="Customization.html#Customization_features">feature</a>.
The feature can be applied to any class, struct, union or enum declared within a named namespace.
The feature wraps the type within the target language specific concept of a namespace,
for example, a Java package or C# namespace.
Please see the language specific sections to see if the target language you are interested in supports the nspace feature.
The <tt>nspace</tt> feature operates in two modes.
Firstly, in a simple enable/disable mode to mirror the C++ namespaces into the target language specific concept of a C++ namespace.
Secondly, a complex mode for modifying, renaming or moving the hierarchies of the language specific concept of a C++ namespace.
</p>
<p>
The feature is demonstrated below for C# using the following example:
The types of symbols that the feature can be applied to are any class, struct, union or enum declared within a named namespace.
This also includes templates of the aforementioned types.
The feature wraps the type within the target language specific concept of a namespace,
such as a Java package or C# namespace.
Only some target languages provide support for the <tt>nspace</tt> feature.
Please see the target language specific sections to see if the language you are interested in supports the nspace feature.
</p>
<H4><a name="SWIGPlus_nspace_feature_flag">6.19.1.1 %nspace for mirroring namespace hierarchies</a></H4>
<p>
In this simple mode the <tt>nspace</tt> feature works as a <a href="Customization.html#Customization_feature_flags">feature flag</a> to enable or disable the feature for a given C++ symbol.
As described earlier, all namespace are flattened by default, hence the <tt>nspace</tt> feature is disabled by default.
When the feature is enabled, the C++ namespace hierarchies are mirrored into the target language concept of a namespace.
</p>
<p>
The feature flag is demonstrated below using the following example:
</p>
<div class="code">
@ -4795,7 +4816,7 @@ namespace MyWorld {
</div>
<p>
Without the <tt>nspace</tt> feature directives above or <tt>%rename</tt>, you would get the following warning resulting in just one of the <tt>Color</tt> classes being available for use from the target language:
By default, without the above <tt>nspace</tt> feature flags (or an appropriate <tt>%rename</tt>), SWIG outputs the following warning resulting in just one of the <tt>Color</tt> classes being available for use from the target language:
</p>
<div class="shell">
@ -4806,14 +4827,24 @@ example.i:5: Error: Previous declaration of 'Color'
</div>
<p>
With the <tt>nspace</tt> feature the two <tt>Color</tt> classes are wrapped into the equivalent C# namespaces.
Let's consider C# as the target language.
With the two <tt>nspace</tt> feature flags, the two C# <tt>Color</tt> proxy classes are generated into the equivalent C# namespaces that mirror the C++ namespace hierarchies.
A fully qualified constructor call of each these two types in C# is then:
</p>
<div class="targetlang">
<pre>
MyWorld.Material.Color materialColor = new MyWorld.Material.Color();
MyWorld.Wrapping.Color wrappingColor = new MyWorld.Wrapping.Color();
var materialColor = new MyWorld.Material.Color();
var wrappingColor = new MyWorld.Wrapping.Color();
</pre>
</div>
<p>
Without the <tt>nspace</tt> feature flag, no namespaces are available in C# and the fully qualified constructor call of the type in C# would simply be:
</p>
<div class="targetlang">
<pre>
var materialColor = new Color();
</pre>
</div>
@ -4837,9 +4868,186 @@ namespace MyWorld {
</div>
<p>
<b>Compatibility Note:</b> The nspace feature was first introduced in SWIG-2.0.0.
<b>Compatibility Note:</b> The simple <tt>%nspace</tt> feature flag was first introduced in SWIG-2.0.0.
</p>
<H4><a name="SWIGPlus_nspacemove">6.19.1.2 %nspacemove for modifying namespace hierarchies</a></H4>
<p>
The more complex mode for <tt>nspace</tt> provides the ability to move a type into a differently named target language equivalent of a namespace.
This allows a fully flexible approach to mapping C++ namespaces into a target language equivalent of a namespace, such as:
</p>
<ul>
<li> Renaming a namespace.</li>
<li> Renaming any number of sub-namespaces of a namespace.</li>
<li> Moving a type to a completely different namespace.</li>
<li> Splitting many types in one namespace into multiple different namespaces.</li>
<li> Adding nested sub-namespaces to a namespace.</li>
<li> Removing nested sub-namespaces of namespace.</li>
<li> Combinations of the above.</li>
</ul>
<p>
The <tt>nspace</tt> feature attaches to a C++ symbol and provides a target language namespace for that symbol to move to.
The <tt>%nspacemove</tt> directive is a macro for the <tt>nspace</tt> feature as follows:
</p>
<div class="code">
<pre>
#define %nspacemove(NAMESPACE) %feature("nspace", #NAMESPACE)
</pre>
</div>
<p>
where the target namespace is provided in <tt>NAMESPACE</tt> and is specified in valid C++ syntax, such as <tt>A::B::C</tt>.
Internally, SWIG converts the C++ namespace into a target language equivalent,
so this might for example, result in a C# namespace called <tt>A.B.C</tt> or a Java package named <tt>A.B.C</tt>.
Note that the target namespace does not have to actually exist in any of the C++ code that SWIG parses; it could be entirely made-up.
</p>
<p>
Either the <tt>%nspacemove</tt> macro or the more verbose <tt>%feature</tt> syntax can be used. Please see the <a href="Customization.html#Customization_features">Features and the %feature directive</a> section for more details of SWIG features.
</p>
<p>
An example follows:
</p>
<div class="code">
<pre>
// Enable the nspace feature flag for all symbols
%nspace;
// Override the nspace feature for a subset of symbols by moving them into different namespaces
%nspacemove(A) A::B::C::Struct1;
%feature("nspace", "A::B::X") A::B::C::Struct2;
%nspacemove(A::B::C::D) A::B::C::Struct4;
%nspacemove(Somewhere::Else) A::B::C::Struct5;
%inline %{
namespace A {
namespace B {
namespace C {
struct Struct1 {
// ...
};
struct Struct2 {
// ...
};
struct Struct3 {
// ...
};
struct Struct4 {
// ...
};
struct Struct5 {
// ...
};
}
}
}
%}
</pre>
</div>
<p>
The C# code below constructs each of the above classes.
It shows the namespaces that the C# proxy classes have been moved into,
noting though that <tt>Struct4</tt> merely exactly mirrors the C++ namespace hierarchy as it has the <tt>nspace</tt> feature flag attached to it.
</p>
<div class="targetlang">
<pre>
var s1 = new A.Struct1();
var s2 = new A.B.X.Struct2();
var s3 = new A.B.C.Struct3();
var s4 = new A.B.C.D.Struct4();
var s5 = new Somewhere.Else.Struct5();
</pre>
</div>
<H4><a name="SWIGPlus_nspace_more">6.19.1.3 More about the nspace feature</a></H4>
<p>
When the <tt>nspace</tt> feature is attached to a class or enum, all contained symbols (members) are also automatically moved into the target language namespace.
Contained symbols include all enum values, static and non-static class members as well as nested classes.
There is no need for additional <tt>nspace</tt> features to be specified for all the contained symbols.
Below is an example showing this.
It also shows the nspace feature working for templates.
</p>
<div class="code">
<pre>
// Easy way to move all the Structure template instantiations into a different namespace
%nspacemove(A::Different::Space) Space::Structure;
%inline %{
namespace Space {
template&lt;typename T&gt;
struct Structure {
static int Count;
static void StaticMethod(T t) {
// ...
}
struct NestedStruct {
// ...
};
};
template&lt;typename T&gt;
int Structure&lt;T&gt;::Count = 0;
}
%}
%template(StructureInt) Space::Structure&lt;int&gt;;
%template(StructureString) Space::Structure&lt;const char *&gt;;
</pre>
</div>
<p>
The C# code below shows the full C# namespace <tt>A.Different.Space</tt> being used as one would expect for all the contained symbols within a C# class.
</p>
<div class="targetlang">
<pre>
var s = new A.Different.Space.StructureInt();
int count = A.Different.Space.StructureInt.Count;
var n = new A.Different.Space.StructureInt.NestedStruct();
A.Different.Space.StructureInt.StaticMethod(99);
A.Different.Space.StructureString.StaticMethod("hi");
</pre>
</div>
<p>
Any attempt to give a different namespace value to a nested class or enum will issue a warning.
For example, adding the following to the above in an attempt to move one of the instantiated nested classes into another namespace like this:
</p>
<div class="code">
<pre>
%nspacemove(Bad::Space) Space::Structure&lt;int&gt;::NestedStruct;
... rest of example above ...
</pre>
</div>
<p>
will result in the following warning:
</p>
<div class="shell">
<pre>
Warning 406: Ignoring nspace setting (Bad::Space) for 'Space::Structure&lt; int &gt;::NestedStruct',
Warning 406: as it conflicts with the nspace setting (A::Different::Space) for outer class 'Space::Structure&lt; int &gt;'.
</pre>
</div>
<p>
<b>Compatibility Note:</b> Modifying namespace hierarchies via <tt>%nspacemove</tt> was first introduced in SWIG-4.3.0.
</p>
<H2><a name="SWIGPlus_renaming_templated_types_namespaces">6.20 Renaming templated types in namespaces</a></H2>

View File

@ -144,7 +144,7 @@
#define %nspace %feature("nspace")
#define %nonspace %feature("nspace","0")
#define %clearnspace %feature("nspace","")
#define %nspacemove(NAME) %feature("nspace", #NAME)
#define %nspacemove(NAMESPACE) %feature("nspace", #NAMESPACE)
/* valuewrapper directives */
#define %valuewrapper %feature("valuewrapper")