// 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 }
// 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 }