diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 56afca857..67f0c3965 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -246,6 +246,15 @@
-Starting with SWIG-1.3.7, simple C++ template declarations can also be -wrapped. SWIG-1.3.12 greatly expands upon the earlier implementation. Before discussing this any further, there are a few things -you need to know about template wrapping. First, a bare C++ template +There are a couple of important points about template wrapping. +First, a bare C++ template does not define any sort of runnable object-code for which SWIG can normally create a wrapper. Therefore, in order to wrap a template, you need to give SWIG information about a particular template -instantiation (e.g., vector<int>, +instantiation (e.g., vector<int>, array<double>, etc.). Second, an instantiation name such as vector<int> is generally not a valid identifier name in most target languages. Thus, you will need to give the -template instantiation a more suitable name such as intvector -when creating a wrapper. +template instantiation a more suitable name such as intvector.
-To illustrate, consider the following template definition: +To illustrate, consider the following class template definition:
@@ -2985,14 +2995,26 @@ public:
-By itself, this template declaration is useless--SWIG simply ignores it -because it doesn't know how to generate any code until unless a definition of +By itself, this class template is useless--SWIG simply ignores it +because it doesn't know how to generate any code unless a definition of T is provided. +The %template directive is required to instantiate the template for use in a target language. +The directive requires an identifier name for use in the target language plus the template for instantiation. +The example below instantiates List<int> for use as a class named intList:
++%template(intList) List<int>; ++
-One way to create wrappers for a specific template instantiation is to simply -provide an expanded version of the class directly like this: +The instantiation expands the template code as a C++ compiler would do and then makes it available +under the given identifier name. +Essentially it is the same as wrapping the following concept code where +the class template definition has T expanded to int +(note that this is not entirely valid syntax):
-The %rename directive is needed to give the template class an appropriate identifier -name in the target language (most languages would not recognize C++ template syntax as a valid -class name). The rest of the code is the same as what would appear in a normal -class definition. -
- --Since manual expansion of templates gets old in a hurry, the %template directive can -be used to create instantiations of a template class. Semantically, %template is -simply a shortcut---it expands template code in exactly the same way as shown above. Here -are some examples: -
- --/* Instantiate a few different versions of the template */ -%template(intList) List<int>; -%template(doubleList) List<double>; --
The argument to %template() is the name of the instantiation in the target language. The name you choose should not conflict with @@ -3053,7 +3053,67 @@ typedef List<int> intList; // OK
-SWIG can also generate wrappers for function templates using a similar technique. +The %template directive +must always appear after the definition of the template to be expanded, so the following will work: +
+ +
+template<class T> class List { ... };
+%template(intList) List<int>;
+
++but if %template is used before the template definition, such as: +
+ +
+%template(intList) List<int>;
+template<class T> class List { ... };
+
++SWIG will generate an error: +
+ ++example.i:3: Error: Template 'List' undefined. ++
+Since the type system knows how to handle typedef, it is +generally not necessary to instantiate different versions of a template +for typenames that are equivalent. For instance, consider this code: +
+ ++%template(intList) List<int>; +typedef int Integer; +... +void foo(List<Integer> *x); ++
+In this case, List<Integer> is exactly the same type as +List<int>. Any use of List<Integer> is mapped back to the +instantiation of List<int> created earlier. Therefore, it is +not necessary to instantiate a new class for the type Integer (doing so is +redundant and will simply result in code bloat). +
+ ++SWIG can also generate wrappers for function templates using a similar technique +to that shown above for class templates. For example:
@@ -3073,6 +3133,28 @@ In this case, maxint and maxdouble become unique names for spe instantiations of the function. ++SWIG even supports overloaded templated functions. As usual the %template directive +is used to wrap templated functions. For example: +
+ +
+template<class T> void foo(T x) { };
+template<class T> void foo(T x, T y) { };
+
+%template(foo) foo<int>;
+
++This will generate two overloaded wrapper methods, the first will take a single integer as an argument +and the second will take two integer arguments. +
+ +The number of arguments supplied to %template should match that in the original template definition. Template default arguments are supported. For example: @@ -3110,28 +3192,8 @@ instantiation only once in order to reduce the potential for code bloat.
--Since the type system knows how to handle typedef, it is -generally not necessary to instantiate different versions of a template -for typenames that are equivalent. For instance, consider this code: -
+-%template(intList) vector<int>; -typedef int Integer; -... -void foo(vector<Integer> *x); --
-In this case, vector<Integer> is exactly the same type as -vector<int>. Any use of Vector<Integer> is mapped back to the -instantiation of vector<int> created earlier. Therefore, it is -not necessary to instantiate a new class for the type Integer (doing so is -redundant and will simply result in code bloat). -
When a template is instantiated using %template, information @@ -3158,13 +3220,13 @@ nothing is known about List<int>, you will get a warning message
-example.h:42: Warning 401. Nothing known about class 'List<int >'. Ignored. -example.h:42: Warning 401. Maybe you forgot to instantiate 'List<int >' using %template. +example.h:42: Warning 401. Nothing known about class 'List< int >'. Ignored. +example.h:42: Warning 401. Maybe you forgot to instantiate 'List< int >' using %template.
-If a template class inherits from another template class, you need to +If a class template inherits from another class template, you need to make sure that base classes are instantiated before derived classes. For example:
@@ -3235,6 +3297,9 @@ TEMPLATE_WRAP(PairStringInt, std::pair<string, int>) Note the use of a vararg macro for the type T. If this wasn't used, the comma in the templated type in the last example would not be possible. +The SWIG template mechanism does support specialization. For instance, if you define a class like this, @@ -3281,7 +3346,7 @@ private: public: List(int max); ~List(); - void append(int obj); + void append(T obj); int length(); T get(int n); }; @@ -3322,10 +3387,13 @@ SWIG implements template argument deduction so that the following partial specia +
-Member function templates are supported. The underlying principle is the same +Member templates are supported. The underlying principle is the same as for normal templates--SWIG can't create a wrapper unless you provide -more information about types. For example, a class with a member template might +more information about types. For example, a class with a member function template might look like this:
@@ -3399,11 +3467,6 @@ methods to the Foo class. --Note: because of the way that templates are handled, the %template directive -must always appear after the definition of the template to be expanded. -
-Now, if your target language supports overloading, you can even try
@@ -3424,7 +3487,7 @@ depending on the argument type.When used with members, the %template directive may be placed in another -template class. Here is a slightly perverse example: +class template. Here is a slightly perverse example:
This declaration is perfectly acceptable to SWIG, but the constructor template will be ignored unless you explicitly expand it. To do that, you could expand a few versions of the constructor -in the template class itself. For example: +in the class template itself. For example:
If all of this isn't quite enough and you really want to make someone's head explode, SWIG directives such as @@ -3568,7 +3634,7 @@ instantiation.
-It is also possible to separate these declarations from the template class. For example: +It is also possible to separate these declarations from the class template. For example:
-SWIG even supports overloaded templated functions. As usual the %template directive -is used to wrap templated functions. For example: -
- -
-template<class T> void foo(T x) { };
-template<class T> void foo(T x, T y) { };
-
-%template(foo) foo<int>;
-
--This will generate two overloaded wrapper methods, the first will take a single integer as an argument -and the second will take two integer arguments. -
-It is even possible to extend a class via %extend with template methods, for example:
@@ -3694,7 +3741,7 @@ For example:
template <class T> class OuterTemplateClass {};
-// The nested class OuterClass::InnerClass inherits from the template class
+// The nested class OuterClass::InnerClass inherits from the class template
// OuterTemplateClass<OuterClass::InnerStruct> and thus the template needs
// to be expanded with %template before the OuterClass declaration.
%template(OuterTemplateClass_OuterClass__InnerStruct)
@@ -4524,7 +4571,7 @@ for member pointers.
In some C++ programs, objects are often encapsulated by smart-pointers
or proxy classes. This is sometimes done to implement automatic memory management (reference counting) or
-persistence. Typically a smart-pointer is defined by a template class where
+persistence. Typically a smart-pointer is defined by a class template where
the -> operator has been overloaded. This class is then wrapped
around some other class. For example: