From 90a9ac99a8d45522c86ccc5f46efcf0c2155c605 Mon Sep 17 00:00:00 2001
From: William S Fulton
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]];
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++.
+SWIG target languages offer their own threading facilities so there is limited use for them. + -+SWIG does not provide library files for the new tuple types yet. +Variadic template support requires further work to provide substantial tuple wrappers. +
-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.
++The new hash tables in the STL are unordered_set, unordered_multiset, unordered_map, unordered_multimap. +These are not available in SWIG, but in principle should be easily implemented by adapting the current STL containers. +
SWIG does not wrap the new C++11 regular expressions classes, because the SWIG target languages use their own facilities for this.
++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. +
-SWIG provides special smart pointer handling for std::tr1::shared_ptr in the same way it has support for boost::shared_ptr. -There is no special smart pointer handling available for std::weak_ptr and std::unique_ptr. +SWIG provides special smart pointer handling for std::shared_ptr in the same way it has support for boost::shared_ptr. +Please see the shared_ptr smart pointer library section. +There is no special smart pointer handling available for std::weak_ptr and std::unique_ptr yet.
This feature extends and standardizes the standard library only and does not effect the C++ language and SWIG.
+This feature extends and standardizes the standard library only and does not effect the C++ language nor SWIG.
The new ref and cref classes are used to instantiate a parameter as a reference of a template function. For example:
++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 std::reference_wrapper 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. +
-
-void f(int &r) { r++; }
-
-// Template function.
-template< class F, class P > void g(F f, P t) { f(t); }
-
-int main() {
- int i = 0 ;
- g(f, i) ; // 'g<void (int &r), int>' is instantiated
- // then 'i' will not be modified.
- cout << i << endl ; // Output -> 0
-
- g(f, ref(i)) ; // 'g<void(int &r),reference_wrapper<int>>' is instantiated
- // then 'i' will be modified.
- cout << i << endl ; // Output -> 1
-}
-The ref and cref classes are not wrapped by SWIG because the SWIG target languages do not support referencing.
-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 std::function template. SWIG will parse usage of the template like any other template.
@@ -1059,57 +1057,117 @@ b = t(1,2) # invoke C++ function objectThe new C++ metaprogramming is useful at compile time and is aimed specifically for C++ development:
+The type_traits functions to support C++ metaprogramming is useful at compile time and is aimed specifically at C++ development:
+#include <type_traits>
+
// First way of operating.
template< bool B > struct algorithm {
- template< class T1, class T2 > int do_it(T1 &, T2 &) { /*...*/ }
+ template< class T1, class T2 > static int do_it(T1 &, T2 &) { /*...*/ return 1; }
};
+
// Second way of operating.
template<> struct algorithm<true> {
- template< class T1, class T2 > int do_it(T1, T2) { /*...*/ }
+ template< class T1, class T2 > 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< class T1, class T2 > 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< is_integral<T1>::value && is_floating_point<T2>::value >::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< std::is_integral<T1>::value && std::is_floating_point<T2>::value >::do_it(A, B);
}
SWIG correctly parses the template specialization, template types and values inside the <> block and the new helper functions: is_convertible, is_integral, is_const etc. -However, SWIG still explicitly requires concrete types when using the %template directive, so the C++ metaprogramming features are not really of interest at runtime in the target languages.
++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 %template, there isn't much that std::is_integral<int> 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: +
+ ++%template(Elaborate) elaborate<int, int>; +%template(Elaborate) elaborate<int, double>; +
+Then the appropriate algorithm can be called for the subset of types given by the above %template instantiations from a target language, such as Python: +
+ ++>>> Elaborate(0, 0) +1 +>>> Elaborate(0, 0.0) +2 +
SWIG does not wrap the new result_of class introduced in the <functional> header and map the result_of::type to the concrete type yet. For example:
++The new std::result_of class introduced in the <functional> header provides a generic way to obtain the return type of a function type via std::result_of::type. +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 std::result_of using the approach shown below. +The technique basically forward declares the std::result_of template class, then partially specializes it for the function types of interest. +SWIG will use the partial specialization and hence correctly use the std::result_of::type provided in the partial specialization. +
+
%inline %{
#include <functional>
+typedef double(*fn_ptr)(double);
+%}
+
+namespace std {
+ // Forward declaration of result_of
+ template<typename Func> struct result_of;
+ // Add in a partial specialization of result_of
+ template<> struct result_of< fn_ptr(double) > {
+ typedef double type;
+ };
+}
+
+%template() std::result_of< fn_ptr(double) >;
+
+%inline %{
+
double square(double x) {
- return (x * x);
+ return (x * x);
}
template<class Fun, class Arg>
typename std::result_of<Fun(Arg)>::type test_result_impl(Fun fun, Arg arg) {
- return fun(arg);
+ return fun(arg);
}
%}
-%template(test_result) test_result_impl<double(*)(double), double>;
+%template(test_result) test_result_impl< fn_ptr, double >;
%constant double (*SQUARE)(double) = square;
will result in:
++Note the first use of %template which SWIG requires to instantiate the template. +The empty template instantiation suffices as no proxy class is required for std::result_of<Fun(Arg)>::type as this type is really just a double. +The second %template instantiates the template function which is being wrapped for use as a callback. +The %constant can then be used for any callback function as described in Pointers to functions and callbacks. +
+ ++Example usage from Python should give the not too surprising result: +
->>> test_result_impl(SQUARE, 5.0) -<SWIG Object of type 'std::result_of< Fun(Arg) >::type *' at 0x7faf99ed8a50> +>>> test_result(SQUARE, 5.0) +25.0
Instead, please use decltype() where possible for now.
++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 double as the return type in the function declaration instead of result_of! +