Advertisement
Guest User

Untitled

a guest
Dec 14th, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.50 KB | None | 0 0
  1. #ifndef KEYED_QUEUE_H
  2. #define KEYED_QUEUE_H
  3.  
  4. #include <map>
  5. #include <list>
  6. #include <memory>
  7. #include <exception>
  8. #include <cassert>
  9. #include <vector>
  10.  
  11.  
  12. class lookup_error : public std::exception {
  13. virtual const char* what () const noexcept {
  14. return "Lookup error";
  15. }
  16. };
  17.  
  18.  
  19. template <class K, class V> class keyed_queue {
  20. private:
  21. using kv_pair = std::pair<K, V>;
  22. using kv_queue = std::list<kv_pair>;
  23. using iterator_list = std::list<typename kv_queue::iterator>;
  24. using k_map = std::map<K, iterator_list>;
  25.  
  26. struct queue_data {
  27. kv_queue queue;
  28. k_map map;
  29. bool shareable;
  30.  
  31. queue_data() : queue({}), map({}), shareable(true) {}
  32.  
  33. queue_data(queue_data const& other) :
  34. queue(other.queue),
  35. map(set_k_maps(queue)),
  36. shareable(true) {}
  37. };
  38. class k_iterator {
  39. friend class keyed_queue<K, V>;
  40. private:
  41. typename k_map::const_iterator k_map_iterator;
  42.  
  43. public:
  44. k_iterator(){}
  45. k_iterator(k_iterator const & other) : k_map_iterator(other.k_map_iterator){}
  46. k_iterator(typename k_map::const_iterator k_map_iterator) : k_map_iterator(k_map_iterator) {}
  47. k_iterator & operator++(){
  48. ++k_map_iterator;
  49. return *this;
  50. }
  51. bool operator==(k_iterator const & other){ return k_map_iterator == other.k_map_iterator;}
  52. bool operator!=(k_iterator const & other){ return k_map_iterator != other.k_map_iterator;}
  53. K const & operator*(){ return k_map_iterator->first;}
  54. };
  55. kv_queue key_queue;
  56. k_map iterators_map;
  57. std::shared_ptr<queue_data>data_pointer;
  58. static k_map set_k_maps(kv_queue &queue) {
  59. k_map map;
  60. for (auto element_it = queue.begin(); element_it != queue.end(); element_it++) {
  61. const K& key = element_it->first;
  62. map[key].push_back(element_it);
  63. }
  64. return std::move(map);
  65. }
  66.  
  67. std::pair<std::shared_ptr<unique_data>, bool> foo() {
  68. if (data_pointer.use_count() > 1) {
  69. return {std::make_shared<unique_data>(*data_pointer), true};
  70. } else {
  71. data_pointer->shareable = true;
  72. return {data_pointer, false};
  73. }
  74. }
  75.  
  76.  
  77. public:
  78.  
  79. keyed_queue() : data_pointer(std::make_shared<queue_data>()) {}
  80.  
  81. keyed_queue(const keyed_queue& other){
  82. if (other.data_pointer->shareable) {
  83. data_pointer = other.data_pointer;
  84. } else {
  85. data_pointer = std::make_shared<queue_data>(*other.data_pointer);
  86. data_pointer->shareable = true;
  87. }
  88. }
  89.  
  90. keyed_queue(keyed_queue &&other) : data_pointer(std::move(other.data_pointer)) {}
  91.  
  92. keyed_queue &operator=(keyed_queue other) {
  93. data_pointer = other.data_pointer;
  94. return *this;
  95. }
  96. void push(K const &k, V const &v) {
  97. std::shared_ptr<queue_data> new_pointer;
  98. bool copied = false;
  99. if (data_pointer.use_count() > 1){
  100. new_pointer = std::make_shared<queue_data>(*data_pointer);
  101. copied = true;
  102. }
  103. else {
  104. data_pointer->shareable = true;
  105. new_pointer = data_pointer;
  106. }
  107. new_pointer->queue.push_back(std::make_pair(k, v));
  108. try {
  109. new_pointer->map[k].push_back(--new_pointer->queue.end());
  110. } catch (...) {
  111. new_pointer->queue.pop_back();
  112. throw;
  113. }
  114.  
  115. if (copied) std::swap(data_pointer, new_pointer);
  116. }
  117.  
  118. void pop() {
  119. if (data_pointer->queue.size() == 0) throw lookup_error();
  120.  
  121. std::shared_ptr<queue_data> new_pointer;
  122. bool copied = false;
  123. if (data_pointer.use_count() > 1){
  124. new_pointer = std::make_shared<queue_data>(*data_pointer);
  125. copied = true;
  126. }
  127. else {
  128. data_pointer->shareable = true;
  129. new_pointer = data_pointer;
  130. }
  131.  
  132. auto& element = data_pointer->queue.front();
  133. auto map_it = new_pointer->map.find(element.first);
  134. auto& k_list = map_it->second;
  135. new_pointer->queue.erase(k_list.front());
  136. k_list.pop_front();
  137. if (k_list.empty()) {
  138. new_pointer->map.erase(map_it);
  139. }
  140.  
  141. if (copied) std::swap(data_pointer, new_pointer);
  142. }
  143.  
  144. void pop(K const &key) {
  145. bool copied = false;
  146. std::shared_ptr<queue_data> new_pointer;
  147. if (data_pointer.use_count > 1){
  148. new_pointer = std::make_shared<queue_data>(*data_pointer);
  149. copied = true;
  150. }
  151. else {
  152. data_pointer->shareable = true;
  153. new_pointer = data_pointer;
  154. }
  155. auto it = data_pointer->map.find(key);
  156. if (it == data_pointer->map.end()) throw lookup_error();
  157. }
  158.  
  159. void move_to_back(const K &key) {
  160. auto map_iterator = data_pointer->map.find(key);
  161. if (map_iterator == data_pointer->map.end()) throw lookup_error();
  162.  
  163. std::shared_ptr<queue_data> new_pointer;
  164. bool copied = false;
  165. if (data_pointer.use_count() > 1){
  166. new_pointer = std::make_shared<queue_data>(*data_pointer);
  167. copied = true;
  168. }
  169. else {
  170. data_pointer->shareable = true;
  171. new_pointer = data_pointer;
  172. }
  173.  
  174. auto &map = new_pointer->map[key];
  175.  
  176. for (auto element_it: map) {
  177. new_pointer->queue.splice(new_pointer->queue.end(), new_pointer->queue, element_it);
  178. }
  179.  
  180. if (copied) std::swap(data_pointer, new_pointer);
  181. }
  182.  
  183. std::pair<K const &, V &> front() {
  184. if (data_pointer->queue.empty()) throw lookup_error();
  185. if (data_pointer.use_count() > 1) {
  186. data_pointer = std::make_shared<queue_data>(*data_pointer);
  187. }
  188. data_pointer->shareable = false;
  189. kv_pair kv = data_pointer->queue.front();
  190. return {kv.first, kv.second};
  191. }
  192.  
  193. std::pair<K const &, V &> back() {
  194. if (data_pointer->queue.empty()) throw lookup_error();
  195. if (data_pointer.use_count() > 1) {
  196. data_pointer = std::make_shared<queue_data>(*data_pointer);
  197. }
  198. data_pointer->shareable = false;
  199. kv_pair kv = data_pointer->queue.back();
  200. return {kv.first, kv.second};
  201. }
  202.  
  203. std::pair<K const &, V const &> front() const {
  204. if (data_pointer->queue.empty()) throw lookup_error();
  205.  
  206. kv_pair kv = data_pointer->queue.front();
  207. return {kv.first, kv.second};
  208. }
  209.  
  210. std::pair<K const &, V const &> back() const {
  211. if (data_pointer->queue.empty()) throw lookup_error();
  212.  
  213. kv_pair kv = data_pointer->queue.back();
  214. return {kv.first, kv.second};
  215. }
  216.  
  217. std::pair<K const &, V &> first(K const &key) {
  218. auto map_iterator = data_pointer->map.find(key);
  219. if (map_iterator == data_pointer->map.end()) throw lookup_error();
  220.  
  221. std::shared_ptr<queue_data> new_pointer;
  222. bool copied = false;
  223. if (data_pointer.use_count() > 1){
  224. new_pointer = std::make_shared<queue_data>(*data_pointer);
  225. copied = true;
  226. }
  227. else {
  228. data_pointer->shareable = true;
  229. new_pointer = data_pointer;
  230. }
  231.  
  232. auto &pair_ref = *new_pointer->map.at(key).front();
  233. new_pointer->shareable = false;
  234.  
  235. if (copied) std::swap(data_pointer, new_pointer);
  236. return {pair_ref.first, pair_ref.second};
  237. }
  238.  
  239. std::pair<K const &, V &> last(K const &key) {
  240. auto map_iterator = data_pointer->map.find(key);
  241. if (map_iterator == data_pointer->map.end()) throw lookup_error();
  242.  
  243. std::shared_ptr<queue_data> new_pointer;
  244. bool copied = false;
  245. if (data_pointer.use_count() > 1){
  246. new_pointer = std::make_shared<queue_data>(*data_pointer);
  247. copied = true;
  248. }
  249. else {
  250. data_pointer->shareable = true;
  251. new_pointer = data_pointer;
  252. }
  253.  
  254. auto &pair_ref = *data_pointer->map.at(key).back();
  255. data_pointer->shareable = false;
  256.  
  257. if (copied) std::swap(this->data_pointer, data_pointer);
  258. return {pair_ref.first, pair_ref.second};
  259. }
  260.  
  261. std::pair<K const &, V const &> first(K const &key) const {
  262. auto map_iterator = data_pointer->map.find(key);
  263. if (map_iterator == data_pointer->map.end()) throw lookup_error();
  264.  
  265. auto &pair_ref = *data_pointer->map.at(key).front();
  266. return {pair_ref.first, pair_ref.second};
  267. }
  268.  
  269. std::pair<K const &, V const &> last(K const &key) const {
  270. auto map_iterator = data_pointer->map.find(key);
  271. if (map_iterator == data_pointer->map.end()) throw lookup_error();
  272.  
  273. auto &pair_ref = *data_pointer->map.at(key).back();
  274. return {pair_ref.first, pair_ref.second};
  275. }
  276.  
  277. size_t size() const {
  278. return data_pointer->queue.size();
  279. }
  280.  
  281. bool empty() const {
  282. return data_pointer->queue.empty();
  283. }
  284.  
  285. void clear() {
  286. if (data_pointer.use_count() > 1) {
  287. data_pointer = std::make_shared<queue_data>(*data_pointer);
  288. }
  289. data_pointer->shareable = true;
  290. data_pointer->map.clear();
  291. data_pointer->queue.clear();
  292. }
  293.  
  294. size_t count(K const &key) const {
  295. if (data_pointer->map.find(key) == data_pointer->map.end()) return 0;
  296. return (data_pointer->map.at(key)).size();
  297. }
  298.  
  299. k_iterator k_begin() {
  300. return k_iterator(data_pointer->map.cbegin());
  301. }
  302.  
  303. k_iterator k_end() {
  304. return k_iterator(data_pointer->map.cend());
  305. }
  306.  
  307. };
  308.  
  309. #endif
  310.  
  311. auto f(keyed_queue<int, int> q)
  312. {
  313. return q;
  314. }
  315.  
  316. int main()
  317. {
  318. int keys[] = {3, 1, 2};
  319.  
  320. keyed_queue<int, int> kq1 = f({});
  321.  
  322. for (int i = 0; i < 3; ++i) {
  323. kq1.push(keys[i], i);
  324. }
  325. auto &ref = kq1.front().second;
  326.  
  327. keyed_queue<int, int> kq2(kq1); // Wykonuje się pełna kopia, dlaczego?
  328. keyed_queue<int, int> kq3;
  329. kq3 = kq2;
  330.  
  331. ref = 10;
  332. assert(kq1.front().second == 10);
  333. assert(kq2.front().second != 10);
  334.  
  335. kq2.pop(); // Obiekt kq2 dokonuje kopii i przestaje współdzielić dane z kq3.
  336. assert(kq2.size() == 2);
  337. assert(kq2.count(3) == 0);
  338. assert(kq2.count(2) == 1);
  339.  
  340. assert(kq3.size() == 3);
  341. assert(kq3.count(3) == 1);
  342.  
  343. kq2.push(1, 3);
  344. kq2.move_to_back(1);
  345. assert(kq2.size() == 3);
  346. assert(kq2.front().second == 2
  347. && kq2.first(1).second == 1
  348. && kq2.last(1).second == 3
  349. && kq2.back().second == 3);
  350.  
  351. keyed_queue<int, int> const kq4 = kq2;
  352. assert(kq4.front().second == 2
  353. && kq4.first(1).second == 1
  354. && kq4.last(1).second == 3
  355. && kq4.back().second == 3);
  356.  
  357. int i = 1;
  358. for (auto k_it = kq1.k_begin(), k_end = kq1.k_end();
  359. k_it != k_end;
  360. ++k_it, ++i) {
  361. assert(i <= 3 && *k_it == i);
  362. }
  363.  
  364. auto kq5 = std::make_unique<keyed_queue<int, int>>();
  365. kq5->push(4, 0);
  366. assert(kq5->front().first == 4 && kq5->front().second == 0);
  367. auto kq6(*kq5);
  368. kq5.reset();
  369. assert(kq6.front().first == 4 && kq6.front().second == 0);
  370.  
  371. std::swap(kq1, kq2);
  372. std::vector<keyed_queue<int, int>> vec;
  373. for (int i = 0; i < 100000; i++) {
  374. kq1.push(i, i);
  375. }
  376. for (int i = 0; i < 1000000; i++) {
  377. vec.push_back(kq1); // Wszystkie obiekty w vec współdzielą dane.
  378. }
  379.  
  380. return 0;
  381. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement