/*
 * Copyright (C) 2007-2017 Apple Inc. All rights reserved.
 * Copyright (C) 2009 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

// FIXME: Could move what Vector and Deque share into a separate file.
// Deque doesn't actually use Vector.

#include <algorithm>
#include <iterator>
#include <wtf/Vector.h>

namespace WTF {

template<typename T, size_t inlineCapacity> class DequeIteratorBase;
template<typename T, size_t inlineCapacity> class DequeIterator;
template<typename T, size_t inlineCapacity> class DequeConstIterator;

template<typename T, size_t inlineCapacity = 0>
class Deque final {
    WTF_MAKE_FAST_ALLOCATED;
public:
    typedef T ValueType;

    typedef DequeIterator<T, inlineCapacity> iterator;
    typedef DequeConstIterator<T, inlineCapacity> const_iterator;
    typedef std::reverse_iterator<iterator> reverse_iterator;
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

    Deque();
    Deque(std::initializer_list<T>);
    Deque(const Deque&);
    Deque(Deque&&);
    ~Deque();

    Deque& operator=(const Deque&);
    Deque& operator=(Deque&&);

    void swap(Deque&);

    size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + m_buffer.capacity() - m_start; }
    bool isEmpty() const { return m_start == m_end; }

    iterator begin() { return iterator(this, m_start); }
    iterator end() { return iterator(this, m_end); }
    const_iterator begin() const { return const_iterator(this, m_start); }
    const_iterator end() const { return const_iterator(this, m_end); }
    reverse_iterator rbegin() { return reverse_iterator(end()); }
    reverse_iterator rend() { return reverse_iterator(begin()); }
    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
    const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
    
    template<typename U> bool contains(const U&) const;

    T& first() { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
    const T& first() const { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
    T takeFirst();

    T& last() { ASSERT(m_start != m_end); return *(--end()); }
    const T& last() const { ASSERT(m_start != m_end); return *(--end()); }
    T takeLast();

    void append(T&& value) { append<T>(std::forward<T>(value)); }
    template<typename U> void append(U&&);
    template<typename U> void prepend(U&&);
    void removeFirst();
    void removeLast();
    void remove(iterator&);
    void remove(const_iterator&);
    
    template<typename Func> void removeAllMatching(const Func&);
    
    // This is a priority enqueue. The callback is given a value, and if it returns true, then this
    // will put the appended value before that value. It will keep bubbling until the callback returns
    // false or the value ends up at the head of the queue.
    template<typename U, typename Func>
    void appendAndBubble(U&&, const Func&);
    
    // Remove and return the first element for which the callback returns true. Returns a null version of
    // T if it the callback always returns false.
    template<typename Func>
    T takeFirst(const Func&);

    // Remove and return the last element for which the callback returns true. Returns a null version of
    // T if it the callback always returns false.
    template<typename Func>
    T takeLast(const Func&);

    void clear();

    template<typename Predicate> iterator findIf(const Predicate&);
    template<typename Predicate> const_iterator findIf(const Predicate&) const;

private:
    friend class DequeIteratorBase<T, inlineCapacity>;

    typedef VectorBuffer<T, inlineCapacity> Buffer;
    typedef VectorTypeOperations<T> TypeOperations;
    typedef DequeIteratorBase<T, inlineCapacity> IteratorBase;

    void remove(size_t position);
    void invalidateIterators();
    void destroyAll();
    void checkValidity() const;
    void checkIndexValidity(size_t) const;
    void expandCapacityIfNeeded();
    void expandCapacity();

    size_t m_start;
    size_t m_end;
    Buffer m_buffer;
#ifndef NDEBUG
    mutable IteratorBase* m_iterators;
#endif
};

template<typename T, size_t inlineCapacity = 0>
class DequeIteratorBase {
    WTF_MAKE_FAST_ALLOCATED;
protected:
    DequeIteratorBase();
    DequeIteratorBase(const Deque<T, inlineCapacity>*, size_t);
    DequeIteratorBase(const DequeIteratorBase&);
    DequeIteratorBase& operator=(const DequeIteratorBase&);
    ~DequeIteratorBase();

    void assign(const DequeIteratorBase& other) { *this = other; }

    void increment();
    void decrement();

    T* before() const;
    T* after() const;

    bool isEqual(const DequeIteratorBase&) const;

private:
    void addToIteratorsList();
    void removeFromIteratorsList();
    void checkValidity() const;
    void checkValidity(const DequeIteratorBase&) const;

    Deque<T, inlineCapacity>* m_deque;
    size_t m_index;

    friend class Deque<T, inlineCapacity>;

#ifndef NDEBUG
    mutable DequeIteratorBase* m_next;
    mutable DequeIteratorBase* m_previous;
#endif
};

template<typename T, size_t inlineCapacity = 0>
class DequeIterator : public DequeIteratorBase<T, inlineCapacity> {
    WTF_MAKE_FAST_ALLOCATED;
private:
    typedef DequeIteratorBase<T, inlineCapacity> Base;
    typedef DequeIterator<T, inlineCapacity> Iterator;

public:
    typedef ptrdiff_t difference_type;
    typedef T value_type;
    typedef T* pointer;
    typedef T& reference;
    typedef std::bidirectional_iterator_tag iterator_category;

    DequeIterator(Deque<T, inlineCapacity>* deque, size_t index)
        : Base(deque, index) { }

    DequeIterator(const Iterator& other) : Base(other) { }
    DequeIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }

    T& operator*() const { return *Base::after(); }
    T* operator->() const { return Base::after(); }

    bool operator==(const Iterator& other) const { return Base::isEqual(other); }
    bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }

    Iterator& operator++() { Base::increment(); return *this; }
    // postfix ++ intentionally omitted
    Iterator& operator--() { Base::decrement(); return *this; }
    // postfix -- intentionally omitted
};

template<typename T, size_t inlineCapacity = 0>
class DequeConstIterator : public DequeIteratorBase<T, inlineCapacity> {
    WTF_MAKE_FAST_ALLOCATED;
private:
    typedef DequeIteratorBase<T, inlineCapacity> Base;
    typedef DequeConstIterator<T, inlineCapacity> Iterator;
    typedef DequeIterator<T, inlineCapacity> NonConstIterator;

public:
    typedef ptrdiff_t difference_type;
    typedef T value_type;
    typedef const T* pointer;
    typedef const T& reference;
    typedef std::bidirectional_iterator_tag iterator_category;

    DequeConstIterator(const Deque<T, inlineCapacity>* deque, size_t index)
        : Base(deque, index) { }

    DequeConstIterator(const Iterator& other) : Base(other) { }
    DequeConstIterator(const NonConstIterator& other) : Base(other) { }
    DequeConstIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
    DequeConstIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; }

    const T& operator*() const { return *Base::after(); }
    const T* operator->() const { return Base::after(); }

    bool operator==(const Iterator& other) const { return Base::isEqual(other); }
    bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }

    Iterator& operator++() { Base::increment(); return *this; }
    // postfix ++ intentionally omitted
    Iterator& operator--() { Base::decrement(); return *this; }
    // postfix -- intentionally omitted
};

#ifdef NDEBUG
template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkValidity() const { }
template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkIndexValidity(size_t) const { }
template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::invalidateIterators() { }
#else
template<typename T, size_t inlineCapacity>
void Deque<T, inlineCapacity>::checkValidity() const
{
    // In this implementation a capacity of 1 would confuse append() and
    // other places that assume the index after capacity - 1 is 0.
    ASSERT(m_buffer.capacity() != 1);

    if (!m_buffer.capacity()) {
        ASSERT(!m_start);
        ASSERT(!m_end);
    } else {
        ASSERT(m_start < m_buffer.capacity());
        ASSERT(m_end < m_buffer.capacity());
    }
}

template<typename T, size_t inlineCapacity>
void Deque<T, inlineCapacity>::checkIndexValidity(size_t index) const
{
    ASSERT_UNUSED(index, index <= m_buffer.capacity());
    if (m_start <= m_end) {
        ASSERT(index >= m_start);
        ASSERT(index <= m_end);
    } else {
        ASSERT(index >= m_start || index <= m_end);
    }
}

template<typename T, size_t inlineCapacity>
void Deque<T, inlineCapacity>::invalidateIterators()
{
    IteratorBase* next;
    for (IteratorBase* p = m_iterators; p; p = next) {
        next = p->m_next;
        p->m_deque = 0;
        p->m_next = 0;
        p->m_previous = 0;
    }
    m_iterators = 0;
}
#endif

template<typename T, size_t inlineCapacity>
inline Deque<T, inlineCapacity>::Deque()
    : m_start(0)
    , m_end(0)
#ifndef NDEBUG
    , m_iterators(0)
#endif
{
    checkValidity();
}

template<typename T, size_t inlineCapacity>
inline Deque<T, inlineCapacity>::Deque(std::initializer_list<T> initializerList)
    : Deque()
{
    for (auto& element : initializerList)
        append(element);
}

template<typename T, size_t inlineCapacity>
inline Deque<T, inlineCapacity>::Deque(const Deque& other)
    : m_start(other.m_start)
    , m_end(other.m_end)
    , m_buffer(other.m_buffer.capacity())
#ifndef NDEBUG
    , m_iterators(0)
#endif
{
    const T* otherBuffer = other.m_buffer.buffer();
    if (m_start <= m_end)
        TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_end, m_buffer.buffer() + m_start);
    else {
        TypeOperations::uninitializedCopy(otherBuffer, otherBuffer + m_end, m_buffer.buffer());
        TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_buffer.capacity(), m_buffer.buffer() + m_start);
    }
}

template<typename T, size_t inlineCapacity>
inline Deque<T, inlineCapacity>::Deque(Deque&& other)
    : Deque()
{
    swap(other);
}

template<typename T, size_t inlineCapacity>
inline auto Deque<T, inlineCapacity>::operator=(const Deque& other) -> Deque&
{
    // FIXME: This is inefficient if we're using an inline buffer and T is
    // expensive to copy since it will copy the buffer twice instead of once.
    Deque<T, inlineCapacity> copy(other);
    swap(copy);
    return *this;
}

template<typename T, size_t inlineCapacity>
inline auto Deque<T, inlineCapacity>::operator=(Deque&& other) -> Deque&
{
    swap(other);
    return *this;
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::destroyAll()
{
    if (m_start <= m_end)
        TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_end);
    else {
        TypeOperations::destruct(m_buffer.buffer(), m_buffer.buffer() + m_end);
        TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_buffer.capacity());
    }
}

template<typename T, size_t inlineCapacity>
inline Deque<T, inlineCapacity>::~Deque()
{
    checkValidity();
    invalidateIterators();
    destroyAll();
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::swap(Deque<T, inlineCapacity>& other)
{
    checkValidity();
    other.checkValidity();
    invalidateIterators();
    std::swap(m_start, other.m_start);
    std::swap(m_end, other.m_end);
    m_buffer.swap(other.m_buffer, 0, 0);
    checkValidity();
    other.checkValidity();
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::clear()
{
    checkValidity();
    invalidateIterators();
    destroyAll();
    m_start = 0;
    m_end = 0;
    m_buffer.deallocateBuffer(m_buffer.buffer());
    checkValidity();
}

template<typename T, size_t inlineCapacity>
template<typename Predicate>
inline auto Deque<T, inlineCapacity>::findIf(const Predicate& predicate) -> iterator
{
    return std::find_if(begin(), end(), predicate);
}

template<typename T, size_t inlineCapacity>
template<typename Predicate>
inline auto Deque<T, inlineCapacity>::findIf(const Predicate& predicate) const -> const_iterator
{
    return std::find_if(begin(), end(), predicate);
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::expandCapacityIfNeeded()
{
    if (m_start) {
        if (m_end + 1 != m_start)
            return;
    } else if (m_end) {
        if (m_end != m_buffer.capacity() - 1)
            return;
    } else if (m_buffer.capacity())
        return;

    expandCapacity();
}

template<typename T, size_t inlineCapacity>
void Deque<T, inlineCapacity>::expandCapacity()
{
    checkValidity();
    size_t oldCapacity = m_buffer.capacity();
    T* oldBuffer = m_buffer.buffer();
    m_buffer.allocateBuffer(std::max(static_cast<size_t>(16), oldCapacity + oldCapacity / 4 + 1));
    if (m_start <= m_end)
        TypeOperations::move(oldBuffer + m_start, oldBuffer + m_end, m_buffer.buffer() + m_start);
    else {
        TypeOperations::move(oldBuffer, oldBuffer + m_end, m_buffer.buffer());
        size_t newStart = m_buffer.capacity() - (oldCapacity - m_start);
        TypeOperations::move(oldBuffer + m_start, oldBuffer + oldCapacity, m_buffer.buffer() + newStart);
        m_start = newStart;
    }
    m_buffer.deallocateBuffer(oldBuffer);
    checkValidity();
}

template<typename T, size_t inlineCapacity>
template<typename U>
bool Deque<T, inlineCapacity>::contains(const U& searchValue) const
{
    auto endIterator = end();
    return std::find(begin(), endIterator, searchValue) != endIterator;
}

template<typename T, size_t inlineCapacity>
inline auto Deque<T, inlineCapacity>::takeFirst() -> T
{
    T oldFirst = WTFMove(first());
    removeFirst();
    return oldFirst;
}

template<typename T, size_t inlineCapacity>
inline auto Deque<T, inlineCapacity>::takeLast() -> T
{
    T oldLast = WTFMove(last());
    removeLast();
    return oldLast;
}

template<typename T, size_t inlineCapacity> template<typename U>
inline void Deque<T, inlineCapacity>::append(U&& value)
{
    checkValidity();
    expandCapacityIfNeeded();
    new (NotNull, std::addressof(m_buffer.buffer()[m_end])) T(std::forward<U>(value));
    if (m_end == m_buffer.capacity() - 1)
        m_end = 0;
    else
        ++m_end;
    checkValidity();
}

template<typename T, size_t inlineCapacity> template<typename U>
inline void Deque<T, inlineCapacity>::prepend(U&& value)
{
    checkValidity();
    expandCapacityIfNeeded();
    if (!m_start)
        m_start = m_buffer.capacity() - 1;
    else
        --m_start;
    new (NotNull, std::addressof(m_buffer.buffer()[m_start])) T(std::forward<U>(value));
    checkValidity();
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::removeFirst()
{
    checkValidity();
    invalidateIterators();
    ASSERT(!isEmpty());
    TypeOperations::destruct(std::addressof(m_buffer.buffer()[m_start]), std::addressof(m_buffer.buffer()[m_start + 1]));
    if (m_start == m_buffer.capacity() - 1)
        m_start = 0;
    else
        ++m_start;
    checkValidity();
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::removeLast()
{
    checkValidity();
    invalidateIterators();
    ASSERT(!isEmpty());
    if (!m_end)
        m_end = m_buffer.capacity() - 1;
    else
        --m_end;
    TypeOperations::destruct(std::addressof(m_buffer.buffer()[m_end]), std::addressof(m_buffer.buffer()[m_end + 1]));
    checkValidity();
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::remove(iterator& it)
{
    it.checkValidity();
    remove(it.m_index);
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::remove(const_iterator& it)
{
    it.checkValidity();
    remove(it.m_index);
}

template<typename T, size_t inlineCapacity>
inline void Deque<T, inlineCapacity>::remove(size_t position)
{
    if (position == m_end)
        return;

    checkValidity();
    invalidateIterators();

    T* buffer = m_buffer.buffer();
    TypeOperations::destruct(std::addressof(buffer[position]), std::addressof(buffer[position + 1]));

    // Find which segment of the circular buffer contained the remove element, and only move elements in that part.
    if (position >= m_start) {
        TypeOperations::moveOverlapping(buffer + m_start, buffer + position, buffer + m_start + 1);
        m_start = (m_start + 1) % m_buffer.capacity();
    } else {
        TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_end, buffer + position);
        m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity();
    }
    checkValidity();
}

template<typename T, size_t inlineCapacity>
template<typename Func>
inline void Deque<T, inlineCapacity>::removeAllMatching(const Func& func)
{
    size_t count = size();
    while (count--) {
        T value = takeFirst();
        if (!func(value))
            append(WTFMove(value));
    }
}

template<typename T, size_t inlineCapacity>
template<typename U, typename Func>
inline void Deque<T, inlineCapacity>::appendAndBubble(U&& value, const Func& func)
{
    append(WTFMove(value));
    iterator begin = this->begin();
    iterator iter = end();
    --iter;
    while (iter != begin) {
        iterator prev = iter;
        --prev;
        if (!func(*prev))
            return;
        std::swap(*prev, *iter);
        iter = prev;
    }
}

template<typename T, size_t inlineCapacity>
template<typename Func>
inline T Deque<T, inlineCapacity>::takeFirst(const Func& func)
{
    unsigned count = 0;
    unsigned size = this->size();
    while (count < size) {
        T candidate = takeFirst();
        if (func(candidate)) {
            while (count--)
                prepend(takeLast());
            return candidate;
        }
        count++;
        append(WTFMove(candidate));
    }
    return T();
}

template<typename T, size_t inlineCapacity>
template<typename Func>
inline T Deque<T, inlineCapacity>::takeLast(const Func& func)
{
    unsigned count = 0;
    unsigned size = this->size();
    while (count < size) {
        T candidate = takeLast();
        if (func(candidate)) {
            while (count--)
                append(takeFirst());
            return candidate;
        }
        count++;
        prepend(WTFMove(candidate));
    }
    return T();
}

#ifdef NDEBUG
template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity() const { }
template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity(const DequeIteratorBase<T, inlineCapacity>&) const { }
template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList() { }
template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList() { }
#else
template<typename T, size_t inlineCapacity>
void DequeIteratorBase<T, inlineCapacity>::checkValidity() const
{
    ASSERT(m_deque);
    m_deque->checkIndexValidity(m_index);
}

template<typename T, size_t inlineCapacity>
void DequeIteratorBase<T, inlineCapacity>::checkValidity(const DequeIteratorBase& other) const
{
    checkValidity();
    other.checkValidity();
    ASSERT(m_deque == other.m_deque);
}

template<typename T, size_t inlineCapacity>
void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList()
{
    if (!m_deque)
        m_next = 0;
    else {
        m_next = m_deque->m_iterators;
        m_deque->m_iterators = this;
        if (m_next)
            m_next->m_previous = this;
    }
    m_previous = 0;
}

template<typename T, size_t inlineCapacity>
void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList()
{
    if (!m_deque) {
        ASSERT(!m_next);
        ASSERT(!m_previous);
    } else {
        if (m_next) {
            ASSERT(m_next->m_previous == this);
            m_next->m_previous = m_previous;
        }
        if (m_previous) {
            ASSERT(m_deque->m_iterators != this);
            ASSERT(m_previous->m_next == this);
            m_previous->m_next = m_next;
        } else {
            ASSERT(m_deque->m_iterators == this);
            m_deque->m_iterators = m_next;
        }
    }
    m_next = 0;
    m_previous = 0;
}
#endif

template<typename T, size_t inlineCapacity>
inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase()
    : m_deque(0)
{
}

template<typename T, size_t inlineCapacity>
inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const Deque<T, inlineCapacity>* deque, size_t index)
    : m_deque(const_cast<Deque<T, inlineCapacity>*>(deque))
    , m_index(index)
{
    addToIteratorsList();
    checkValidity();
}

template<typename T, size_t inlineCapacity>
inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const DequeIteratorBase& other)
    : m_deque(other.m_deque)
    , m_index(other.m_index)
{
    addToIteratorsList();
    checkValidity();
}

template<typename T, size_t inlineCapacity>
inline DequeIteratorBase<T, inlineCapacity>& DequeIteratorBase<T, inlineCapacity>::operator=(const DequeIteratorBase& other)
{
    other.checkValidity();
    removeFromIteratorsList();

    m_deque = other.m_deque;
    m_index = other.m_index;
    addToIteratorsList();
    checkValidity();
    return *this;
}

template<typename T, size_t inlineCapacity>
inline DequeIteratorBase<T, inlineCapacity>::~DequeIteratorBase()
{
#ifndef NDEBUG
    removeFromIteratorsList();
    m_deque = 0;
#endif
}

template<typename T, size_t inlineCapacity>
inline bool DequeIteratorBase<T, inlineCapacity>::isEqual(const DequeIteratorBase& other) const
{
    checkValidity(other);
    return m_index == other.m_index;
}

template<typename T, size_t inlineCapacity>
inline void DequeIteratorBase<T, inlineCapacity>::increment()
{
    checkValidity();
    ASSERT(m_index != m_deque->m_end);
    ASSERT(m_deque->m_buffer.capacity());
    if (m_index == m_deque->m_buffer.capacity() - 1)
        m_index = 0;
    else
        ++m_index;
    checkValidity();
}

template<typename T, size_t inlineCapacity>
inline void DequeIteratorBase<T, inlineCapacity>::decrement()
{
    checkValidity();
    ASSERT(m_index != m_deque->m_start);
    ASSERT(m_deque->m_buffer.capacity());
    if (!m_index)
        m_index = m_deque->m_buffer.capacity() - 1;
    else
        --m_index;
    checkValidity();
}

template<typename T, size_t inlineCapacity>
inline T* DequeIteratorBase<T, inlineCapacity>::after() const
{
    checkValidity();
    ASSERT(m_index != m_deque->m_end);
    return std::addressof(m_deque->m_buffer.buffer()[m_index]);
}

template<typename T, size_t inlineCapacity>
inline T* DequeIteratorBase<T, inlineCapacity>::before() const
{
    checkValidity();
    ASSERT(m_index != m_deque->m_start);
    if (!m_index)
        return std::addressof(m_deque->m_buffer.buffer()[m_deque->m_buffer.capacity() - 1]);
    return std::addressof(m_deque->m_buffer.buffer()[m_index - 1]);
}

} // namespace WTF

using WTF::Deque;
