C++11 doc updates

This commit is contained in:
William S Fulton 2014-03-14 01:56:41 +00:00
commit 90a9ac99a8
2 changed files with 135 additions and 50 deletions

View file

@ -65,7 +65,7 @@ implementation of the C++11 standard. This part of SWIG is still a work in
progress.
</p>
<p>SWIG supports the new C++ syntax changes with some minor limitations
(decltype expressions, variadic templates number). Wrappers for the
in some areas such as decltype expressions and variadic templates. Wrappers for the
new STL types (unordered_ containers, result_of, tuples) are incomplete.
The wrappers for the new containers would work much like the C++03 containers and
users are welcome to help by adapting the existing container interface files and submitting them
@ -974,62 +974,60 @@ int [[attr1]] i [[attr2, attr3]];
<p>SWIG does not currently wrap or use any of the new threading
classes introduced (thread, mutex, locks, condition variables, task). The main reason is that
SWIG target languages offer their own threading facilities that do not rely on C++.</p>
SWIG target languages offer their own threading facilities so there is limited use for them.
</p>
<H3><a name="CPlusPlus11_tuple_types"></a>7.3.2 Tuple types and hash tables</H3>
<H3><a name="CPlusPlus11_tuple_types"></a>7.3.2 Tuple types</H3>
<p>
SWIG does not provide library files for the new tuple types yet.
Variadic template support requires further work to provide substantial tuple wrappers.
</p>
<p>SWIG does not wrap the new tuple types and the unordered_ container classes yet. Variadic template support is working so it is possible to
include the tuple header file; it is parsed without any problems.</p>
<H3><a name="CPlusPlus11_hash_tables"></a>7.3.2 Hash tables</H3>
<p>
The new hash tables in the STL are <tt>unordered_set</tt>, <tt>unordered_multiset</tt>, <tt>unordered_map</tt>, <tt>unordered_multimap</tt>.
These are not available in SWIG, but in principle should be easily implemented by adapting the current STL containers.
</p>
<H3><a name="CPlusPlus11_regular_expressions"></a>7.3.3 Regular expressions</H3>
<p>SWIG does not wrap the new C++11 regular expressions classes, because the SWIG target languages use their own facilities for this.</p>
<p>
While SWIG could provide wrappers for the new C++11 regular expressions classes, there is little need as the target languages have their own regular expression facilities.
</p>
<H3><a name="CPlusPlus11_general_purpose_smart_pointers"></a>7.3.4 General-purpose smart pointers</H3>
<p>
SWIG provides special smart pointer handling for <tt>std::tr1::shared_ptr</tt> in the same way it has support for <tt>boost::shared_ptr</tt>.
There is no special smart pointer handling available for <tt>std::weak_ptr</tt> and <tt>std::unique_ptr</tt>.
SWIG provides special smart pointer handling for <tt>std::shared_ptr</tt> in the same way it has support for <tt>boost::shared_ptr</tt>.
Please see the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a> library section.
There is no special smart pointer handling available for <tt>std::weak_ptr</tt> and <tt>std::unique_ptr</tt> yet.
</p>
<H3><a name="CPlusPlus11_extensible_random_number_facility"></a>7.3.5 Extensible random number facility</H3>
<p>This feature extends and standardizes the standard library only and does not effect the C++ language and SWIG.</p>
<p>This feature extends and standardizes the standard library only and does not effect the C++ language nor SWIG.</p>
<H3><a name="CPlusPlus11_wrapper_reference"></a>7.3.6 Wrapper reference</H3>
<p>The new ref and cref classes are used to instantiate a parameter as a reference of a template function. For example:</p>
<p>
Wrapper references are similar to normal C++ references but are copy-constructible and copy-assignable.
They could conceivably be used in public APIs.
There is no special support for <tt>std::reference_wrapper</tt> in SWIG though.
Users would need to write their own typemaps if wrapper references are being used and these would be similar to the plain C++ reference typemaps.
</p>
<div class="code"><pre>
void f(int &amp;r) { r++; }
// Template function.
template&lt; class F, class P &gt; void g(F f, P t) { f(t); }
int main() {
int i = 0 ;
g(f, i) ; // 'g&lt;void (int &amp;r), int&gt;' is instantiated
// then 'i' will not be modified.
cout &lt;&lt; i &lt;&lt; endl ; // Output -&gt; 0
g(f, ref(i)) ; // 'g&lt;void(int &amp;r),reference_wrapper&lt;int&gt;&gt;' is instantiated
// then 'i' will be modified.
cout &lt;&lt; i &lt;&lt; endl ; // Output -&gt; 1
}
</pre></div>
<p>The ref and cref classes are not wrapped by SWIG because the SWIG target languages do not support referencing.</p>
<H3><a name="CPlusPlus11_polymorphous_wrappers_for_function_objects"></a>7.3.7 Polymorphous wrappers for function objects</H3>
<p>
SWIG supports functor classes in some languages in a very natural way.
SWIG supports functor classes in a few languages in a very natural way.
However nothing is provided yet for the new <tt>std::function</tt> template.
SWIG will parse usage of the template like any other template.
</p>
@ -1059,57 +1057,117 @@ b = t(1,2) # invoke C++ function object
<H3><a name="CPlusPlus11_type_traits_for_metaprogramming"></a>7.3.8 Type traits for metaprogramming</H3>
<p>The new C++ metaprogramming is useful at compile time and is aimed specifically for C++ development:</p>
<p>The type_traits functions to support C++ metaprogramming is useful at compile time and is aimed specifically at C++ development:</p>
<div class="code"><pre>
#include &lt;type_traits&gt;
// First way of operating.
template&lt; bool B &gt; struct algorithm {
template&lt; class T1, class T2 &gt; int do_it(T1 &amp;, T2 &amp;) { /*...*/ }
template&lt; class T1, class T2 &gt; static int do_it(T1 &amp;, T2 &amp;) { /*...*/ return 1; }
};
// Second way of operating.
template&lt;&gt; struct algorithm&lt;true&gt; {
template&lt; class T1, class T2 &gt; int do_it(T1, T2) { /*...*/ }
template&lt; class T1, class T2 &gt; static int do_it(T1, T2) { /*...*/ return 2; }
};
// Instantiating 'elaborate' will automatically instantiate the correct way to operate.
// Instantiating 'elaborate' will automatically instantiate the correct way to operate, depending on the types used.
template&lt; class T1, class T2 &gt; int elaborate(T1 A, T2 B) {
// Use the second way only if 'T1' is an integer and if 'T2' is
// in floating point, otherwise use the first way.
return algorithm&lt; is_integral&lt;T1&gt;::value &amp;&amp; is_floating_point&lt;T2&gt;::value &gt;::do_it(A, B);
// Use the second way only if 'T1' is an integer and if 'T2' is a floating point,
// otherwise use the first way.
return algorithm&lt; std::is_integral&lt;T1&gt;::value &amp;&amp; std::is_floating_point&lt;T2&gt;::value &gt;::do_it(A, B);
}
</pre></div>
<p>SWIG correctly parses the template specialization, template types and values inside the &lt;&gt; block and the new helper functions: is_convertible, is_integral, is_const etc.
However, SWIG still explicitly requires concrete types when using the <tt>%template</tt> directive, so the C++ metaprogramming features are not really of interest at runtime in the target languages.</p>
<p>
SWIG correctly parses the template specialization, template types etc.
However, metaprogramming and the additional support in the type_traits header is really for compile time and is not much use at runtime for the target languages.
For example, as SWIG requires explicit instantiation of templates via <tt>%template</tt>, there isn't much that <tt>std::is_integral&lt;int&gt;</tt> is going to provide by itself.
However, template functions using such metaprogramming techniques might be useful to wrap.
For example, the following instantiations could be made:
</p>
<div class="code"><pre>
%template(Elaborate) elaborate&lt;int, int&gt;;
%template(Elaborate) elaborate&lt;int, double&gt;;
</pre></div>
<p>
Then the appropriate algorithm can be called for the subset of types given by the above <tt>%template</tt> instantiations from a target language, such as Python:
</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; Elaborate(0, 0)
1
&gt;&gt;&gt; Elaborate(0, 0.0)
2
</pre></div>
<H3><a name="CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects"></a>7.3.9 Uniform method for computing return type of function objects</H3>
<p>SWIG does not wrap the new result_of class introduced in the &lt;functional&gt; header and map the result_of::type to the concrete type yet. For example:</p>
<p>
The new <tt>std::result_of</tt> class introduced in the &lt;functional&gt; header provides a generic way to obtain the return type of a function type via <tt>std::result_of::type</tt>.
There isn't any library interface file to support this type.
With a bit of work, SWIG will deduce the return type of functions when used in <tt>std::result_of</tt> using the approach shown below.
The technique basically forward declares the <tt>std::result_of</tt> template class, then partially specializes it for the function types of interest.
SWIG will use the partial specialization and hence correctly use the <tt>std::result_of::type</tt> provided in the partial specialization.
</p>
<div class="code"><pre>
%inline %{
#include &lt;functional&gt;
typedef double(*fn_ptr)(double);
%}
namespace std {
// Forward declaration of result_of
template&lt;typename Func&gt; struct result_of;
// Add in a partial specialization of result_of
template&lt;&gt; struct result_of&lt; fn_ptr(double) &gt; {
typedef double type;
};
}
%template() std::result_of&lt; fn_ptr(double) &gt;;
%inline %{
double square(double x) {
return (x * x);
return (x * x);
}
template&lt;class Fun, class Arg&gt;
typename std::result_of&lt;Fun(Arg)&gt;::type test_result_impl(Fun fun, Arg arg) {
return fun(arg);
return fun(arg);
}
%}
%template(test_result) test_result_impl&lt;double(*)(double), double&gt;;
%template(test_result) test_result_impl&lt; fn_ptr, double &gt;;
%constant double (*SQUARE)(double) = square;
</pre></div>
<p>will result in:</p>
<p>
Note the first use of <tt>%template</tt> which SWIG requires to instantiate the template.
The empty template instantiation suffices as no proxy class is required for <tt>std::result_of&lt;Fun(Arg)&gt;::type</tt> as this type is really just a <tt>double</tt>.
The second <tt>%template</tt> instantiates the template function which is being wrapped for use as a callback.
The <tt>%constant</tt> can then be used for any callback function as described in <a href="SWIG.html#SWIG_nn30">Pointers to functions and callbacks</a>.
</p>
<p>
Example usage from Python should give the not too surprising result:
</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; test_result_impl(SQUARE, 5.0)
&lt;SWIG Object of type 'std::result_of&lt; Fun(Arg) &gt;::type *' at 0x7faf99ed8a50&gt;
&gt;&gt;&gt; test_result(SQUARE, 5.0)
25.0
</pre></div>
<p>Instead, please use <tt>decltype()</tt> where possible for now.</p>
<p>
Phew, that is a lot of hard work to get a callback working.
You could just go with the more attractive option of just using <tt>double</tt> as the return type in the function declaration instead of <tt>result_of</tt>!
</p>
</body>
</html>

