ionous / container Goto Github PK
View Code? Open in Web Editor NEWan intrusive version of golang container/list
an intrusive version of golang container/list
i have changed some code,make it more like standard api
type Intrusive interface {
Prev() Intrusive
Next() Intrusive
List() *List
// use for internal
getPrev() Intrusive
getNext() Intrusive
setPrev(e Intrusive)
setNext(e Intrusive)
getList() *List
setList(l *List)
}
so you can use like this
for e := l.Front(); e != nil; e = e.Next() {
// do something
}
before
for e := l.Front(); e != nil; e = Next(e) {
// do something
}
thank you for your code!
the full code
package inlist
type Element struct {
Hook
Value interface{}
}
// NewElement creates an intrusive Element to store the passed value.
func NewElement(v interface{}) Intrusive {
return &Element{Value: v}
}
func Value(i Intrusive) interface{} {
return i.(*Element).Value
}
func Next(e Intrusive) (ret Intrusive) {
return e.Next()
}
func Prev(e Intrusive) (ret Intrusive) {
return e.Prev()
}
type Intrusive interface {
Prev() Intrusive
Next() Intrusive
List() *List
// use for internal
getPrev() Intrusive
getNext() Intrusive
setPrev(e Intrusive)
setNext(e Intrusive)
getList() *List
setList(l *List)
}
type Hook struct {
prev, next Intrusive
list *List
}
func (h *Hook) Prev() Intrusive {
if p := h.prev; h.list != nil && p != &h.list.root {
return p
}
return nil
}
func (h *Hook) Next() Intrusive {
if p := h.next; h.list != nil && p != &h.list.root {
return p
}
return nil
}
func (h *Hook) List() *List {
return h.list
}
func (h *Hook) getPrev() Intrusive {
return h.prev
}
func (h *Hook) setPrev(e Intrusive) {
h.prev = e
}
func (h *Hook) getNext() Intrusive {
return h.next
}
func (h *Hook) setNext(e Intrusive) {
h.next = e
}
func (h *Hook) getList() *List {
return h.list
}
func (h *Hook) setList(l *List) {
h.list = l
}
type List struct {
root Hook
len int
}
func (l *List) Init() *List {
l.root.next = &l.root
l.root.prev = &l.root
l.len = 0
return l
}
func New() *List {
return new(List).Init()
}
func (l *List) Len() int {
return l.len
}
// Front returns the first element of list l or nil if the list is empty.
func (l *List) Front() Intrusive {
if l.len == 0 {
return nil
}
return l.root.next
}
// Back returns the last element of list l or nil if the list is empty.
func (l *List) Back() Intrusive {
if l.len == 0 {
return nil
}
return l.root.prev
}
// lazyInit lazily initializes a zero List value.
func (l *List) lazyInit() {
if l.root.next == nil {
l.Init()
}
}
// insert inserts e after at, increments l.len, and returns e.
func (l *List) insert(e, at Intrusive) Intrusive {
n := at.getNext()
at.setNext(e)
e.setPrev(at)
e.setNext(n)
n.setPrev(e)
e.setList(l)
l.len++
return e
}
// remove removes e from its list, decrements l.len, and returns e.
func (l *List) remove(e Intrusive) Intrusive {
e.getPrev().setNext(e.getNext())
e.getNext().setPrev(e.getPrev())
e.setNext(nil)
e.setPrev(nil)
e.setList(nil)
l.len--
return e
}
// Remove removes e from l if e is an element of list l.
// It returns the element value e.Value.
// The element must not be nil.
func (l *List) Remove(e Intrusive) bool {
if e.getList() == l {
// if e.list == l, l must have been initialized when e was inserted
// in l or l == nil (e is a zero Element) and l.remove will crash
l.remove(e)
return true
}
return false
}
// PushFront inserts a new element e with value v at the front of list l and returns e.
func (l *List) PushFront(e Intrusive) Intrusive {
l.lazyInit()
return l.insert(e, &l.root)
}
// PushBack inserts a new element e with value v at the back of list l and returns e.
func (l *List) PushBack(e Intrusive) Intrusive {
l.lazyInit()
return l.insert(e, l.root.prev)
}
// InsertBefore inserts a new element e with value v immediately before mark and returns e.
// If mark is not an element of l, the list is not modified.
// The mark must not be nil.
func (l *List) InsertBefore(e Intrusive, mark Intrusive) Intrusive {
if mark.getList() != l {
return nil
}
// see comment in List.Remove about initialization of l
return l.insert(e, mark.getPrev())
}
// InsertAfter inserts a new element e with value v immediately after mark and returns e.
// If mark is not an element of l, the list is not modified.
// The mark must not be nil.
func (l *List) InsertAfter(e Intrusive, mark Intrusive) Intrusive {
if mark.getList() != l {
return nil
}
// see comment in List.Remove about initialization of l
return l.insert(e, mark)
}
// MoveToFront moves element e to the front of list l.
// If e is not an element of l, the list is not modified.
// The element must not be nil.
func (l *List) MoveToFront(e Intrusive) {
if e.getList() != l || l.root.next == e {
return
}
// see comment in List.Remove about initialization of l
l.insert(l.remove(e), &l.root)
}
// MoveToBack moves element e to the back of list l.
// If e is not an element of l, the list is not modified.
// The element must not be nil.
func (l *List) MoveToBack(e Intrusive) {
if e.getList() != l || l.root.prev == e {
return
}
// see comment in List.Remove about initialization of l
l.insert(l.remove(e), l.root.prev)
}
// MoveBefore moves element e to its new position before mark.
// If e or mark is not an element of l, or e == mark, the list is not modified.
// The element and mark must not be nil.
func (l *List) MoveBefore(e, mark Intrusive) {
if e.getList() != l || e == mark || mark.getList() != l {
return
}
l.insert(l.remove(e), mark.getPrev())
}
// MoveAfter moves element e to its new position after mark.
// If e or mark is not an element of l, or e == mark, the list is not modified.
// The element and mark must not be nil.
func (l *List) MoveAfter(e, mark Intrusive) {
if e.getList() != l || e == mark || mark.getList() != l {
return
}
l.insert(l.remove(e), mark)
}
// MoveBackList moves all elements from other to the end of this list.
// diff with MoveBackList, because that is copy, here is move
func (l *List) MoveBackList(other *List) {
if l != other {
l.lazyInit()
for e := other.Front(); e != nil; {
n := e.Next()
l.insert(e, l.root.prev)
e = n
}
other.Init()
}
}
// MoveFrontList moves all elements from other to the front of this list.
// diff with PushFrontList, because that is copy, here is move
func (l *List) MoveFrontList(other *List) {
if l != other {
l.lazyInit()
for e := other.Back(); e != nil; {
p := e.Prev()
l.insert(e, &l.root)
e = p
}
other.Init()
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.