diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in index a4ae7131d..c9e48f804 100644 --- a/Examples/test-suite/csharp/Makefile.in +++ b/Examples/test-suite/csharp/Makefile.in @@ -26,7 +26,8 @@ CPP_TEST_CASES = \ enum_thorough_typesafe \ exception_partial_info \ intermediary_classname \ - li_boost_intrusive_ptr + li_boost_intrusive_ptr \ + li_std_list \ CPP11_TEST_CASES = \ cpp11_shared_ptr_const \ diff --git a/Examples/test-suite/csharp/li_std_list_runme.cs b/Examples/test-suite/csharp/li_std_list_runme.cs new file mode 100644 index 000000000..fdcd0d9ac --- /dev/null +++ b/Examples/test-suite/csharp/li_std_list_runme.cs @@ -0,0 +1,402 @@ +using System; +using li_std_listNamespace; + +public class li_std_list_runme { + private static readonly int collectionSize = 20; + + public static void Main() { + // Setup a list of int + IntList list = new IntList(); + IntList.IntListNode node; + + for (int i = 0; i < 20; i++) { + int nb = i * 10; + list.Add(nb); + } + + // Count property test + if (list.Count != collectionSize) + throw new Exception("Count test failed"); + + // IsReadOnly property test + if (list.IsReadOnly) + throw new Exception("IsReadOnly test failed"); + + // Contains method test + if (!list.Contains(0)) + throw new Exception("Contains method test 1 failed"); + if (!list.Contains(2 * 10)) + throw new Exception("Contains method test 2 failed"); + if (!list.Contains(19 * 10)) + throw new Exception("Contains method test 3 failed"); + if (list.Contains(20 * 10)) + throw new Exception("Contains method test 4 failed"); + + // Nodes comparison method overload + { + IntList.IntListNode temp = new IntList.IntListNode(3); + if (list.First == temp) + throw new Exception("== overload method test (1) failed"); + temp = new IntList.IntListNode(0); + if (list.First == temp) + throw new Exception("== overload method test (2) failed"); + IntList.IntListNode temp2 = new IntList.IntListNode(0); + if (temp == temp2) + throw new Exception("== overload method test (3) failed"); + if (!(list.First == list.First)) + throw new Exception("== overload method test (4) failed"); + if (list.First != list.First) + throw new Exception("!= overload method test (1) failed"); + if (!(temp != temp2)) + throw new Exception("!= overload method test (2) failed"); + if (list.First.Equals(temp)) + throw new Exception("Equals method test failed"); + if (list.First.GetHashCode() == temp.GetHashCode()) + throw new Exception("GetHashCode method test (1) failed"); + if (list.First.GetHashCode() == list.First.GetHashCode()) + throw new Exception("GetHashCode method test (2) failed"); + + } + + // Getter test + { + if (list.First == null) + throw new Exception("First getter test (1) failed"); + if (list.Last == null) + throw new Exception("Last getter test (1) failed"); + if (list.Last.Next != null) + throw new Exception("Next getter test (1) failed"); + if (list.First.Next == null) + throw new Exception("Next getter test (2) failed"); + if (list.First.Previous != null) + throw new Exception("Previous getter test (1) failed"); + if (list.Last.Previous == null) + throw new Exception("Previous getter test (2) failed"); + } + + // AddFirst method test + node = list.AddFirst(34); + if (list.First.Value != 34 || node.Value != 34 || node != list.First) + throw new Exception("AddFirst method test failed"); + try { + list.AddFirst(null); + } catch (ArgumentNullException) { + try { + list.AddFirst(list.First); + } catch (InvalidOperationException) { + } + } + + // RemoveFirst method test + int tmp = list.First.Value; + list.RemoveFirst(); + if (list.First.Value == tmp || list.First.Value != 0 * 10) + throw new Exception("RemoveFirst method test failed"); + + // AddLast method test + node = list.AddLast(8); + if (list.Last.Value != 8 || node.Value != 8 || node != list.Last) + throw new Exception("AddLast method test failed"); + try { + list.AddLast(null); + } catch (ArgumentNullException) { + try { + list.AddLast(list.First); + } catch (InvalidOperationException) { + } + } + + // RemoveLast method test + int tmp2 = list.Last.Value; + list.RemoveLast(); + if (list.Last.Value == tmp2 || list.Last.Value != (list.Count - 1) * 10) + throw new Exception("RemoveLast method test failed"); + + // AddBefore method test + node = list.AddBefore(list.Last, 17); + if (list.Last.Previous.Value != 17 || node.Value != 17 || node != list.Last.Previous) + throw new Exception("AddBefore method test (1) failed"); + try { + node = null; + list.AddBefore(list.Last, node); + throw new Exception("AddBefore method test (2) failed"); + } catch (ArgumentNullException) { + try { + node = new IntList.IntListNode(1); + list.AddBefore(null, node); + throw new Exception("AddBefore method test (3) failed"); + } catch (ArgumentNullException) { + try { + list.AddBefore(list.Last, list.First); + } catch (InvalidOperationException) { + } + } + } + + // AddAfter method test + node = list.AddAfter(list.First, 47); + if (list.First.Next.Value != 47 || node.Value != 47 || node != list.First.Next) + throw new Exception("AddAfter method test (1) failed"); + try { + node = null; + list.AddAfter(list.First.Next, node); + throw new Exception("AddAfter method test (2) failed"); + } catch (ArgumentNullException) { + try { + list.AddAfter(list.First, list.Last); + } catch (InvalidOperationException) { + } + } + + // Find method test + node = list.Find(0); + if (node == null || node.Value != 0) + throw new Exception("Find method test (1) failed"); + node = list.Find(47); + if (node == null || node.Value != 47) + throw new Exception("Find method test (2) failed"); + node = list.Find(190); + if (node == null || node.Value != 190) + throw new Exception("Find method test (3) failed"); + node = list.Find(-3); + if (node != null) + throw new Exception("Find method test (4) failed"); + + // Remove method test + if (!list.Remove(17) || list.Contains(17) || list.Last.Previous.Value == 17) + throw new Exception("Remove method test (1) failed"); + if (!list.Remove(47) || list.Contains(47) || list.First.Next.Value == 47) + throw new Exception("Remove method test (2) failed"); + if (!list.Remove(0) || list.Contains(0) || list.First.Value == 0) + throw new Exception("Remove method test (3) failed"); + if (!list.Remove(190) || list.Contains(190) || list.Last.Value == 190) + throw new Exception("Remove method test (4) failed"); + try { + node = null; + list.Remove(node); + throw new Exception("Remove method test (5) failed"); + } catch (ArgumentNullException) { + try { + node = new IntList.IntListNode(4); + list.Remove(node); + throw new Exception("Remove method test (5) failed"); + } catch (InvalidOperationException) { + } + } + + // ICollection constructor test + { + int[] intArray = new int[] { 0, 11, 22, 33, 44, 55, 33 }; + IntList il = new IntList(intArray); + if (intArray.Length != il.Count) + throw new Exception("ICollection constructor length check failed: " + intArray.Length + "-" + il.Count); + node = il.First; + for (int i = 0; i < intArray.Length; i++) { + if (intArray[i] != node.Value) + throw new Exception("ICollection constructor failed, index:" + i); + node = node.Next; + } + try { + new IntList((System.Collections.ICollection)null); + throw new Exception("ICollection constructor null test failed"); + } catch (ArgumentNullException) { + } + } + + // Enumerator test + { + node = list.First; + System.Collections.IEnumerator myEnumerator = list.GetEnumerator(); + while (myEnumerator.MoveNext()) { + if ((int)myEnumerator.Current != node.Value) + throw new Exception("Enumerator (1) test failed"); + node = node.Next; + } + } + { + node = list.First; + System.Collections.Generic.IEnumerator myEnumerator = list.GetEnumerator(); + while (myEnumerator.MoveNext()) { + if (myEnumerator.Current != node.Value) + throw new Exception("Enumerator (2) test failed"); + node = node.Next; + } + } + { + node = list.First; + IntList.IntListEnumerator myEnumerator = list.GetEnumerator(); + while (myEnumerator.MoveNext()) { + if (myEnumerator.Current != node.Value) + throw new Exception("Enumerator (3) test failed"); + node = node.Next; + } + } + { + node = list.First; + foreach (var elem in list) { + if (elem != node.Value) + throw new Exception("Enumerator (4) test failed"); + node = node.Next; + } + } + + // CopyTo method test + { + int[] outputarray = new int[collectionSize - 2]; + list.CopyTo(outputarray, 0); + int index = 0; + IntList.IntListNode temp = list.First; + foreach (int val in outputarray) { + if (temp.Value != val) { + throw new Exception("CopyTo method test (1) failed, index:" + index); + } + index++; + temp = temp.Next; + } + } + { + DoubleList inputlist = new DoubleList(); + int arrayLen = 10; + for (int i = 0; i < arrayLen; i++) { + double num = i * 10.1; + inputlist.Add(num); + } + double[] outputarray = new double[arrayLen]; + inputlist.CopyTo(outputarray, 0); + DoubleList.DoubleListNode temp = inputlist.First; + for (int i = 0; i < arrayLen; i++) { + if (outputarray[i] != temp.Value) + throw new Exception("CopyTo method test (2) failed, index:" + i); + temp = temp.Next; + } + } + { + StructList inputlist = new StructList(); + int arrayLen = 10; + for (int i = 0; i < arrayLen; i++) + inputlist.Add(new Struct(i / 10.0)); + Struct[] outputarray = new Struct[arrayLen]; + inputlist.CopyTo(outputarray, 0); + StructList.StructListNode temp = inputlist.First; + for (int i = 0; i < arrayLen; i++) { + if (outputarray[i].num != temp.Value.num) + throw new Exception("CopyTo method test (3) failed, index:" + i); + temp = temp.Next; + } + foreach (Struct s in inputlist) { + s.num += 20.0; + } + temp = inputlist.First; + for (int i = 0; i < arrayLen; i++) { + if (outputarray[i].num != temp.Value.num) + throw new Exception("CopyTo method test (4) failed, index:" + i); + temp = temp.Next; + } + } + try { + list.CopyTo(null, 0); + throw new Exception("CopyTo method test (5) failed"); + } catch (ArgumentNullException) { + } + + // Clear() test + list.Clear(); + if (list.Count != 0) + throw new Exception("Clear method failed"); + + // Finally test the methods being wrapped + { + IntList il = new IntList(); + for (int i = 0; i < 4; i++) { + il.Add(i); + } + + double x = li_std_list.average(il); + x += li_std_list.average(new IntList(new int[] { 1, 2, 3, 4 })); + + DoubleList dlist = new DoubleList(); + for (int i = 0; i < 10; i++) { + dlist.Add(i / 2.0); + } + li_std_list.halve_in_place(dlist); + } + + // Dispose() + { + using (StructList ls = new StructList(new Struct[] { new Struct(0.0), new Struct(11.1) })) + using (DoubleList ld = new DoubleList(new double[] { 0.0, 11.1 })) { } + } + + // More wrapped methods + { + FloatList l0 = li_std_list.listreal(new FloatList()); + float flo = 123.456f; + l0.Add(flo); + flo = l0.First.Value; + + IntList l1 = li_std_list.listint(new IntList()); + IntPtrList l2 = li_std_list.listintptr(new IntPtrList()); + IntConstPtrList l3 = li_std_list.listintconstptr(new IntConstPtrList()); + + l1.Add(123); + l2.Clear(); + l3.Clear(); + + StructList l4 = li_std_list.liststruct(new StructList()); + StructPtrList l5 = li_std_list.liststructptr(new StructPtrList()); + StructConstPtrList l6 = li_std_list.liststructconstptr(new StructConstPtrList()); + + l4.Add(new Struct(123)); + l5.Add(new Struct(123)); + l6.Add(new Struct(123)); + } + + // Test lists of pointers + { + StructPtrList inputlist = new StructPtrList(); + int arrayLen = 10; + for (int i = 0; i < arrayLen; i++) { + inputlist.Add(new Struct(i / 10.0)); + } + Struct[] outputarray = new Struct[arrayLen]; + inputlist.CopyTo(outputarray, 0); + StructPtrList.StructPtrListNode temp = inputlist.First; + for (int i = 0; i < arrayLen; i++) { + if (outputarray[i].num != temp.Value.num) + throw new Exception("StructPtrList test (1) failed, i:" + i); + temp = temp.Next; + } + foreach (Struct s in inputlist) { + s.num += 20.0; + } + for (int i = 0; i < arrayLen; i++) { + if (outputarray[i].num != 20.0 + i / 10.0) + throw new Exception("StructPtrList test (2) failed (a deep copy was incorrectly made), i:" + i); + } + } + + // Test lists of const pointers + { + StructConstPtrList inputlist = new StructConstPtrList(); + int arrayLen = 10; + for (int i = 0; i < arrayLen; i++) { + inputlist.Add(new Struct(i / 10.0)); + } + Struct[] outputarray = new Struct[arrayLen]; + inputlist.CopyTo(outputarray, 0); + StructConstPtrList.StructConstPtrListNode temp = inputlist.First; + for (int i = 0; i < arrayLen; i++) { + if (outputarray[i].num != temp.Value.num) + throw new Exception("StructConstPtrList test (1) failed, i:" + i); + temp = temp.Next; + } + foreach (Struct s in inputlist) { + s.num += 20.0; + } + for (int i = 0; i < arrayLen; i++) { + if (outputarray[i].num != 20.0 + i / 10.0) + throw new Exception("StructConstPtrList test (2) failed (a deep copy was incorrectly made), i:" + i); + } + } + } +} \ No newline at end of file diff --git a/Examples/test-suite/li_std_list.i b/Examples/test-suite/li_std_list.i index d1ec4e7e4..6a60f032c 100644 --- a/Examples/test-suite/li_std_list.i +++ b/Examples/test-suite/li_std_list.i @@ -38,13 +38,23 @@ struct Struct { double num; Struct() : num(0.0) {} Struct(double d) : num(d) {} -// bool operator==(const Struct &other) { return (num == other.num); } + bool operator==(const Struct &other) { return (num == other.num); } }; const std::list & CopyContainerStruct(const std::list & container) { return container; } const std::list & CopyContainerStructPtr(const std::list & container) { return container; } const std::list & CopyContainerStructConstPtr(const std::list & container) { return container; } +const std::list & listreal(const std::list & list) { return list; } + +const std::list & listint(const std::list & list) { return list; } +const std::list & listintptr(const std::list & list) { return list; } +const std::list & listintconstptr(const std::list & list) { return list; } + +const std::list & liststruct(const std::list & list) { return list; } +const std::list & liststructptr(const std::list & list) { return list; } +const std::list & liststructconstptr(const std::list & list) { return list; } + enum Fruit { APPLE, BANANNA, @@ -53,8 +63,11 @@ enum Fruit { }; %} +#if !defined(SWIGR) +%template(IntPtrList) std::list; +%template(IntConstPtrList) std::list; +#endif %template(StructList) std::list; -%template(StructPtrList) std::list; +%template(StructPtrList) std::list; %template(StructConstPtrList) std::list; - -%template(FruitList) std::list; +%template(FruitList) std::list; \ No newline at end of file diff --git a/Lib/csharp/std_list.i b/Lib/csharp/std_list.i new file mode 100644 index 000000000..6194f94ea --- /dev/null +++ b/Lib/csharp/std_list.i @@ -0,0 +1,483 @@ +/* ----------------------------------------------------------------------------- + * std_list.i + * + * SWIG typemaps for std::list + * C# implementation + * The C# wrapper is made to look and feel like a C# System.Collections.Generic.LinkedList<> collection. + * + * ----------------------------------------------------------------------------- */ + +%include +%define SWIG_STD_LIST_MINIMUM_INTERNAL(CONST_REFERENCE, CTYPE...) +%typemap(csinterfaces) std::list< CTYPE > "global::System.Collections.Generic.ICollection<$typemap(cstype, CTYPE)>, global::System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)>, global::System.Collections.IEnumerable, global::System.IDisposable" +%proxycode %{ + public $csclassname(global::System.Collections.IEnumerable c) : this() { + if (c == null) + throw new global::System.ArgumentNullException("c"); + foreach ($typemap(cstype, CTYPE) element in c) { + this.AddLast(element); + } + } + + public bool IsReadOnly { + get { + return false; + } + } + + public int Count { + get { + return (int)size(); + } + } + + public $csclassnameNode First { + get { + if (Count == 0) + return null; + return new $csclassnameNode(getFirstIter(), this); + } + } + + public $csclassnameNode Last { + get { + if (Count == 0) + return null; + return new $csclassnameNode(getLastIter(), this); + } + } + + public $csclassnameNode AddFirst($typemap(cstype, CTYPE) value) { + push_front(value); + return new $csclassnameNode(getFirstIter(), this); + } + + public void AddFirst($csclassnameNode newNode) { + ValidateNewNode(newNode); + if (!newNode.inlist) { + push_front(newNode.csharpvalue); + newNode.iter = getFirstIter(); + newNode.inlist = true; + } else { + throw new global::System.InvalidOperationException("The " + newNode.GetType().Name + " node already belongs to a " + this.GetType().Name); + } + } + + public $csclassnameNode AddLast($typemap(cstype, CTYPE) value) { + push_back(value); + return new $csclassnameNode(getLastIter(), this); + } + + public void AddLast($csclassnameNode newNode) { + ValidateNewNode(newNode); + if (!newNode.inlist) { + push_back(newNode.csharpvalue); + newNode.iter = getLastIter(); + newNode.inlist = true; + } else { + throw new global::System.InvalidOperationException("The " + newNode.GetType().Name + " node already belongs to a " + this.GetType().Name); + } + } + + public $csclassnameNode AddBefore($csclassnameNode node, $typemap(cstype, CTYPE) value) { + return new $csclassnameNode(insertNode(node.iter, value), this); + } + + public void AddBefore($csclassnameNode node, $csclassnameNode newNode) { + ValidateNode(node); + ValidateNewNode(newNode); + if (!newNode.inlist) { + newNode.iter = insertNode(node.iter, newNode.csharpvalue); + newNode.inlist = true; + } else { + throw new global::System.InvalidOperationException("The " + newNode.GetType().Name + " node already belongs to a " + this.GetType().Name); + } + } + + public $csclassnameNode AddAfter($csclassnameNode node, $typemap(cstype, CTYPE) value) { + node = node.Next; + return new $csclassnameNode(insertNode(node.iter, value), this); + } + + public void AddAfter($csclassnameNode node, $csclassnameNode newNode) { + ValidateNode(node); + ValidateNewNode(newNode); + if (!newNode.inlist) { + if (node == this.Last) + AddLast(newNode); + else + { + node = node.Next; + newNode.iter = insertNode(node.iter, newNode.csharpvalue); + newNode.inlist = true; + } + } else { + throw new global::System.InvalidOperationException("The " + newNode.GetType().Name + " node already belongs to a " + this.GetType().Name); + } + } + + public void Add($typemap(cstype, CTYPE) value) { + AddLast(value); + } + + public bool Remove($typemap(cstype, CTYPE) value) { + var node = Find(value); + if (node == null) + return false; + Remove(node); + return true; + } + + public void Remove($csclassnameNode node) { + ValidateNode(node); + eraseIter(node.iter); + } + + public $csclassnameNode Find($typemap(cstype, CTYPE) value) { + System.IntPtr tmp = find(value); + if (tmp != System.IntPtr.Zero) { + return new $csclassnameNode(tmp, this); + } + return null; + } + + public void CopyTo($typemap(cstype, CTYPE)[] array, int index) { + if (array == null) + throw new global::System.ArgumentNullException("array"); + if (index < 0 || index > array.Length) + throw new global::System.ArgumentOutOfRangeException("index", "Value is less than zero"); + if (array.Rank > 1) + throw new global::System.ArgumentException("Multi dimensional array.", "array"); + $csclassnameNode node = this.First; + if (node != null) { + do { + array[index++] = node.Value; + node = node.Next; + } while (node != null); + } + } + + internal void ValidateNode($csclassnameNode node) { + if (node == null) { + throw new System.ArgumentNullException("node"); + } + if (!node.inlist || node.list != this) { + throw new System.InvalidOperationException("node"); + } + } + + internal void ValidateNewNode($csclassnameNode node) { + if (node == null) { + throw new System.ArgumentNullException("node"); + } + } + + global::System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)>.GetEnumerator() { + return new $csclassnameEnumerator(this); + } + + global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() { + return new $csclassnameEnumerator(this); + } + + public $csclassnameEnumerator GetEnumerator() { + return new $csclassnameEnumerator(this); + } + + public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator, + global::System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)> + { + private $csclassname collectionRef; + private $csclassnameNode currentNode; + private int currentIndex; + private object currentObject; + private int currentSize; + + public $csclassnameEnumerator($csclassname collection) { + collectionRef = collection; + currentNode = collection.First; + currentIndex = 0; + currentObject = null; + currentSize = collectionRef.Count; + } + + // Type-safe iterator Current + public $typemap(cstype, CTYPE) Current { + get { + if (currentIndex == -1) + throw new global::System.InvalidOperationException("Enumeration not started."); + if (currentIndex > currentSize) + throw new global::System.InvalidOperationException("Enumeration finished."); + if (currentObject == null) + throw new global::System.InvalidOperationException("Collection modified."); + return ($typemap(cstype, CTYPE))currentObject; + } + } + + // Type-unsafe IEnumerator.Current + object global::System.Collections.IEnumerator.Current { + get { + return Current; + } + } + + public bool MoveNext() { + if (currentNode == null) { + currentIndex = collectionRef.Count + 1; + return false; + } + ++currentIndex; + currentObject = currentNode.Value; + currentNode = currentNode.Next; + return true; + } + + public void Reset() { + currentIndex = -1; + currentObject = null; + if (collectionRef.Count != currentSize) { + throw new global::System.InvalidOperationException("Collection modified."); + } + } + + public void Dispose() { + currentIndex = -1; + currentObject = null; + } + } + + public sealed class $csclassnameNode { + internal $csclassname list; + internal System.IntPtr iter; + internal $typemap(cstype, CTYPE) csharpvalue; + internal bool inlist; + + public $csclassnameNode($typemap(cstype, CTYPE) value) { + csharpvalue = value; + inlist = false; + } + + internal $csclassnameNode(System.IntPtr _iter, $csclassname _list) { + list = _list; + iter = _iter; + inlist = true; + } + + public $csclassname List { + get { + return this.list; + } + } + + public $csclassnameNode Next { + get { + if (list.getNextIter(iter) == System.IntPtr.Zero) + return null; + return new $csclassnameNode(list.getNextIter(iter), list); + } + } + + public $csclassnameNode Previous { + get { + if (list.getPrevIter(iter) == System.IntPtr.Zero) + return null; + return new $csclassnameNode(list.getPrevIter(iter), list); + } + } + + public $typemap(cstype, CTYPE) Value { + get { + return list.getItem(this.iter); + } + set { + list.setItem(this.iter, value); + } + } + + public static bool operator== ($csclassnameNode node1, $csclassnameNode node2) { + if (object.ReferenceEquals(node1, null) && object.ReferenceEquals(node2, null)) + return true; + if (object.ReferenceEquals(node1, null) || object.ReferenceEquals(node2, null)) + return false; + return node1.Equals(node2); + } + + public static bool operator!= ($csclassnameNode node1, $csclassnameNode node2) { + if (node1 == null && node2 == null) + return false; + if (node1 == null || node2 == null) + return true; + return !node1.Equals(node2); + } + + public bool Equals($csclassnameNode node) { + if (node == null) + return false; + if (!node.inlist || !this.inlist) + return object.ReferenceEquals(this, node); + return list.equals(this.iter, node.iter); + } + + public override bool Equals(object node) { + return Equals(($csclassnameNode)node); + } + + public override int GetHashCode() { + int hash = 13; + if (inlist) { + hash = (hash * 7) + this.list.GetHashCode(); + hash = (hash * 7) + this.Value.GetHashCode(); + hash = (hash * 7) + this.list.getNextIter(this.iter).GetHashCode(); + hash = (hash * 7) + this.list.getPrevIter(this.iter).GetHashCode(); + } else { + hash = (hash * 7) + this.csharpvalue.GetHashCode(); + } + return hash; + } + + public void Dispose() { + list.deleteIter(this.iter); + } + } +%} + +public: + typedef size_t size_type; + typedef CTYPE value_type; + typedef CONST_REFERENCE const_reference; + void push_front(CTYPE const& x); + void push_back(CTYPE const& x); + %rename(RemoveFirst) pop_front; + void pop_front(); + %rename(RemoveLast) pop_back; + void pop_back(); + size_type size() const; + %rename(Clear) clear; + void clear(); + %extend { + CONST_REFERENCE getItem(void *iter) { + std::list< CTYPE >::iterator it = *reinterpret_cast::iterator*>(iter); + return *it; + } + + void setItem(void *iter, CTYPE const& val) { + std::list< CTYPE >::iterator* it = reinterpret_cast::iterator*>(iter); + *(*it) = val; + } + + void *getFirstIter() { + if ($self->size() == 0) + return NULL; + std::list< CTYPE >::iterator* it = new std::list< CTYPE >::iterator($self->begin()); + return reinterpret_cast(it); + } + + void *getLastIter() { + if ($self->size() == 0) + return NULL; + std::list< CTYPE >::iterator* it = new std::list< CTYPE >::iterator(--$self->end()); + return reinterpret_cast(it); + } + + void *getNextIter(void *iter) { + std::list< CTYPE >::iterator it = *(reinterpret_cast::iterator *>(iter)); + if (std::distance(it, --$self->end()) != 0) { + std::list< CTYPE >::iterator* itnext = new std::list< CTYPE >::iterator(++it); + return reinterpret_cast(itnext); + } + return NULL; + } + + void *getPrevIter(void *iter) { + std::list< CTYPE >::iterator it = *(reinterpret_cast::iterator *>(iter)); + if (std::distance($self->begin(), it) != 0) { + std::list< CTYPE >::iterator* itprev = new std::list< CTYPE >::iterator(--it); + return reinterpret_cast(itprev); + } + return NULL; + } + + void *insertNode(void *iter, CTYPE const& value) { + std::list< CTYPE >::iterator it = $self->insert(*(reinterpret_cast::iterator *>(iter)), value); + void* newit = reinterpret_cast(new std::list< CTYPE >::iterator(it)); + return newit; + } + + void *find(CTYPE const& value) { + if (std::find($self->begin(), $self->end(), value) != $self->end()) { + void* it = reinterpret_cast(new std::list< CTYPE >::iterator(std::find($self->begin(), $self->end(), value))); + return it; + } + return NULL; + } + + void eraseIter(void *iter) { + std::list< CTYPE >::iterator it = *reinterpret_cast::iterator*>(iter); + $self->erase(it); + } + + void deleteIter(void *iter) { + std::list< CTYPE >::iterator* it = reinterpret_cast::iterator*>(iter); + delete it; + } + + bool equals(void *iter1, void *iter2) { + if (iter1 == NULL && iter2 == NULL) + return true; + std::list< CTYPE >::iterator it1 = *reinterpret_cast::iterator*>(iter1); + std::list< CTYPE >::iterator it2 = *reinterpret_cast::iterator*>(iter2); + return it1 == it2; + } + + bool Contains(CTYPE const& value) { + return std::find($self->begin(), $self->end(), value) != $self->end(); + } + } +%enddef + +%apply void *VOID_INT_PTR { void *iter1, void *iter2, void *iter, void *find, void *insertNode, void *getPrevIter, void *getNextIter, void *getFirstIter, void *getLastIter } + +%define SWIG_STD_LIST_ENHANCED(CTYPE...) +namespace std { + template<> class list< CTYPE > { + SWIG_STD_LIST_MINIMUM_INTERNAL(%arg(CTYPE const&), %arg(CTYPE)); + }; +} +%enddef + + + +%{ +#include +#include +#include +#include +%} + +%csmethodmodifiers std::list::size "private" +%csmethodmodifiers std::list::getItem "private" +%csmethodmodifiers std::list::setItem "private" +%csmethodmodifiers std::list::push_front "private" +%csmethodmodifiers std::list::push_back "private" +%csmethodmodifiers std::list::getFirstIter "private" +%csmethodmodifiers std::list::getNextIter "private" +%csmethodmodifiers std::list::getPrevIter "private" +%csmethodmodifiers std::list::getLastIter "private" +%csmethodmodifiers std::list::find "private" +%csmethodmodifiers std::list::deleteIter "private" + +namespace std { + template + class list { + SWIG_STD_LIST_MINIMUM_INTERNAL(T const&, T) + }; + template + class list + { + SWIG_STD_LIST_MINIMUM_INTERNAL(T *const&, T *) + }; + template<> + class list { + SWIG_STD_LIST_MINIMUM_INTERNAL(bool, bool) + }; +}