//==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- C++ -*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// This file defines classes to implement an intrusive doubly linked list class /// (i.e. each node of the list must contain a next and previous field for the /// list. /// /// The ilist class itself should be a plug in replacement for list. This list /// replacement does not provide a constant time size() method, so be careful to /// use empty() when you really want to know if it's empty. /// /// The ilist class is implemented as a circular list. The list itself contains /// a sentinel node, whose Next points at begin() and whose Prev points at /// rbegin(). The sentinel node itself serves as end() and rend(). /// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_ILIST_H #define LLVM_ADT_ILIST_H #include "llvm/ADT/simple_ilist.h" #include <cassert> #include <cstddef> #include <iterator> namespace llvm { /// Use delete by default for iplist and ilist. /// /// Specialize this to get different behaviour for ownership-related API. (If /// you really want ownership semantics, consider using std::list or building /// something like \a BumpPtrList.) /// /// \see ilist_noalloc_traits template <typename NodeTy> struct ilist_alloc_traits { … }; /// Custom traits to do nothing on deletion. /// /// Specialize ilist_alloc_traits to inherit from this to disable the /// non-intrusive deletion in iplist (which implies ownership). /// /// If you want purely intrusive semantics with no callbacks, consider using \a /// simple_ilist instead. /// /// \code /// template <> /// struct ilist_alloc_traits<MyType> : ilist_noalloc_traits<MyType> {}; /// \endcode template <typename NodeTy> struct ilist_noalloc_traits { … }; /// Callbacks do nothing by default in iplist and ilist. /// /// Specialize this for to use callbacks for when nodes change their list /// membership. template <typename NodeTy> struct ilist_callback_traits { … }; /// A fragment for template traits for intrusive list that provides default /// node related operations. /// /// TODO: Remove this layer of indirection. It's not necessary. template <typename NodeTy> struct ilist_node_traits : ilist_alloc_traits<NodeTy>, ilist_callback_traits<NodeTy> { … }; /// Template traits for intrusive list. /// /// Customize callbacks and allocation semantics. template <typename NodeTy> struct ilist_traits : public ilist_node_traits<NodeTy> { … }; /// Const traits should never be instantiated. ilist_traits<const Ty>; //===----------------------------------------------------------------------===// // /// A wrapper around an intrusive list with callbacks and non-intrusive /// ownership. /// /// This wraps a purely intrusive list (like simple_ilist) with a configurable /// traits class. The traits can implement callbacks and customize the /// ownership semantics. /// /// This is a subset of ilist functionality that can safely be used on nodes of /// polymorphic types, i.e. a heterogeneous list with a common base class that /// holds the next/prev pointers. The only state of the list itself is an /// ilist_sentinel, which holds pointers to the first and last nodes in the /// list. template <class IntrusiveListT, class TraitsT> class iplist_impl : public TraitsT, IntrusiveListT { … }; /// An intrusive list with ownership and callbacks specified/controlled by /// ilist_traits, only with API safe for polymorphic types. /// /// The \p Options parameters are the same as those for \a simple_ilist. See /// there for a description of what's available. template <class T, class... Options> class iplist : public iplist_impl<simple_ilist<T, Options...>, ilist_traits<T>> { … }; ilist; } // end namespace llvm namespace std { // Ensure that swap uses the fast list swap... template<class Ty> void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) { … } } // end namespace std #endif // LLVM_ADT_ILIST_H