Marine Library  1.0
C++ library for Linux Networking Development
ring_buf.hh
1 #ifndef DOZERG_RING_BUFFER_H_20090218
2 #define DOZERG_RING_BUFFER_H_20090218
3 
4 /*
5  环形缓冲区,可作为“单生产者-单消费者”模型中的消息队列,无需加锁 CRingBuf //*/ #include <cassert> #include <cstddef> //std::ptrdiff_t #include "tools/memory.hh" NS_SERVER_BEGIN template<class T, class Alloc = std::allocator<T> > class CRingBuf { //typedefs: typedef CRingBuf<T> __Myt; public: typedef T value_type; typedef T & reference; typedef const T & const_reference; typedef T * pointer; typedef const T * const_pointer; typedef size_t size_type; typedef std::ptrdiff_t difference_type; typedef typename Alloc:: template rebind<T>::other allocator_type; //functions: explicit CRingBuf(size_type capacity) : buf_(NULL) , capa_(capacity + 1) , head_(0) , tail_(0) { init(); } ~CRingBuf(){uninit();} size_type capacity() const{return capa_ - 1;} bool empty() const{return head_ == tail_;} size_type size() const{return (tail_ + capa_ - head_) % capa_;} bool push(const_reference v){ assert(head_ < capa_ && tail_ < capa_); const size_type n = next(tail_); if(n == head_) return false; //full tools::Construct(buf_ + tail_, v); tail_ = n; return true; } bool pop(pointer v){ assert(head_ < capa_ && tail_ < capa_); if(empty()) return false; const size_type n = next(head_); if(v) *v = buf_[head_]; tools::Destroy(buf_ + head_); head_ = n; return true; } private: CRingBuf(const __Myt &); //disable copy and assignment __Myt & operator =(const __Myt &); void init(){ assert(!buf_); assert(capa_ > 1); buf_ = tools::Allocate<value_type>(allocator_type(), capa_); } void uninit(){ assert(buf_); clear(); tools::Deallocate(buf_, capa_, allocator_type()); } void clear(){ while(!empty()) pop(NULL); } size_type next(size_type cur) const{ if(++cur >= capa_) cur -= capa_; return cur; } //fields: pointer buf_; const size_type capa_; //实际容量+1(因为留了一个位置来区分空和满) volatile size_type head_; volatile size_type tail_; }; NS_SERVER_END #endif
6  CRingBuf
7 //*/
8 
9 #include <cassert>
10 #include <cstddef> //std::ptrdiff_t
11 #include "tools/memory.hh"
12 
13 NS_SERVER_BEGIN
14 
15 template<class T, class Alloc = std::allocator<T> >
16 class CRingBuf
17 {
18  //typedefs:
19  typedef CRingBuf<T> __Myt;
20 public:
21  typedef T value_type;
22  typedef T & reference;
23  typedef const T & const_reference;
24  typedef T * pointer;
25  typedef const T * const_pointer;
26  typedef size_t size_type;
27  typedef std::ptrdiff_t difference_type;
28  typedef typename Alloc::
29  template rebind<T>::other allocator_type;
30  //functions:
31  explicit CRingBuf(size_type capacity)
32  : buf_(NULL)
33  , capa_(capacity + 1)
34  , head_(0)
35  , tail_(0)
36  {
37  init();
38  }
39  ~CRingBuf(){uninit();}
40  size_type capacity() const{return capa_ - 1;}
41  bool empty() const{return head_ == tail_;}
42  size_type size() const{return (tail_ + capa_ - head_) % capa_;}
43  bool push(const_reference v){
44  assert(head_ < capa_ && tail_ < capa_);
45  const size_type n = next(tail_);
46  if(n == head_)
47  return false; //full
48  tools::Construct(buf_ + tail_, v);
49  tail_ = n;
50  return true;
51  }
52  bool pop(pointer v){
53  assert(head_ < capa_ && tail_ < capa_);
54  if(empty())
55  return false;
56  const size_type n = next(head_);
57  if(v)
58  *v = buf_[head_];
59  tools::Destroy(buf_ + head_);
60  head_ = n;
61  return true;
62  }
63 private:
64  CRingBuf(const __Myt &); //disable copy and assignment
65  __Myt & operator =(const __Myt &);
66  void init(){
67  assert(!buf_);
68  assert(capa_ > 1);
69  buf_ = tools::Allocate<value_type>(allocator_type(), capa_);
70  }
71  void uninit(){
72  assert(buf_);
73  clear();
74  tools::Deallocate(buf_, capa_, allocator_type());
75  }
76  void clear(){
77  while(!empty())
78  pop(NULL);
79  }
80  size_type next(size_type cur) const{
81  if(++cur >= capa_)
82  cur -= capa_;
83  return cur;
84  }
85  //fields:
86  pointer buf_;
87  const size_type capa_; //实际容量+1(因为留了一个位置来区分空和满)
88  volatile size_type head_;
89  volatile size_type tail_;
90 };
91 
92 NS_SERVER_END
93 
94 #endif
Definition: ring_buf.hh:16