| /* ----------------------------------------------------------------------------- | |
| * std_set.i | |
| * | |
| * SWIG typemaps for std::set<T>. | |
| * | |
| * Note that ISet<> used here requires .NET 4 or later. | |
| * | |
| * The C# wrapper implements ISet<> interface and shares performance | |
| * characteristics of C# System.Collections.Generic.SortedSet<> class, but | |
| * doesn't provide quite all of its methods. | |
| * ----------------------------------------------------------------------------- */ | |
| %{ | |
| #include <set> | |
| #include <algorithm> | |
| %} | |
| %csmethodmodifiers std::set::empty "private" | |
| %csmethodmodifiers std::set::size "private" | |
| %csmethodmodifiers std::set::getitem "private" | |
| %csmethodmodifiers std::set::create_iterator_begin "private" | |
| %csmethodmodifiers std::set::get_next "private" | |
| %csmethodmodifiers std::set::destroy_iterator "private" | |
| namespace std { | |
| // TODO: Add support for comparator and allocator template parameters. | |
| template <class T> | |
| class set { | |
| %typemap(csinterfaces) std::set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n" | |
| %proxycode %{ | |
| void global::System.Collections.Generic.ICollection<$typemap(cstype, T)>.Add($typemap(cstype, T) item) { | |
| ((global::System.Collections.Generic.ISet<$typemap(cstype, T)>)this).Add(item); | |
| } | |
| public bool TryGetValue($typemap(cstype, T) equalValue, out $typemap(cstype, T) actualValue) { | |
| try { | |
| actualValue = getitem(equalValue); | |
| return true; | |
| } catch { | |
| actualValue = default($typemap(cstype, T)); | |
| return false; | |
| } | |
| } | |
| public bool IsEmpty { | |
| get { | |
| return empty(); | |
| } | |
| } | |
| public int Count { | |
| get { | |
| return (int)size(); | |
| } | |
| } | |
| public bool IsReadOnly { | |
| get { | |
| return false; | |
| } | |
| } | |
| public void CopyTo($typemap(cstype, T)[] array) { | |
| CopyTo(array, 0); | |
| } | |
| public void CopyTo($typemap(cstype, T)[] array, int arrayIndex) { | |
| if (array == null) | |
| throw new global::System.ArgumentNullException("array"); | |
| if (arrayIndex < 0) | |
| throw new global::System.ArgumentOutOfRangeException("arrayIndex", "Value is less than zero"); | |
| if (array.Rank > 1) | |
| throw new global::System.ArgumentException("Multi dimensional array.", "array"); | |
| if (arrayIndex+this.Count > array.Length) | |
| throw new global::System.ArgumentException("Number of elements to copy is too large."); | |
| foreach ($typemap(cstype, T) item in this) { | |
| array.SetValue(item, arrayIndex++); | |
| } | |
| } | |
| public void ExceptWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| foreach ($typemap(cstype, T) item in other) { | |
| Remove(item); | |
| } | |
| } | |
| public void IntersectWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| $csclassname old = new $csclassname(this); | |
| Clear(); | |
| foreach ($typemap(cstype, T) item in other) { | |
| if (old.Contains(item)) | |
| Add(item); | |
| } | |
| } | |
| private static int count_enum(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| int count = 0; | |
| foreach ($typemap(cstype, T) item in other) { | |
| count++; | |
| } | |
| return count; | |
| } | |
| public bool IsProperSubsetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| return IsSubsetOf(other) && Count < count_enum(other); | |
| } | |
| public bool IsProperSupersetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| return IsSupersetOf(other) && Count > count_enum(other); | |
| } | |
| public bool IsSubsetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| int countContained = 0; | |
| foreach ($typemap(cstype, T) item in other) { | |
| if (Contains(item)) | |
| countContained++; | |
| } | |
| return countContained == Count; | |
| } | |
| public bool IsSupersetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| foreach ($typemap(cstype, T) item in other) { | |
| if (!Contains(item)) | |
| return false; | |
| } | |
| return true; | |
| } | |
| public bool Overlaps(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| foreach ($typemap(cstype, T) item in other) { | |
| if (Contains(item)) | |
| return true; | |
| } | |
| return false; | |
| } | |
| public bool SetEquals(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| return IsSupersetOf(other) && Count == count_enum(other); | |
| } | |
| public void SymmetricExceptWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| foreach ($typemap(cstype, T) item in other) { | |
| if (!Remove(item)) | |
| Add(item); | |
| } | |
| } | |
| public void UnionWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) { | |
| foreach ($typemap(cstype, T) item in other) { | |
| Add(item); | |
| } | |
| } | |
| private global::System.Collections.Generic.ICollection<$typemap(cstype, T)> Items { | |
| get { | |
| global::System.Collections.Generic.ICollection<$typemap(cstype, T)> items = new global::System.Collections.Generic.List<$typemap(cstype, T)>(); | |
| int size = this.Count; | |
| if (size > 0) { | |
| global::System.IntPtr iter = create_iterator_begin(); | |
| for (int i = 0; i < size; i++) { | |
| items.Add(get_next(iter)); | |
| } | |
| destroy_iterator(iter); | |
| } | |
| return items; | |
| } | |
| } | |
| global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>.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); | |
| } | |
| // Type-safe enumerator | |
| /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown | |
| /// whenever the collection is modified. This has been done for changes in the size of the | |
| /// collection but not when one of the elements of the collection is modified as it is a bit | |
| /// tricky to detect unmanaged code that modifies the collection under our feet. | |
| public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator, | |
| global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)> | |
| { | |
| private $csclassname collectionRef; | |
| private global::System.Collections.Generic.IList<$typemap(cstype, T)> ItemsCollection; | |
| private int currentIndex; | |
| private object currentObject; | |
| private int currentSize; | |
| public $csclassnameEnumerator($csclassname collection) { | |
| collectionRef = collection; | |
| ItemsCollection = new global::System.Collections.Generic.List<$typemap(cstype, T)>(collection.Items); | |
| currentIndex = -1; | |
| currentObject = null; | |
| currentSize = collectionRef.Count; | |
| } | |
| // Type-safe iterator Current | |
| public $typemap(cstype, T) Current { | |
| get { | |
| if (currentIndex == -1) | |
| throw new global::System.InvalidOperationException("Enumeration not started."); | |
| if (currentIndex > currentSize - 1) | |
| throw new global::System.InvalidOperationException("Enumeration finished."); | |
| if (currentObject == null) | |
| throw new global::System.InvalidOperationException("Collection modified."); | |
| return ($typemap(cstype, T))currentObject; | |
| } | |
| } | |
| // Type-unsafe IEnumerator.Current | |
| object global::System.Collections.IEnumerator.Current { | |
| get { | |
| return Current; | |
| } | |
| } | |
| public bool MoveNext() { | |
| int size = collectionRef.Count; | |
| bool moveOkay = (currentIndex+1 < size) && (size == currentSize); | |
| if (moveOkay) { | |
| currentIndex++; | |
| currentObject = ItemsCollection[currentIndex]; | |
| } else { | |
| currentObject = null; | |
| } | |
| return moveOkay; | |
| } | |
| 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: | |
| typedef size_t size_type; | |
| typedef ptrdiff_t difference_type; | |
| typedef T key_type; | |
| typedef T value_type; | |
| typedef value_type* pointer; | |
| typedef const value_type* const_pointer; | |
| typedef value_type& reference; | |
| typedef const value_type& const_reference; | |
| set(); | |
| set(const set& other); | |
| size_type size() const; | |
| bool empty() const; | |
| %rename(Clear) clear; | |
| void clear(); | |
| %extend { | |
| bool Add(const value_type& item) { | |
| return $self->insert(item).second; | |
| } | |
| bool Contains(const value_type& item) { | |
| return $self->count(item) != 0; | |
| } | |
| bool Remove(const value_type& item) { | |
| return $self->erase(item) != 0; | |
| } | |
| const value_type& getitem(const value_type& item) throw (std::out_of_range) { | |
| std::set<T>::iterator iter = $self->find(item); | |
| if (iter == $self->end()) | |
| throw std::out_of_range("item not found"); | |
| return *iter; | |
| } | |
| // create_iterator_begin(), get_next() and destroy_iterator work together to provide a collection of items to C# | |
| %apply void *VOID_INT_PTR { std::set<T>::iterator *create_iterator_begin } | |
| %apply void *VOID_INT_PTR { std::set<T>::iterator *swigiterator } | |
| std::set<T>::iterator *create_iterator_begin() { | |
| return new std::set<T>::iterator($self->begin()); | |
| } | |
| const key_type& get_next(std::set<T>::iterator *swigiterator) { | |
| (void)$self; | |
| std::set<T>::iterator iter = *swigiterator; | |
| (*swigiterator)++; | |
| return *iter; | |
| } | |
| void destroy_iterator(std::set<T>::iterator *swigiterator) { | |
| (void)$self; | |
| delete swigiterator; | |
| } | |
| } | |
| }; | |
| } |