From ce895e0abda3e88806ccf108534eae557992b1a8 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Tue, 24 Oct 2023 01:49:56 +0900 Subject: [PATCH 01/40] [#44] add VecDeque --- vec_deque.go | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 vec_deque.go diff --git a/vec_deque.go b/vec_deque.go new file mode 100644 index 0000000..f8a8280 --- /dev/null +++ b/vec_deque.go @@ -0,0 +1,7 @@ +package gost + +type VecDeque[T any] struct { + buffer []T + head uint + tail uint +} From 5bc08556f51f98dfba2bd698d8292a1047fc9ad9 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:02:08 +0900 Subject: [PATCH 02/40] [#44] add VecDequeWithCapacity --- vec_deque.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/vec_deque.go b/vec_deque.go index f8a8280..c760237 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -1,7 +1,27 @@ package gost +const ( + _VECDEQUE_INITIAL_CAPACITY uint = 7 // 2^3 - 1 + _VECDEQUE_MINIMUM_CAPACITY uint = 1 // 2 - 1 +) + +// A double-ended queue implemented with a growable ring buffer. type VecDeque[T any] struct { buffer []T + len uint head uint - tail uint +} + +// Creates an empty VecDeque. +func VecDequeNew[T any]() VecDeque[T] { + return VecDequeWithCapacity[T](_VECDEQUE_INITIAL_CAPACITY) +} + +// Creates an empty VecDeque with at least the specified capacity. +func VecDequeWithCapacity[T any](capacity uint) VecDeque[T] { + if capacity < _VECDEQUE_MINIMUM_CAPACITY { + capacity = _VECDEQUE_MINIMUM_CAPACITY + } + + return VecDeque[T]{buffer: make([]T, capacity), len: 0, head: 0} } From e565e70f7d1b84db72bb930dfd16a54ba1049045 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:03:07 +0900 Subject: [PATCH 03/40] [#44] feat: VecDeque::Len --- vec_deque.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index c760237..66c1e73 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -25,3 +25,7 @@ func VecDequeWithCapacity[T any](capacity uint) VecDeque[T] { return VecDeque[T]{buffer: make([]T, capacity), len: 0, head: 0} } + +func (self VecDeque[T]) Len() USize { + return USize(self.len) +} From b567218f87af24631e515be98cd38122934683af Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:03:49 +0900 Subject: [PATCH 04/40] [#44] feat: VecDeque::_IsFull --- vec_deque.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 66c1e73..cecb24b 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -29,3 +29,7 @@ func VecDequeWithCapacity[T any](capacity uint) VecDeque[T] { func (self VecDeque[T]) Len() USize { return USize(self.len) } + +func (self VecDeque[T]) _IsFull() bool { + return self.len == uint(len(self.buffer)) +} From 6c79921b1f779b74f755359237b4c36e6ef4382c Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:10:03 +0900 Subject: [PATCH 05/40] [#44] feat: VecDeque::_Grow --- vec_deque.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index cecb24b..c5c9c76 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -33,3 +33,21 @@ func (self VecDeque[T]) Len() USize { func (self VecDeque[T]) _IsFull() bool { return self.len == uint(len(self.buffer)) } + +func (self *VecDeque[T]) _Grow() { + if !self._IsFull() { + panic("VecDeque._Grow: VecDeque is not full") + } + + oldCapacity := uint(len(self.buffer)) + newCapacity := oldCapacity * 2 + + newBuffer := make([]T, newCapacity) + copy(newBuffer, self.buffer) + + self.buffer = newBuffer + + if self._IsFull() { + panic("VecDeque._Grow: VecDeque is full") + } +} From 80fae4029bf38d5bc7c5d3470ae1531876b284ca Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:23:52 +0900 Subject: [PATCH 06/40] [#44] feat: impl WrappingAdd for primitives --- ops.go | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ vec_deque.go | 32 ++++++++++++++-- 2 files changed, 132 insertions(+), 3 deletions(-) diff --git a/ops.go b/ops.go index d61ed8a..245b03e 100644 --- a/ops.go +++ b/ops.go @@ -1,5 +1,7 @@ package gost +import "math" + // Add is a trait for types that support addition. type Add[T any] interface { Add(rhs T) T @@ -567,3 +569,104 @@ func (self *Complex64) DivAssign(rhs Complex64) { func (self *Complex128) DivAssign(rhs Complex128) { *self /= rhs } + +// Wrapping (modular) addition. Computes self + rhs, wrapping around at the boundary of the type. +func (self ISize) WrappingAdd(rhs ISize) ISize { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - ISize(math.MaxInt) - 1 + } + return result +} + +func (self I8) WrappingAdd(rhs I8) I8 { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - I8(math.MaxInt8) - 1 + } + return result +} + +func (self I16) WrappingAdd(rhs I16) I16 { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - I16(math.MaxInt16) - 1 + } + return result +} + +func (self I32) WrappingAdd(rhs I32) I32 { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - I32(math.MaxInt32) - 1 + } + return result +} + +func (self I64) WrappingAdd(rhs I64) I64 { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - I64(math.MaxInt64) - 1 + } + return result +} + +func (self USize) WrappingAdd(rhs USize) USize { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - USize(math.MaxUint) - 1 + } + return result +} + +func (self U8) WrappingAdd(rhs U8) U8 { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - U8(math.MaxUint8) - 1 + } + return result +} + +func (self U16) WrappingAdd(rhs U16) U16 { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - U16(math.MaxUint16) - 1 + } + return result +} + +func (self U32) WrappingAdd(rhs U32) U32 { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - U32(math.MaxUint32) - 1 + } + return result +} + +func (self U64) WrappingAdd(rhs U64) U64 { + result := self + rhs + + if result < self || result < rhs { + // Overflow occurred, wrap around + result = result - U64(math.MaxUint64) - 1 + } + return result +} diff --git a/vec_deque.go b/vec_deque.go index c5c9c76..43760b8 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -8,8 +8,8 @@ const ( // A double-ended queue implemented with a growable ring buffer. type VecDeque[T any] struct { buffer []T - len uint - head uint + len USize + head USize } // Creates an empty VecDeque. @@ -26,12 +26,22 @@ func VecDequeWithCapacity[T any](capacity uint) VecDeque[T] { return VecDeque[T]{buffer: make([]T, capacity), len: 0, head: 0} } +// Returns the number of elements in the vecdeque, also referred to as its ‘length’. func (self VecDeque[T]) Len() USize { return USize(self.len) } +// Appends an element to the back of the deque. +func (self *VecDeque[T]) PushBack(value T) { + if self._IsFull() { + self._Grow() + } + + self.len++ +} + func (self VecDeque[T]) _IsFull() bool { - return self.len == uint(len(self.buffer)) + return self.len == USize(len(self.buffer)) } func (self *VecDeque[T]) _Grow() { @@ -51,3 +61,19 @@ func (self *VecDeque[T]) _Grow() { panic("VecDeque._Grow: VecDeque is full") } } + +func _WrapIndex(logicalIndex USize, capacity USize) USize { + if logicalIndex >= capacity { + return logicalIndex - capacity + } else { + return logicalIndex + } +} + +func (self VecDeque[T]) _WrapAdd(index USize, addend USize) USize { + return _WrapIndex(index+addend, USize(len(self.buffer))) +} + +func (self VecDeque[T]) _ToPhysicalIndex(index USize) USize { + return self._WrapAdd(self.head, index) +} From ab3a7be813551d104a427c5ceabb3eca1c08b430 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:25:09 +0900 Subject: [PATCH 07/40] [#44] feat: VecDeque::PushBack --- vec_deque.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vec_deque.go b/vec_deque.go index 43760b8..497fd45 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -37,6 +37,7 @@ func (self *VecDeque[T]) PushBack(value T) { self._Grow() } + self.buffer[self._ToPhysicalIndex(self.len)] = value self.len++ } @@ -71,7 +72,7 @@ func _WrapIndex(logicalIndex USize, capacity USize) USize { } func (self VecDeque[T]) _WrapAdd(index USize, addend USize) USize { - return _WrapIndex(index+addend, USize(len(self.buffer))) + return _WrapIndex(index.WrappingAdd(addend), USize(len(self.buffer))) } func (self VecDeque[T]) _ToPhysicalIndex(index USize) USize { From 1481689971a857139db736281fb1e308d3b7c4a1 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:27:10 +0900 Subject: [PATCH 08/40] [#44] feat: impl WrappingSub for primitives --- ops.go | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ vec_deque.go | 12 ++++++ 2 files changed, 113 insertions(+) diff --git a/ops.go b/ops.go index 245b03e..60dbef8 100644 --- a/ops.go +++ b/ops.go @@ -670,3 +670,104 @@ func (self U64) WrappingAdd(rhs U64) U64 { } return result } + +// Wrapping (modular) subtraction. Computes self - rhs, wrapping around at the boundary of the type. +func (self ISize) WrappingSub(rhs ISize) ISize { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + ISize(math.MaxInt) + 1 + } + return result +} + +func (self I8) WrappingSub(rhs I8) I8 { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + I8(math.MaxInt8) + 1 + } + return result +} + +func (self I16) WrappingSub(rhs I16) I16 { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + I16(math.MaxInt16) + 1 + } + return result +} + +func (self I32) WrappingSub(rhs I32) I32 { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + I32(math.MaxInt32) + 1 + } + return result +} + +func (self I64) WrappingSub(rhs I64) I64 { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + I64(math.MaxInt64) + 1 + } + return result +} + +func (self USize) WrappingSub(rhs USize) USize { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + USize(math.MaxUint) + 1 + } + return result +} + +func (self U8) WrappingSub(rhs U8) U8 { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + U8(math.MaxUint8) + 1 + } + return result +} + +func (self U16) WrappingSub(rhs U16) U16 { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + U16(math.MaxUint16) + 1 + } + return result +} + +func (self U32) WrappingSub(rhs U32) U32 { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + U32(math.MaxUint32) + 1 + } + return result +} + +func (self U64) WrappingSub(rhs U64) U64 { + result := self - rhs + + if result > self || result > rhs { + // Overflow occurred, wrap around + result = result + U64(math.MaxUint64) + 1 + } + return result +} diff --git a/vec_deque.go b/vec_deque.go index 497fd45..6133526 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -31,12 +31,24 @@ func (self VecDeque[T]) Len() USize { return USize(self.len) } +// Prepends an element to the deque. +func (self *VecDeque[T]) PushFront(value T) { + if self._IsFull() { + self._Grow() + } + + self.head = self._WrapAdd(self.head, -1) + self.buffer[self.head] = value + self.len++ +} + // Appends an element to the back of the deque. func (self *VecDeque[T]) PushBack(value T) { if self._IsFull() { self._Grow() } + self.head = self._WrapAdd(self.head, self.len) self.buffer[self._ToPhysicalIndex(self.len)] = value self.len++ } From 8c41b1ea5fce7128e0a1866cc1c23736aaf189dd Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:29:13 +0900 Subject: [PATCH 09/40] [#44] feat: VecDeque::_WrapSub --- vec_deque.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vec_deque.go b/vec_deque.go index 6133526..80beb71 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -83,8 +83,14 @@ func _WrapIndex(logicalIndex USize, capacity USize) USize { } } -func (self VecDeque[T]) _WrapAdd(index USize, addend USize) USize { - return _WrapIndex(index.WrappingAdd(addend), USize(len(self.buffer))) +func (self VecDeque[T]) _WrapAdd(index USize, subtrahend USize) USize { + return _WrapIndex(index.WrappingSub(subtrahend), USize(len(self.buffer))) +} + +func (self VecDeque[T]) _WrapSub(index USize, subtrahend USize) USize { + capacity := USize(len(self.buffer)) + + return _WrapIndex(index.WrappingAdd(subtrahend).WrappingAdd(capacity), capacity) } func (self VecDeque[T]) _ToPhysicalIndex(index USize) USize { From 5dc0b1fda52c4bc408f546b7a36113734c8a7e78 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:30:16 +0900 Subject: [PATCH 10/40] [#44] feat: VecDeque::Pushfront --- vec_deque.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vec_deque.go b/vec_deque.go index 80beb71..cf54d32 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -37,7 +37,7 @@ func (self *VecDeque[T]) PushFront(value T) { self._Grow() } - self.head = self._WrapAdd(self.head, -1) + self.head = self._WrapSub(self.head, 1) self.buffer[self.head] = value self.len++ } From cf7a31531412ff4fb685dc467151da12113043e2 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Thu, 26 Oct 2023 02:32:07 +0900 Subject: [PATCH 11/40] [#44] feat: VecDeque::Get --- vec_deque.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index cf54d32..2ac65db 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -53,6 +53,16 @@ func (self *VecDeque[T]) PushBack(value T) { self.len++ } +// / Provides a reference to the element at the given index. +// / Element at index 0 is the front of the queue. +func (self VecDeque[T]) Get(index USize) Option[T] { + if index >= self.Len() { + return None[T]() + } + + return Some[T](self.buffer[uint(self._ToPhysicalIndex(index))]) +} + func (self VecDeque[T]) _IsFull() bool { return self.len == USize(len(self.buffer)) } From b89172675e99730dc088bcd17b297770d8e321f9 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Tue, 31 Oct 2023 02:31:47 +0900 Subject: [PATCH 12/40] backup --- vec_deque.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 2ac65db..cf47e46 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -80,11 +80,72 @@ func (self *VecDeque[T]) _Grow() { self.buffer = newBuffer + self._HandleCapacityIncrease(USize(oldCapacity)) + if self._IsFull() { panic("VecDeque._Grow: VecDeque is full") } } +func (self *VecDeque[T]) _HandleCapacityIncrease(oldCapacity USize) { + newCapacity := USize(len(self.buffer)) + if newCapacity < oldCapacity { + panic("VecDeque._HandleCapacityIncrease: newCapacity < oldCapacity") + } + + // Move the shortest contiguous section of the ring buffer + // + // H := head + // L := last element (`self.to_physical_idx(self.len - 1)`) + // + // H L + // [o o o o o o o . ] + // H L + // A [o o o o o o o . . . . . . . . . ] + // L H + // [o o o o o o o o ] + // H L + // B [. . . o o o o o o o . . . . . . ] + // L H + // [o o o o o o o o ] + // L H + // C [o o o o o . . . . . . . . . o o ] + + // can't use is_contiguous() because the capacity is already updated. + if self.head <= oldCapacity-self.len { + // A + // Nop + } else { + headLen := oldCapacity - self.head + tailLen := self.len - headLen + + if headLen > tailLen && newCapacity-oldCapacity >= tailLen { + // B + // self.copy_nonoverlapping(0, old_capacity, tail_len); + copy(self.buffer[oldCapacity:], self.buffer[:tailLen]) + } else { + // C + newHead := newCapacity - headLen + self._Copy(self.head, newHead, headLen) + self.head = newHead + } + } +} + +func (self *VecDeque[T]) _Copy(src USize, dst USize, len USize) { + // unsafe { + // ptr::copy(self.ptr().add(src), self.ptr().add(dst), len); + // } + + copy(self.buffer[src:], self.buffer[dst:dst+len]) +} + +func (self *VecDeque[T]) _CopyNonoverlapping() { + // unsafe { + // ptr::copy_nonoverlapping(self.ptr().add(src), self.ptr().add(dst), len); + // } +} + func _WrapIndex(logicalIndex USize, capacity USize) USize { if logicalIndex >= capacity { return logicalIndex - capacity From c9d7c27cbd52569a7040641d7ee7ebcfa6f7da29 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:08:45 +0900 Subject: [PATCH 13/40] [#44] fix: push_back bug --- vec_deque.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/vec_deque.go b/vec_deque.go index cf47e46..3dc519a 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -48,13 +48,12 @@ func (self *VecDeque[T]) PushBack(value T) { self._Grow() } - self.head = self._WrapAdd(self.head, self.len) self.buffer[self._ToPhysicalIndex(self.len)] = value self.len++ } -// / Provides a reference to the element at the given index. -// / Element at index 0 is the front of the queue. +// Provides a reference to the element at the given index. +// Element at index 0 is the front of the queue. func (self VecDeque[T]) Get(index USize) Option[T] { if index >= self.Len() { return None[T]() @@ -63,6 +62,7 @@ func (self VecDeque[T]) Get(index USize) Option[T] { return Some[T](self.buffer[uint(self._ToPhysicalIndex(index))]) } +// Returns `true` if the buffer is at full capacity. func (self VecDeque[T]) _IsFull() bool { return self.len == USize(len(self.buffer)) } @@ -146,6 +146,7 @@ func (self *VecDeque[T]) _CopyNonoverlapping() { // } } +// / Returns the index in the underlying buffer for a given logical element index. func _WrapIndex(logicalIndex USize, capacity USize) USize { if logicalIndex >= capacity { return logicalIndex - capacity @@ -154,10 +155,16 @@ func _WrapIndex(logicalIndex USize, capacity USize) USize { } } -func (self VecDeque[T]) _WrapAdd(index USize, subtrahend USize) USize { - return _WrapIndex(index.WrappingSub(subtrahend), USize(len(self.buffer))) +// Returns the index in the underlying buffer for a given logical element +// index + addend. +func (self VecDeque[T]) _WrapAdd(index USize, addend USize) USize { + capacity := USize(len(self.buffer)) + + return _WrapIndex(index.WrappingAdd(addend), capacity) } +// Returns the index in the underlying buffer for a given logical element +// index - subtrahend. func (self VecDeque[T]) _WrapSub(index USize, subtrahend USize) USize { capacity := USize(len(self.buffer)) From a016b6021986cd433d4f013ffd2fe76efa13eb6c Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:13:13 +0900 Subject: [PATCH 14/40] [#44] docs --- vec_deque.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 3dc519a..f92b3f8 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -27,11 +27,21 @@ func VecDequeWithCapacity[T any](capacity uint) VecDeque[T] { } // Returns the number of elements in the vecdeque, also referred to as its ‘length’. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.Len(), gost.USize(2)) func (self VecDeque[T]) Len() USize { return USize(self.len) } // Prepends an element to the deque. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushFront(gost.I32(3)) +// deque.PushFront(gost.I32(4)) +// gost.AssertEqual(deque.Len(), gost.USize(2)) func (self *VecDeque[T]) PushFront(value T) { if self._IsFull() { self._Grow() @@ -43,6 +53,11 @@ func (self *VecDeque[T]) PushFront(value T) { } // Appends an element to the back of the deque. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.Len(), gost.USize(2)) func (self *VecDeque[T]) PushBack(value T) { if self._IsFull() { self._Grow() From c081abda2f9b805974a4867b0f1d82b1dd941a5d Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:15:06 +0900 Subject: [PATCH 15/40] [#44] fix: push_front bug --- vec_deque.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vec_deque.go b/vec_deque.go index f92b3f8..9633628 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -183,7 +183,7 @@ func (self VecDeque[T]) _WrapAdd(index USize, addend USize) USize { func (self VecDeque[T]) _WrapSub(index USize, subtrahend USize) USize { capacity := USize(len(self.buffer)) - return _WrapIndex(index.WrappingAdd(subtrahend).WrappingAdd(capacity), capacity) + return _WrapIndex(index.WrappingSub(subtrahend).WrappingAdd(capacity), capacity) } func (self VecDeque[T]) _ToPhysicalIndex(index USize) USize { From 7d407c1c3a76d6db1a6ca38cbb6163c08b7f0a72 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:26:07 +0900 Subject: [PATCH 16/40] [#44] feat: VecDeque::Capacity --- vec_deque.go | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/vec_deque.go b/vec_deque.go index 9633628..55b4b8a 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -36,6 +36,18 @@ func (self VecDeque[T]) Len() USize { return USize(self.len) } +// Returns the number of elements the deque can hold without reallocating. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// deque.Reserve(gost.USize(8)) +// gost.AssertEqual(deque.Capacity(), gost.USize(8)) +// gost.AssertEqual(deque.Len(), gost.USize(2)) +func (self VecDeque[T]) Capacity() USize { + return USize(len(self.buffer)) +} + // Prepends an element to the deque. // // deque := gost.VecDequeNew[gost.I32]() @@ -82,6 +94,9 @@ func (self VecDeque[T]) _IsFull() bool { return self.len == USize(len(self.buffer)) } +// Double the buffer size. +// This method is inline(never), so we expect it to only be called in cold paths. +// This may panic or abort func (self *VecDeque[T]) _Grow() { if !self._IsFull() { panic("VecDeque._Grow: VecDeque is not full") @@ -102,6 +117,8 @@ func (self *VecDeque[T]) _Grow() { } } +// Frobs the head and tail sections around to handle the fact that we just reallocated. +// Unsafe because it trusts old_capacity. func (self *VecDeque[T]) _HandleCapacityIncrease(oldCapacity USize) { newCapacity := USize(len(self.buffer)) if newCapacity < oldCapacity { @@ -136,11 +153,13 @@ func (self *VecDeque[T]) _HandleCapacityIncrease(oldCapacity USize) { if headLen > tailLen && newCapacity-oldCapacity >= tailLen { // B - // self.copy_nonoverlapping(0, old_capacity, tail_len); - copy(self.buffer[oldCapacity:], self.buffer[:tailLen]) + self._CopyNonoverlapping(USize(0), oldCapacity, tailLen) } else { // C newHead := newCapacity - headLen + + // can't use copy_nonoverlapping here, because if e.g. head_len = 2 + // and new_capacity = old_capacity + 1, then the heads overlap. self._Copy(self.head, newHead, headLen) self.head = newHead } @@ -155,10 +174,8 @@ func (self *VecDeque[T]) _Copy(src USize, dst USize, len USize) { copy(self.buffer[src:], self.buffer[dst:dst+len]) } -func (self *VecDeque[T]) _CopyNonoverlapping() { - // unsafe { - // ptr::copy_nonoverlapping(self.ptr().add(src), self.ptr().add(dst), len); - // } +func (self *VecDeque[T]) _CopyNonoverlapping(src USize, dst USize, len USize) { + copy(self.buffer[src:], self.buffer[dst:dst+len]) } // / Returns the index in the underlying buffer for a given logical element index. From b85971e8fdcebbaef6ffda23b2d162c9f7dd46a8 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:37:54 +0900 Subject: [PATCH 17/40] [#44] fix: grow bug --- vec_deque.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/vec_deque.go b/vec_deque.go index 55b4b8a..fe507c3 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -1,5 +1,7 @@ package gost +import "fmt" + const ( _VECDEQUE_INITIAL_CAPACITY uint = 7 // 2^3 - 1 _VECDEQUE_MINIMUM_CAPACITY uint = 1 // 2 - 1 @@ -102,7 +104,7 @@ func (self *VecDeque[T]) _Grow() { panic("VecDeque._Grow: VecDeque is not full") } - oldCapacity := uint(len(self.buffer)) + oldCapacity := USize(len(self.buffer)) newCapacity := oldCapacity * 2 newBuffer := make([]T, newCapacity) @@ -110,7 +112,10 @@ func (self *VecDeque[T]) _Grow() { self.buffer = newBuffer - self._HandleCapacityIncrease(USize(oldCapacity)) + fmt.Println("#$", self.buffer) + self._HandleCapacityIncrease(oldCapacity) + + fmt.Println("%%%%", self.buffer) if self._IsFull() { panic("VecDeque._Grow: VecDeque is full") @@ -166,16 +171,14 @@ func (self *VecDeque[T]) _HandleCapacityIncrease(oldCapacity USize) { } } +// Copies a contiguous block of memory len long from src to dst func (self *VecDeque[T]) _Copy(src USize, dst USize, len USize) { - // unsafe { - // ptr::copy(self.ptr().add(src), self.ptr().add(dst), len); - // } - - copy(self.buffer[src:], self.buffer[dst:dst+len]) + copy(self.buffer[dst:dst+len], self.buffer[src:]) } +// Copies a contiguous block of memory len long from src to dst func (self *VecDeque[T]) _CopyNonoverlapping(src USize, dst USize, len USize) { - copy(self.buffer[src:], self.buffer[dst:dst+len]) + copy(self.buffer[dst:dst+len], self.buffer[src:]) } // / Returns the index in the underlying buffer for a given logical element index. From ff12c837f25ff191cc44f5cc9407244fb177ebd3 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:42:00 +0900 Subject: [PATCH 18/40] [#44] feat: VecDeque::Clear --- vec_deque.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index fe507c3..bd24121 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -83,6 +83,11 @@ func (self *VecDeque[T]) PushBack(value T) { // Provides a reference to the element at the given index. // Element at index 0 is the front of the queue. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.Get(gost.USize(0)), gost.Some[gost.I32](gost.I32(3))) func (self VecDeque[T]) Get(index USize) Option[T] { if index >= self.Len() { return None[T]() @@ -91,6 +96,19 @@ func (self VecDeque[T]) Get(index USize) Option[T] { return Some[T](self.buffer[uint(self._ToPhysicalIndex(index))]) } +// Clears the deque, removing all values. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// deque.Clear() +// gost.AssertEqual(deque.Len(), gost.USize(0)) +func (self *VecDeque[T]) Clear() { + self.len = 0 + self.head = 0 + self.buffer = make([]T, _VECDEQUE_INITIAL_CAPACITY) +} + // Returns `true` if the buffer is at full capacity. func (self VecDeque[T]) _IsFull() bool { return self.len == USize(len(self.buffer)) From 1509f4a4fd7b6656be88dbf0df5deb88a35934e9 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:42:50 +0900 Subject: [PATCH 19/40] [#44] feat: VecDeque::IsEmpty --- vec_deque.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index bd24121..d739b7e 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -38,6 +38,16 @@ func (self VecDeque[T]) Len() USize { return USize(self.len) } +// Returns true if the deque is empty. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.IsEmpty(), gost.Bool(false)) +func (self VecDeque[T]) IsEmpty() Bool { + return self.len == 0 +} + // Returns the number of elements the deque can hold without reallocating. // // deque := gost.VecDequeNew[gost.I32]() From dc6937bf1025ced2c1e060840adb91e99665f6d0 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:45:02 +0900 Subject: [PATCH 20/40] [#44] feat: VecDeque::PopBack --- vec_deque.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index d739b7e..bcbe900 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -91,6 +91,23 @@ func (self *VecDeque[T]) PushBack(value T) { self.len++ } +// Removes the last element from the deque and returns it, or `None` if it is empty. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.PopBack(), gost.Some[gost.I32](gost.I32(4))) +// gost.AssertEqual(deque.PopBack(), gost.Some[gost.I32](gost.I32(3))) +// gost.AssertEqual(deque.PopBack(), gost.None[gost.I32]()) +func (self *VecDeque[T]) PopBack() Option[T] { + if self.IsEmpty() { + return None[T]() + } + + self.len-- + return Some[T](self.buffer[self._ToPhysicalIndex(self.len)]) +} + // Provides a reference to the element at the given index. // Element at index 0 is the front of the queue. // From 2d05626ca64724f91af4cc83c74589acb38c6e8a Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 02:50:33 +0900 Subject: [PATCH 21/40] [#44] feat: VecDeque::PopFront --- vec_deque.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index bcbe900..a1315f2 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -91,6 +91,28 @@ func (self *VecDeque[T]) PushBack(value T) { self.len++ } +// Removes the first element and returns it, or `None` if the deque is empty. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.PopFront(), gost.Some[gost.I32](gost.I32(3))) +// gost.AssertEqual(deque.PopFront(), gost.Some[gost.I32](gost.I32(4))) +// gost.AssertEqual(deque.PopFront(), gost.None[gost.I32]()) +func (self *VecDeque[T]) PopFront() Option[T] { + if self.IsEmpty() { + return None[T]() + } + + oldHead := self.head + self.head = self._ToPhysicalIndex(1) + self.len-- + + value := self.buffer[oldHead] + + return Some[T](value) +} + // Removes the last element from the deque and returns it, or `None` if it is empty. // // deque := gost.VecDequeNew[gost.I32]() From 07a462c382e0180788ec0456dacfd77aaa032944 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:00:33 +0900 Subject: [PATCH 22/40] [#44] feat: VecDeque::Reserve --- vec_deque.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index a1315f2..3ccd04a 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -60,6 +60,28 @@ func (self VecDeque[T]) Capacity() USize { return USize(len(self.buffer)) } +// Reserves capacity for at least additional more elements to be inserted in the given deque. +// The collection may reserve more space to speculatively avoid frequent reallocations. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// deque.Reserve(gost.USize(8)) +// gost.AssertEqual(deque.Capacity(), gost.USize(8)) +func (self *VecDeque[T]) Reserve(additional USize) { + // TODO: overflow check + oldCapacity := self.Capacity() + newCapacity := oldCapacity + additional + + if newCapacity > oldCapacity { + newBuffer := make([]T, newCapacity) + copy(newBuffer, self.buffer) + self.buffer = newBuffer + + self._HandleCapacityIncrease(oldCapacity) + } +} + // Prepends an element to the deque. // // deque := gost.VecDequeNew[gost.I32]() From 902f0d2269401fc9cbfbb6ae84e91ef48237f52f Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:02:52 +0900 Subject: [PATCH 23/40] [#44] feat: VecDeque::Back --- vec_deque.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 3ccd04a..c8d6f7c 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -167,6 +167,16 @@ func (self VecDeque[T]) Get(index USize) Option[T] { return Some[T](self.buffer[uint(self._ToPhysicalIndex(index))]) } +// Provides a reference to the back element, or None if the deque is empty. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.Back(), gost.Some[gost.I32](gost.I32(4))) +func (self VecDeque[T]) Back() Option[T] { + return self.Get(self.Len().WrappingSub(1)) +} + // Clears the deque, removing all values. // // deque := gost.VecDequeNew[gost.I32]() From f06bca116faeeca773c5eaf5805ca89aa1a8d039 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:04:03 +0900 Subject: [PATCH 24/40] [#44] feat: VecDeque::Front --- vec_deque.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index c8d6f7c..8937e89 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -177,6 +177,16 @@ func (self VecDeque[T]) Back() Option[T] { return self.Get(self.Len().WrappingSub(1)) } +// Provides a reference to the front element, or None if the deque is empty. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.Front(), gost.Some[gost.I32](gost.I32(3))) +func (self VecDeque[T]) Front() Option[T] { + return self.Get(0) +} + // Clears the deque, removing all values. // // deque := gost.VecDequeNew[gost.I32]() From 16c0607beee69c9429ccefe6e9afe87a5da97381 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:07:30 +0900 Subject: [PATCH 25/40] [#44] feat: VecDeque::Contains --- vec_deque.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 8937e89..0d880ec 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -200,6 +200,33 @@ func (self *VecDeque[T]) Clear() { self.buffer = make([]T, _VECDEQUE_INITIAL_CAPACITY) } +// Returns true if the deque contains an element equal to the given value. +// This operation is O(n). +// Note that if you have a sorted VecDeque, binary_search may be faster. +// +// deque := gost.VecDequeNew[gost.I32]() +// deque.PushBack(gost.I32(3)) +// deque.PushBack(gost.I32(4)) +// gost.AssertEqual(deque.Contains(gost.I32(3)), gost.Bool(true)) +// gost.AssertEqual(deque.Contains(gost.I32(4)), gost.Bool(true)) +// gost.AssertEqual(deque.Contains(gost.I32(5)), gost.Bool(false)) +func (self VecDeque[T]) Contains(value T) Bool { + equalableValue := castToEq(value) + + if equalableValue.IsNone() { + typeName := getTypeName(value) + panic(fmt.Sprintf("'%s' does not implement Eq[%s]", typeName, typeName)) + } + + for i := USize(0); i < self.Len(); i++ { + if equalableValue.Unwrap().Eq(self.Get(i).Unwrap()) { + return true + } + } + + return false +} + // Returns `true` if the buffer is at full capacity. func (self VecDeque[T]) _IsFull() bool { return self.len == USize(len(self.buffer)) From 0db98a3c78568e7b58fdd94c46a8dd0a16c6412c Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:11:56 +0900 Subject: [PATCH 26/40] [#44] add: VecDequeIterator --- vec_deque.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 0d880ec..4fd86f9 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -200,6 +200,7 @@ func (self *VecDeque[T]) Clear() { self.buffer = make([]T, _VECDEQUE_INITIAL_CAPACITY) } +// Require `impl Eq[T] for T` // Returns true if the deque contains an element equal to the given value. // This operation is O(n). // Note that if you have a sorted VecDeque, binary_search may be faster. @@ -345,3 +346,9 @@ func (self VecDeque[T]) _WrapSub(index USize, subtrahend USize) USize { func (self VecDeque[T]) _ToPhysicalIndex(index USize) USize { return self._WrapAdd(self.head, index) } + +// iterator for VecDeque +type VecDequeIter[T any] struct { + deque *VecDeque[T] + index USize +} From e2a7933035e54ac6a2c737642450b115cdac4c9c Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:12:33 +0900 Subject: [PATCH 27/40] [#44] impl: VecDeque::IntoIter --- vec_deque.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 4fd86f9..15cfa1f 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -352,3 +352,8 @@ type VecDequeIter[T any] struct { deque *VecDeque[T] index USize } + +// into_iter +func (self VecDequeIter[T]) IntoIter() Iterator[T] { + return &VecDequeIter[T]{deque: self, position: 0} +} From 39f913203435c3a5476bef847f3a7c53d9ebf7e3 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:13:20 +0900 Subject: [PATCH 28/40] [#44] impl: VecDequeIter::Next --- vec_deque.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/vec_deque.go b/vec_deque.go index 15cfa1f..fd32ded 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -349,11 +349,23 @@ func (self VecDeque[T]) _ToPhysicalIndex(index USize) USize { // iterator for VecDeque type VecDequeIter[T any] struct { - deque *VecDeque[T] - index USize + deque *VecDeque[T] + position USize } // into_iter func (self VecDequeIter[T]) IntoIter() Iterator[T] { return &VecDequeIter[T]{deque: self, position: 0} } + +// next +func (self *VecDequeIter[T]) Next() Option[T] { + if self.position >= self.deque.Len() { + return None[T]() + } + + value := self.deque.Get(self.position) + self.position++ + + return value +} From c77f3ec0cb959b6bb4405448106f9b72cac43859 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:16:58 +0900 Subject: [PATCH 29/40] [#44] impl: VecDequeIter::Map --- vec_deque.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/vec_deque.go b/vec_deque.go index fd32ded..00d5a0d 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -3,8 +3,8 @@ package gost import "fmt" const ( - _VECDEQUE_INITIAL_CAPACITY uint = 7 // 2^3 - 1 - _VECDEQUE_MINIMUM_CAPACITY uint = 1 // 2 - 1 + _VECDEQUE_INITIAL_CAPACITY USize = 7 // 2^3 - 1 + _VECDEQUE_MINIMUM_CAPACITY USize = 1 // 2 - 1 ) // A double-ended queue implemented with a growable ring buffer. @@ -20,7 +20,7 @@ func VecDequeNew[T any]() VecDeque[T] { } // Creates an empty VecDeque with at least the specified capacity. -func VecDequeWithCapacity[T any](capacity uint) VecDeque[T] { +func VecDequeWithCapacity[T any](capacity USize) VecDeque[T] { if capacity < _VECDEQUE_MINIMUM_CAPACITY { capacity = _VECDEQUE_MINIMUM_CAPACITY } @@ -354,7 +354,7 @@ type VecDequeIter[T any] struct { } // into_iter -func (self VecDequeIter[T]) IntoIter() Iterator[T] { +func (self VecDeque[T]) IntoIter() Iterator[T] { return &VecDequeIter[T]{deque: self, position: 0} } @@ -369,3 +369,14 @@ func (self *VecDequeIter[T]) Next() Option[T] { return value } + +// map +func (self *VecDequeIter[T]) Map(f func(T) T) Iterator[T] { + newDeque := VecDequeWithCapacity[T](self.deque.Capacity()) + + for i := USize(0); i < self.deque.Len(); i++ { + newDeque.PushBack(f(self.deque.Get(i).Unwrap())) + } + + return newDeque.IntoIter() +} From 6c91acb25affd9b3f26afcf0833583f42642f4e3 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:17:22 +0900 Subject: [PATCH 30/40] [#44] impl: VecDequeIter::Filter --- vec_deque.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 00d5a0d..3d3417c 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -380,3 +380,17 @@ func (self *VecDequeIter[T]) Map(f func(T) T) Iterator[T] { return newDeque.IntoIter() } + +// filter +func (self *VecDequeIter[T]) Filter(f func(T) bool) Iterator[T] { + newDeque := VecDequeWithCapacity[T](self.deque.Capacity()) + + for i := USize(0); i < self.deque.Len(); i++ { + value := self.deque.Get(i).Unwrap() + if f(value) { + newDeque.PushBack(value) + } + } + + return newDeque.IntoIter() +} From e6489e5589264291bc38b6dbdcdfa31071bfdf90 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:17:54 +0900 Subject: [PATCH 31/40] [#44] impl: VecDequeIter::Fold --- vec_deque.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 3d3417c..24ad548 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -394,3 +394,14 @@ func (self *VecDequeIter[T]) Filter(f func(T) bool) Iterator[T] { return newDeque.IntoIter() } + +// fold +func (self *VecDequeIter[T]) Fold(initial T, f func(T, T) T) T { + accumulator := initial + + for i := USize(0); i < self.deque.Len(); i++ { + accumulator = f(accumulator, self.deque.Get(i).Unwrap()) + } + + return accumulator +} From 823de1514877c07e8a6ab8909daedfc6841bd0f7 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:18:07 +0900 Subject: [PATCH 32/40] [#44] impl: VecDequeIter::Rev --- vec_deque.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 24ad548..c945097 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -405,3 +405,14 @@ func (self *VecDequeIter[T]) Fold(initial T, f func(T, T) T) T { return accumulator } + +// rev +func (self *VecDequeIter[T]) Rev() Iterator[T] { + newDeque := VecDequeWithCapacity[T](self.deque.Capacity()) + + for i := self.deque.Len().WrappingSub(1); i >= 0; i-- { + newDeque.PushBack(self.deque.Get(i).Unwrap()) + } + + return newDeque.IntoIter() +} From 1c0fba57546bb398eaa524bc90514c71d662c5fe Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:18:43 +0900 Subject: [PATCH 33/40] [#44] impl: VecDequeIter::CollectToVec --- vec_deque.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index c945097..87135ef 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -416,3 +416,14 @@ func (self *VecDequeIter[T]) Rev() Iterator[T] { return newDeque.IntoIter() } + +// collect to Vec +func (self *VecDequeIter[T]) Collect() Vec[T] { + newVec := VecWithCapacity[T](self.deque.Capacity()) + + for i := USize(0); i < self.deque.Len(); i++ { + newVec.Push(self.deque.Get(i).Unwrap()) + } + + return newVec +} From 2b02bb22fe578f45c2d10cbeb655f9dc32dbd039 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:19:00 +0900 Subject: [PATCH 34/40] [#44] impl: VecDequeIter::CollectToLinkedList --- vec_deque.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/vec_deque.go b/vec_deque.go index 87135ef..2c67309 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -418,7 +418,7 @@ func (self *VecDequeIter[T]) Rev() Iterator[T] { } // collect to Vec -func (self *VecDequeIter[T]) Collect() Vec[T] { +func (self *VecDequeIter[T]) CollectToVec() Vec[T] { newVec := VecWithCapacity[T](self.deque.Capacity()) for i := USize(0); i < self.deque.Len(); i++ { @@ -427,3 +427,14 @@ func (self *VecDequeIter[T]) Collect() Vec[T] { return newVec } + +// collect to LinkedList +func (self *VecDequeIter[T]) CollectToLinkedList() LinkedList[T] { + newLinkedList := LinkedListNew[T]() + + for i := USize(0); i < self.deque.Len(); i++ { + newLinkedList.PushBack(self.deque.Get(i).Unwrap()) + } + + return newLinkedList +} From bc8a3b139f698d805c4662fbb6482706c5e21e18 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:21:17 +0900 Subject: [PATCH 35/40] [#44] impl Display for VecDeque --- vec_deque.go | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/vec_deque.go b/vec_deque.go index 2c67309..72d34ca 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -355,7 +355,7 @@ type VecDequeIter[T any] struct { // into_iter func (self VecDeque[T]) IntoIter() Iterator[T] { - return &VecDequeIter[T]{deque: self, position: 0} + return &VecDequeIter[T]{deque: &self, position: 0} } // next @@ -382,7 +382,7 @@ func (self *VecDequeIter[T]) Map(f func(T) T) Iterator[T] { } // filter -func (self *VecDequeIter[T]) Filter(f func(T) bool) Iterator[T] { +func (self *VecDequeIter[T]) Filter(f func(T) Bool) Iterator[T] { newDeque := VecDequeWithCapacity[T](self.deque.Capacity()) for i := USize(0); i < self.deque.Len(); i++ { @@ -438,3 +438,30 @@ func (self *VecDequeIter[T]) CollectToLinkedList() LinkedList[T] { return newLinkedList } + +// impl Display for VecDeque +func (self VecDeque[T]) Display() String { + buffer := String("") + buffer += "VecDeque[" + + for i := USize(0); i < self.Len(); i++ { + e := self.Get(i).Unwrap() + + display := castToDisplay(e) + if display.IsSome() { + buffer += display.Unwrap().Display() + } else { + typeName := getTypeName(e) + + panic(fmt.Sprintf("'%s' does not implement Display[%s]", typeName, typeName)) + } + + if i != self.Len()-1 { + buffer += ", " + } + } + + buffer += "]" + + return String(buffer) +} From e75e1b08863e684bc29eca4913f31eff07c15030 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:21:37 +0900 Subject: [PATCH 36/40] [#44] impl Debug for VecDeque --- vec_deque.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index 72d34ca..ed07144 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -465,3 +465,8 @@ func (self VecDeque[T]) Display() String { return String(buffer) } + +// impl Debug for VecDeque +func (self VecDeque[T]) Debug() String { + return self.Display() +} From b77498ef616485f79cd9f6438089b4e30d7feefd Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:21:54 +0900 Subject: [PATCH 37/40] [#44] impl AsRef for VecDeque --- vec_deque.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index ed07144..da9bd6b 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -470,3 +470,8 @@ func (self VecDeque[T]) Display() String { func (self VecDeque[T]) Debug() String { return self.Display() } + +// impl AsRef for VecDeque +func (self VecDeque[T]) AsRef() *VecDeque[T] { + return &self +} From 7fc631ac19be24bd4397744c54f427458bb053fd Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:22:25 +0900 Subject: [PATCH 38/40] [#44] impl Clone for VecDeque --- vec_deque.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index da9bd6b..c92b414 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -475,3 +475,14 @@ func (self VecDeque[T]) Debug() String { func (self VecDeque[T]) AsRef() *VecDeque[T] { return &self } + +// impl Clone for VecDeque +func (self VecDeque[T]) Clone() *VecDeque[T] { + cloned := VecDequeWithCapacity[T](self.Capacity()) + + for i := USize(0); i < self.Len(); i++ { + cloned.PushBack(self.Get(i).Unwrap()) + } + + return &cloned +} From 1c68e3f1ea8981185bbed415d948fc6848187792 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:23:49 +0900 Subject: [PATCH 39/40] [#44] impl Eq for VecDeque --- vec_deque.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/vec_deque.go b/vec_deque.go index c92b414..a218b2b 100644 --- a/vec_deque.go +++ b/vec_deque.go @@ -486,3 +486,18 @@ func (self VecDeque[T]) Clone() *VecDeque[T] { return &cloned } + +// impl Eq for Vec +func (self VecDeque[T]) Eq(other VecDeque[T]) Bool { + if self.Len() != other.Len() { + return false + } + + for i := USize(0); i < self.Len(); i++ { + if !castToEq(self.Get(i).Unwrap()).Unwrap().Eq(other.Get(i).Unwrap()) { + return false + } + } + + return true +} From 00309308d8a5ef514893e7d79c72fec6711607e5 Mon Sep 17 00:00:00 2001 From: myyrakle Date: Fri, 3 Nov 2023 03:24:20 +0900 Subject: [PATCH 40/40] v0.8.0 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3cf0994..64b9cac 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # gost -![](https://img.shields.io/badge/language-Go-00ADD8) ![](https://img.shields.io/badge/version-v0.7.3-brightgreen) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) +![](https://img.shields.io/badge/language-Go-00ADD8) ![](https://img.shields.io/badge/version-v0.8.0-brightgreen) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) ![](./etc/gorris.jpg) @@ -11,7 +11,7 @@ Experience the true taste of Rust in Go ## Install ``` -go get github.com/myyrakle/gost@v0.7.3 +go get github.com/myyrakle/gost@v0.8.0 ``` ## Example