All Downloads are FREE. Search and download functionalities are using the official Maven repository.

parsley.internal.collection.mutable.SinglyLinkedList.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2020 Parsley Contributors 
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package parsley.internal.collection.mutable

import parsley.XAssert._

import SinglyLinkedList.{LinkedListIterator, Node}

private [internal] class SinglyLinkedList[A] private
    (private var start: Node[A],
     private var end: Node[A]) extends Iterable[A] {

    private def this() = this(null, null)

    private def unsafeAddOne(x: A): this.type = {
        assume(this.nonEmpty, "list is empty when unsafely adding an element")
        val next = new Node(x, null)
        if (this.end != null) this.end.next = next
        this.end = next
        this
    }
    def addOne(x: A): this.type = {
        if (this.start == null) {
            this.start = new Node(x, null)
            this.end = this.start
            this
        }
        else unsafeAddOne(x)
    }
    def +=(x: A): this.type = addOne(x)

    def ::(x: A): SinglyLinkedList[A] = new SinglyLinkedList(new Node(x, this.start), this.end)

    def addAll(xs: Iterable[A]): this.type = addAll(xs.iterator)
    def addAll(it: Iterator[A]): this.type = {
        if (it.hasNext) {
            addOne(it.next())
            for (x <- it) {
                unsafeAddOne(x)
            }
        }
        this
    }

    def prependOne(x: A): this.type = {
        val start = new Node(x, this.start)
        this.start = start
        if (this.end == null) this.end = this.start
        this
    }

    def stealAll(other: SinglyLinkedList[A]): this.type = if (other.nonEmpty) {
        if (this.end != null) this.end.next = other.start
        else this.start = other.start
        this.end = other.end
        other.start = null
        other.end = null
        this
    } else this

    override def isEmpty: Boolean = start == null

    override def lastOption: Option[A] = if (end != null) Some(end.x) else None
    override def headOption: Option[A] = if (start != null) Some(start.x) else None

    override def iterator: LinkedListIterator[A] = new LinkedListIterator[A] {
        var current = start
        override val end = SinglyLinkedList.this.end
    }
}

private [internal] object SinglyLinkedList {
    private class Node[A](val x: A, var next: Node[A])
    def empty[A]: SinglyLinkedList[A] = new SinglyLinkedList[A]
    def apply[A](x: A, xs: A*): SinglyLinkedList[A] = {
        val list = new SinglyLinkedList[A]
        list += x
        for (x <- xs) list.unsafeAddOne(x)
        list
    }

    abstract class LinkedListIterator[A] extends Iterator[A] {
        protected [SinglyLinkedList] var current: Node[A]
        protected [SinglyLinkedList] val end: Node[A]
        def hasNext: Boolean = current != null
        def next(): A = { val r = current.x; current = current.next; r }
        def remaining: SinglyLinkedList[A] = {
            if (hasNext) {
                new SinglyLinkedList(current, end)
            }
            else {
                new SinglyLinkedList
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy