/**!
 * x3-linkedlist
 *
 * MIT License
 *
 * Copyright (c) 2019 Benno Dreißig
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
export declare class LinkedListItem<T> {
    /**
     * Value of this item
     */
    value: T;
    /**
     *Function to run on unlink() call. Usually used by LinkedList to fix first and last pointers and reduce length.
     */
    protected unlinkCleanup?: ((item: LinkedListItem<T>) => void) | undefined;
    /**
     * Item behind this item
     * ```
     * A -> ThisItem -> C
     *                  ^
     * ```
     */
    behind: LinkedListItem<T> | undefined;
    /**
     * Item before this item
     * ```
     * A -> ThisItem -> C
     * ^
     * ```
     */
    before: LinkedListItem<T> | undefined;
    constructor(
    /**
     * Value of this item
     */
    value: T, 
    /**
     *Function to run on unlink() call. Usually used by LinkedList to fix first and last pointers and reduce length.
     */
    unlinkCleanup?: ((item: LinkedListItem<T>) => void) | undefined);
    /**
     * This will link given LinkListItem behind this item.
     * If there's already a LinkedListItem linked behind, it will be relinked accordingly
     */
    insertBehind(
    /** LinkListItem to be inserted behind this one */
    item: LinkedListItem<T>): void;
    /**
     * Unlinks this LinkedListItem and calls unlinkCleanup
     * @see LinkedListItem#unlinkCleanup
     */
    unlink(
    /** If true, additionally removes the reference to the item before and behind */
    unchain?: boolean): void;
    /**
     * Item given will be inserted before this item.
     * unlinkCleanup will be copied if neccessary.
     * This function is protected, because LinkedListItem's can only be attached behind.
     * @see insertBehind
     */
    protected insertBefore(
    /** LinkListItem to be inserted before this one */
    before: LinkedListItem<T>): void;
}
/**
 * Implements a linked list structure
 * @typeparam T - Type of values within this LinkedList
 */
