File indexing completed on 2026-05-10 08:43:08
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_ADT_SIMPLE_ILIST_H
0010 #define LLVM_ADT_SIMPLE_ILIST_H
0011
0012 #include "llvm/ADT/ilist_base.h"
0013 #include "llvm/ADT/ilist_iterator.h"
0014 #include "llvm/ADT/ilist_node.h"
0015 #include "llvm/ADT/ilist_node_options.h"
0016 #include "llvm/Support/Compiler.h"
0017 #include <algorithm>
0018 #include <cassert>
0019 #include <cstddef>
0020 #include <functional>
0021 #include <iterator>
0022 #include <utility>
0023
0024 namespace llvm {
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 template <typename T, class... Options>
0078 class simple_ilist
0079 : ilist_detail::compute_node_options<T, Options...>::type::list_base_type,
0080 ilist_detail::SpecificNodeAccess<
0081 typename ilist_detail::compute_node_options<T, Options...>::type> {
0082 static_assert(ilist_detail::check_options<Options...>::value,
0083 "Unrecognized node option!");
0084 using OptionsT =
0085 typename ilist_detail::compute_node_options<T, Options...>::type;
0086 using list_base_type = typename OptionsT::list_base_type;
0087 ilist_sentinel<OptionsT> Sentinel;
0088
0089 public:
0090 using value_type = typename OptionsT::value_type;
0091 using pointer = typename OptionsT::pointer;
0092 using reference = typename OptionsT::reference;
0093 using const_pointer = typename OptionsT::const_pointer;
0094 using const_reference = typename OptionsT::const_reference;
0095 using iterator =
0096 typename ilist_select_iterator_type<OptionsT::has_iterator_bits, OptionsT,
0097 false, false>::type;
0098 using const_iterator =
0099 typename ilist_select_iterator_type<OptionsT::has_iterator_bits, OptionsT,
0100 false, true>::type;
0101 using reverse_iterator =
0102 typename ilist_select_iterator_type<OptionsT::has_iterator_bits, OptionsT,
0103 true, false>::type;
0104 using const_reverse_iterator =
0105 typename ilist_select_iterator_type<OptionsT::has_iterator_bits, OptionsT,
0106 true, true>::type;
0107 using size_type = size_t;
0108 using difference_type = ptrdiff_t;
0109
0110 simple_ilist() = default;
0111 ~simple_ilist() = default;
0112
0113
0114 simple_ilist(const simple_ilist &) = delete;
0115 simple_ilist &operator=(const simple_ilist &) = delete;
0116
0117
0118 simple_ilist(simple_ilist &&X) { splice(end(), X); }
0119 simple_ilist &operator=(simple_ilist &&X) {
0120 clear();
0121 splice(end(), X);
0122 return *this;
0123 }
0124
0125 iterator begin() { return ++iterator(Sentinel); }
0126 const_iterator begin() const { return ++const_iterator(Sentinel); }
0127 iterator end() { return iterator(Sentinel); }
0128 const_iterator end() const { return const_iterator(Sentinel); }
0129 reverse_iterator rbegin() { return ++reverse_iterator(Sentinel); }
0130 const_reverse_iterator rbegin() const {
0131 return ++const_reverse_iterator(Sentinel);
0132 }
0133 reverse_iterator rend() { return reverse_iterator(Sentinel); }
0134 const_reverse_iterator rend() const {
0135 return const_reverse_iterator(Sentinel);
0136 }
0137
0138
0139 [[nodiscard]] bool empty() const { return Sentinel.empty(); }
0140
0141
0142 [[nodiscard]] size_type size() const { return std::distance(begin(), end()); }
0143
0144 reference front() { return *begin(); }
0145 const_reference front() const { return *begin(); }
0146 reference back() { return *rbegin(); }
0147 const_reference back() const { return *rbegin(); }
0148
0149
0150 void push_front(reference Node) { insert(begin(), Node); }
0151
0152
0153 void push_back(reference Node) { insert(end(), Node); }
0154
0155
0156 void pop_front() { erase(begin()); }
0157
0158
0159 void pop_back() { erase(--end()); }
0160
0161
0162 void swap(simple_ilist &X) { std::swap(*this, X); }
0163
0164
0165 iterator insert(iterator I, reference Node) {
0166 list_base_type::insertBefore(*I.getNodePtr(), *this->getNodePtr(&Node));
0167 return iterator(&Node);
0168 }
0169
0170
0171 template <class Iterator>
0172 void insert(iterator I, Iterator First, Iterator Last) {
0173 for (; First != Last; ++First)
0174 insert(I, *First);
0175 }
0176
0177
0178 template <class Cloner, class Disposer>
0179 void cloneFrom(const simple_ilist &L2, Cloner clone, Disposer dispose) {
0180 clearAndDispose(dispose);
0181 for (const_reference V : L2)
0182 push_back(*clone(V));
0183 }
0184
0185
0186
0187
0188
0189 void remove(reference N) { list_base_type::remove(*this->getNodePtr(&N)); }
0190
0191
0192 template <class Disposer>
0193 void removeAndDispose(reference N, Disposer dispose) {
0194 remove(N);
0195 dispose(&N);
0196 }
0197
0198
0199
0200
0201
0202 iterator erase(iterator I) {
0203 assert(I != end() && "Cannot remove end of list!");
0204 remove(*I++);
0205 return I;
0206 }
0207
0208
0209
0210
0211 iterator erase(iterator First, iterator Last) {
0212 list_base_type::removeRange(*First.getNodePtr(), *Last.getNodePtr());
0213 return Last;
0214 }
0215
0216
0217 template <class Disposer>
0218 iterator eraseAndDispose(iterator I, Disposer dispose) {
0219 auto Next = std::next(I);
0220 erase(I);
0221 dispose(&*I);
0222 return Next;
0223 }
0224
0225
0226 template <class Disposer>
0227 iterator eraseAndDispose(iterator First, iterator Last, Disposer dispose) {
0228 while (First != Last)
0229 First = eraseAndDispose(First, dispose);
0230 return Last;
0231 }
0232
0233
0234
0235
0236 void clear() { Sentinel.reset(); }
0237
0238
0239 template <class Disposer> void clearAndDispose(Disposer dispose) {
0240 eraseAndDispose(begin(), end(), dispose);
0241 }
0242
0243
0244 void splice(iterator I, simple_ilist &L2) {
0245 splice(I, L2, L2.begin(), L2.end());
0246 }
0247
0248
0249 void splice(iterator I, simple_ilist &L2, iterator Node) {
0250 splice(I, L2, Node, std::next(Node));
0251 }
0252
0253
0254 void splice(iterator I, simple_ilist &, iterator First, iterator Last) {
0255 list_base_type::transferBefore(*I.getNodePtr(), *First.getNodePtr(),
0256 *Last.getNodePtr());
0257 }
0258
0259
0260
0261
0262
0263 void merge(simple_ilist &RHS) { merge(RHS, std::less<T>()); }
0264 template <class Compare> void merge(simple_ilist &RHS, Compare comp);
0265
0266
0267
0268
0269 void sort() { sort(std::less<T>()); }
0270 template <class Compare> void sort(Compare comp);
0271
0272 };
0273
0274 template <class T, class... Options>
0275 template <class Compare>
0276 void simple_ilist<T, Options...>::merge(simple_ilist &RHS, Compare comp) {
0277 if (this == &RHS || RHS.empty())
0278 return;
0279 iterator LI = begin(), LE = end();
0280 iterator RI = RHS.begin(), RE = RHS.end();
0281 while (LI != LE) {
0282 if (comp(*RI, *LI)) {
0283
0284 iterator RunStart = RI++;
0285 RI = std::find_if(RI, RE, [&](reference RV) { return !comp(RV, *LI); });
0286 splice(LI, RHS, RunStart, RI);
0287 if (RI == RE)
0288 return;
0289 }
0290 ++LI;
0291 }
0292
0293 splice(LE, RHS, RI, RE);
0294 }
0295
0296 template <class T, class... Options>
0297 template <class Compare>
0298 void simple_ilist<T, Options...>::sort(Compare comp) {
0299
0300 if (empty() || std::next(begin()) == end())
0301 return;
0302
0303
0304 iterator Center = begin(), End = begin();
0305 while (End != end() && ++End != end()) {
0306 ++Center;
0307 ++End;
0308 }
0309 simple_ilist RHS;
0310 RHS.splice(RHS.end(), *this, Center, end());
0311
0312
0313 sort(comp);
0314 RHS.sort(comp);
0315 merge(RHS, comp);
0316 }
0317
0318 }
0319
0320 #endif