コード例 #1
0
ファイル: header.go プロジェクト: gaowt1/lists
func (l *ListHeader) Append(v interface{}) {
	switch {
	case l.start == nil:
		l.start = l.NewListNode(v)
		l.end = l.start

	default:
		tail := chain.Next(l.end)
		l.end.Link(chain.NEXT_NODE, l.NewListNode(v))
		l.end = chain.Next(l.end)
		l.end.Link(chain.NEXT_NODE, tail)
	}
	l.length++
}
コード例 #2
0
ファイル: header.go プロジェクト: gaowt1/lists
func (l *ListHeader) Expand(i, n int) {
	if i > -1 && i <= l.length {
		switch {
		case l == nil:
			fallthrough
		case i == l.length:
			for ; n > 0; n-- {
				l.Append(l.newListNode())
			}

		case i == 0:
			l.length = n
			for ; n > 0; n-- {
				x := l.newListNode()
				x.Link(chain.NEXT_NODE, l.start)
				l.start = x
			}

		default:
			x1 := l.findNode(i - 1)
			x2 := l.findNode(i)
			l.length += n
			for ; n > 0; n-- {
				x1.Link(chain.NEXT_NODE, l.newListNode())
				x1 = chain.Next(x1)
			}
			x1.Link(chain.NEXT_NODE, x2)
		}
	}
}
コード例 #3
0
ファイル: header.go プロジェクト: gaowt1/lists
func (l *ListHeader) Tail() {
	if n := l.start; n != nil {
		l.start = chain.Next(n)
		n.Link(chain.NEXT_NODE, nil)
		l.length--
	}
}
コード例 #4
0
ファイル: header.go プロジェクト: gaowt1/lists
//	Iterates through the list reducing the nesting of each element which can be flattened.
//	Elements which are themselves LinearLists will be inlined as part of the containing list and their contained list destroyed.
func (l *ListHeader) Flatten() {
	l.eachNode(func(i int, n chain.Node) {
		value := n.Content()
		if h, ok := value.(Flattenable); ok {
			h.Flatten()
		}

		if h, ok := value.(Linkable); ok {
			switch length := h.Len(); {
			case length == 0:
				n.Set(chain.CURRENT_NODE, nil)

			case length == 1:
				n.Set(chain.CURRENT_NODE, h.Start().Content())

			default:
				l.length += length - 1
				h.End().Link(chain.NEXT_NODE, chain.Next(n))
				n.Link(chain.CURRENT_NODE, h.Start())
				if n == l.start {
					l.start = h.Start()
				}

				if n == l.end {
					l.end = h.End()
				}
			}
		} else {
			n.Set(chain.CURRENT_NODE, value)
		}
	})
}
コード例 #5
0
ファイル: header.go プロジェクト: gaowt1/lists
func (l *ListHeader) eachNode(f func(int, chain.Node)) {
	n := l.start
	for i := 0; i < l.length; i++ {
		f(i, n)
		n = chain.Next(n)
	}
}
コード例 #6
0
ファイル: header.go プロジェクト: gaowt1/lists
func (l ListHeader) equal(o ListHeader) (r bool) {
	if l.length == o.length {
		var e Equatable

		r = true
		n := l.start
		x := o.start
		for i := l.length; r && i > 0; i-- {
			if e, r = n.(Equatable); r && e.Equal(x) {
				n = chain.Next(n)
				x = chain.Next(x)
			}
		}
	}
	return
}
コード例 #7
0
ファイル: header.go プロジェクト: gaowt1/lists
func (l ListHeader) Each(f func(interface{})) {
	n := l.start
	for i := l.length; i > 0; i-- {
		f(n.Content())
		n = chain.Next(n)
	}
}
コード例 #8
0
ファイル: header.go プロジェクト: gaowt1/lists
func (l ListHeader) String() (t string) {
	terms := []string{}
	l.Each(func(term interface{}) {
		terms = append(terms, fmt.Sprintf("%v", term))
	})
	if l.length > 0 && l.start == chain.Next(l.end) {
		terms = append(terms, "...")
	}
	t = strings.Join(terms, " ")
	t = strings.Replace(t, "()", "nil", -1)
	t = strings.Replace(t, "<nil>", "nil", -1)
	return "(" + t + ")"
}
コード例 #9
0
ファイル: header.go プロジェクト: gaowt1/lists
//	Reverses the order in which elements of a List are traversed
func (l *ListHeader) Reverse() {
	if l != nil {
		current := l.start
		l.end = current

		for i := l.length; i > 0; i-- {
			next := chain.Next(current)
			current.Link(chain.NEXT_NODE, l.start)
			l.start = current
			current = next
		}
	}
	return
}
コード例 #10
0
ファイル: linear_test.go プロジェクト: gaowt1/lists
func TestLinearListString(t *testing.T) {
	ConfirmFormat := func(l *LinearList, x string) {
		if s := l.String(); s != x {
			t.Fatalf("'%v' erroneously serialised as '%v'", x, s)
		}
	}

	ConfirmFormat(&LinearList{}, "()")
	ConfirmFormat(List(0), "(0)")
	ConfirmFormat(List(0, nil), "(0 nil)")
	ConfirmFormat(List(1, List(0, nil)), "(1 (0 nil))")

	ConfirmFormat(List(1, 0, nil), "(1 0 nil)")

	c := List(10, List(0, 1, 2, 3))
	ConfirmFormat(c, "(10 (0 1 2 3))")
	ConfirmFormat(chain.Next(c.start).Content().(*LinearList), "(0 1 2 3)")
}
コード例 #11
0
ファイル: linear.go プロジェクト: gaowt1/lists
//	Removes all elements in the range from the list.
func (l *LinearList) Delete(from, to int) {
	if l != nil && l.EnforceBounds(&from, &to) {
		last_element_index := l.length - 1
		switch {
		case from == 0:
			switch {
			case to == 0:
				l.start = chain.Next(l.start)
				l.length--

			case to == last_element_index:
				l.start = nil
				l.end = nil
				l.length = 0

			default:
				l.start = l.findNode(to + 1)
				l.length -= to + 1
			}

		case from == last_element_index:
			l.end = l.findNode(from - 1)
			l.end.Link(chain.NEXT_NODE, nil)
			l.length--

		case to == last_element_index:
			l.end = l.findNode(from - 1)
			l.end.Link(chain.NEXT_NODE, nil)
			l.length = from

		case from == to:
			s := l.findNode(from - 1)
			s.Link(chain.NEXT_NODE, s.MoveTo(2))
			l.length--

		default:
			e := l.findNode(from - 1)
			e.Link(chain.NEXT_NODE, e.MoveTo(to-from+2))
			l.length -= to - from + 1
		}
	}
}
コード例 #12
0
ファイル: header.go プロジェクト: gaowt1/lists
func (l *ListHeader) Concatenate(s interface{}) {
	switch s := s.(type) {
	case []interface{}:
		if length := len(s); length > 0 {
			l.Append(s[0])
			if length > 1 {
				tail := chain.Next(l.end)
				for _, v := range s[1:] {
					l.end.Link(chain.NEXT_NODE, l.NewListNode(v))
					l.end = chain.Next(l.end)
				}
				l.end.Link(chain.NEXT_NODE, tail)
				l.length += length - 1
			}
		}

	case Sequence:
		if length := s.Len(); length > 0 {
			l.Append(s.At(0))
			if length > 1 {
				tail := chain.Next(l.end)
				for i := 1; i < length; i++ {
					l.end.Link(chain.NEXT_NODE, l.NewListNode(s.At(i)))
					l.end = chain.Next(l.end)
				}
				l.end.Link(chain.NEXT_NODE, tail)
				l.length += length - 1
			}
		}

	default:
		switch s := reflect.ValueOf(s); s.Kind() {
		case reflect.Slice:
			if length := s.Len(); length > 0 {
				l.Append(s.Index(0).Interface())
				if length > 1 {
					tail := chain.Next(l.end)
					for i := 1; i < length; i++ {
						l.end.Link(chain.NEXT_NODE, l.NewListNode(s.Index(i).Interface()))
						l.end = chain.Next(l.end)
					}
					l.end.Link(chain.NEXT_NODE, tail)
					l.length += length - 1
				}
			}
		}
	}
}
コード例 #13
0
ファイル: linear.go プロジェクト: gaowt1/lists
//	Insert an item into the list at the given location.
func (l *LinearList) Insert(i int, o interface{}) {
	if i > -1 && i <= l.length {
		switch {
		case l == nil:
			fallthrough
		case i == l.length:
			l.Append(o)

		case i == 0:
			n := l.NewListNode(o)
			n.Link(chain.NEXT_NODE, l.start)
			l.start = n
			l.length++

		default:
			n1 := l.findNode(i - 1)
			n2 := l.findNode(i)
			n1.Link(chain.NEXT_NODE, l.NewListNode(o))
			chain.Next(n1).Link(chain.NEXT_NODE, n2)
			l.length++
		}
	}
}
コード例 #14
0
ファイル: cyclic.go プロジェクト: gaowt1/lists
func (c *CycList) Rotate(i int) {
	if c != nil && c.end != nil {
		c.end = c.end.MoveTo(c.index(i))
		c.start = chain.Next(c.end)
	}
}
コード例 #15
0
ファイル: cyclic.go プロジェクト: gaowt1/lists
//	Iterate over all elements of the list indefinitely
//	The only way to terminate iteration is by raising a panic() in the applied function
func (c CycList) Cycle(f func(interface{})) {
	for n := c.start; ; n = chain.Next(n) {
		f(n.Content())
	}
}