Line data Source code
1 : /* 2 : * 3 : * 4 : * Distributed under the OpenDDS License. 5 : * See: http://www.opendds.org/license.html 6 : */ 7 : 8 : #ifndef OPENDDS_DCPS_TRANSPORT_FRAMEWORK_BASICQUEUE_T_H 9 : #define OPENDDS_DCPS_TRANSPORT_FRAMEWORK_BASICQUEUE_T_H 10 : 11 : #include <deque> 12 : #include <algorithm> 13 : #include <iterator> 14 : 15 : #include "dds/DCPS/PoolAllocationBase.h" 16 : #include "dds/DCPS/PoolAllocator.h" 17 : #include "BasicQueueVisitor_T.h" 18 : 19 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL 20 : 21 : namespace OpenDDS { 22 : namespace DCPS { 23 : 24 : 25 : template <typename T> 26 : class BasicQueue : public PoolAllocationBase { 27 : private: 28 : 29 : typedef BasicQueueVisitor<T> VisitorType; 30 : typedef OPENDDS_DEQUE(T*) QueueImpl; 31 : typedef typename QueueImpl::iterator iterator; 32 : typedef typename QueueImpl::const_iterator const_iterator; 33 : QueueImpl elements_; 34 : public: 35 : /// Put a pointer to an element (T*) on to the queue. 36 4 : int put(T* elem) { 37 4 : elements_.push_back(elem); 38 4 : return 0; 39 : } 40 : 41 : /// Peek at the element at the top of the queue. This is just 42 : /// like the get() operation except that the queue remains intact. 43 2 : T* peek() const { 44 2 : return elements_.size() ? elements_[0] : 0; 45 : } 46 : 47 0 : void replace_head(T* value) { 48 0 : if (elements_.size()) { 49 0 : elements_[0] = value; 50 : } 51 0 : } 52 : 53 : /// Extract the top element from the queue. Returns 0 if there 54 : /// are no elements in the queue. 55 0 : T* get() { 56 0 : T* result = 0; 57 0 : if (elements_.size()) { 58 0 : result = elements_.front(); 59 0 : elements_.pop_front(); 60 : } 61 0 : return result; 62 : } 63 : 64 : /// Accessor for the current number of elements in the queue. 65 6 : size_t size() const { 66 6 : return elements_.size(); 67 : } 68 : 69 : /// Standard way to supply a visitor to the queue - this will 70 : /// invoke visit_element(T* element) on the supplied visitor object 71 : /// once for each element in this BasicQueue<T> object, in order. 72 : /// The visitor can stop visitation early by returning 0 from 73 : /// its visit_element(T* element) method. 74 2 : void accept_visitor(VisitorType& visitor) const { 75 2 : for (const_iterator itr = elements_.begin(); 76 4 : itr != elements_.end(); ++itr) { 77 2 : visitor.visit_element(*itr); 78 : } 79 2 : } 80 : 81 : /// Alternate way to supply a visitor to the queue - this will 82 : /// invoke visit_element(T* element, int& remove) on the supplied 83 : /// visitor object once for each element in this BasicQueue<T> 84 : /// object, in order. 85 : /// 86 : /// The remove argument is a flag that should be set to true (1) 87 : /// in the visitor's visit_element_remove(T* element, int& remove) 88 : /// method if the visitor decides that the element should be removed 89 : /// from the queue. The remove flag is always set to false (0) 90 : /// prior to calling the visitor's visit_element_remove(T* element, 91 : /// int& remove) method. 92 : /// 93 : /// The visitor can stop visitation early by returning 0 from 94 : /// its visit_element_remove(T* element, int& remove) method. 95 4 : void accept_remove_visitor(VisitorType& visitor) { 96 4 : QueueImpl tmp; 97 4 : for (iterator itr = elements_.begin(); 98 8 : itr != elements_.end(); ++itr) { 99 : 100 4 : int remove = 0; 101 4 : int keep_going = visitor.visit_element_remove(*itr, remove); 102 4 : if (!remove) 103 0 : tmp.push_back(*itr); 104 4 : if (keep_going == 0) { 105 0 : std::copy(++itr,elements_.end(), std::back_inserter(tmp)); 106 0 : break; 107 : } 108 : } 109 4 : elements_.swap(tmp); 110 4 : } 111 : /// This kind of visitation may cause the visitor to replace 112 : /// the currently visited element with a new element. 113 0 : void accept_replace_visitor(VisitorType& visitor) { 114 0 : for (iterator itr = elements_.begin(); 115 0 : itr != elements_.end(); ++itr) { 116 0 : if (visitor.visit_element_ref(*itr) == 0) 117 0 : return; 118 : } 119 : } 120 : 121 : 122 0 : void swap(BasicQueue& other) 123 : { 124 0 : elements_.swap(other.elements_); 125 0 : } 126 : }; 127 : 128 : } // namespace DCPS 129 : } // namespace OpenDDS 130 : 131 : OPENDDS_END_VERSIONED_NAMESPACE_DECL 132 : 133 : #endif /* OPENDDS_DCPS_BASICQUEUE_T_H */