1 // Copyright 2003-2008 Jan Gaspar.
2 // Copyright 2013 Paul A. Bristow. Added some Quickbook snippet markers.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See the accompanying file LICENSE_1_0.txt
6 // or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
8 //[circular_buffer_bound_example_1
10 This example shows how the `circular_buffer` can be utilized
11 as an underlying container of the bounded buffer.
14 #include <boost/circular_buffer.hpp>
15 #include <boost/thread/mutex.hpp>
16 #include <boost/thread/condition.hpp>
17 #include <boost/thread/thread.hpp>
18 #include <boost/call_traits.hpp>
19 #include <boost/bind.hpp>
21 #include <boost/timer/timer.hpp> // for auto_cpu_timer
28 typedef boost::circular_buffer
<T
> container_type
;
29 typedef typename
container_type::size_type size_type
;
30 typedef typename
container_type::value_type value_type
;
31 typedef typename
boost::call_traits
<value_type
>::param_type param_type
;
33 explicit bounded_buffer(size_type capacity
) : m_unread(0), m_container(capacity
) {}
35 void push_front(typename
boost::call_traits
<value_type
>::param_type item
)
36 { // `param_type` represents the "best" way to pass a parameter of type `value_type` to a method.
38 boost::mutex::scoped_lock
lock(m_mutex
);
39 m_not_full
.wait(lock
, boost::bind(&bounded_buffer
<value_type
>::is_not_full
, this));
40 m_container
.push_front(item
);
43 m_not_empty
.notify_one();
46 void pop_back(value_type
* pItem
) {
47 boost::mutex::scoped_lock
lock(m_mutex
);
48 m_not_empty
.wait(lock
, boost::bind(&bounded_buffer
<value_type
>::is_not_empty
, this));
49 *pItem
= m_container
[--m_unread
];
51 m_not_full
.notify_one();
55 bounded_buffer(const bounded_buffer
&); // Disabled copy constructor.
56 bounded_buffer
& operator = (const bounded_buffer
&); // Disabled assign operator.
58 bool is_not_empty() const { return m_unread
> 0; }
59 bool is_not_full() const { return m_unread
< m_container
.capacity(); }
62 container_type m_container
;
64 boost::condition m_not_empty
;
65 boost::condition m_not_full
;
68 //] [/circular_buffer_bound_example_1]
70 const unsigned long queue_size
= 1000L;
71 const unsigned long total_elements
= queue_size
* 1000L;
73 //[circular_buffer_bound_example_2]
74 /*`To demonstrate, create two classes to exercise the buffer.
76 The producer class fills the buffer with elements.
78 The consumer class consumes the buffer contents.
82 template<class Buffer
>
86 typedef typename
Buffer::value_type value_type
;
90 Producer(Buffer
* buffer
) : m_container(buffer
)
95 for (unsigned long i
= 0L; i
< total_elements
; ++i
)
97 m_container
->push_front(value_type());
102 template<class Buffer
>
106 typedef typename
Buffer::value_type value_type
;
111 Consumer(Buffer
* buffer
) : m_container(buffer
)
116 for (unsigned long i
= 0L; i
< total_elements
; ++i
)
118 m_container
->pop_back(&m_item
);
123 /*`Create a first-int first-out test of the bound_buffer.
124 Include a call to boost::progress_timer
126 [@http://www.boost.org/doc/libs/1_53_0/libs/timer/doc/cpu_timers.html CPU timer]
129 template<class Buffer
>
130 void fifo_test(Buffer
* buffer
)
133 boost::timer::auto_cpu_timer progress
;
135 // Initialize the buffer with some values before launching producer and consumer threads.
136 for (unsigned long i
= queue_size
/ 2L; i
> 0; --i
)
138 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
139 buffer
->push_front(Buffer::value_type());
141 buffer
->push_front(BOOST_DEDUCED_TYPENAME
Buffer::value_type());
145 // Construct the threads.
146 Consumer
<Buffer
> consumer(buffer
);
147 Producer
<Buffer
> producer(buffer
);
149 // Start the threads.
150 boost::thread
consume(consumer
);
151 boost::thread
produce(producer
);
153 // Wait for completion.
158 // destructor of boost::timer::auto_cpu_timer will output the time to std::cout.
161 //] [/circular_buffer_bound_example_2]
166 //[circular_buffer_bound_example_3]
167 //`Construct a bounded_buffer to hold the chosen type, here int.
168 bounded_buffer
<int> bb_int(queue_size
);
169 std::cout
<< "Testing bounded_buffer<int> ";
171 //`Start the fifo test.
173 //` destructor of boost::timer::auto_cpu_timer will output the time to std::cout
175 //] [/circular_buffer_bound_example_3]
182 //[circular_buffer_bound_output
184 Description: Autorun "J:\Cpp\Misc\Debug\circular_buffer_bound_example.exe"
186 Testing bounded_buffer<int> 15.010692s wall, 9.188459s user + 7.207246s system = 16.395705s CPU (109.2%)
188 //] [/circular_buffer_bound_output]