LLVM  4.0.0
AllocatorList.h
Go to the documentation of this file.
1 //===- llvm/ADT/AllocatorList.h - Custom allocator list ---------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_ADT_ALLOCATORLIST_H
11 #define LLVM_ADT_ALLOCATORLIST_H
12 
13 #include "llvm/ADT/iterator.h"
14 #include "llvm/ADT/simple_ilist.h"
15 #include "llvm/Support/Allocator.h"
16 #include <type_traits>
17 
18 namespace llvm {
19 
20 /// A linked-list with a custom, local allocator.
21 ///
22 /// Expose a std::list-like interface that owns and uses a custom LLVM-style
23 /// allocator (e.g., BumpPtrAllocator), leveraging \a simple_ilist for the
24 /// implementation details.
25 ///
26 /// Because this list owns the allocator, calling \a splice() with a different
27 /// list isn't generally safe. As such, \a splice has been left out of the
28 /// interface entirely.
29 template <class T, class AllocatorT> class AllocatorList : AllocatorT {
30  struct Node : ilist_node<Node> {
31  Node(Node &&) = delete;
32  Node(const Node &) = delete;
33  Node &operator=(Node &&) = delete;
34  Node &operator=(const Node &) = delete;
35 
36  Node(T &&V) : V(std::move(V)) {}
37  Node(const T &V) : V(V) {}
38  template <class... Ts> Node(Ts &&... Vs) : V(std::forward<Ts>(Vs)...) {}
39  T V;
40  };
41 
43  list_type List;
44 
45  AllocatorT &getAlloc() { return *this; }
46  const AllocatorT &getAlloc() const { return *this; }
47 
48  template <class... ArgTs> Node *create(ArgTs &&... Args) {
49  return new (getAlloc()) Node(std::forward<ArgTs>(Args)...);
50  }
51 
52  struct Cloner {
53  AllocatorList &AL;
54  Cloner(AllocatorList &AL) : AL(AL) {}
55  Node *operator()(const Node &N) const { return AL.create(N.V); }
56  };
57 
58  struct Disposer {
59  AllocatorList &AL;
60  Disposer(AllocatorList &AL) : AL(AL) {}
61  void operator()(Node *N) const {
62  N->~Node();
63  AL.getAlloc().Deallocate(N);
64  }
65  };
66 
67 public:
68  typedef T value_type;
69  typedef T *pointer;
70  typedef T &reference;
71  typedef const T *const_pointer;
72  typedef const T &const_reference;
73  typedef typename list_type::size_type size_type;
75 
76 private:
77  template <class ValueT, class IteratorBase>
78  class IteratorImpl
79  : public iterator_adaptor_base<IteratorImpl<ValueT, IteratorBase>,
80  IteratorBase,
81  std::bidirectional_iterator_tag, ValueT> {
82  template <class OtherValueT, class OtherIteratorBase>
83  friend class IteratorImpl;
84  friend AllocatorList;
85 
87  IteratorBase, std::bidirectional_iterator_tag,
88  ValueT>
89  base_type;
90 
91  public:
92  typedef ValueT value_type;
93  typedef ValueT *pointer;
94  typedef ValueT &reference;
95 
96  IteratorImpl() = default;
97  IteratorImpl(const IteratorImpl &) = default;
98  IteratorImpl &operator=(const IteratorImpl &) = default;
99  ~IteratorImpl() = default;
100 
101  explicit IteratorImpl(const IteratorBase &I) : base_type(I) {}
102 
103  template <class OtherValueT, class OtherIteratorBase>
104  IteratorImpl(const IteratorImpl<OtherValueT, OtherIteratorBase> &X,
105  typename std::enable_if<std::is_convertible<
106  OtherIteratorBase, IteratorBase>::value>::type * = nullptr)
107  : base_type(X.wrapped()) {}
108 
109  reference operator*() const { return base_type::wrapped()->V; }
110  pointer operator->() const { return &operator*(); }
111 
112  friend bool operator==(const IteratorImpl &L, const IteratorImpl &R) {
113  return L.wrapped() == R.wrapped();
114  }
115  friend bool operator!=(const IteratorImpl &L, const IteratorImpl &R) {
116  return !(L == R);
117  }
118  };
119 
120 public:
121  typedef IteratorImpl<T, typename list_type::iterator> iterator;
122  typedef IteratorImpl<T, typename list_type::reverse_iterator>
124  typedef IteratorImpl<const T, typename list_type::const_iterator>
126  typedef IteratorImpl<const T, typename list_type::const_reverse_iterator>
128 
129  AllocatorList() = default;
131  : AllocatorT(std::move(X.getAlloc())), List(std::move(X.List)) {}
133  List.cloneFrom(X.List, Cloner(*this), Disposer(*this));
134  }
136  clear(); // Dispose of current nodes explicitly.
137  List = std::move(X.List);
138  getAlloc() = std::move(X.getAlloc());
139  return *this;
140  }
142  List.cloneFrom(X.List, Cloner(*this), Disposer(*this));
143  return *this;
144  }
146 
147  void swap(AllocatorList &RHS) {
148  List.swap(RHS.List);
149  std::swap(getAlloc(), RHS.getAlloc());
150  }
151 
152  bool empty() { return List.empty(); }
153  size_t size() { return List.size(); }
154 
155  iterator begin() { return iterator(List.begin()); }
156  iterator end() { return iterator(List.end()); }
157  const_iterator begin() const { return const_iterator(List.begin()); }
158  const_iterator end() const { return const_iterator(List.end()); }
162  return const_reverse_iterator(List.rbegin());
163  }
165  return const_reverse_iterator(List.rend());
166  }
167 
168  T &back() { return List.back().V; }
169  T &front() { return List.front().V; }
170  const T &back() const { return List.back().V; }
171  const T &front() const { return List.front().V; }
172 
173  template <class... Ts> iterator emplace(iterator I, Ts &&... Vs) {
174  return iterator(List.insert(I.wrapped(), *create(std::forward<Ts>(Vs)...)));
175  }
176 
178  return iterator(List.insert(I.wrapped(), *create(std::move(V))));
179  }
180  iterator insert(iterator I, const T &V) {
181  return iterator(List.insert(I.wrapped(), *create(V)));
182  }
183 
184  template <class Iterator>
185  void insert(iterator I, Iterator First, Iterator Last) {
186  for (; First != Last; ++First)
187  List.insert(I.wrapped(), *create(*First));
188  }
189 
191  return iterator(List.eraseAndDispose(I.wrapped(), Disposer(*this)));
192  }
193 
195  return iterator(
196  List.eraseAndDispose(First.wrapped(), Last.wrapped(), Disposer(*this)));
197  }
198 
199  void clear() { List.clearAndDispose(Disposer(*this)); }
200  void pop_back() { List.eraseAndDispose(--List.end(), Disposer(*this)); }
201  void pop_front() { List.eraseAndDispose(List.begin(), Disposer(*this)); }
202  void push_back(T &&V) { insert(end(), std::move(V)); }
203  void push_front(T &&V) { insert(begin(), std::move(V)); }
204  void push_back(const T &V) { insert(end(), V); }
205  void push_front(const T &V) { insert(begin(), V); }
206  template <class... Ts> void emplace_back(Ts &&... Vs) {
207  emplace(end(), std::forward<Ts>(Vs)...);
208  }
209  template <class... Ts> void emplace_front(Ts &&... Vs) {
210  emplace(begin(), std::forward<Ts>(Vs)...);
211  }
212 
213  /// Reset the underlying allocator.
214  ///
215  /// \pre \c empty()
216  void resetAlloc() {
217  assert(empty() && "Cannot reset allocator if not empty");
218  getAlloc().Reset();
219  }
220 };
221 
223 
224 } // end namespace llvm
225 
226 #endif // LLVM_ADT_ALLOCATORLIST_H
MachineLoop * L
reverse_iterator rend()
AllocatorList & operator=(AllocatorList &&X)
iterator emplace(iterator I, Ts &&...Vs)
A linked-list with a custom, local allocator.
Definition: AllocatorList.h:29
void emplace_front(Ts &&...Vs)
void push_front(T &&V)
void push_front(const T &V)
list_type::size_type size_type
Definition: AllocatorList.h:73
void insert(iterator I, Iterator First, Iterator Last)
void resetAlloc()
Reset the underlying allocator.
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
void push_back(T &&V)
iterator erase(iterator I)
AllocatorList()=default
IteratorImpl< const T, typename list_type::const_iterator > const_iterator
IteratorImpl< const T, typename list_type::const_reverse_iterator > const_reverse_iterator
AllocatorList & operator=(const AllocatorList &X)
const T & const_reference
Definition: AllocatorList.h:72
const_reverse_iterator rbegin() const
const_iterator end() const
const T & back() const
CRTP base class for adapting an iterator to a different type.
Definition: iterator.h:195
const_iterator begin() const
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
const T * const_pointer
Definition: AllocatorList.h:71
void emplace_back(Ts &&...Vs)
const T & front() const
list_type::difference_type difference_type
Definition: AllocatorList.h:74
BlockMass operator*(BlockMass L, BranchProbability R)
IteratorImpl< T, typename list_type::reverse_iterator > reverse_iterator
AllocatorList(AllocatorList &&X)
iterator erase(iterator First, iterator Last)
iterator insert(iterator I, T &&V)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:586
iterator insert(iterator I, const T &V)
AllocatorList(const AllocatorList &X)
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:1724
const_reverse_iterator rend() const
void swap(AllocatorList &RHS)
const NodeList & List
Definition: RDFGraph.cpp:205
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
IteratorImpl< T, typename list_type::iterator > iterator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
reverse_iterator rbegin()
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1722
void push_back(const T &V)