Example #1
0
// RemoveAt attempts to remove the value v at the given logical index i. The
// return value v is the item that was found at i. If i is out of bounds, then
// v is set to nil and exists will be false. Otherwise, exists will be true.
func (s *GapSlice) RemoveAt(i int) (v interface{}, exists bool) {
	list := s.list

	e, offset := s.locate(i)
	if e == nil {
		return nil, false
	}

	// The given index is within a gap slice chunk.
	if slice, isSlice := e.Value.(gapSliceChunk); isSlice {
		v = slice[offset]
		// If the index is at the beginning or end of the chunk, simply reslice.
		// Else, split the chunk.
		switch offset {
		case 0:
			e.Value = slice[1:]
		case len(slice) - 1:
			e.Value = slice[:len(slice)-1]
		default:
			a, b := slice[:offset], slice[offset+1:]
			e.Value = a
			list.InsertAfter(b, e)
		}
		s.size -= 1
		return v, true
	}

	v = list.Remove(e)
	s.size -= 1
	return v, true
}
Example #2
0
// InsertAt attempts to insert the value v at the given logical index i. It
// returns false if i is out of bounds. Note that a value of i equal to the
// length of this GapSlice is not considered out of bounds; it is handled as
// a special case of appending to this GapSlice.
func (s *GapSlice) InsertAt(i int, v interface{}) (success bool) {
	if i > s.size {
		return false
	}

	list := s.list

	// Special case: inserting in the very end of this gap slice.
	if i == s.size {
		list.PushBack(v)
		s.size += 1
		return true
	}

	e, offset := s.locate(i)
	if e == nil {
		return false
	}

	if slice, isSlice := e.Value.(gapSliceChunk); isSlice {
		if offset == 0 {
			list.InsertBefore(v, e)
		} else {
			a, b := slice[:offset], slice[offset:]
			e.Value = a
			e = list.InsertAfter(v, e)
			list.InsertAfter(b, e)
		}
		s.size += 1
		return true
	}

	list.InsertBefore(v, e)
	s.size += 1
	return true
}