// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vector

// StringVector is a specialization of Vector that hides the wrapping of Elements around strings.
type StringVector struct {
	Vector;
}


// Init initializes a new or resized vector.  The initial length may be <= 0 to
// request a default length.  If initial_len is shorter than the current
// length of the StringVector, trailing elements of the StringVector will be cleared.
func (p *StringVector) Init(len int) *StringVector {
	p.Vector.Init(len);
	return p;
}


// NewStringVector returns an initialized new StringVector with length at least len.
func NewStringVector(len int) *StringVector {
	return new(StringVector).Init(len);
}


// At returns the i'th element of the vector.
func (p *StringVector) At(i int) string {
	return p.Vector.At(i).(string);
}


// Set sets the i'th element of the vector to value x.
func (p *StringVector) Set(i int, x string) {
	p.a[i] = x;
}


// Last returns the element in the vector of highest index.
func (p *StringVector) Last() string {
	return p.Vector.Last().(string);
}


// Data returns all the elements as a slice.
func (p *StringVector) Data() []string {
	arr := make([]string, p.Len());
	for i, v := range p.a {
		arr[i] = v.(string);
	}
	return arr;
}


// Insert inserts into the vector an element of value x before
// the current element at index i.
func (p *StringVector) Insert(i int, x string) {
	p.Vector.Insert(i, x);
}


// InsertVector inserts into the vector the contents of the Vector
// x such that the 0th element of x appears at index i after insertion.
func (p *StringVector) InsertVector(i int, x *StringVector) {
	p.Vector.InsertVector(i, &x.Vector);
}


// Slice returns a new StringVector by slicing the old one to extract slice [i:j].
// The elements are copied. The original vector is unchanged.
func (p *StringVector) Slice(i, j int) *StringVector {
	return &StringVector{*p.Vector.Slice(i, j)};
}


// Push appends x to the end of the vector.
func (p *StringVector) Push(x string) {
	p.Vector.Push(x);
}


// Pop deletes and returns the last element of the vector.
func (p *StringVector) Pop() string {
	return p.Vector.Pop().(string);
}


// AppendVector appends the entire StringVector x to the end of this vector.
func (p *StringVector) AppendVector(x *StringVector) {
	p.Vector.InsertVector(len(p.a), &x.Vector);
}


// sort.Interface support
// Less returns a boolean denoting whether the i'th element is less than the j'th element.
func (p *StringVector) Less(i, j int) bool {
	return p.At(i) < p.At(j);
}


// Iterate over all elements; driver for range
func (p *StringVector) iterate(c chan<- string) {
	for _, v := range p.a {
		c <- v.(string);
	}
	close(c);
}


// Channel iterator for range.
func (p *StringVector) Iter() <-chan string {
	c := make(chan string);
	go p.iterate(c);
	return c;
}
