Skip to content

Instantly share code, notes, and snippets.

@firejox
Created October 7, 2019 16:57
Show Gist options
  • Save firejox/6f86e42fb7048e5d04ae63aadf976e1b to your computer and use it in GitHub Desktop.
Save firejox/6f86e42fb7048e5d04ae63aadf976e1b to your computer and use it in GitHub Desktop.
Circular Linked List
macro container_of(ptr, _type, member)
{% if _type.resolve < Reference %}
(({{ ptr }}).as(Void*) - offsetof({{ _type }}, {{ member }})).as({{ _type }})
{% else %}
(({{ ptr }}).as(Void*) - offsetof({{ _type }}, {{ member }})).as(Pointer({{ _type }}))
{% end %}
end
struct StaticList
@prev = uninitialized Pointer(StaticList)
@next = uninitialized Pointer(StaticList)
def prev
@prev
end
def prev=(@prev)
end
def next
@next
end
def next=(@next)
end
def self_pointer
(->self.itself).closure_data.as(Pointer(StaticList))
end
def self.link(prev : StaticList*, _next : StaticList*)
prev.value.next = _next
_next.value.prev = prev
end
protected def self.insert_impl(new : StaticList*, prev : StaticList*, _next : StaticList*)
link prev, new
link new, _next
end
def init
tmp = self_pointer
typeof(self).link tmp, tmp
end
def append_to(list : StaticList*)
typeof(self).insert_impl self_pointer, list.value.prev, list
end
def prepend_to(list : StaticList*)
typeof(self).insert_impl self_pointer, list, list.value.next
end
def remove
typeof(self).link @prev, @next
end
def move_to_front(list : StaticList*)
remove
prepend_to list
end
def move_to_back(list : StaticList*)
remove
append_to list
end
def empty?
@next == self_pointer
end
def each
head = self_pointer
it = @next
while it != head
yield it
it = it.value.next
end
end
end
class Node
@link = StaticList.new
def initialize(@x : Int32)
end
def x
@x
end
def link
@link
end
def link_pointer
pointerof(@link)
end
end
list = StaticList.new
list.init
pp GC.stats
10.times do |i|
node = Node.new i
node.link.append_to(pointerof(list))
end
pp GC.stats
GC.collect
pp GC.stats
list.each do |it|
node = container_of(it, Node, @link)
puts node.x
end
GC.stats
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment