00001 /* 00002 * 00003 * 00004 * Distributed under the OpenDDS License. 00005 * See: http://www.opendds.org/license.html 00006 */ 00007 00008 #ifndef OPENDDS_DCPS_BASICQUEUE_T_H 00009 #define OPENDDS_DCPS_BASICQUEUE_T_H 00010 00011 #include <deque> 00012 #include <algorithm> 00013 #include "dds/DCPS/PoolAllocationBase.h" 00014 #include "dds/DCPS/PoolAllocator.h" 00015 #include "BasicQueueVisitor_T.h" 00016 00017 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL 00018 00019 namespace OpenDDS { 00020 namespace DCPS { 00021 00022 00023 template <typename T> 00024 class BasicQueue : public PoolAllocationBase { 00025 private: 00026 00027 typedef BasicQueueVisitor<T> VisitorType; 00028 typedef OPENDDS_DEQUE(T*) QueueImpl; 00029 typedef typename QueueImpl::iterator iterator; 00030 typedef typename QueueImpl::const_iterator const_iterator; 00031 QueueImpl elements_; 00032 public: 00033 /// Put a pointer to an element (T*) on to the queue. 00034 int put(T* elem) { 00035 elements_.push_back(elem); 00036 return 0; 00037 } 00038 00039 /// Peek at the element at the top of the queue. This is just 00040 /// like the get() operation except that the queue remains intact. 00041 T* peek() const { 00042 return elements_.size() ? elements_[0] : 0; 00043 } 00044 00045 void replace_head(T* value) { 00046 if (elements_.size()) { 00047 elements_[0] = value; 00048 } 00049 } 00050 00051 /// Extract the top element from the queue. Returns 0 if there 00052 /// are no elements in the queue. 00053 T* get() { 00054 T* result = 0; 00055 if (elements_.size()) { 00056 result = elements_.front(); 00057 elements_.pop_front(); 00058 } 00059 return result; 00060 } 00061 00062 /// Accessor for the current number of elements in the queue. 00063 size_t size() const { 00064 return elements_.size(); 00065 } 00066 00067 /// Standard way to supply a visitor to the queue - this will 00068 /// invoke visit_element(T* element) on the supplied visitor object 00069 /// once for each element in this BasicQueue<T> object, in order. 00070 /// The visitor can stop visitation early by returning 0 from 00071 /// its visit_element(T* element) method. 00072 void accept_visitor(VisitorType& visitor) const { 00073 for (const_iterator itr = elements_.begin(); 00074 itr != elements_.end(); ++itr) { 00075 visitor.visit_element(*itr); 00076 } 00077 } 00078 00079 /// Alternate way to supply a visitor to the queue - this will 00080 /// invoke visit_element(T* element, int& remove) on the supplied 00081 /// visitor object once for each element in this BasicQueue<T> 00082 /// object, in order. 00083 /// 00084 /// The remove argument is a flag that should be set to true (1) 00085 /// in the visitor's visit_element_remove(T* element, int& remove) 00086 /// method if the visitor decides that the element should be removed 00087 /// from the queue. The remove flag is always set to false (0) 00088 /// prior to calling the visitor's visit_element_remove(T* element, 00089 /// int& remove) method. 00090 /// 00091 /// The visitor can stop visitation early by returning 0 from 00092 /// its visit_element_remove(T* element, int& remove) method. 00093 void accept_remove_visitor(VisitorType& visitor) { 00094 QueueImpl tmp; 00095 for (iterator itr = elements_.begin(); 00096 itr != elements_.end(); ++itr) { 00097 00098 int remove = 0; 00099 int keep_going = visitor.visit_element_remove(*itr, remove); 00100 if (!remove) 00101 tmp.push_back(*itr); 00102 if (keep_going == 0) { 00103 std::copy(++itr,elements_.end(), std::back_inserter(tmp)); 00104 break; 00105 } 00106 } 00107 elements_.swap(tmp); 00108 } 00109 /// This kind of visitation may cause the visitor to replace 00110 /// the currently visited element with a new element. 00111 void accept_replace_visitor(VisitorType& visitor) { 00112 for (iterator itr = elements_.begin(); 00113 itr != elements_.end(); ++itr) { 00114 if (visitor.visit_element_ref(*itr) == 0) 00115 return; 00116 } 00117 } 00118 00119 00120 void swap(BasicQueue& other) 00121 { 00122 elements_.swap(other.elements_); 00123 } 00124 }; 00125 00126 } // namespace DCPS 00127 } // namespace OpenDDS 00128 00129 OPENDDS_END_VERSIONED_NAMESPACE_DECL 00130 00131 #endif /* OPENDDS_DCPS_BASICQUEUE_T_H */