diff --git a/src/Runtime/StdVector.cs b/src/Runtime/StdVector.cs index 7d7a673a..5509485e 100644 --- a/src/Runtime/StdVector.cs +++ b/src/Runtime/StdVector.cs @@ -19,23 +19,76 @@ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define MSVC + using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.InteropServices; using CppSharp.Runtime; namespace Std { - public struct Vector + [StructLayout(LayoutKind.Sequential)] + public unsafe struct Vector { +#if MSVC + public byte* _Myfirst; + public byte* _Mylast; + public byte* _Myend; +#endif + + public long Size() + { + return _Mylast - _Myfirst; + } + + public bool Capacity() + { + return (_Myend - _Myfirst) != 0; + } + + public bool UnusedCapacity() + { + return (_Myend - _Mylast) != 0; + } + + public bool HasUnusedCapacity() + { + return _Myend != _Mylast; + } + + public void Add(T item) where T : ICppMarshal + { + item.MarshalManagedToNative(new IntPtr(_Mylast)); + _Mylast += item.NativeDataSize; + } + + public void ReserveNew(long count, int dataSize) + { + // Allocate some storage if we do not have any yet. + if (_Myfirst == null) + { + _Myfirst = (byte*) Marshal.AllocHGlobal(dataSize); + _Mylast = _Myfirst; + _Myend = _Myfirst + dataSize; + } + + // Ensure room for count new elements, grow exponentially. + } } - public struct Vector : ICollection where T : ICppMarshal + [StructLayout(LayoutKind.Sequential)] + public struct Vector : IList where T : ICppMarshal { public Vector Internal; - public int Count { get; private set; } + public int Count + { + get { return (int)Internal.Size(); } + } + public bool IsReadOnly { get; private set; } public Vector(Vector vector) : this() @@ -45,7 +98,8 @@ namespace Std public IEnumerator GetEnumerator() { - throw new NotImplementedException(); + var enumerator = new VectorEnumerator(this); + return enumerator; } IEnumerator IEnumerable.GetEnumerator() @@ -55,7 +109,10 @@ namespace Std public void Add(T item) { - throw new NotImplementedException(); + if (!Internal.HasUnusedCapacity()) + Internal.ReserveNew(1, item.NativeDataSize); + + Internal.Add(item); } public void Clear() @@ -77,5 +134,84 @@ namespace Std { throw new NotImplementedException(); } + + public void Resize(int newSize) + { + throw new NotImplementedException(); + } + + public int IndexOf(T item) + { + throw new NotImplementedException(); + } + + public void Insert(int index, T item) + { + throw new NotImplementedException(); + } + + public void RemoveAt(int index) + { + throw new NotImplementedException(); + } + + public T this[int index] + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + } + + public static class ListExtensions + { + public static Std.Vector ToStd(this List list) + where T : ICppMarshal + { + var vec = new Std.Vector(); + return vec; + } + } + + public unsafe class VectorEnumerator : IEnumerator + where T : ICppMarshal + { + public Vector Vector; + public byte* Position; + public int DataSize; + + public VectorEnumerator(Vector vector) + { + Vector = vector; + + if (Vector.Count > 0) + DataSize = Vector[0].NativeDataSize; + } + + public void Dispose() + { + } + + public bool MoveNext() + { + Position = (byte*)Vector.Internal._Myfirst; + + if (Position == Vector.Internal._Mylast) + return false; + + Position += DataSize; + return false; + } + + public void Reset() + { + throw new NotImplementedException(); + } + + public T Current { get; private set; } + + object IEnumerator.Current + { + get { return Current; } + } } }