github.com/kazu/loncha@v0.6.3/container_list/list.go (about)

     1  // ListEntry is a base of http://golang.org/pkg/container/list/
     2  // this is tuning performancem, reduce heap usage.
     3  // Copyright 2009 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package list
     8  
     9  import (
    10  	"errors"
    11  	"unsafe"
    12  
    13  	"github.com/kazu/loncha/list_head"
    14  )
    15  
    16  func New() (l *ListEntry) {
    17  	l = &ListEntry{}
    18  	l.Init()
    19  	return
    20  }
    21  
    22  func (d *ListEntry) Init() {
    23  	d.ListHead.Init()
    24  }
    25  
    26  // Next ... returns the next list element or nil.
    27  func (d *ListEntry) Next() *ListEntry {
    28  	if d.ListHead.Next() == nil {
    29  		panic(errors.New("d.next is nil"))
    30  	}
    31  	return (*ListEntry)(unsafe.Pointer(uintptr(unsafe.Pointer(d.ListHead.Next())) - unsafe.Offsetof(d.ListHead)))
    32  }
    33  
    34  // Prev ... returns the previous list element or nil.
    35  func (d *ListEntry) Prev() *ListEntry {
    36  	if d.ListHead.Next() == nil {
    37  		panic(errors.New("d.prev is nil"))
    38  	}
    39  	return (*ListEntry)(unsafe.Pointer(uintptr(unsafe.Pointer(d.ListHead.Prev())) - unsafe.Offsetof(d.ListHead)))
    40  }
    41  
    42  // NewListEntryList ... New returns an initialized list.
    43  func NewListEntryList(h *ListEntry) *ListEntry {
    44  	h.Init()
    45  	return h
    46  }
    47  
    48  // Len ... size of list
    49  func (d *ListEntry) Len() int {
    50  	return d.ListHead.Len()
    51  }
    52  
    53  // Add ... insert n after d
    54  func (d *ListEntry) Add(n *ListEntry) *ListEntry {
    55  	d.ListHead.Add(&n.ListHead)
    56  	return n
    57  }
    58  
    59  // Delete ... delete d from linked-list
    60  func (d *ListEntry) Delete() *ListEntry {
    61  	ptr := d.ListHead.Delete()
    62  	return (*ListEntry)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) - unsafe.Offsetof(d.ListHead)))
    63  }
    64  
    65  // Remove ... Alias of Delete()
    66  func (d *ListEntry) Remove() *ListEntry {
    67  	return d.Delete()
    68  }
    69  
    70  // ContainOf ... find same entry of ptr
    71  func (d *ListEntry) ContainOf(ptr *list_head.ListHead) *ListEntry {
    72  	return (*ListEntry)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) - unsafe.Offsetof(d.ListHead)))
    73  }
    74  
    75  // Front ... first value of ListEntry
    76  func (d *ListEntry) Front() *ListEntry {
    77  	return d.ContainOf(d.ListHead.Front())
    78  }
    79  
    80  // Back ... last entry of linked-list
    81  func (d *ListEntry) Back() *ListEntry {
    82  	return d.ContainOf(d.ListHead.Back())
    83  }
    84  
    85  // PushFront ... inserts a new value v at the front of list l and returns e.
    86  func (d *ListEntry) PushFront(v *ListEntry) *ListEntry {
    87  	front := d.Front()
    88  	v.Add(front)
    89  	return v
    90  }
    91  
    92  // PushBack ... inserts a new element e with value v at the back of list l and returns e.
    93  func (l *ListEntry) PushBack(v *ListEntry) *ListEntry {
    94  	last := l.Back()
    95  	last.Add(v)
    96  	return v
    97  }
    98  
    99  // InsertBefore inserts a new element e with value v immediately before mark and returns e.
   100  // If mark is not an element of l, the list is not modified.
   101  func (l *ListEntry) InsertBefore(v *ListEntry) *ListEntry {
   102  	l.Prev().Add(v)
   103  	return v
   104  }
   105  
   106  // InsertAfter ... inserts a new element e with value v immediately after mark and returns e.
   107  // If mark is not an element of l, the list is not modified.
   108  func (l *ListEntry) InsertAfter(v *ListEntry) *ListEntry {
   109  	l.Next().Add(v)
   110  	return v
   111  }
   112  
   113  // MoveToFront ... moves element e to the front of list l.
   114  // If e is not an element of l, the list is not modified.
   115  func (l *ListEntry) MoveToFront(v *ListEntry) *ListEntry {
   116  	v.Remove()
   117  	return l.PushFront(v)
   118  }
   119  
   120  // MoveToBack ... moves element e to later of list l.
   121  // If e is not an element of l, the list is not modified.
   122  func (l *ListEntry) MoveToBack(v *ListEntry) *ListEntry {
   123  	v.Remove()
   124  	return l.PushBack(v)
   125  }
   126  
   127  // MoveBefore ... moves element e to its new position before mark.
   128  // If e or mark is not an element of l, or e == mark, the list is not modified.
   129  func (l *ListEntry) MoveBefore(v *ListEntry) *ListEntry {
   130  	v.Remove()
   131  	l.Prev().Add(v)
   132  	return v
   133  }
   134  
   135  // MoveAfter ... moves element e to its new position after mark.
   136  // If e is not an element of l, or e == mark, the list is not modified.
   137  func (l *ListEntry) MoveAfter(v *ListEntry) *ListEntry {
   138  	v.Remove()
   139  	l.Add(v)
   140  	return v
   141  }
   142  
   143  func (l *ListEntry) PushBackList(other *ListEntry) {
   144  	l.Back().Add(other)
   145  	return
   146  }
   147  
   148  func (l *ListEntry) PushFrontList(other *ListEntry) {
   149  	other.PushBackList(l)
   150  	return
   151  }
   152  
   153  func (l *ListEntry) Each(fn func(e *ListEntry)) {
   154  
   155  	cur := l.Cursor()
   156  
   157  	for cur.Next() {
   158  		fn(l.ContainOf(cur.Pos))
   159  	}
   160  
   161  }