/* * Copyright (C) 2016 Apple 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. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR * 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. */ #ifndef List_h #define List_h namespace bmalloc { template struct ListNode { ListNode() : prev(this) , next(this) { } ListNode* prev; ListNode* next; }; template class List { static_assert(std::is_trivially_destructible::value, "List must have a trivial destructor."); public: bool isEmpty() { return m_root.next == &m_root; } T* head() { return static_cast(m_root.next); } T* tail() { return static_cast(m_root.prev); } void push(T* node) { ListNode* it = tail(); insertAfter(it, node); } T* pop() { ListNode* result = tail(); remove(result); return static_cast(result); } T* popFront() { ListNode* result = head(); remove(result); return static_cast(result); } void insertAfter(ListNode* it, ListNode* node) { ListNode* prev = it; ListNode* next = it->next; node->next = next; next->prev = node; node->prev = prev; prev->next = node; } void remove(ListNode* node) { ListNode* next = node->next; ListNode* prev = node->prev; next->prev = prev; prev->next = next; node->prev = node; node->next = node; } private: ListNode m_root; }; } // namespace bmalloc #endif // List_h