gitlab.com/apertussolutions/u-root@v7.0.0+incompatible/cmds/core/elvish/vector/vector.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  // Package vector implements persistent vector.
     5  package vector
     6  
     7  // Vectors from elvish. I'm not convinced a lot of the claims were correct
     8  // so I stripped the comment. I'm not sure how much of what this does we need,
     9  // e.g. SubVector, but we'll see.
    10  type Vector interface {
    11  	// Len returns the length of the vector.
    12  	Len() int
    13  	// Index returns the i-th element of the vector, if it exists. The second
    14  	// return value indicates whether the element exists.
    15  	Index(i int) (interface{}, bool)
    16  	// Assoc returns an almost identical Vector, with the i-th element
    17  	// replaced. If the index is smaller than 0 or greater than the length of
    18  	// the vector, it returns nil. If the index is equal to the size of the
    19  	// vector, it is equivalent to Cons.
    20  	Assoc(i int, val interface{}) Vector
    21  	// Cons returns an almost identical Vector, with an additional element
    22  	// appended to the end.
    23  	Cons(val interface{}) Vector
    24  	// Pop returns an almost identical Vector, with the last element removed. It
    25  	// returns nil if the vector is already empty.
    26  	Pop() Vector
    27  	// SubVector returns a subvector containing the elements from i up to but
    28  	// not including j.
    29  	SubVector(i, j int) Vector
    30  	// Iterator returns an iterator over the vector.
    31  	Iterator() Iterator
    32  }
    33  
    34  // Iterator is an iterator over vector elements. It can be used like this:
    35  //
    36  //     for it := v.Iterator(); it.HasElem(); it.Next() {
    37  //         elem := it.Elem()
    38  //         // do something with elem...
    39  //     }
    40  type Iterator interface {
    41  	// Elem returns the element at the current position.
    42  	Elem() interface{}
    43  	// HasElem returns whether the iterator is pointing to an element.
    44  	HasElem() bool
    45  	// Next moves the iterator to the next position.
    46  	Next()
    47  }
    48  
    49  type vector struct {
    50  	pos   int
    51  	nodes []interface{}
    52  }
    53  
    54  // Empty is an empty Vector.
    55  var Empty Vector = &vector{}
    56  
    57  // Count returns the number of elements in a Vector.
    58  func (v *vector) Len() int {
    59  	return len(v.nodes)
    60  }
    61  
    62  func (v *vector) Index(i int) (interface{}, bool) {
    63  	if i < 0 || i >= len(v.nodes) {
    64  		return nil, false
    65  	}
    66  
    67  	return v.nodes[i], true
    68  }
    69  
    70  func (v *vector) Assoc(i int, val interface{}) Vector {
    71  	if i < 0 || i > len(v.nodes) {
    72  		return nil
    73  	}
    74  	n := append(append(v.nodes[:i], val), v.nodes[i:]...)
    75  	return &vector{nodes: n}
    76  }
    77  
    78  func (v *vector) Cons(val interface{}) Vector {
    79  	return &vector{nodes: append(v.nodes, val)}
    80  }
    81  
    82  func (v *vector) Pop() Vector {
    83  	switch len(v.nodes) {
    84  	case 0:
    85  		return nil
    86  	case 1:
    87  		return Empty
    88  	}
    89  	return &vector{nodes: v.nodes[:len(v.nodes)-1]}
    90  }
    91  
    92  func (v *vector) SubVector(begin, end int) Vector {
    93  	if begin < 0 || begin > end || end > len(v.nodes) {
    94  		return nil
    95  	}
    96  	return &subVector{v, begin, end}
    97  }
    98  
    99  func (v *vector) Iterator() Iterator {
   100  	return newIterator(v)
   101  }
   102  
   103  type subVector struct {
   104  	v     *vector
   105  	begin int
   106  	end   int
   107  }
   108  
   109  func (s *subVector) Len() int {
   110  	return s.end - s.begin
   111  }
   112  
   113  func (s *subVector) Index(i int) (interface{}, bool) {
   114  	if i < 0 || s.begin+i >= s.end {
   115  		return nil, false
   116  	}
   117  	return s.v.Index(s.begin + i)
   118  }
   119  
   120  func (s *subVector) Assoc(i int, val interface{}) Vector {
   121  	if i < 0 || s.begin+i > s.end {
   122  		return nil
   123  	} else if s.begin+i == s.end {
   124  		return s.Cons(val)
   125  	}
   126  	return s.v.Assoc(s.begin+i, val).SubVector(s.begin, s.end)
   127  }
   128  
   129  func (s *subVector) Cons(val interface{}) Vector {
   130  	return s.v.Assoc(s.end, val).SubVector(s.begin, s.end+1)
   131  }
   132  
   133  func (s *subVector) Pop() Vector {
   134  	switch s.Len() {
   135  	case 0:
   136  		return nil
   137  	case 1:
   138  		return Empty
   139  	default:
   140  		return s.v.SubVector(s.begin, s.end-1)
   141  	}
   142  }
   143  
   144  func (s *subVector) SubVector(i, j int) Vector {
   145  	return s.v.SubVector(s.begin+i, s.begin+j)
   146  }
   147  
   148  func (s *subVector) Iterator() Iterator {
   149  	return newIteratorWithRange(s.v, s.begin, s.end)
   150  }
   151  
   152  type iterator struct {
   153  	v     *vector
   154  	index int
   155  	end   int
   156  }
   157  
   158  func newIterator(v *vector) *iterator {
   159  	return newIteratorWithRange(v, 0, v.Len())
   160  }
   161  
   162  func newIteratorWithRange(v *vector, begin, end int) *iterator {
   163  	it := &iterator{v, begin, end}
   164  	return it
   165  }
   166  
   167  func (it *iterator) Elem() interface{} {
   168  	if it.index >= len(it.v.nodes) {
   169  		return nil
   170  	}
   171  	return it.v.nodes[it.index]
   172  }
   173  
   174  func (it *iterator) HasElem() bool {
   175  	return it.index < it.end
   176  }
   177  
   178  func (it *iterator) Next() {
   179  	if it.index+1 >= len(it.v.nodes) {
   180  		it.index++
   181  		return
   182  	}
   183  	it.index++
   184  }