Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.23 KB | None | 0 0
  1. // Submitter: edwardk6(Kim, Edward)
  2. // Partner : jessihn4(Nguyen, Jessica)
  3. // We certify that we worked cooperatively on this programming
  4. // assignment, according to the rules for pair programming
  5.  
  6. #ifndef HEAP_PRIORITY_QUEUE_HPP_
  7. #define HEAP_PRIORITY_QUEUE_HPP_
  8.  
  9. #include <string>
  10. #include <iostream>
  11. #include <sstream>
  12. #include <initializer_list>
  13. #include "ics_exceptions.hpp"
  14. #include <utility> //For std::swap function
  15. #include "array_stack.hpp" //See operator <<
  16.  
  17.  
  18. namespace ics {
  19.  
  20.  
  21. //Instantiate the templated class supplying tgt(a,b): true, iff a has higher priority than b.
  22. //If tgt is defaulted to nullptr in the template, then a constructor must supply cgt.
  23. //If both tgt and cgt are supplied, then they must be the same (by ==) function.
  24. //If neither is supplied, or both are supplied but different, TemplateFunctionError is raised.
  25. //The (unique) non-nullptr value supplied by tgt/cgt is stored in the instance variable gt.
  26. template<class T, bool (*tgt)(const T& a, const T& b) = nullptr> class HeapPriorityQueue {
  27. public:
  28. //Destructor/Constructors
  29. ~HeapPriorityQueue();
  30.  
  31. HeapPriorityQueue(bool (*cgt)(const T& a, const T& b) = nullptr);
  32. explicit HeapPriorityQueue(int initial_length, bool (*cgt)(const T& a, const T& b));
  33. HeapPriorityQueue(const HeapPriorityQueue<T,tgt>& to_copy, bool (*cgt)(const T& a, const T& b) = nullptr);
  34. explicit HeapPriorityQueue(const std::initializer_list<T>& il, bool (*cgt)(const T& a, const T& b) = nullptr);
  35.  
  36. //Iterable class must support "for-each" loop: .begin()/.end() and prefix ++ on returned result
  37. template <class Iterable>
  38. explicit HeapPriorityQueue (const Iterable& i, bool (*cgt)(const T& a, const T& b) = nullptr);
  39.  
  40.  
  41. //Queries
  42. bool empty () const;
  43. int size () const;
  44. T& peek () const;
  45. std::string str () const; //supplies useful debugging information; contrast to operator <<
  46.  
  47.  
  48. //Commands
  49. int enqueue (const T& element);
  50. T dequeue ();
  51. void clear ();
  52.  
  53. //Iterable class must support "for-each" loop: .begin()/.end() and prefix ++ on returned result
  54. template <class Iterable>
  55. int enqueue_all (const Iterable& i);
  56.  
  57.  
  58. //Operators
  59. HeapPriorityQueue<T,tgt>& operator = (const HeapPriorityQueue<T,tgt>& rhs);
  60. bool operator == (const HeapPriorityQueue<T,tgt>& rhs) const;
  61. bool operator != (const HeapPriorityQueue<T,tgt>& rhs) const;
  62.  
  63. template<class T2, bool (*gt2)(const T2& a, const T2& b)>
  64. friend std::ostream& operator << (std::ostream& outs, const HeapPriorityQueue<T2,gt2>& pq);
  65.  
  66.  
  67.  
  68. class Iterator {
  69. public:
  70. //Private constructor called in begin/end, which are friends of HeapPriorityQueue<T,tgt>
  71. ~Iterator();
  72. T erase();
  73. std::string str () const;
  74. HeapPriorityQueue<T,tgt>::Iterator& operator ++ ();
  75. HeapPriorityQueue<T,tgt>::Iterator operator ++ (int);
  76. bool operator == (const HeapPriorityQueue<T,tgt>::Iterator& rhs) const;
  77. bool operator != (const HeapPriorityQueue<T,tgt>::Iterator& rhs) const;
  78. T& operator * () const;
  79. T* operator -> () const;
  80. friend std::ostream& operator << (std::ostream& outs, const HeapPriorityQueue<T,tgt>::Iterator& i) {
  81. outs << i.str(); //Use the same meaning as the debugging .str() method
  82. return outs;
  83. }
  84.  
  85. friend Iterator HeapPriorityQueue<T,tgt>::begin () const;
  86. friend Iterator HeapPriorityQueue<T,tgt>::end () const;
  87.  
  88. private:
  89. //If can_erase is false, the value has been removed from "it" (++ does nothing)
  90. HeapPriorityQueue<T,tgt> it; //copy of HPQ (from begin), to use as iterator via dequeue
  91. HeapPriorityQueue<T,tgt>* ref_pq;
  92. int expected_mod_count;
  93. bool can_erase = true;
  94.  
  95. //Called in friends begin/end
  96. //These constructors have different initializers (see it(...) in first one)
  97. Iterator(HeapPriorityQueue<T,tgt>* iterate_over, bool from_begin); // Called by begin
  98. Iterator(HeapPriorityQueue<T,tgt>* iterate_over); // Called by end
  99. };
  100.  
  101.  
  102. Iterator begin () const;
  103. Iterator end () const;
  104.  
  105.  
  106. private:
  107. bool (*gt) (const T& a, const T& b); // The gt used by enqueue (from template or constructor)
  108. T* pq; // Smaller values in lower indexes (biggest is at used-1)
  109. int length = 0; //Physical length of array: must be >= .size()
  110. int used = 0; //Amount of array used: invariant: 0 <= used <= length
  111. int mod_count = 0; //For sensing concurrent modification
  112.  
  113.  
  114. //Helper methods
  115. void ensure_length (int new_length);
  116. int left_child (int i) const; //Useful abstractions for heaps as arrays
  117. int right_child (int i) const;
  118. int parent (int i) const;
  119. bool is_root (int i) const;
  120. bool in_heap (int i) const;
  121. void percolate_up (int i);
  122. void percolate_down (int i);
  123. void heapify (); // Percolate down all value is array (from indexes used-1 to 0): O(N)
  124. };
  125.  
  126.  
  127.  
  128.  
  129.  
  130. ////////////////////////////////////////////////////////////////////////////////
  131. //
  132. //HeapPriorityQueue class and related definitions
  133.  
  134. //Destructor/Constructors
  135.  
  136. template<class T, bool (*tgt)(const T& a, const T& b)>
  137. HeapPriorityQueue<T,tgt>::~HeapPriorityQueue() {
  138. delete[] pq;
  139. }
  140.  
  141.  
  142. template<class T, bool (*tgt)(const T& a, const T& b)>
  143. HeapPriorityQueue<T,tgt>::HeapPriorityQueue(bool (*cgt)(const T& a, const T& b))
  144. :gt(tgt != nullptr ? tgt : cgt)
  145. {
  146. if (gt == nullptr)
  147. throw TemplateFunctionError("HeapPriorityQueue::No priority specified!");
  148.  
  149. if (tgt != nullptr && cgt != nullptr && tgt != cgt)
  150. throw TemplateFunctionError("HeapPriorityQueue::Priorities don't match!");
  151.  
  152. pq = new T[length]; // creates an array of type T
  153. }
  154.  
  155.  
  156. template<class T, bool (*tgt)(const T& a, const T& b)>
  157. HeapPriorityQueue<T,tgt>::HeapPriorityQueue(int initial_length, bool (*cgt)(const T& a, const T& b))
  158. :gt(tgt != nullptr ? tgt : cgt), length(initial_length)
  159. {
  160. if (gt == nullptr)
  161. throw TemplateFunctionError("HeapPriorityQueue::No priority specified!");
  162.  
  163. if (tgt != nullptr && cgt != nullptr && tgt != cgt)
  164. throw TemplateFunctionError("HeapPriorityQueue::Priorities don't match!");
  165.  
  166. pq = new T[length];
  167. }
  168.  
  169.  
  170. template<class T, bool (*tgt)(const T& a, const T& b)>
  171. HeapPriorityQueue<T,tgt>::HeapPriorityQueue(const HeapPriorityQueue<T,tgt>& to_copy, bool (*cgt)(const T& a, const T& b))
  172. :gt(tgt != nullptr ? tgt : cgt), length(to_copy.length), used(to_copy.used)
  173. {
  174. if (gt == nullptr)
  175. gt = to_copy.gt;
  176. if (tgt != nullptr && cgt != nullptr && tgt != cgt)
  177. throw TemplateFunctionError("HeapPrioroityQueue::Priorities don't match!");
  178.  
  179. pq = new T[length];
  180.  
  181. int i = 0;
  182. while (i != to_copy.used)
  183. {
  184. pq[i] = to_copy.pq[i];
  185. ++i;
  186. }
  187. heapify();
  188. }
  189.  
  190.  
  191. template<class T, bool (*tgt)(const T& a, const T& b)>
  192. HeapPriorityQueue<T,tgt>::HeapPriorityQueue(const std::initializer_list<T>& il, bool (*cgt)(const T& a, const T& b))
  193. :gt(tgt != nullptr ? tgt : cgt), length(il.size())
  194. {
  195. if (gt == nullptr)
  196. throw TemplateFunctionError("HeapPriorityQueue::Priority not specified!");
  197.  
  198. if (tgt != nullptr && cgt != nullptr && tgt != cgt)
  199. throw TemplateFunctionError("HeapPriorityQueue::Priorities don't match!");
  200.  
  201. pq = new T[length];
  202. for (auto e: il)
  203. enqueue(e);
  204. heapify();
  205.  
  206. }
  207.  
  208.  
  209. template<class T, bool (*tgt)(const T& a, const T& b)>
  210. template<class Iterable>
  211. HeapPriorityQueue<T,tgt>::HeapPriorityQueue(const Iterable& i, bool (*cgt)(const T& a, const T& b))
  212. :gt(tgt != nullptr ? tgt : cgt), length(i.size())
  213. {
  214. if (gt == nullptr)
  215. throw TemplateFunctionError("HeapPriorityQueue::Priority not specified!");
  216.  
  217. if (tgt != nullptr && cgt != nullptr && tgt != cgt)
  218. throw TemplateFunctionError("HeapPriorityQueue::Priorities don't match!");
  219.  
  220. pq = new T[length];
  221.  
  222. for (auto e: i)
  223. {
  224. enqueue(e);
  225. }
  226. heapify();
  227. }
  228.  
  229.  
  230. ////////////////////////////////////////////////////////////////////////////////
  231. //
  232. //Queries
  233.  
  234. template<class T, bool (*tgt)(const T& a, const T& b)>
  235. bool HeapPriorityQueue<T,tgt>::empty() const {
  236. return used == 0;
  237. }
  238.  
  239.  
  240. template<class T, bool (*tgt)(const T& a, const T& b)>
  241. int HeapPriorityQueue<T,tgt>::size() const {
  242. return used;
  243. }
  244.  
  245.  
  246. template<class T, bool (*tgt)(const T& a, const T& b)>
  247. T& HeapPriorityQueue<T,tgt>::peek () const {
  248. if (empty())
  249. throw EmptyError("HeapPriorityQueue::peek");
  250.  
  251. return pq[0];
  252. }
  253.  
  254.  
  255. template<class T, bool (*tgt)(const T& a, const T& b)>
  256. std::string HeapPriorityQueue<T,tgt>::str() const {
  257. std::ostringstream answer;
  258. if (empty()) {
  259. answer << "heap_priority_queue[]";
  260. } else {
  261. answer << "heap_priority_queue[";
  262. for (int i = 0; i < used - 1; ++i)
  263. answer << i << ":" << pq[i] << ",";
  264. answer << used - 1 << ":" << pq[used - 1] << "]";
  265. }
  266. answer << "(length=" << length << ",used=" << used << ",mod_count=" << mod_count << ")";
  267. return answer.str();
  268. }
  269.  
  270.  
  271. ////////////////////////////////////////////////////////////////////////////////
  272. //
  273. //Commands
  274.  
  275. template<class T, bool (*tgt)(const T& a, const T& b)>
  276. int HeapPriorityQueue<T,tgt>::enqueue(const T& element) {
  277. ensure_length(used+1);
  278. pq[used++] = element;
  279. percolate_up(used-1);
  280. ++mod_count;
  281. return 1;
  282. }
  283.  
  284.  
  285. template<class T, bool (*tgt)(const T& a, const T& b)>
  286. T HeapPriorityQueue<T,tgt>::dequeue() {
  287. if (empty())
  288. throw EmptyError("HeapPriorityQueue::dequeue");
  289.  
  290. ++mod_count;
  291. T to_return = pq[0];
  292. pq[0] = pq[--used];
  293. percolate_down(0);
  294. return to_return;
  295. }
  296.  
  297.  
  298. template<class T, bool (*tgt)(const T& a, const T& b)>
  299. void HeapPriorityQueue<T,tgt>::clear() {
  300. used = 0;
  301. ++mod_count;
  302. }
  303.  
  304.  
  305. template<class T, bool (*tgt)(const T& a, const T& b)>
  306. template <class Iterable>
  307. int HeapPriorityQueue<T,tgt>::enqueue_all (const Iterable& i) {
  308. int count = 0;
  309. for(const T&v: i)
  310. count += enqueue(v);
  311. return count;
  312. }
  313.  
  314.  
  315. ////////////////////////////////////////////////////////////////////////////////
  316. //
  317. //Operators
  318.  
  319. template<class T, bool (*tgt)(const T& a, const T& b)>
  320. HeapPriorityQueue<T,tgt>& HeapPriorityQueue<T,tgt>::operator = (const HeapPriorityQueue<T,tgt>& rhs) {
  321. if (this == &rhs)
  322. return *this;
  323. gt = rhs.gt;
  324. ensure_length(rhs.used);
  325. used = rhs.used;
  326. for (int i=0; i<rhs.used; ++i)
  327. pq[i] = rhs.pq[i];
  328. ++mod_count;
  329. return *this;
  330. }
  331.  
  332.  
  333. template<class T, bool (*tgt)(const T& a, const T& b)>
  334. bool HeapPriorityQueue<T,tgt>::operator == (const HeapPriorityQueue<T,tgt>& rhs) const {
  335. if (this == &rhs)// *this == rhs
  336. return true;
  337. if (used != rhs.size() or gt != rhs.gt)
  338. return false;
  339.  
  340. return true;
  341. }
  342.  
  343.  
  344. template<class T, bool (*tgt)(const T& a, const T& b)>
  345. bool HeapPriorityQueue<T,tgt>::operator != (const HeapPriorityQueue<T,tgt>& rhs) const {
  346. return !(*this == rhs);
  347. }
  348.  
  349.  
  350. template<class T, bool (*tgt)(const T& a, const T& b)>
  351. std::ostream& operator << (std::ostream& outs, const HeapPriorityQueue<T,tgt>& p) {
  352. HeapPriorityQueue<T,tgt> temp;
  353. temp = p;
  354. outs << "priority_queue[";
  355.  
  356. if(!p.empty()){
  357. ArrayStack<T> temp(p);
  358. outs << temp.pop();
  359. for(int i = 1; i != p.size(); ++i)
  360. outs << "," << temp.pop();
  361. }
  362. outs << "]:highest";
  363. return outs;
  364. }
  365.  
  366.  
  367. ////////////////////////////////////////////////////////////////////////////////
  368. //
  369. //Iterator constructors
  370.  
  371. template<class T, bool (*tgt)(const T& a, const T& b)>
  372. auto HeapPriorityQueue<T,tgt>::begin () const -> HeapPriorityQueue<T,tgt>::Iterator {
  373. return Iterator(const_cast<HeapPriorityQueue<T,tgt>*>(this), true);
  374. }
  375.  
  376.  
  377. template<class T, bool (*tgt)(const T& a, const T& b)>
  378. auto HeapPriorityQueue<T,tgt>::end () const -> HeapPriorityQueue<T,tgt>::Iterator {
  379. return Iterator(const_cast<HeapPriorityQueue<T,tgt>*>(this));
  380. }
  381.  
  382.  
  383. ////////////////////////////////////////////////////////////////////////////////
  384. //
  385. //Private helper methods
  386.  
  387. template<class T, bool (*tgt)(const T& a, const T& b)>
  388. void HeapPriorityQueue<T,tgt>::ensure_length(int new_length) {
  389. if (length >= new_length)
  390. return;
  391. T* old_pq = pq;
  392. length = std::max(new_length,2*length);
  393. pq = new T[length];
  394. for (int i=0; i<used; ++i)
  395. pq[i] = old_pq[i];
  396.  
  397. delete [] old_pq;
  398. }
  399.  
  400.  
  401. template<class T, bool (*tgt)(const T& a, const T& b)>
  402. int HeapPriorityQueue<T,tgt>::left_child(int i) const {
  403. if (in_heap(2*i+1))
  404. return 2*i+1;
  405. }
  406.  
  407. template<class T, bool (*tgt)(const T& a, const T& b)>
  408. int HeapPriorityQueue<T,tgt>::right_child(int i) const {
  409. if (in_heap(2*i+2))
  410. return 2*i+2;
  411. }
  412.  
  413. template<class T, bool (*tgt)(const T& a, const T& b)>
  414. int HeapPriorityQueue<T,tgt>::parent(int i) const {
  415. if (in_heap((i-1)/2))
  416. return (i-1)/2;
  417. }
  418.  
  419. template<class T, bool (*tgt)(const T& a, const T& b)>
  420. bool HeapPriorityQueue<T,tgt>::is_root(int i) const {
  421. return i == 0;
  422. }
  423.  
  424. template<class T, bool (*tgt)(const T& a, const T& b)>
  425. bool HeapPriorityQueue<T,tgt>::in_heap(int i) const {
  426. return i < used;
  427. }
  428.  
  429.  
  430. template<class T, bool (*tgt)(const T& a, const T& b)>
  431. void HeapPriorityQueue<T,tgt>::percolate_up(int i) {
  432. for (; !is_root(i) && gt(pq[i], pq[i-1]); --i)
  433. std::swap(pq[i], pq[i-1]);
  434. }
  435.  
  436.  
  437. template<class T, bool (*tgt)(const T& a, const T& b)>
  438. void HeapPriorityQueue<T,tgt>::percolate_down(int i) {
  439. for (;in_heap(i+1) && gt(pq[i+1], pq[i]); ++i)
  440. {
  441. if (gt(pq[i+1], pq[i]))
  442. std::swap(pq[i+1], pq[i]);
  443. }
  444. }
  445.  
  446.  
  447. template<class T, bool (*tgt)(const T& a, const T& b)>
  448. void HeapPriorityQueue<T,tgt>::heapify() {
  449. for (int i = used-1; i >= 0; --i)
  450. percolate_down(i);
  451. }
  452.  
  453.  
  454. ////////////////////////////////////////////////////////////////////////////////
  455. //
  456. //Iterator class definitions
  457. template<class T, bool (*tgt)(const T& a, const T& b)>
  458. HeapPriorityQueue<T,tgt>::Iterator::Iterator(HeapPriorityQueue<T,tgt>* iterate_over, bool tgt_nullptr)
  459. : it(*iterate_over,iterate_over->gt), ref_pq(iterate_over), expected_mod_count(iterate_over->mod_count) {
  460. }
  461.  
  462.  
  463. template<class T, bool (*tgt)(const T& a, const T& b)>
  464. HeapPriorityQueue<T,tgt>::Iterator::Iterator(HeapPriorityQueue<T,tgt>* iterate_over)
  465. : it(iterate_over->gt), ref_pq(iterate_over), expected_mod_count(iterate_over->mod_count) {
  466. }
  467.  
  468.  
  469. template<class T, bool (*tgt)(const T& a, const T& b)>
  470. HeapPriorityQueue<T,tgt>::Iterator::~Iterator()
  471. {}
  472.  
  473.  
  474. template<class T, bool (*tgt)(const T& a, const T& b)>
  475. T HeapPriorityQueue<T,tgt>::Iterator::erase() {
  476. if (expected_mod_count != ref_pq->mod_count)
  477. throw ConcurrentModificationError("HeapPriorityQueue::Iterator::erase");
  478. if (!can_erase)
  479. throw CannotEraseError("HeapPriorityQueue::Iterator::erase");
  480. if (it.empty())
  481. throw CannotEraseError("HeapPriorityQueue::Iterator::erase");
  482.  
  483. can_erase = false;
  484. T to_return = it.dequeue();
  485. for (int i=0; i<ref_pq->used; ++i)
  486. if (ref_pq->pq[i] == to_return) {
  487. ref_pq->pq[i] = ref_pq->pq[--ref_pq->used];
  488. ref_pq->percolate_up(i);
  489. ref_pq->percolate_down(i);
  490. break;
  491. }
  492.  
  493. expected_mod_count = ref_pq->mod_count;
  494. return to_return;
  495. }
  496.  
  497.  
  498. template<class T, bool (*tgt)(const T& a, const T& b)>
  499. std::string HeapPriorityQueue<T,tgt>::Iterator::str() const {
  500. std::ostringstream answer;
  501. answer << it.str() << "/expected_mod_count=" << expected_mod_count << "/can_erase=" << can_erase;
  502. return answer.str();
  503. }
  504.  
  505.  
  506.  
  507. template<class T, bool (*tgt)(const T& a, const T& b)>
  508. auto HeapPriorityQueue<T,tgt>::Iterator::operator ++ () -> HeapPriorityQueue<T,tgt>::Iterator& {
  509. if (expected_mod_count != ref_pq->mod_count)
  510. throw ConcurrentModificationError("HeapPriorityQueue::Iterator::operator++");
  511. if (it.empty())
  512. return *this;
  513. if (can_erase)
  514. it.dequeue();
  515. else
  516. can_erase = true;
  517. return *this;
  518. }
  519.  
  520.  
  521. template<class T, bool (*tgt)(const T& a, const T& b)>
  522. auto HeapPriorityQueue<T,tgt>::Iterator::operator ++ (int) -> HeapPriorityQueue<T,tgt>::Iterator {
  523. if (expected_mod_count != ref_pq->mod_count)
  524. throw ConcurrentModificationError("HeapPriorityQueue::Iterator::operator++");
  525. if (it.empty())
  526. return *this;
  527. Iterator to_return(*this);
  528. if (can_erase)
  529. it.dequeue();
  530. else
  531. can_erase = true;
  532. return to_return;
  533. }
  534.  
  535.  
  536. template<class T, bool (*tgt)(const T& a, const T& b)>
  537. bool HeapPriorityQueue<T,tgt>::Iterator::operator == (const HeapPriorityQueue<T,tgt>::Iterator& rhs) const {
  538. const Iterator* rhsASI = dynamic_cast<const Iterator*>(&rhs);
  539. if (rhsASI == 0)
  540. throw IteratorTypeError("HeapPriorityQueue::Iterator::operator ==");
  541. if (expected_mod_count != ref_pq->mod_count)
  542. throw ConcurrentModificationError("HeapPriorityQueue::Iterator::operator ==");
  543. if (ref_pq != rhsASI->ref_pq)
  544. throw ComparingDifferentIteratorsError("HeapPriorityQueue::Iterator::operator ==");
  545. return it.size() == rhsASI->it.size();
  546. }
  547.  
  548.  
  549. template<class T, bool (*tgt)(const T& a, const T& b)>
  550. bool HeapPriorityQueue<T,tgt>::Iterator::operator != (const HeapPriorityQueue<T,tgt>::Iterator& rhs) const {
  551. const Iterator* rhsASI = dynamic_cast<const Iterator*>(&rhs);
  552. if (rhsASI == 0)
  553. throw IteratorTypeError("HeapPriorityQueue::Iterator::operator !=");
  554. if (expected_mod_count != ref_pq->mod_count)
  555. throw ConcurrentModificationError("HeapPriorityQueue::Iterator::operator !=");
  556. if (ref_pq != rhsASI->ref_pq)
  557. throw ComparingDifferentIteratorsError("HeapPriorityQueue::Iterator::operator !=");
  558. return it.size() != rhsASI->it.size();
  559. }
  560.  
  561.  
  562. template<class T, bool (*tgt)(const T& a, const T& b)>
  563. T& HeapPriorityQueue<T,tgt>::Iterator::operator *() const {
  564. if (expected_mod_count != ref_pq->mod_count)
  565. throw ConcurrentModificationError("HeapPriorityQueue::Iterator::operator *");
  566. if (!can_erase || it.empty())
  567. throw IteratorPositionIllegal("HeapPriorityQueue::Iterator::operator *");
  568. return it.peek();
  569. }
  570.  
  571.  
  572. template<class T, bool (*tgt)(const T& a, const T& b)>
  573. T* HeapPriorityQueue<T,tgt>::Iterator::operator ->() const {
  574. if (expected_mod_count != ref_pq->mod_count)
  575. throw ConcurrentModificationError("HeapPriorityQueue::Iterator::operator ->");
  576. if (!can_erase || it.empty())
  577. throw IteratorPositionIllegal("HeapPriorityQueue::Iterator::operator ->");
  578. return &it.peek();
  579. }
  580. }
  581.  
  582. #endif /* HEAP_PRIORITY_QUEUE_HPP_ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement