1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * SWIG typemaps for std::vector<T>
9 * The C# wrapper is made to look and feel like a C# System.Collections.Generic.List<> collection.
10 * For .NET 1 compatibility, define SWIG_DOTNET_1 when compiling the C# code; then the C# wrapper is
11 * made to look and feel like a typesafe C# System.Collections.ArrayList.
13 * Note that IEnumerable<> is implemented in the proxy class which is useful for using LINQ with
14 * C++ std::vector wrappers. The IList<> interface is also implemented to provide enhanced functionality
15 * whenever we are confident that the required C++ operator== is available. This is the case for when
16 * T is a primitive type or a pointer. If T does define an operator==, then use the SWIG_STD_VECTOR_ENHANCED
17 * macro to obtain this enhanced functionality, for example:
19 * SWIG_STD_VECTOR_ENHANCED(SomeNamespace::Klass)
20 * %template(VectKlass) std::vector<SomeNamespace::Klass>;
22 * Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents!
23 * ----------------------------------------------------------------------------- */
25 // Warning: Use the typemaps here in the expectation that the macros they are in will change name.
28 %include <std_common.i>
30 // MACRO for use within the std::vector class body
31 %define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CSINTERFACE, CONST_REFERENCE_TYPE, CTYPE...)
32 %typemap(csinterfaces) std::vector<CTYPE > "IDisposable, System.Collections.IEnumerable\n#if !SWIG_DOTNET_1\n , System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n#endif\n";
33 %typemap(cscode) std::vector<CTYPE > %{
34 public $csclassname(System.Collections.ICollection c) : this() {
36 throw new ArgumentNullException("c");
37 foreach ($typemap(cstype, CTYPE) element in c) {
42 public bool IsFixedSize {
48 public bool IsReadOnly {
54 public $typemap(cstype, CTYPE) this[int index] {
56 return getitem(index);
59 setitem(index, value);
65 return (int)capacity();
69 throw new ArgumentOutOfRangeException("Capacity");
80 public bool IsSynchronized {
87 public void CopyTo(System.Array array)
89 public void CopyTo($typemap(cstype, CTYPE)[] array)
92 CopyTo(0, array, 0, this.Count);
96 public void CopyTo(System.Array array, int arrayIndex)
98 public void CopyTo($typemap(cstype, CTYPE)[] array, int arrayIndex)
101 CopyTo(0, array, arrayIndex, this.Count);
105 public void CopyTo(int index, System.Array array, int arrayIndex, int count)
107 public void CopyTo(int index, $typemap(cstype, CTYPE)[] array, int arrayIndex, int count)
111 throw new ArgumentNullException("array");
113 throw new ArgumentOutOfRangeException("index", "Value is less than zero");
115 throw new ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
117 throw new ArgumentOutOfRangeException("count", "Value is less than zero");
119 throw new ArgumentException("Multi dimensional array.", "array");
120 if (index+count > this.Count || arrayIndex+count > array.Length)
121 throw new ArgumentException("Number of elements to copy is too large.");
122 for (int i=0; i<count; i++)
123 array.SetValue(getitemcopy(index+i), arrayIndex+i);
127 System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)> System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)>.GetEnumerator() {
128 return new $csclassnameEnumerator(this);
132 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
133 return new $csclassnameEnumerator(this);
136 public $csclassnameEnumerator GetEnumerator() {
137 return new $csclassnameEnumerator(this);
140 // Type-safe enumerator
141 /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
142 /// whenever the collection is modified. This has been done for changes in the size of the
143 /// collection but not when one of the elements of the collection is modified as it is a bit
144 /// tricky to detect unmanaged code that modifies the collection under our feet.
145 public sealed class $csclassnameEnumerator : System.Collections.IEnumerator
147 , System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)>
150 private $csclassname collectionRef;
151 private int currentIndex;
152 private object currentObject;
153 private int currentSize;
155 public $csclassnameEnumerator($csclassname collection) {
156 collectionRef = collection;
158 currentObject = null;
159 currentSize = collectionRef.Count;
162 // Type-safe iterator Current
163 public $typemap(cstype, CTYPE) Current {
165 if (currentIndex == -1)
166 throw new InvalidOperationException("Enumeration not started.");
167 if (currentIndex > currentSize - 1)
168 throw new InvalidOperationException("Enumeration finished.");
169 if (currentObject == null)
170 throw new InvalidOperationException("Collection modified.");
171 return ($typemap(cstype, CTYPE))currentObject;
175 // Type-unsafe IEnumerator.Current
176 object System.Collections.IEnumerator.Current {
182 public bool MoveNext() {
183 int size = collectionRef.Count;
184 bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
187 currentObject = collectionRef[currentIndex];
189 currentObject = null;
194 public void Reset() {
196 currentObject = null;
197 if (collectionRef.Count != currentSize) {
198 throw new InvalidOperationException("Collection modified.");
203 public void Dispose() {
205 currentObject = null;
212 typedef size_t size_type;
213 typedef CTYPE value_type;
214 typedef CONST_REFERENCE_TYPE const_reference;
215 %rename(Clear) clear;
217 %rename(Add) push_back;
218 void push_back(const value_type& x);
219 size_type size() const;
220 size_type capacity() const;
221 void reserve(size_type n);
222 %newobject GetRange(int index, int count);
223 %newobject Repeat(const value_type& value, int count);
225 vector(const vector &other);
227 vector(int capacity) throw (std::out_of_range) {
228 std::vector<CTYPE >* pv = 0;
230 pv = new std::vector<CTYPE >();
231 pv->reserve(capacity);
233 throw std::out_of_range("capacity");
237 CTYPE getitemcopy(int index) throw (std::out_of_range) {
238 if (index>=0 && index<(int)$self->size())
239 return (*$self)[index];
241 throw std::out_of_range("index");
243 const_reference getitem(int index) throw (std::out_of_range) {
244 if (index>=0 && index<(int)$self->size())
245 return (*$self)[index];
247 throw std::out_of_range("index");
249 void setitem(int index, const value_type& val) throw (std::out_of_range) {
250 if (index>=0 && index<(int)$self->size())
251 (*$self)[index] = val;
253 throw std::out_of_range("index");
255 // Takes a deep copy of the elements unlike ArrayList.AddRange
256 void AddRange(const std::vector<CTYPE >& values) {
257 $self->insert($self->end(), values.begin(), values.end());
259 // Takes a deep copy of the elements unlike ArrayList.GetRange
260 std::vector<CTYPE > *GetRange(int index, int count) throw (std::out_of_range, std::invalid_argument) {
262 throw std::out_of_range("index");
264 throw std::out_of_range("count");
265 if (index >= (int)$self->size()+1 || index+count > (int)$self->size())
266 throw std::invalid_argument("invalid range");
267 return new std::vector<CTYPE >($self->begin()+index, $self->begin()+index+count);
269 void Insert(int index, const value_type& x) throw (std::out_of_range) {
270 if (index>=0 && index<(int)$self->size()+1)
271 $self->insert($self->begin()+index, x);
273 throw std::out_of_range("index");
275 // Takes a deep copy of the elements unlike ArrayList.InsertRange
276 void InsertRange(int index, const std::vector<CTYPE >& values) throw (std::out_of_range) {
277 if (index>=0 && index<(int)$self->size()+1)
278 $self->insert($self->begin()+index, values.begin(), values.end());
280 throw std::out_of_range("index");
282 void RemoveAt(int index) throw (std::out_of_range) {
283 if (index>=0 && index<(int)$self->size())
284 $self->erase($self->begin() + index);
286 throw std::out_of_range("index");
288 void RemoveRange(int index, int count) throw (std::out_of_range, std::invalid_argument) {
290 throw std::out_of_range("index");
292 throw std::out_of_range("count");
293 if (index >= (int)$self->size()+1 || index+count > (int)$self->size())
294 throw std::invalid_argument("invalid range");
295 $self->erase($self->begin()+index, $self->begin()+index+count);
297 static std::vector<CTYPE > *Repeat(const value_type& value, int count) throw (std::out_of_range) {
299 throw std::out_of_range("count");
300 return new std::vector<CTYPE >(count, value);
303 std::reverse($self->begin(), $self->end());
305 void Reverse(int index, int count) throw (std::out_of_range, std::invalid_argument) {
307 throw std::out_of_range("index");
309 throw std::out_of_range("count");
310 if (index >= (int)$self->size()+1 || index+count > (int)$self->size())
311 throw std::invalid_argument("invalid range");
312 std::reverse($self->begin()+index, $self->begin()+index+count);
314 // Takes a deep copy of the elements unlike ArrayList.SetRange
315 void SetRange(int index, const std::vector<CTYPE >& values) throw (std::out_of_range) {
317 throw std::out_of_range("index");
318 if (index+values.size() > $self->size())
319 throw std::out_of_range("index");
320 std::copy(values.begin(), values.end(), $self->begin()+index);
325 %define SWIG_STD_VECTOR_MINIMUM(CTYPE...)
326 SWIG_STD_VECTOR_MINIMUM_INTERNAL(IEnumerable, const value_type&, CTYPE)
329 // Extra methods added to the collection class if operator== is defined for the class being wrapped
330 // The class will then implement IList<>, which adds extra functionality
331 %define SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(CTYPE...)
333 bool Contains(const value_type& value) {
334 return std::find($self->begin(), $self->end(), value) != $self->end();
336 int IndexOf(const value_type& value) {
338 std::vector<CTYPE >::iterator it = std::find($self->begin(), $self->end(), value);
339 if (it != $self->end())
340 index = (int)(it - $self->begin());
343 int LastIndexOf(const value_type& value) {
345 std::vector<CTYPE >::reverse_iterator rit = std::find($self->rbegin(), $self->rend(), value);
346 if (rit != $self->rend())
347 index = (int)($self->rend() - 1 - rit);
350 bool Remove(const value_type& value) {
351 std::vector<CTYPE >::iterator it = std::find($self->begin(), $self->end(), value);
352 if (it != $self->end()) {
361 // Macros for std::vector class specializations/enhancements
362 %define SWIG_STD_VECTOR_ENHANCED(CTYPE...)
364 template<> class vector<CTYPE > {
365 SWIG_STD_VECTOR_MINIMUM_INTERNAL(IList, const value_type&, CTYPE)
366 SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(CTYPE)
372 %define SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE...)
373 #warning SWIG_STD_VECTOR_SPECIALIZE macro deprecated, please see csharp/std_vector.i and switch to SWIG_STD_VECTOR_ENHANCED
374 SWIG_STD_VECTOR_ENHANCED(CTYPE)
377 %define SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE...)
378 #warning SWIG_STD_VECTOR_SPECIALIZE_MINIMUM macro deprecated, it is no longer required
387 %csmethodmodifiers std::vector::getitemcopy "private"
388 %csmethodmodifiers std::vector::getitem "private"
389 %csmethodmodifiers std::vector::setitem "private"
390 %csmethodmodifiers std::vector::size "private"
391 %csmethodmodifiers std::vector::capacity "private"
392 %csmethodmodifiers std::vector::reserve "private"
395 // primary (unspecialized) class template for std::vector
396 // does not require operator== to be defined
397 template<class T> class vector {
398 SWIG_STD_VECTOR_MINIMUM(T)
400 // specializations for pointers
401 template<class T> class vector<T*> {
402 SWIG_STD_VECTOR_MINIMUM_INTERNAL(IList, const value_type&, T*)
403 SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(T*)
405 template<class T> class vector<const T*> {
406 SWIG_STD_VECTOR_MINIMUM_INTERNAL(IList, const value_type&, const T*)
407 SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(const T*)
409 // bool is a bit different in the C++ standard
410 template<> class vector<bool> {
411 SWIG_STD_VECTOR_MINIMUM_INTERNAL(IList, bool, bool)
412 SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(bool)
416 // template specializations for std::vector
417 // these provide extra collections methods as operator== is defined
418 SWIG_STD_VECTOR_ENHANCED(char)
419 SWIG_STD_VECTOR_ENHANCED(signed char)
420 SWIG_STD_VECTOR_ENHANCED(unsigned char)
421 SWIG_STD_VECTOR_ENHANCED(short)
422 SWIG_STD_VECTOR_ENHANCED(unsigned short)
423 SWIG_STD_VECTOR_ENHANCED(int)
424 SWIG_STD_VECTOR_ENHANCED(unsigned int)
425 SWIG_STD_VECTOR_ENHANCED(long)
426 SWIG_STD_VECTOR_ENHANCED(unsigned long)
427 SWIG_STD_VECTOR_ENHANCED(long long)
428 SWIG_STD_VECTOR_ENHANCED(unsigned long long)
429 SWIG_STD_VECTOR_ENHANCED(float)
430 SWIG_STD_VECTOR_ENHANCED(double)
431 SWIG_STD_VECTOR_ENHANCED(std::string) // also requires a %include <std_string.i>