View file

@ -1719,9 +1719,24 @@ Any thrown STL exceptions will then be gracefully handled instead of causing a c
<p>
Some target languages have support for handling the widely used <tt>boost::shared_ptr</tt> smart pointer.
This smart pointer is also available as <tt>std::tr1::shared_ptr</tt> before it becomes fully standardized as <tt>std::shared_ptr</tt>.
The <tt>boost_shared_ptr.i</tt> library provides support for <tt>boost::shared_ptr</tt> and <tt>std_shared_ptr.i</tt> provides support for <tt>std::shared_ptr</tt>, but if the following macro is defined as shown, it can be used for <tt>std::tr1::shared_ptr</tt>:
Some target languages have support for handling the shared_ptr reference counted smart pointer.
This smart pointer is available in the standard C++11 library as <tt>std::shared_ptr</tt>.
It was also in TR1 as <tt>std::tr1::shared_ptr</tt> before it was fully standardized.
Support for the widely used <tt>boost::shared_ptr</tt> is also available.
</p>
<p>
In order to use <tt>std::shared_ptr</tt>, the <tt>std_shared_ptr.i</tt> library file should be included:
</p>
<div class="code">
<pre>
%include &lt;std_shared_ptr.i&gt;
</pre>
</div>
<p>
The pre-standard <tt>std::tr1::shared_ptr</tt> can be used by including the following macro before including the <tt>std_shared_ptr.i</tt> library file:
</p>
<div class="code">
@ -1731,6 +1746,16 @@ The <tt>boost_shared_ptr.i</tt> library provides support for <tt>boost::shared_p
</pre>
</div>
<p>
In order to use <tt>boost::shared_ptr</tt>, the <tt>boost_shared_ptr.i</tt> library file should be included:
</p>
<div class="code">
<pre>
%include &lt;boost_shared_ptr.i&gt;
</pre>
</div>
<p>
You can only use one of these variants of shared_ptr in your interface file at a time.
and all three variants must be used in conjunction with the <tt>%shared_ptr(T)</tt> macro,
@ -1874,7 +1899,9 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
</pre>
</div>
<p>
<b>Note:</b> There is currently no support for <tt>%shared_ptr</tt> and the director feature.
</p>
<H3><a name="Library_std_auto_ptr"></a>8.4.5 auto_ptr smart pointer</H3>