export declare class LinkedList<T> {
    /**
     * First item in list
     */
    first: LinkedListItem<T> | undefined;
    /**
     * Last item in list
     */
    last: LinkedListItem<T> | undefined;
    /**
     * Current length of this LinkedList.
     * Note that this does not work anymore if you for some reason add your own LinkedListItems to LinkedList by hand
     */
    length: number;
    constructor(
    /** Values to be added initially into list */
    values?: Iterable<T> | LinkedList<T>);
    /**
     * Clears this LinkedList.
     * The default complexity is O(1), because it only removes links to the first and last item and resets the length.
     * Note that if any LinkedListItem is still referenced outside the LinkedList, their before and behind fields might
     * still reference the chain, not freeing space.
     *
     * You can set the unchain parameter to true, so every item in the linked list will be unchained,
     * meaning all references to before and behind items will be removed.
     * This increases complexity to O(n), but removes accidental outside references to the full chain.
     */
    clear(
    /** If `true`, remove link info from every item. Changes complexity to O(n)! */
    unchain?: boolean): void;
    /**
     * As Array#every() given callback is called for every element until one call returns falsy or all elements had been processed
     * @returns `false` if there was a falsy response from the callback, `true` if all elements have been processed "falselesly"
     * @see Array#every
     */
    every<C>(
    /** Runs for every item in the LinkedList */
    callback: (value: T, item: LinkedListItem<T>, list: this) => boolean, 
    /** If given, callback function will be bound to thisArg */
    thisArg?: C): boolean;
    /**
     * Filters values into a new LinkedList
     * @see Array#filter
     */
    filter<C>(
    /** decides wether given element should be part of new LinkedList */
    callback: (value: T, item: LinkedListItem<T>, list: this) => boolean, 
    /** If given, callback function will be bound to thisArg */
    thisArg?: C): LinkedList<T>;
    /**
     * Returns value for which given callback returns truthy
     * @see Array#find
     */
    find<C>(
    /** runs for every value in LinkedList. If it returns truthy, current value is returned. */
    callback: (value: T, item: LinkedListItem<T>, list: this) => boolean, 
    /** If given, callback function will be bound to thisArg */
    thisArg?: C): T | undefined;
    /**
     * Returns the LinkedListItem for which given callback returns truthy
     * @see Array#findIndex
     */
    findItem<C>(
    /** runs for every LinkedListItem in LinkedList. If it returns truthy, current LinkedListItem is returned. */
    callback: (value: T, item: LinkedListItem<T>, list: this) => boolean, 
    /** If given, callback function will be bound to thisArg */
    thisArg?: C): LinkedListItem<T> | undefined;
    /**
     * Iterates this LinkedList's items and values
     * @see Array#forEach
     */
    forEach<C>(
    /** Gets every value in LinkedList once with corresponding LinkedListItem and LinkedList */
    callback: (value: T, item: LinkedListItem<T>, list: this) => void, 
    /** If given, callback function will be bound to thisArg */
    thisArg?: C): void;
    /**
     * Checks if value can be found within LinkedList, starting from fromIndex, if given.
     * @returns true if value could be found in LinkedList (respecting fromIndex), false otherwhise
     * @see Array#includes
     */
    includes(
    /** value to be found in this */
    value: T, 
    /** Starting index. Supports negative values for which `this.size - 1 + fromIndex` will be used as starting point. */
    fromIndex?: number): boolean;
    /**
     * Searches forward for given value and returns the first corresponding LinkedListItem found
     * @see Array#indexOf
     */
    itemOf(
    /** Value to be found */
    searchedValue: T, 
    /** Index to start from */
    fromIndex?: number): LinkedListItem<T> | undefined;
    /**
     * Searches backwards for given value and returns the first corresponding LinkedListItem found
     * @see Array#indexOf
     */
    lastItemOf(
    /** Value to be found */
    searchedValue: T, 
    /** Index to start from */
    fromIndex?: number): LinkedListItem<T> | undefined;
    /**
     * Creates a new LinkedList with each of its itesm representing the output of the callback with each item in current LinkedList.
     * @see Array#map
     */
    map<V, C>(
    /** Gets value, LinkedListeItem and LinkedList. The response will be used as value in the new LinkedList */
    callback: (value: T, item: LinkedListItem<T>, list: this) => V, 
    /** If given, callback function will be bound to thisArg */
    thisArg?: C): LinkedList<V>;
    /**
     * From Array#reduce on MDN: The reduce() method executes a reducer function (that you provide) on each element of the LinkedList,
     * resulting in a single output value.
     * @see Array#reduce
     */
    reduce<V>(
    /**
     * Gets first value, current value (starting with the second value), LinkedListeItem and LinkedList.
     * Note that currentItem will be the second item on first call.
     * The response will be used as the next accumulator.
     */
    callback: (accumulator: T, currentValue: T, currentItem: LinkedListItem<T>, list: this) => V): V;
    reduce<V>(
    /**
     * Gets initialValue as accumulator initially, LinkedListeItem and LinkedList.
     * The response will be used as the next accumulator.
     */
    callback: (accumulator: V, currentValue: T, currentItem: LinkedListItem<T>, list: this) => V, 
    /** Value for the first call of callback */
    initialValue: V): V;
    /**
     * From Array#reduceRight on MDN: The reduceRight() method applies a function against an accumulator and each value of the LinkedList (from last-to-first)
     * to reduce it to a single value.
     * @see Array#reduceRight
     * @see LinkedList#reduce
     */
    reduceRight<V>(
    /**
     * Gets the last value, current value (starting with the second-to-last value), LinkedListeItem and LinkedList.
     * Note that currentItem will be the second-to-last item on the first call.
     * The response will be used as the next accumulator.
     */
    callback: (accumulator: T, currentValue: T, currentItem: LinkedListItem<T>, list: this) => V): V;
    reduceRight<V>(
    /**
     * Gets initialValue as accumulator initially, LinkedListeItem and LinkedList.
     * The response will be used as the next accumulator.
     */
    callback: (accumulator: V, currentValue: T, currentItem: LinkedListItem<T>, list: this) => V, 
    /** Value for the first call of callback */
    initialValue: V): V;
    /**
     * Runs callback for every entry and returns true immediately if call of callback returns truthy.
     * @returns `true` once a callback call returns truthy, `false` if none returned truthy.
     */
    some<C>(
    /** called for every element. If response is truthy, this currentvalue will be returned by `.some()`. */
    callback: (currentValue: T, item: LinkedListItem<T>, list: this) => boolean, 
    /** If given, callback function will be bound to thisArg */
    thisArg?: C): boolean;
    /**
     * Joins values within this by given separator. Uses Array#join directly.
     * @see Array#join
     */
    join(
    /** separator between items in the resulting string */
    separator?: string): string;
    /**
     * Concats given values and returns a new LinkedList with all given values.
     * If LinkedList's are given, they will be spread.
     * @see Array#concat
     */
    concat<V>(
    /** Other values or lists to be concat'ed together */
    ...others: Array<V | LinkedList<V>>): LinkedList<V | T>;
    /**
     * Removes the last LinkedListItem and returns its inner value
     */
    pop(): T | undefined;
    /**
     * Adds given values on the end of this LinkedList
     */
    push(
    /** Values to be added */
    ...values: T[]): number;
    /**
     * Adds given values to the beginning of this LinkedList
     */
    unshift(
    /** Values to be added */
    ...values: T[]): number;
    /**
     * Removes first occurrence of value found.
     */
    remove(
    /** value to remove once */
    value: T): boolean;
    /**
     * Removes every occurrance of value within this.
     */
    removeAllOccurrences(
    /** value to remove completely */
    value: T): boolean;
    /**
     * Returns and removes first element from LinkedList
     */
    shift(): T | undefined;
    /**
     * Returns LinkedListItem and value for every entry of this LinkedList
     */
    [Symbol.iterator](): IterableIterator<[LinkedListItem<T>, T]>;
    /**
     * Returns LinkedListItem and value for every entry of this LinkedList
     * @see LinkedList#Symbol.iterator
     */
    entries(): IterableIterator<[LinkedListItem<T>, T]>;
    /**
     * Iterates the LinkedListItem's of this LinkedList
     */
    keys(): IterableIterator<LinkedListItem<T>>;
    /**
     * Returns a value for every entry of this LinkedList
     */
    values(): IterableIterator<T>;
    /**
     * Returns the item by given index.
     * Supports negative values and will return the item at `LinkedList.size - 1 + index` in that case.
     */
    private getItemByIndex;
    /**
     * Given to own LinkedListItem's for following jobs regarding an unlink:
     * - If item is first item, set the next item as first item
     * - If item is last item, set the previous item as last item
     * - Decrease length
     */
    private unlinkCleanup;
}
//# sourceMappingURL=x3-linkedlist.d.ts.map