1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_XLIST_H
16 #define CEPH_XLIST_H
17
18 #include <iterator>
19 #include <cstdlib>
20 #include <ostream>
21
22 #include "include/ceph_assert.h"
23
24 template<typename T>
25 class xlist {
26 public:
27 class item {
28 public:
29 item(T i) : _item(i) {}
30 ~item() {
31 ceph_assert(!is_on_list());
32 }
33
34 item(const item& other) = delete;
35 item(item&& other) = delete;
36 const item& operator= (const item& right) = delete;
37 item& operator= (item&& right) = delete;
38
39 xlist* get_list() { return _list; }
40 bool is_on_list() const { return _list ? true:false; }
41 bool remove_myself() {
42 if (_list) {
43 _list->remove(this);
44 ceph_assert(_list == 0);
45 return true;
46 } else
47 return false;
48 }
49 void move_to_front() {
50 ceph_assert(_list);
51 _list->push_front(this);
52 }
53 void move_to_back() {
54 ceph_assert(_list);
55 _list->push_back(this);
56 }
57
58 private:
59 friend xlist;
60 T _item;
61 item *_prev = nullptr, *_next = nullptr;
62 xlist *_list = nullptr;
63 };
64
65 typedef item* value_type;
66 typedef item* const_reference;
67
68 private:
69 item *_front, *_back;
70 size_t _size;
71
72 public:
73 xlist(const xlist& other) {
74 _front = other._front;
75 _back = other._back;
76 _size = other._size;
77 }
78
79 xlist() : _front(0), _back(0), _size(0) {}
(1) Event exn_spec_violation: |
An exception of type "_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEEE" is thrown but the throw list "throw()" doesn't allow it to be thrown. This will cause a call to unexpected() which usually calls terminate(). |
Also see events: |
[fun_call_w_exception] |
80 ~xlist() {
81 ceph_assert(_size == 0);
82 ceph_assert(_front == 0);
(2) Event fun_call_w_exception: |
Called function throws an exception of type "_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEEE". [details] |
Also see events: |
[exn_spec_violation] |
83 ceph_assert(_back == 0);
84 }
85
86 size_t size() const {
87 ceph_assert((bool)_front == (bool)_size);
88 return _size;
89 }
90 bool empty() const {
91 ceph_assert((bool)_front == (bool)_size);
92 return _front == 0;
93 }
94
95 void clear() {
96 while (_front)
97 remove(_front);
98 ceph_assert((bool)_front == (bool)_size);
99 }
100
101 void push_front(item *i) {
102 if (i->_list)
103 i->_list->remove(i);
104
105 i->_list = this;
106 i->_next = _front;
107 i->_prev = 0;
108 if (_front)
109 _front->_prev = i;
110 else
111 _back = i;
112 _front = i;
113 _size++;
114 }
115 void push_back(item *i) {
116 if (i->_list)
117 i->_list->remove(i);
118
119 i->_list = this;
120 i->_next = 0;
121 i->_prev = _back;
122 if (_back)
123 _back->_next = i;
124 else
125 _front = i;
126 _back = i;
127 _size++;
128 }
129 void remove(item *i) {
130 ceph_assert(i->_list == this);
131
132 if (i->_prev)
133 i->_prev->_next = i->_next;
134 else
135 _front = i->_next;
136 if (i->_next)
137 i->_next->_prev = i->_prev;
138 else
139 _back = i->_prev;
140 _size--;
141
142 i->_list = 0;
143 i->_next = i->_prev = 0;
144 ceph_assert((bool)_front == (bool)_size);
145 }
146
147 T front() { return static_cast<T>(_front->_item); }
148 const T front() const { return static_cast<const T>(_front->_item); }
149
150 T back() { return static_cast<T>(_back->_item); }
151 const T back() const { return static_cast<const T>(_back->_item); }
152
153 void pop_front() {
154 ceph_assert(!empty());
155 remove(_front);
156 }
157 void pop_back() {
158 ceph_assert(!empty());
159 remove(_back);
160 }
161
162 class iterator: std::iterator<std::forward_iterator_tag, T> {
163 private:
164 item *cur;
165 public:
166 iterator(item *i = 0) : cur(i) {}
167 T operator*() { return static_cast<T>(cur->_item); }
168 iterator& operator++() {
169 ceph_assert(cur);
170 ceph_assert(cur->_list);
171 cur = cur->_next;
172 return *this;
173 }
174 bool end() const { return cur == 0; }
175 bool operator==(const iterator& rhs) const {
176 return cur == rhs.cur;
177 }
178 bool operator!=(const iterator& rhs) const {
179 return cur != rhs.cur;
180 }
181 };
182
183 iterator begin() { return iterator(_front); }
184 iterator end() { return iterator(NULL); }
185
186 class const_iterator: std::iterator<std::forward_iterator_tag, T> {
187 private:
188 item *cur;
189 public:
190 const_iterator(item *i = 0) : cur(i) {}
191 const T operator*() { return static_cast<const T>(cur->_item); }
192 const_iterator& operator++() {
193 ceph_assert(cur);
194 ceph_assert(cur->_list);
195 cur = cur->_next;
196 return *this;
197 }
198 bool end() const { return cur == 0; }
199 bool operator==(const_iterator& rhs) const {
200 return cur == rhs.cur;
201 }
202 bool operator!=(const_iterator& rhs) const {
203 return cur != rhs.cur;
204 }
205 };
206
207 const_iterator begin() const { return const_iterator(_front); }
208 const_iterator end() const { return const_iterator(NULL); }
209
210 friend std::ostream &operator<<(std::ostream &oss, const xlist<T> &list) {
211 bool first = true;
212 for (const auto &item : list) {
213 if (!first) {
214 oss << ", ";
215 }
216 oss << *item; /* item should be a pointer */
217 first = false;
218 }
219 return oss;
220 }
221 };
222
223
224 #endif
225