diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/circular_buffer | |
parent | Initial commit. (diff) | |
download | ceph-upstream/16.2.11+ds.tar.xz ceph-upstream/16.2.11+ds.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/circular_buffer')
18 files changed, 5764 insertions, 0 deletions
diff --git a/src/boost/libs/circular_buffer/CMakeLists.txt b/src/boost/libs/circular_buffer/CMakeLists.txt new file mode 100644 index 000000000..1926e7300 --- /dev/null +++ b/src/boost/libs/circular_buffer/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2018 Glen Joseph Fernandes +# (glenjofe@gmail.com) +# +# Distributed under the Boost Software License, Version 1.0. +# (http://www.boost.org/LICENSE_1_0.txt) + +cmake_minimum_required(VERSION 3.5) + +project(BoostCircularBuffer LANGUAGES CXX) + +add_library(boost_circular_buffer INTERFACE) + +add_library(Boost::circular_buffer ALIAS boost_circular_buffer) + +target_include_directories(boost_circular_buffer INTERFACE include) + +target_link_libraries(boost_circular_buffer INTERFACE + Boost::assert + Boost::concept_check + Boost::config + Boost::core + Boost::move + Boost::static_assert + Boost::throw_exception + Boost::type_traits) diff --git a/src/boost/libs/circular_buffer/example/bounded_buffer_comparison.cpp b/src/boost/libs/circular_buffer/example/bounded_buffer_comparison.cpp new file mode 100644 index 000000000..9eba99648 --- /dev/null +++ b/src/boost/libs/circular_buffer/example/bounded_buffer_comparison.cpp @@ -0,0 +1,316 @@ +// Comparison of bounded buffers based on different containers. + +// Copyright (c) 2003-2008 Jan Gaspar +// Copyright 2013 Paul A. Bristow. Added some Quickbook snippet markers. + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/circular_buffer.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition.hpp> +#include <boost/thread/thread.hpp> +#include <boost/timer/timer.hpp> +#include <boost/call_traits.hpp> +#include <boost/bind.hpp> +#include <deque> +#include <list> +#include <string> +#include <iostream> + +const unsigned long QUEUE_SIZE = 1000L; +const unsigned long TOTAL_ELEMENTS = QUEUE_SIZE * 1000L; + +template <class T> +class bounded_buffer { +public: + + typedef boost::circular_buffer<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {} + + void push_front(param_type item) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_full, this)); + m_container.push_front(item); + ++m_unread; + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_empty, this)); + *pItem = m_container[--m_unread]; + lock.unlock(); + m_not_full.notify_one(); + } + +private: + bounded_buffer(const bounded_buffer&); // Disabled copy constructor + bounded_buffer& operator = (const bounded_buffer&); // Disabled assign operator + + bool is_not_empty() const { return m_unread > 0; } + bool is_not_full() const { return m_unread < m_container.capacity(); } + + size_type m_unread; + container_type m_container; + boost::mutex m_mutex; + boost::condition m_not_empty; + boost::condition m_not_full; +}; + +template <class T> +class bounded_buffer_space_optimized { +public: + + typedef boost::circular_buffer_space_optimized<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer_space_optimized(size_type capacity) : m_container(capacity) {} + + void push_front(param_type item) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer_space_optimized<value_type>::is_not_full, this)); + m_container.push_front(item); + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer_space_optimized<value_type>::is_not_empty, this)); + *pItem = m_container.back(); + m_container.pop_back(); + lock.unlock(); + m_not_full.notify_one(); + } + +private: + + bounded_buffer_space_optimized(const bounded_buffer_space_optimized&); // Disabled copy constructor + bounded_buffer_space_optimized& operator = (const bounded_buffer_space_optimized&); // Disabled assign operator + + bool is_not_empty() const { return m_container.size() > 0; } + bool is_not_full() const { return m_container.size() < m_container.capacity(); } + + container_type m_container; + boost::mutex m_mutex; + boost::condition m_not_empty; + boost::condition m_not_full; +}; + +template <class T> +class bounded_buffer_deque_based { +public: + + typedef std::deque<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer_deque_based(size_type capacity) : m_capacity(capacity) {} + + void push_front(param_type item) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer_deque_based<value_type>::is_not_full, this)); + m_container.push_front(item); + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer_deque_based<value_type>::is_not_empty, this)); + *pItem = m_container.back(); + m_container.pop_back(); + lock.unlock(); + m_not_full.notify_one(); + } + +private: + + bounded_buffer_deque_based(const bounded_buffer_deque_based&); // Disabled copy constructor + bounded_buffer_deque_based& operator = (const bounded_buffer_deque_based&); // Disabled assign operator + + bool is_not_empty() const { return m_container.size() > 0; } + bool is_not_full() const { return m_container.size() < m_capacity; } + + const size_type m_capacity; + container_type m_container; + boost::mutex m_mutex; + boost::condition m_not_empty; + boost::condition m_not_full; +}; + +template <class T> +class bounded_buffer_list_based { +public: + + typedef std::list<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer_list_based(size_type capacity) : m_capacity(capacity) {} + + void push_front(param_type item) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer_list_based<value_type>::is_not_full, this)); + m_container.push_front(item); + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer_list_based<value_type>::is_not_empty, this)); + *pItem = m_container.back(); + m_container.pop_back(); + lock.unlock(); + m_not_full.notify_one(); + } + +private: + + bounded_buffer_list_based(const bounded_buffer_list_based&); // Disabled copy constructor + bounded_buffer_list_based& operator = (const bounded_buffer_list_based&); // Disabled assign operator + + bool is_not_empty() const { return m_container.size() > 0; } + bool is_not_full() const { return m_container.size() < m_capacity; } + + const size_type m_capacity; + container_type m_container; + boost::mutex m_mutex; + boost::condition m_not_empty; + boost::condition m_not_full; +}; + +template<class Buffer> +class Consumer { + + typedef typename Buffer::value_type value_type; + Buffer* m_container; + value_type m_item; + +public: + Consumer(Buffer* buffer) : m_container(buffer) {} + + void operator()() { + for (unsigned long i = 0L; i < TOTAL_ELEMENTS; ++i) { + m_container->pop_back(&m_item); + } + } +}; + +template<class Buffer> +class Producer { + + typedef typename Buffer::value_type value_type; + Buffer* m_container; + +public: + Producer(Buffer* buffer) : m_container(buffer) {} + + void operator()() { + for (unsigned long i = 0L; i < TOTAL_ELEMENTS; ++i) { + m_container->push_front(value_type()); + } + } +}; + +template<class Buffer> +void fifo_test(Buffer* buffer) { + + // Start of measurement + boost::timer::auto_cpu_timer progress; + + // Initialize the buffer with some values before launching producer and consumer threads. + for (unsigned long i = QUEUE_SIZE / 2L; i > 0; --i) { +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581)) + buffer->push_front(Buffer::value_type()); +#else + buffer->push_front(BOOST_DEDUCED_TYPENAME Buffer::value_type()); +#endif + } + + Consumer<Buffer> consumer(buffer); + Producer<Buffer> producer(buffer); + + // Start the threads. + boost::thread consume(consumer); + boost::thread produce(producer); + + // Wait for completion. + consume.join(); + produce.join(); + + // End of measurement +} + +int main(int /*argc*/, char* /*argv*/[]) { + + bounded_buffer<int> bb_int(QUEUE_SIZE); + std::cout << "bounded_buffer<int> "; + fifo_test(&bb_int); + + bounded_buffer_space_optimized<int> bb_space_optimized_int(QUEUE_SIZE); + std::cout << "bounded_buffer_space_optimized<int> "; + fifo_test(&bb_space_optimized_int); + + bounded_buffer_deque_based<int> bb_deque_based_int(QUEUE_SIZE); + std::cout << "bounded_buffer_deque_based<int> "; + fifo_test(&bb_deque_based_int); + + bounded_buffer_list_based<int> bb_list_based_int(QUEUE_SIZE); + std::cout << "bounded_buffer_list_based<int> "; + fifo_test(&bb_list_based_int); + + bounded_buffer<std::string> bb_string(QUEUE_SIZE); + std::cout << "bounded_buffer<std::string> "; + fifo_test(&bb_string); + + bounded_buffer_space_optimized<std::string> bb_space_optimized_string(QUEUE_SIZE); + std::cout << "bounded_buffer_space_optimized<std::string> "; + fifo_test(&bb_space_optimized_string); + + bounded_buffer_deque_based<std::string> bb_deque_based_string(QUEUE_SIZE); + std::cout << "bounded_buffer_deque_based<std::string> "; + fifo_test(&bb_deque_based_string); + + bounded_buffer_list_based<std::string> bb_list_based_string(QUEUE_SIZE); + std::cout << "bounded_buffer_list_based<std::string> "; + fifo_test(&bb_list_based_string); + + return 0; +} +/* + +//[bounded_buffer_comparison_output + + Description: Autorun "J:\Cpp\Misc\Debug\bounded_buffer_comparison.exe" + bounded_buffer<int> 5.15 s + + bounded_buffer_space_optimized<int> 5.71 s + + bounded_buffer_deque_based<int> 15.57 s + + bounded_buffer_list_based<int> 17.33 s + + bounded_buffer<std::string> 24.49 s + + bounded_buffer_space_optimized<std::string> 28.33 s + + bounded_buffer_deque_based<std::string> 29.45 s + + bounded_buffer_list_based<std::string> 31.29 s + + //] //[bounded_buffer_comparison_output] + +*/ diff --git a/src/boost/libs/circular_buffer/example/circular_buffer_bound_example.cpp b/src/boost/libs/circular_buffer/example/circular_buffer_bound_example.cpp new file mode 100644 index 000000000..b5b7c12f7 --- /dev/null +++ b/src/boost/libs/circular_buffer/example/circular_buffer_bound_example.cpp @@ -0,0 +1,192 @@ +// Copyright 2003-2008 Jan Gaspar. +// Copyright 2013 Paul A. Bristow. Added some Quickbook snippet markers. + +// Distributed under the Boost Software License, Version 1.0. +// (See the accompanying file LICENSE_1_0.txt +// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.) + +//[circular_buffer_bound_example_1 +/*` +This example shows how the `circular_buffer` can be utilized +as an underlying container of the bounded buffer. +*/ + +#include <boost/circular_buffer.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition.hpp> +#include <boost/thread/thread.hpp> +#include <boost/call_traits.hpp> +#include <boost/bind.hpp> + +#include <boost/timer/timer.hpp> // for auto_cpu_timer +#include <iostream> + +template <class T> +class bounded_buffer +{ +public: + + typedef boost::circular_buffer<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {} + + void push_front(typename boost::call_traits<value_type>::param_type item) + { // `param_type` represents the "best" way to pass a parameter of type `value_type` to a method. + + boost::mutex::scoped_lock lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_full, this)); + m_container.push_front(item); + ++m_unread; + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::mutex::scoped_lock lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_empty, this)); + *pItem = m_container[--m_unread]; + lock.unlock(); + m_not_full.notify_one(); + } + +private: + bounded_buffer(const bounded_buffer&); // Disabled copy constructor. + bounded_buffer& operator = (const bounded_buffer&); // Disabled assign operator. + + bool is_not_empty() const { return m_unread > 0; } + bool is_not_full() const { return m_unread < m_container.capacity(); } + + size_type m_unread; + container_type m_container; + boost::mutex m_mutex; + boost::condition m_not_empty; + boost::condition m_not_full; +}; // + +//] [/circular_buffer_bound_example_1] + +const unsigned long queue_size = 1000L; +const unsigned long total_elements = queue_size * 1000L; + +//[circular_buffer_bound_example_2] +/*`To demonstrate, create two classes to exercise the buffer. + +The producer class fills the buffer with elements. + +The consumer class consumes the buffer contents. + +*/ + +template<class Buffer> +class Producer +{ + + typedef typename Buffer::value_type value_type; + Buffer* m_container; + +public: + Producer(Buffer* buffer) : m_container(buffer) + {} + + void operator()() + { + for (unsigned long i = 0L; i < total_elements; ++i) + { + m_container->push_front(value_type()); + } + } +}; + +template<class Buffer> +class Consumer +{ + + typedef typename Buffer::value_type value_type; + Buffer* m_container; + value_type m_item; + +public: + Consumer(Buffer* buffer) : m_container(buffer) + {} + + void operator()() + { + for (unsigned long i = 0L; i < total_elements; ++i) + { + m_container->pop_back(&m_item); + } + } +}; + +/*`Create a first-int first-out test of the bound_buffer. +Include a call to boost::progress_timer + +[@http://www.boost.org/doc/libs/1_53_0/libs/timer/doc/cpu_timers.html CPU timer] + +*/ +template<class Buffer> +void fifo_test(Buffer* buffer) +{ + // Start of timing. + boost::timer::auto_cpu_timer progress; + + // Initialize the buffer with some values before launching producer and consumer threads. + for (unsigned long i = queue_size / 2L; i > 0; --i) + { +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581)) + buffer->push_front(Buffer::value_type()); +#else + buffer->push_front(BOOST_DEDUCED_TYPENAME Buffer::value_type()); +#endif + } + + // Construct the threads. + Consumer<Buffer> consumer(buffer); + Producer<Buffer> producer(buffer); + + // Start the threads. + boost::thread consume(consumer); + boost::thread produce(producer); + + // Wait for completion. + consume.join(); + produce.join(); + + // End of timing. + // destructor of boost::timer::auto_cpu_timer will output the time to std::cout. + +} +//] [/circular_buffer_bound_example_2] + + +int main() +{ +//[circular_buffer_bound_example_3] + //`Construct a bounded_buffer to hold the chosen type, here int. + bounded_buffer<int> bb_int(queue_size); + std::cout << "Testing bounded_buffer<int> "; + + //`Start the fifo test. + fifo_test(&bb_int); + //` destructor of boost::timer::auto_cpu_timer will output the time to std::cout + +//] [/circular_buffer_bound_example_3] + +return 0; +} // int main() + +/* + +//[circular_buffer_bound_output + + Description: Autorun "J:\Cpp\Misc\Debug\circular_buffer_bound_example.exe" + + Testing bounded_buffer<int> 15.010692s wall, 9.188459s user + 7.207246s system = 16.395705s CPU (109.2%) + +//] [/circular_buffer_bound_output] +*/ + + diff --git a/src/boost/libs/circular_buffer/example/circular_buffer_example.cpp b/src/boost/libs/circular_buffer/example/circular_buffer_example.cpp new file mode 100644 index 000000000..010074122 --- /dev/null +++ b/src/boost/libs/circular_buffer/example/circular_buffer_example.cpp @@ -0,0 +1,63 @@ +// Copyright 2003-2008 Jan Gaspar. +// Copyright 2013 Paul A. Bristow. Added some Quickbook snippet markers. + +// Distributed under the Boost Software License, Version 1.0. +// (See the accompanying file LICENSE_1_0.txt +// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.) + +//[circular_buffer_example_1 +/*`For all examples, we need this include: +*/ + +#include <boost/circular_buffer.hpp> + +//] [/circular_buffer_example_1] + + int main() + { + +//[circular_buffer_example_2 + // Create a circular buffer with a capacity for 3 integers. + boost::circular_buffer<int> cb(3); + + // Insert three elements into the buffer. + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + int a = cb[0]; // a == 1 + int b = cb[1]; // b == 2 + int c = cb[2]; // c == 3 + + // The buffer is full now, so pushing subsequent + // elements will overwrite the front-most elements. + + cb.push_back(4); // Overwrite 1 with 4. + cb.push_back(5); // Overwrite 2 with 5. + + // The buffer now contains 3, 4 and 5. + a = cb[0]; // a == 3 + b = cb[1]; // b == 4 + c = cb[2]; // c == 5 + + // Elements can be popped from either the front or the back. + cb.pop_back(); // 5 is removed. + cb.pop_front(); // 3 is removed. + + // Leaving only one element with value = 4. + int d = cb[0]; // d == 4 + +//] [/circular_buffer_example_2] + return 0; + } + + /* + + //[circular_buffer_example_output + +There is no output from this example. + +//] [/circular_buffer_example_output] + + */ + diff --git a/src/boost/libs/circular_buffer/example/circular_buffer_examples.bat b/src/boost/libs/circular_buffer/example/circular_buffer_examples.bat new file mode 100644 index 000000000..9f6c8f789 --- /dev/null +++ b/src/boost/libs/circular_buffer/example/circular_buffer_examples.bat @@ -0,0 +1,14 @@ +echo off +rem quickbook doxygen auto-index docs template circular_buffer_html_index.bat +rem echo circular_buffer_html_index_%date%_%time:~0,2%_%time:~3,2%.log +rem The DOS time format is assumed 12:34 and the : separator is not used. +set t=%time% /T +set tim=%t:~0,2%%t:~3,2% +rem pick just hours and minutes. +rem time may include leading space, like " 915", so remove space. +set tim=%tim: =% +rem boost-no-inspect +rem cd \boost-trunk/circular_buffer\libs\circular_buffer\example +bjam -a > circular_buffer_examples_%date%_%tim%.log +if not ERRORLEVEL 0 (echo Errorlevel is %ERRORLEVEL%) else (echo OK) +pause diff --git a/src/boost/libs/circular_buffer/example/circular_buffer_iter_example.cpp b/src/boost/libs/circular_buffer/example/circular_buffer_iter_example.cpp new file mode 100644 index 000000000..339d284fe --- /dev/null +++ b/src/boost/libs/circular_buffer/example/circular_buffer_iter_example.cpp @@ -0,0 +1,40 @@ +// Copyright 2003-2008 Jan Gaspar. +// Copyright 2013 Paul A. Bristow. Added some Quickbook snippet markers. + +// Distributed under the Boost Software License, Version 1.0. +// (See the accompanying file LICENSE_1_0.txt +// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.) + +#undef BOOST_CB_ENABLE_DEBUG + +//[circular_buffer_iter_example_1 +/*` +*/ + +#define BOOST_CB_ENABLE_DEBUG 0 // The Debug Support has to be disabled, otherwise the code produces a runtime error. + +#include <boost/circular_buffer.hpp> +#include <boost/assert.hpp> +#include <assert.h> + +int main(int /*argc*/, char* /*argv*/[]) +{ + + boost::circular_buffer<int> cb(3); + + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + boost::circular_buffer<int>::iterator it = cb.begin(); + + assert(*it == 1); + + cb.push_back(4); + + assert(*it == 4); // The iterator still points to the initialized memory. + + return 0; +} + +//] [/circular_buffer_iter_example_1] diff --git a/src/boost/libs/circular_buffer/example/circular_buffer_sum_example.cpp b/src/boost/libs/circular_buffer/example/circular_buffer_sum_example.cpp new file mode 100644 index 000000000..16f00174f --- /dev/null +++ b/src/boost/libs/circular_buffer/example/circular_buffer_sum_example.cpp @@ -0,0 +1,64 @@ +// Copyright 2003-2008 Jan Gaspar. +// Copyright 2013 Paul A. Bristow. Added some Quickbook snippet markers. + +// Distributed under the Boost Software License, Version 1.0. +// (See the accompanying file LICENSE_1_0.txt +// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.) + +//[circular_buffer_sum_example_1 + +/*`This example shows several functions, including summing all valid values. +*/ + + #include <boost/circular_buffer.hpp> + #include <numeric> + #include <assert.h> + + int main(int /*argc*/, char* /*argv*/[]) + { + // Create a circular buffer of capacity 3. + boost::circular_buffer<int> cb(3); + assert(cb.capacity() == 3); + // Check is empty. + assert(cb.size() == 0); + assert(cb.empty()); + + // Insert some elements into the circular buffer. + cb.push_back(1); + cb.push_back(2); + + // Assertions to check push_backs have expected effect. + assert(cb[0] == 1); + assert(cb[1] == 2); + assert(!cb.full()); + assert(cb.size() == 2); + assert(cb.capacity() == 3); + + // Insert some other elements. + cb.push_back(3); + cb.push_back(4); + + // Evaluate the sum of all elements. + int sum = std::accumulate(cb.begin(), cb.end(), 0); + + // Assertions to check state. + assert(sum == 9); + assert(cb[0] == 2); + assert(cb[1] == 3); + assert(cb[2] == 4); + assert(*cb.begin() == 2); + assert(cb.front() == 2); + assert(cb.back() == 4); + assert(cb.full()); + assert(cb.size() == 3); + assert(cb.capacity() == 3); + + return 0; + } + + //] [/circular_buffer_sum_example_1] + + + /* + There is no output from this example. + */ diff --git a/src/boost/libs/circular_buffer/example/jamfile.v2 b/src/boost/libs/circular_buffer/example/jamfile.v2 new file mode 100644 index 000000000..9a6e9e038 --- /dev/null +++ b/src/boost/libs/circular_buffer/example/jamfile.v2 @@ -0,0 +1,42 @@ +# Copyright Paul A. Bristow 2013 + +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# jamfile.v2 to run all circular_buffer examples. + +# bring in the rules for testing. +import testing ; + +project + : requirements + <library>/boost/system//boost_system + <library>/boost/thread//boost_thread + #<define>BOOST_ALL_NO_LIB=1 + <threading>multi + + <toolset>gcc:<cxxflags>-Wno-missing-braces + <toolset>darwin:<cxxflags>-Wno-missing-braces + <toolset>acc:<cxxflags>+W2068,2461,2236,4070 + <toolset>intel:<cxxflags>-Qwd264,239 + <toolset>msvc:<warnings>all + <toolset>msvc:<asynch-exceptions>on + <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE + <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE + <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS + <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS + <toolset>msvc:<cxxflags>/wd4996 + <toolset>msvc:<cxxflags>/wd4512 + <toolset>msvc:<cxxflags>/wd4610 + <toolset>msvc:<cxxflags>/wd4510 + <toolset>msvc:<cxxflags>/wd4127 + <toolset>msvc:<cxxflags>/wd4701 + <toolset>msvc:<cxxflags>/wd4127 + <toolset>msvc:<cxxflags>/wd4305 + ; + +run bounded_buffer_comparison.cpp ../../timer/build//boost_timer ; +run circular_buffer_iter_example.cpp ; +run circular_buffer_sum_example.cpp ; +run circular_buffer_bound_example.cpp ../../thread/build//boost_thread ../../timer/build//boost_timer ; + diff --git a/src/boost/libs/circular_buffer/index.html b/src/boost/libs/circular_buffer/index.html new file mode 100644 index 000000000..59018614f --- /dev/null +++ b/src/boost/libs/circular_buffer/index.html @@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" +"http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <meta http-equiv="refresh" content="0; URL=../../doc/html/circular_buffer.html"> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <title> + Redirection + </title> + </head> + <body> + Automatic redirection failed, please go to + <a href="../../doc/html/circular_buffer.html"> ../../doc/html/circular_buffer.html</a>. + <p> + <small>Copyright © 2003-2008 Jan Gaspar, 2013 Paul A. Bristow</small> + </p> + <p> + <small>Use, modification, and distribution is subject to the Boost Software License, Version 1.0.<br> + (See accompanying file <code>LICENSE_1_0.txt</code> or copy at <a href= + "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</small> + </p> + </body> +</html> + + diff --git a/src/boost/libs/circular_buffer/meta/libraries.json b/src/boost/libs/circular_buffer/meta/libraries.json new file mode 100644 index 000000000..b9f78c391 --- /dev/null +++ b/src/boost/libs/circular_buffer/meta/libraries.json @@ -0,0 +1,14 @@ +{ + "key": "circular_buffer", + "name": "Circular Buffer", + "authors": [ + "Jan Gaspar" + ], + "description": "A STL compliant container also known as ring or cyclic buffer.", + "category": [ + "Containers" + ], + "maintainers": [ + "Jan Gaspar <jano_gaspar -at- yahoo.com>" + ] +} diff --git a/src/boost/libs/circular_buffer/test/Jamfile.v2 b/src/boost/libs/circular_buffer/test/Jamfile.v2 new file mode 100644 index 000000000..7e1ae584e --- /dev/null +++ b/src/boost/libs/circular_buffer/test/Jamfile.v2 @@ -0,0 +1,32 @@ +# Boost circular_buffer test Jamfile. +# +# Copyright (c) 2003-2008 Jan Gaspar +# +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Added warning suppression Paul A. Bristow 25 Nov 2008 + +# Bring in rules for testing. +import testing ; + +project + : requirements + <toolset>msvc:<warnings>all + <toolset>msvc:<asynch-exceptions>on + <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS + <toolset>msvc:<cxxflags>/wd4996 # 'function': was declared deprecated + <toolset>msvc:<cxxflags>/wd4244 # conversion from 'int' to 'unsigned short', possible loss of data + # in date-time + ; + +test-suite "circular_buffer" + : [ run base_test.cpp : : : <threading>single : ] + [ run space_optimized_test.cpp : : : <threading>single : ] + [ run base_test.cpp : : : <threading>single <define>"BOOST_CB_ENABLE_DEBUG=1" : base_test_dbg ] + [ run space_optimized_test.cpp : : : <threading>single <define>"BOOST_CB_ENABLE_DEBUG=1" : space_optimized_test_dbg ] + [ run soft_iterator_invalidation.cpp : : : <threading>single : ] + [ run constant_erase_test.cpp : : : <threading>single : ] + [ compile bounded_buffer_comparison.cpp : <threading>multi : ] + ; diff --git a/src/boost/libs/circular_buffer/test/base_test.cpp b/src/boost/libs/circular_buffer/test/base_test.cpp new file mode 100644 index 000000000..6f51871a9 --- /dev/null +++ b/src/boost/libs/circular_buffer/test/base_test.cpp @@ -0,0 +1,862 @@ +// Test of the base circular buffer container. + +// Copyright (c) 2003-2008 Jan Gaspar +// Copyright (c) 2013 Antony Polukhin + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "test.hpp" + +#define CB_CONTAINER circular_buffer + +#include "common.ipp" + +void iterator_constructor_and_assign_test() { + + circular_buffer<MyInteger> cb(4, 3); + circular_buffer<MyInteger>::iterator it = cb.begin(); + circular_buffer<MyInteger>::iterator itCopy; + itCopy = it; + it = it; + circular_buffer<MyInteger>::const_iterator cit; + cit = it; + circular_buffer<MyInteger>::const_iterator end1 = cb.end(); + circular_buffer<MyInteger>::const_iterator end2 = end1; + + BOOST_TEST(itCopy == it); + BOOST_TEST(cit == it); + BOOST_TEST(end1 == end2); + BOOST_TEST(it != end1); + BOOST_TEST(cit != end2); +} + +void iterator_reference_test() { + + circular_buffer<Dummy> cb(3, Dummy()); + circular_buffer<Dummy>::iterator it = cb.begin(); + circular_buffer<Dummy>::const_iterator cit = cb.begin() + 1; + + BOOST_TEST((*it).m_n == Dummy::eVar); + BOOST_TEST((*it).fnc() == Dummy::eFnc); + BOOST_TEST((*cit).const_fnc() == Dummy::eConst); + BOOST_TEST((*it).virtual_fnc() == Dummy::eVirtual); + BOOST_TEST(it->m_n == Dummy::eVar); + BOOST_TEST(it->fnc() == Dummy::eFnc); + BOOST_TEST(cit->const_fnc() == Dummy::eConst); + BOOST_TEST(it->virtual_fnc() == Dummy::eVirtual); +} + +void iterator_difference_test() { + + circular_buffer<MyInteger> cb(5, 1); + cb.push_back(2); + circular_buffer<MyInteger>::iterator it1 = cb.begin() + 2; + circular_buffer<MyInteger>::iterator it2 = cb.begin() + 3; + circular_buffer<MyInteger>::const_iterator begin = cb.begin(); + circular_buffer<MyInteger>::iterator end = cb.end(); + + BOOST_TEST(begin - begin == 0); + BOOST_TEST(end - cb.begin() == 5); + BOOST_TEST(end - end == 0); + BOOST_TEST(begin - cb.end() == -5); + BOOST_TEST(it1 - cb.begin() == 2); + BOOST_TEST(it1 - begin == 2); + BOOST_TEST(end - it1 == 3); + BOOST_TEST(it2 - it1 == 1); + BOOST_TEST(it1 - it2 == -1); + BOOST_TEST(it2 - it2 == 0); +} + +void iterator_increment_test() { + + circular_buffer<MyInteger> cb(10, 1); + cb.push_back(2); + circular_buffer<MyInteger>::iterator it1 = cb.begin(); + circular_buffer<MyInteger>::iterator it2 = cb.begin() + 5; + circular_buffer<MyInteger>::iterator it3 = cb.begin() + 9; + it1++; + it2++; + ++it3; + + BOOST_TEST(it1 == cb.begin() + 1); + BOOST_TEST(it2 == cb.begin() + 6); + BOOST_TEST(it3 == cb.end()); +} + +void iterator_decrement_test() { + + circular_buffer<MyInteger> cb(10, 1); + cb.push_back(2); + circular_buffer<MyInteger>::iterator it1= cb.end(); + circular_buffer<MyInteger>::iterator it2= cb.end() - 5; + circular_buffer<MyInteger>::iterator it3= cb.end() - 9; + --it1; + it2--; + --it3; + + BOOST_TEST(it1 == cb.end() - 1); + BOOST_TEST(it2 == cb.end() - 6); + BOOST_TEST(it3 == cb.begin()); +} + +void iterator_addition_test() { + + circular_buffer<MyInteger> cb(10, 1); + cb.push_back(2); + cb.push_back(2); + circular_buffer<MyInteger>::iterator it1 = cb.begin() + 2; + circular_buffer<MyInteger>::iterator it2 = cb.end(); + circular_buffer<MyInteger>::iterator it3 = cb.begin() + 5; + circular_buffer<MyInteger>::iterator it4 = cb.begin() + 9; + it1 += 3; + it2 += 0; + it3 += 5; + it4 += -2; + + BOOST_TEST(it1 == 5 + cb.begin()); + BOOST_TEST(it2 == cb.end()); + BOOST_TEST(it3 == cb.end()); + BOOST_TEST(it4 + 3 == cb.end()); + BOOST_TEST((-3) + it4 == cb.begin() + 4); + BOOST_TEST(cb.begin() + 0 == cb.begin()); +} + +void iterator_subtraction_test() { + + circular_buffer<MyInteger> cb(10, 1); + cb.push_back(2); + cb.push_back(2); + cb.push_back(2); + circular_buffer<MyInteger>::iterator it1 = cb.begin(); + circular_buffer<MyInteger>::iterator it2 = cb.end(); + circular_buffer<MyInteger>::iterator it3 = cb.end() - 5; + circular_buffer<MyInteger>::iterator it4 = cb.begin() + 7; + it1 -= -2; + it2 -= 0; + it3 -= 5; + + BOOST_TEST(it1 == cb.begin() + 2); + BOOST_TEST(it2 == cb.end()); + BOOST_TEST(it3 == cb.begin()); + BOOST_TEST(it4 - 7 == cb.begin()); + BOOST_TEST(it4 - (-3) == cb.end()); + BOOST_TEST(cb.begin() - 0 == cb.begin()); +} + +void iterator_element_access_test() { + + circular_buffer<MyInteger> cb(10); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + cb.push_back(4); + cb.push_back(5); + cb.push_back(6); + circular_buffer<MyInteger>::iterator it = cb.begin() + 1; + + BOOST_TEST(it[0] == 2); + BOOST_TEST(it[-1] == 1); + BOOST_TEST(it[2] == 4); +} + +void iterator_comparison_test() { + + circular_buffer<MyInteger> cb(5, 1); + cb.push_back(2); + circular_buffer<MyInteger>::iterator it = cb.begin() + 2; + circular_buffer<MyInteger>::const_iterator begin = cb.begin(); + circular_buffer<MyInteger>::iterator end = cb.end(); + + BOOST_TEST(begin == begin); + BOOST_TEST(end > cb.begin()); + BOOST_TEST(begin < end); + BOOST_TEST(end > begin); + BOOST_TEST(end == end); + BOOST_TEST(begin < cb.end()); + BOOST_TEST(!(begin + 1 > cb.end())); + BOOST_TEST(it > cb.begin()); + BOOST_TEST(end > it); + BOOST_TEST(begin >= begin); + BOOST_TEST(end >= cb.begin()); + BOOST_TEST(end <= end); + BOOST_TEST(begin <= cb.end()); + BOOST_TEST(it >= cb.begin()); + BOOST_TEST(end >= it); + BOOST_TEST(!(begin + 4 < begin + 4)); + BOOST_TEST(begin + 4 < begin + 5); + BOOST_TEST(!(begin + 5 < begin + 4)); + BOOST_TEST(it < end - 1); + BOOST_TEST(!(end - 1 < it)); +} + +void iterator_invalidation_test() { + +#if BOOST_CB_ENABLE_DEBUG + + circular_buffer<MyInteger>::iterator it1; + circular_buffer<MyInteger>::const_iterator it2; + circular_buffer<MyInteger>::iterator it3; + circular_buffer<MyInteger>::const_iterator it4; + circular_buffer<MyInteger>::const_iterator it5; + circular_buffer<MyInteger>::const_iterator it6; + + BOOST_TEST(it1.is_valid(0)); + BOOST_TEST(it2.is_valid(0)); + BOOST_TEST(it3.is_valid(0)); + BOOST_TEST(it4.is_valid(0)); + BOOST_TEST(it5.is_valid(0)); + BOOST_TEST(it6.is_valid(0)); + + { + circular_buffer<MyInteger> cb(5, 0); + const circular_buffer<MyInteger> ccb(5, 0); + + it1 = cb.begin(); + it2 = ccb.begin(); + it3 = cb.end(); + it4 = it1; + it5 = it2; + it6 = it1; + + BOOST_TEST(it1.is_valid(&cb)); + BOOST_TEST(it2.is_valid(&ccb)); + BOOST_TEST(it3.is_valid(&cb)); + BOOST_TEST(it4.is_valid(&cb)); + BOOST_TEST(it5.is_valid(&ccb)); + BOOST_TEST(it6.is_valid(&cb)); + } + + BOOST_TEST(it1.is_valid(0)); + BOOST_TEST(it2.is_valid(0)); + BOOST_TEST(it3.is_valid(0)); + BOOST_TEST(it4.is_valid(0)); + BOOST_TEST(it5.is_valid(0)); + BOOST_TEST(it6.is_valid(0)); + + circular_buffer<MyInteger> cb(10, 0); + it1 = cb.end(); + cb.clear(); + BOOST_TEST(it1.is_valid(&cb)); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + int i = 0; + for (it2 = cb.begin(); it2 != it1; it2++, i++); + BOOST_TEST(i == 3); + + circular_buffer<MyInteger> cb1(10, 0); + circular_buffer<MyInteger> cb2(20, 0); + it1 = cb1.end(); + it2 = cb2.begin(); + BOOST_TEST(it1.is_valid(&cb1)); + BOOST_TEST(it2.is_valid(&cb2)); + + cb1.swap(cb2); + BOOST_TEST(!it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb2)); + + it1 = cb1.begin() + 3; + it2 = cb1.begin(); + cb1.push_back(1); + BOOST_TEST(it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb1)); + BOOST_TEST(*it2.m_it == 1); + + circular_buffer<MyInteger> cb3(5); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(4); + cb3.push_back(5); + it1 = cb3.begin() + 2; + it2 = cb3.begin(); + cb3.insert(cb3.begin() + 3, 6); + BOOST_TEST(it1.is_valid(&cb3)); + BOOST_TEST(!it2.is_valid(&cb3)); + BOOST_TEST(*it2.m_it == 5); + + it1 = cb3.begin() + 3; + it2 = cb3.end() - 1; + cb3.push_front(7); + BOOST_TEST(it1.is_valid(&cb3)); + BOOST_TEST(!it2.is_valid(&cb3)); + BOOST_TEST(*it2.m_it == 7); + + circular_buffer<MyInteger> cb4(5); + cb4.push_back(1); + cb4.push_back(2); + cb4.push_back(3); + cb4.push_back(4); + cb4.push_back(5); + it1 = cb4.begin() + 3; + it2 = cb4.begin(); + cb4.rinsert(cb4.begin() + 2, 6); + BOOST_TEST(it1.is_valid(&cb4)); + BOOST_TEST(!it2.is_valid(&cb4)); + BOOST_TEST(*it2.m_it == 2); + + it1 = cb1.begin() + 5; + it2 = cb1.end() - 1; + cb1.pop_back(); + BOOST_TEST(it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb1)); + + it1 = cb1.begin() + 5; + it2 = cb1.begin(); + cb1.pop_front(); + BOOST_TEST(it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb1)); + + circular_buffer<MyInteger> cb5(20, 0); + it1 = cb5.begin() + 5; + it2 = it3 = cb5.begin() + 15; + cb5.erase(cb5.begin() + 10); + BOOST_TEST(it1.is_valid(&cb5)); + BOOST_TEST(!it2.is_valid(&cb5)); + BOOST_TEST(!it3.is_valid(&cb5)); + + it1 = cb5.begin() + 1; + it2 = it3 = cb5.begin() + 8; + cb5.erase(cb5.begin() + 3, cb5.begin() + 7); + BOOST_TEST(it1.is_valid(&cb5)); + BOOST_TEST(!it2.is_valid(&cb5)); + BOOST_TEST(!it3.is_valid(&cb5)); + + circular_buffer<MyInteger> cb6(20, 0); + it4 = it1 = cb6.begin() + 5; + it2 = cb6.begin() + 15; + cb6.rerase(cb6.begin() + 10); + BOOST_TEST(!it1.is_valid(&cb6)); + BOOST_TEST(!it4.is_valid(&cb6)); + BOOST_TEST(it2.is_valid(&cb6)); + + it4 = it1 = cb6.begin() + 1; + it2 = cb6.begin() + 8; + cb6.rerase(cb6.begin() + 3, cb6.begin() + 7); + BOOST_TEST(!it1.is_valid(&cb6)); + BOOST_TEST(!it4.is_valid(&cb6)); + BOOST_TEST(it2.is_valid(&cb6)); + + circular_buffer<MyInteger> cb7(10, 1); + cb7.push_back(2); + cb7.push_back(3); + cb7.push_back(4); + it1 = cb7.end(); + it2 = cb7.begin(); + it3 = cb7.begin() + 6; + cb7.linearize(); + BOOST_TEST(it1.is_valid(&cb7)); + BOOST_TEST(!it2.is_valid(&cb7)); + BOOST_TEST(!it3.is_valid(&cb7)); + it1 = cb7.end(); + it2 = cb7.begin(); + it3 = cb7.begin() + 6; + cb7.linearize(); + BOOST_TEST(it1.is_valid(&cb7)); + BOOST_TEST(it2.is_valid(&cb7)); + BOOST_TEST(it3.is_valid(&cb7)); + + cb7.push_back(5); + cb7.push_back(6); + it1 = cb7.end(); + it2 = cb7.begin(); + it3 = cb7.begin() + 6; + cb7.set_capacity(10); + BOOST_TEST(it1.is_valid(&cb7)); + BOOST_TEST(it2.is_valid(&cb7)); + BOOST_TEST(it3.is_valid(&cb7)); + cb7.set_capacity(20); + BOOST_TEST(it1.is_valid(&cb7)); + BOOST_TEST(!it2.is_valid(&cb7)); + BOOST_TEST(!it3.is_valid(&cb7)); + cb7.push_back(7); + it1 = cb7.end(); + it2 = cb7.begin(); + it3 = cb7.begin() + 6; + cb7.set_capacity(10); + BOOST_TEST(it1.is_valid(&cb7)); + BOOST_TEST(!it2.is_valid(&cb7)); + BOOST_TEST(!it3.is_valid(&cb7)); + + cb7.push_back(8); + cb7.push_back(9); + it1 = cb7.end(); + it2 = cb7.begin(); + it3 = cb7.begin() + 6; + cb7.rset_capacity(10); + BOOST_TEST(it1.is_valid(&cb7)); + BOOST_TEST(it2.is_valid(&cb7)); + BOOST_TEST(it3.is_valid(&cb7)); + cb7.rset_capacity(20); + BOOST_TEST(it1.is_valid(&cb7)); + BOOST_TEST(!it2.is_valid(&cb7)); + BOOST_TEST(!it3.is_valid(&cb7)); + cb7.push_back(10); + it1 = cb7.end(); + it2 = cb7.begin(); + it3 = cb7.begin() + 6; + cb7.rset_capacity(10); + BOOST_TEST(it1.is_valid(&cb7)); + BOOST_TEST(!it2.is_valid(&cb7)); + BOOST_TEST(!it3.is_valid(&cb7)); + + circular_buffer<MyInteger> cb8(10, 1); + cb8.push_back(2); + cb8.push_back(3); + it1 = cb8.end(); + it2 = cb8.begin(); + it3 = cb8.begin() + 6; + cb8.resize(10); + BOOST_TEST(it1.is_valid(&cb8)); + BOOST_TEST(it2.is_valid(&cb8)); + BOOST_TEST(it3.is_valid(&cb8)); + cb8.resize(20); + BOOST_TEST(it1.is_valid(&cb8)); + BOOST_TEST(!it2.is_valid(&cb8)); + BOOST_TEST(!it3.is_valid(&cb8)); + cb8.push_back(4); + it1 = cb8.end(); + it2 = cb8.begin(); + it3 = cb8.begin() + 6; + it4 = cb8.begin() + 12; + cb8.resize(10); + BOOST_TEST(it1.is_valid(&cb8)); + BOOST_TEST(it2.is_valid(&cb8)); + BOOST_TEST(it3.is_valid(&cb8)); + BOOST_TEST(!it4.is_valid(&cb8)); + + cb8.set_capacity(10); + cb8.push_back(5); + cb8.push_back(6); + it1 = cb8.end(); + it2 = cb8.begin(); + it3 = cb8.begin() + 6; + cb8.rresize(10); + BOOST_TEST(it1.is_valid(&cb8)); + BOOST_TEST(it2.is_valid(&cb8)); + BOOST_TEST(it3.is_valid(&cb8)); + cb8.rresize(20); + BOOST_TEST(it1.is_valid(&cb8)); + BOOST_TEST(!it2.is_valid(&cb8)); + BOOST_TEST(!it3.is_valid(&cb8)); + cb8.push_back(7); + it1 = cb8.end(); + it2 = cb8.begin(); + it3 = cb8.begin() + 6; + it4 = cb8.begin() + 12; + cb8.rresize(10); + BOOST_TEST(it1.is_valid(&cb8)); + BOOST_TEST(!it2.is_valid(&cb8)); + BOOST_TEST(!it3.is_valid(&cb8)); + BOOST_TEST(it4.is_valid(&cb8)); + + circular_buffer<MyInteger> cb9(15, 1); + it1 = cb9.end(); + it2 = cb9.begin(); + it3 = cb9.begin() + 6; + it4 = cb9.begin() + 12; + cb9 = cb8; + BOOST_TEST(it1.is_valid(&cb9)); + BOOST_TEST(!it2.is_valid(&cb9)); + BOOST_TEST(!it3.is_valid(&cb9)); + BOOST_TEST(!it4.is_valid(&cb9)); + + circular_buffer<MyInteger> cb10(10, 1); + it1 = cb10.end(); + it2 = cb10.begin(); + it3 = cb10.begin() + 3; + it4 = cb10.begin() + 7; + cb10.assign(5, 2); + BOOST_TEST(it1.is_valid(&cb10)); + BOOST_TEST(!it2.is_valid(&cb10)); + BOOST_TEST(!it3.is_valid(&cb10)); + BOOST_TEST(!it4.is_valid(&cb10)); + + circular_buffer<MyInteger> cb11(10, 1); + it1 = cb11.end(); + it2 = cb11.begin(); + it3 = cb11.begin() + 3; + it4 = cb11.begin() + 7; + cb11.assign(15, 5, 2); + BOOST_TEST(it1.is_valid(&cb11)); + BOOST_TEST(!it2.is_valid(&cb11)); + BOOST_TEST(!it3.is_valid(&cb11)); + BOOST_TEST(!it4.is_valid(&cb11)); + + circular_buffer<MyInteger> cb12(10, 1); + it1 = cb12.end(); + it2 = cb12.begin(); + it3 = cb12.begin() + 3; + it4 = cb12.begin() + 7; + cb12.assign(cb11.begin(), cb11.end()); + BOOST_TEST(it1.is_valid(&cb12)); + BOOST_TEST(!it2.is_valid(&cb12)); + BOOST_TEST(!it3.is_valid(&cb12)); + BOOST_TEST(!it4.is_valid(&cb12)); + + circular_buffer<MyInteger> cb13(10, 1); + it1 = cb13.end(); + it2 = cb13.begin(); + it3 = cb13.begin() + 3; + it4 = cb13.begin() + 7; + cb13.assign(15, cb11.begin(), cb11.end()); + BOOST_TEST(it1.is_valid(&cb13)); + BOOST_TEST(!it2.is_valid(&cb13)); + BOOST_TEST(!it3.is_valid(&cb13)); + BOOST_TEST(!it4.is_valid(&cb13)); + + circular_buffer<MyInteger> cb14(10); + cb14.push_back(1); + cb14.push_back(2); + cb14.push_back(3); + cb14.push_back(4); + cb14.push_back(5); + cb14.push_back(6); + cb14.push_back(7); + it1 = cb14.end(); + it2 = cb14.begin() + 2; + it3 = cb14.begin() + 1; + it4 = cb14.begin() + 5; + cb14.rotate(it2); + BOOST_TEST(it1.is_valid(&cb14)); + BOOST_TEST(it2.is_valid(&cb14)); + BOOST_TEST(!it3.is_valid(&cb14)); + BOOST_TEST(it4.is_valid(&cb14)); + + circular_buffer<MyInteger> cb15(7); + cb15.push_back(1); + cb15.push_back(2); + cb15.push_back(3); + cb15.push_back(4); + cb15.push_back(5); + cb15.push_back(6); + cb15.push_back(7); + cb15.push_back(8); + cb15.push_back(9); + it1 = cb15.end(); + it2 = cb15.begin() + 2; + it3 = cb15.begin() + 1; + it4 = cb15.begin() + 5; + cb15.rotate(it3); + BOOST_TEST(it1.is_valid(&cb15)); + BOOST_TEST(it2.is_valid(&cb15)); + BOOST_TEST(it3.is_valid(&cb15)); + BOOST_TEST(it4.is_valid(&cb15)); + + circular_buffer<MyInteger> cb16(10); + cb16.push_back(1); + cb16.push_back(2); + cb16.push_back(3); + cb16.push_back(4); + cb16.push_back(5); + cb16.push_back(6); + cb16.push_back(7); + it1 = cb16.end(); + it2 = cb16.begin() + 6; + it3 = cb16.begin(); + it4 = cb16.begin() + 5; + cb16.rotate(it4); + BOOST_TEST(it1.is_valid(&cb16)); + BOOST_TEST(!it2.is_valid(&cb16)); + BOOST_TEST(it3.is_valid(&cb16)); + BOOST_TEST(!it4.is_valid(&cb16)); + +#endif // #if BOOST_CB_ENABLE_DEBUG +} + +// basic exception safety test (it is useful to use any memory-leak detection tool) +void exception_safety_test() { + +#if !defined(BOOST_NO_EXCEPTIONS) + + circular_buffer<MyInteger> cb1(3, 5); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb1.set_capacity(5), std::exception); + BOOST_TEST(cb1.capacity() == 3); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb1.rset_capacity(5), std::exception); + BOOST_TEST(cb1.capacity() == 3); + generic_test(cb1); + + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(circular_buffer<MyInteger> cb2(5, 10), std::exception); + + circular_buffer<MyInteger> cb3(5, 10); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(circular_buffer<MyInteger> cb4(cb3), std::exception); + + vector<MyInteger> v(5, MyInteger(10)); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(circular_buffer<MyInteger> cb5(8, v.begin(), v.end()), std::exception); + + circular_buffer<MyInteger> cb6(5, 10); + circular_buffer<MyInteger> cb7(8, 3); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb7 = cb6, std::exception); + BOOST_TEST(cb7.size() == 8); + BOOST_TEST(cb7.capacity() == 8); + BOOST_TEST(cb7[0] == 3); + BOOST_TEST(cb7[7] == 3); + generic_test(cb7); + + circular_buffer<MyInteger> cb8(5, 10); + MyInteger::set_exception_trigger(2); + BOOST_TEST_THROWS(cb8.push_front(1), std::exception); + + circular_buffer<MyInteger> cb9(5); + cb9.push_back(1); + cb9.push_back(2); + cb9.push_back(3); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb9.insert(cb9.begin() + 1, 4), std::exception); + + circular_buffer<MyInteger> cb10(5); + cb10.push_back(1); + cb10.push_back(2); + cb10.push_back(3); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb10.rinsert(cb10.begin() + 1, 4), std::exception); + + circular_buffer<MyInteger> cb11(5); + cb11.push_back(1); + cb11.push_back(2); + MyInteger::set_exception_trigger(2); + BOOST_TEST_THROWS(cb11.rinsert(cb11.begin(), 1), std::exception); + + circular_buffer<MyInteger> cb12(5, 1); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb12.assign(4, 2), std::exception); + + circular_buffer<MyInteger> cb13(5, 1); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb13.assign(6, 2), std::exception); + + circular_buffer<MyInteger> cb14(5); + cb14.push_back(1); + cb14.push_back(2); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb14.insert(cb14.begin(), 10, 3), std::exception); + + circular_buffer<MyInteger> cb15(5); + cb15.push_back(1); + cb15.push_back(2); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb15.insert(cb15.end(), 10, 3), std::exception); + + circular_buffer<MyInteger> cb16(5); + cb16.push_back(1); + cb16.push_back(2); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb16.rinsert(cb16.begin(), 10, 3), std::exception); + + circular_buffer<MyInteger> cb17(5); + cb17.push_back(1); + cb17.push_back(2); + MyInteger::set_exception_trigger(3); + BOOST_TEST_THROWS(cb17.rinsert(cb17.end(), 10, 3), std::exception); + + circular_buffer<MyInteger> cb18(5, 0); + cb18.push_back(1); + cb18.push_back(2); + cb18.pop_front(); + MyInteger::set_exception_trigger(4); + BOOST_TEST_THROWS(cb18.linearize(), std::exception); + + circular_buffer<MyInteger> cb19(5, 0); + cb19.push_back(1); + cb19.push_back(2); + MyInteger::set_exception_trigger(5); + BOOST_TEST_THROWS(cb19.linearize(), std::exception); + + circular_buffer<MyInteger> cb20(5, 0); + cb20.push_back(1); + cb20.push_back(2); + MyInteger::set_exception_trigger(6); + BOOST_TEST_THROWS(cb20.linearize(), std::exception); + + circular_buffer<MyInteger> cb21(5); + cb21.push_back(1); + cb21.push_back(2); + cb21.push_back(3); + MyInteger::set_exception_trigger(2); + BOOST_TEST_THROWS(cb21.insert(cb21.begin() + 1, 4), std::exception); + + circular_buffer<MyInteger> cb22(5); + cb22.push_back(1); + cb22.push_back(2); + cb22.push_back(3); + MyInteger::set_exception_trigger(2); + BOOST_TEST_THROWS(cb22.insert(cb22.end(), 4), std::exception); + + circular_buffer<MyInteger> cb23(5, 0); + MyInteger::set_exception_trigger(2); + BOOST_TEST_THROWS(cb23.insert(cb23.begin() + 1, 4), std::exception); + + circular_buffer<MyInteger> cb24(5); + cb24.push_back(1); + cb24.push_back(2); + cb24.push_back(3); + MyInteger::set_exception_trigger(2); + BOOST_TEST_THROWS(cb24.rinsert(cb24.begin() + 1, 4), std::exception); + + circular_buffer<MyInteger> cb25(5, 0); + MyInteger::set_exception_trigger(2); + BOOST_TEST_THROWS(cb25.rinsert(cb25.begin() + 3, 4), std::exception); + + circular_buffer<MyInteger> cb26(5); + cb26.push_back(1); + cb26.push_back(2); + MyInteger::set_exception_trigger(5); + BOOST_TEST_THROWS(cb26.insert(cb26.begin(), 10, 3), std::exception); + + circular_buffer<MyInteger> cb27(5); + cb27.push_back(1); + cb27.push_back(2); + MyInteger::set_exception_trigger(5); + BOOST_TEST_THROWS(cb27.insert(cb27.end(), 10, 3), std::exception); + + circular_buffer<MyInteger> cb28(5); + cb28.push_back(1); + cb28.push_back(2); + MyInteger::set_exception_trigger(5); + BOOST_TEST_THROWS(cb28.rinsert(cb28.begin(), 10, 3), std::exception); + + circular_buffer<MyInteger> cb29(5); + cb29.push_back(1); + cb29.push_back(2); + MyInteger::set_exception_trigger(5); + BOOST_TEST_THROWS(cb29.rinsert(cb29.end(), 10, 3), std::exception); + + circular_buffer<MyInteger> cb30(10); + cb30.push_back(1); + cb30.push_back(2); + cb30.push_back(3); + MyInteger::set_exception_trigger(2); + BOOST_TEST_THROWS(cb30.rinsert(cb30.begin(), 10, 3), std::exception); + +#endif // #if !defined(BOOST_NO_EXCEPTIONS) +} + + +void move_container_values_except() { + move_container_values_impl<noncopyable_movable_except_t>(); +} + +template <class T> +void move_container_values_resetting_impl() { + typedef T noncopyable_movable_test_t; + CB_CONTAINER<noncopyable_movable_test_t> cb1(1); + noncopyable_movable_test_t var; + cb1.push_back(); + + cb1.push_back(boost::move(var)); + BOOST_TEST(!cb1.back().is_moved()); + BOOST_TEST(var.is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + cb1.push_front(boost::move(var)); + BOOST_TEST(!cb1.front().is_moved()); + BOOST_TEST(var.is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + cb1.push_back(); + BOOST_TEST(!cb1.back().is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + cb1.push_front(); + BOOST_TEST(!cb1.front().is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + + cb1.insert(cb1.begin()); + // If the circular_buffer is full and the pos points to begin(), + // then the item will not be inserted. + BOOST_TEST(cb1.front().is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + cb1.insert(cb1.begin(), boost::move(var)); + // If the circular_buffer is full and the pos points to begin(), + // then the item will not be inserted. + BOOST_TEST(cb1.front().is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + cb1.rinsert(cb1.begin()); + BOOST_TEST(!cb1.back().is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + var.reinit(); + cb1.rinsert(cb1.begin(), boost::move(var)); + BOOST_TEST(!cb1.back().is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + cb1.rinsert(cb1.end()); + BOOST_TEST(cb1.back().is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + + var.reinit(); + cb1.rinsert(cb1.end(), boost::move(var)); + BOOST_TEST(cb1.back().is_moved()); + BOOST_TEST(cb1.size() == 1); + var = boost::move(cb1.back()); + BOOST_TEST(cb1.back().is_moved()); + cb1.push_back(); + BOOST_TEST(!cb1[0].is_moved()); + + const int val = cb1[0].value(); + cb1.linearize(); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(cb1[0].value() == val); + + cb1.rotate(cb1.begin()); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(cb1[0].value() == val); +} + +void move_container_values_resetting_except() { + move_container_values_resetting_impl<noncopyable_movable_except_t>(); +} + +void move_container_values_resetting_noexcept() { + move_container_values_resetting_impl<noncopyable_movable_noexcept_t>(); +} + +// test main +int main() +{ + run_common_tests(); + iterator_constructor_and_assign_test(); + iterator_reference_test(); + iterator_difference_test(); + iterator_increment_test(); + iterator_decrement_test(); + iterator_addition_test(); + iterator_subtraction_test(); + iterator_element_access_test(); + iterator_comparison_test(); + iterator_invalidation_test(); + exception_safety_test(); + move_container_values_except(); + move_container_values_resetting_except(); + move_container_values_resetting_noexcept(); + return boost::report_errors(); +} diff --git a/src/boost/libs/circular_buffer/test/bounded_buffer_comparison.cpp b/src/boost/libs/circular_buffer/test/bounded_buffer_comparison.cpp new file mode 100644 index 000000000..c2bec05df --- /dev/null +++ b/src/boost/libs/circular_buffer/test/bounded_buffer_comparison.cpp @@ -0,0 +1,316 @@ +// Comparison of bounded buffers based on different containers. + +// Copyright (c) 2003-2008 Jan Gaspar +// Copyright 2013 Paul A. Bristow. Added some Quickbook snippet markers. + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/circular_buffer.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/thread.hpp> +#include <boost/timer/timer.hpp> +#include <boost/call_traits.hpp> +#include <boost/bind.hpp> +#include <deque> +#include <list> +#include <string> +#include <iostream> + +const unsigned long QUEUE_SIZE = 1000L; +const unsigned long TOTAL_ELEMENTS = QUEUE_SIZE * 1000L; + +template <class T> +class bounded_buffer { +public: + + typedef boost::circular_buffer<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {} + + void push_front(param_type item) { + boost::unique_lock<boost::mutex> lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_full, this)); + m_container.push_front(item); + ++m_unread; + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::unique_lock<boost::mutex> lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_empty, this)); + *pItem = m_container[--m_unread]; + lock.unlock(); + m_not_full.notify_one(); + } + +private: + bounded_buffer(const bounded_buffer&); // Disabled copy constructor + bounded_buffer& operator = (const bounded_buffer&); // Disabled assign operator + + bool is_not_empty() const { return m_unread > 0; } + bool is_not_full() const { return m_unread < m_container.capacity(); } + + size_type m_unread; + container_type m_container; + boost::mutex m_mutex; + boost::condition_variable m_not_empty; + boost::condition_variable m_not_full; +}; + +template <class T> +class bounded_buffer_space_optimized { +public: + + typedef boost::circular_buffer_space_optimized<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer_space_optimized(size_type capacity) : m_container(capacity) {} + + void push_front(param_type item) { + boost::unique_lock<boost::mutex> lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer_space_optimized<value_type>::is_not_full, this)); + m_container.push_front(item); + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::unique_lock<boost::mutex> lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer_space_optimized<value_type>::is_not_empty, this)); + *pItem = m_container.back(); + m_container.pop_back(); + lock.unlock(); + m_not_full.notify_one(); + } + +private: + + bounded_buffer_space_optimized(const bounded_buffer_space_optimized&); // Disabled copy constructor + bounded_buffer_space_optimized& operator = (const bounded_buffer_space_optimized&); // Disabled assign operator + + bool is_not_empty() const { return m_container.size() > 0; } + bool is_not_full() const { return m_container.size() < m_container.capacity(); } + + container_type m_container; + boost::mutex m_mutex; + boost::condition_variable m_not_empty; + boost::condition_variable m_not_full; +}; + +template <class T> +class bounded_buffer_deque_based { +public: + + typedef std::deque<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer_deque_based(size_type capacity) : m_capacity(capacity) {} + + void push_front(param_type item) { + boost::unique_lock<boost::mutex> lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer_deque_based<value_type>::is_not_full, this)); + m_container.push_front(item); + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::unique_lock<boost::mutex> lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer_deque_based<value_type>::is_not_empty, this)); + *pItem = m_container.back(); + m_container.pop_back(); + lock.unlock(); + m_not_full.notify_one(); + } + +private: + + bounded_buffer_deque_based(const bounded_buffer_deque_based&); // Disabled copy constructor + bounded_buffer_deque_based& operator = (const bounded_buffer_deque_based&); // Disabled assign operator + + bool is_not_empty() const { return m_container.size() > 0; } + bool is_not_full() const { return m_container.size() < m_capacity; } + + const size_type m_capacity; + container_type m_container; + boost::mutex m_mutex; + boost::condition_variable m_not_empty; + boost::condition_variable m_not_full; +}; + +template <class T> +class bounded_buffer_list_based { +public: + + typedef std::list<T> container_type; + typedef typename container_type::size_type size_type; + typedef typename container_type::value_type value_type; + typedef typename boost::call_traits<value_type>::param_type param_type; + + explicit bounded_buffer_list_based(size_type capacity) : m_capacity(capacity) {} + + void push_front(param_type item) { + boost::unique_lock<boost::mutex> lock(m_mutex); + m_not_full.wait(lock, boost::bind(&bounded_buffer_list_based<value_type>::is_not_full, this)); + m_container.push_front(item); + lock.unlock(); + m_not_empty.notify_one(); + } + + void pop_back(value_type* pItem) { + boost::unique_lock<boost::mutex> lock(m_mutex); + m_not_empty.wait(lock, boost::bind(&bounded_buffer_list_based<value_type>::is_not_empty, this)); + *pItem = m_container.back(); + m_container.pop_back(); + lock.unlock(); + m_not_full.notify_one(); + } + +private: + + bounded_buffer_list_based(const bounded_buffer_list_based&); // Disabled copy constructor + bounded_buffer_list_based& operator = (const bounded_buffer_list_based&); // Disabled assign operator + + bool is_not_empty() const { return m_container.size() > 0; } + bool is_not_full() const { return m_container.size() < m_capacity; } + + const size_type m_capacity; + container_type m_container; + boost::mutex m_mutex; + boost::condition_variable m_not_empty; + boost::condition_variable m_not_full; +}; + +template<class Buffer> +class Consumer { + + typedef typename Buffer::value_type value_type; + Buffer* m_container; + value_type m_item; + +public: + Consumer(Buffer* buffer) : m_container(buffer) {} + + void operator()() { + for (unsigned long i = 0L; i < TOTAL_ELEMENTS; ++i) { + m_container->pop_back(&m_item); + } + } +}; + +template<class Buffer> +class Producer { + + typedef typename Buffer::value_type value_type; + Buffer* m_container; + +public: + Producer(Buffer* buffer) : m_container(buffer) {} + + void operator()() { + for (unsigned long i = 0L; i < TOTAL_ELEMENTS; ++i) { + m_container->push_front(value_type()); + } + } +}; + +template<class Buffer> +void fifo_test(Buffer* buffer) { + + // Start of measurement + boost::timer::auto_cpu_timer progress; + + // Initialize the buffer with some values before launching producer and consumer threads. + for (unsigned long i = QUEUE_SIZE / 2L; i > 0; --i) { +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581)) + buffer->push_front(Buffer::value_type()); +#else + buffer->push_front(BOOST_DEDUCED_TYPENAME Buffer::value_type()); +#endif + } + + Consumer<Buffer> consumer(buffer); + Producer<Buffer> producer(buffer); + + // Start the threads. + boost::thread consume(consumer); + boost::thread produce(producer); + + // Wait for completion. + consume.join(); + produce.join(); + + // End of measurement +} + +int main(int /*argc*/, char* /*argv*/[]) { + + bounded_buffer<int> bb_int(QUEUE_SIZE); + std::cout << "bounded_buffer<int> "; + fifo_test(&bb_int); + + bounded_buffer_space_optimized<int> bb_space_optimized_int(QUEUE_SIZE); + std::cout << "bounded_buffer_space_optimized<int> "; + fifo_test(&bb_space_optimized_int); + + bounded_buffer_deque_based<int> bb_deque_based_int(QUEUE_SIZE); + std::cout << "bounded_buffer_deque_based<int> "; + fifo_test(&bb_deque_based_int); + + bounded_buffer_list_based<int> bb_list_based_int(QUEUE_SIZE); + std::cout << "bounded_buffer_list_based<int> "; + fifo_test(&bb_list_based_int); + + bounded_buffer<std::string> bb_string(QUEUE_SIZE); + std::cout << "bounded_buffer<std::string> "; + fifo_test(&bb_string); + + bounded_buffer_space_optimized<std::string> bb_space_optimized_string(QUEUE_SIZE); + std::cout << "bounded_buffer_space_optimized<std::string> "; + fifo_test(&bb_space_optimized_string); + + bounded_buffer_deque_based<std::string> bb_deque_based_string(QUEUE_SIZE); + std::cout << "bounded_buffer_deque_based<std::string> "; + fifo_test(&bb_deque_based_string); + + bounded_buffer_list_based<std::string> bb_list_based_string(QUEUE_SIZE); + std::cout << "bounded_buffer_list_based<std::string> "; + fifo_test(&bb_list_based_string); + + return 0; +} +/* + +//[bounded_buffer_comparison_output + + Description: Autorun "J:\Cpp\Misc\Debug\bounded_buffer_comparison.exe" + bounded_buffer<int> 5.15 s + + bounded_buffer_space_optimized<int> 5.71 s + + bounded_buffer_deque_based<int> 15.57 s + + bounded_buffer_list_based<int> 17.33 s + + bounded_buffer<std::string> 24.49 s + + bounded_buffer_space_optimized<std::string> 28.33 s + + bounded_buffer_deque_based<std::string> 29.45 s + + bounded_buffer_list_based<std::string> 31.29 s + + //] //[bounded_buffer_comparison_output] + +*/ diff --git a/src/boost/libs/circular_buffer/test/common.ipp b/src/boost/libs/circular_buffer/test/common.ipp new file mode 100644 index 000000000..69215549e --- /dev/null +++ b/src/boost/libs/circular_buffer/test/common.ipp @@ -0,0 +1,2497 @@ +// Common tests for the circular buffer and its adaptor. + +// Copyright (c) 2003-2008 Jan Gaspar +// Copyright (c) 2013 Antony Polukhin + +// Copyright 2014,2018 Glen Joseph Fernandes +// (glenjofe@gmail.com) + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/type_traits/is_nothrow_move_constructible.hpp> +#include <boost/type_traits/is_nothrow_move_assignable.hpp> +#include <boost/type_traits/has_nothrow_constructor.hpp> + +template <class Alloc> +void generic_test(CB_CONTAINER<MyInteger, Alloc>& cb) { + + vector<int> v; + v.push_back(11); + v.push_back(12); + v.push_back(13); + v.push_back(14); + v.push_back(15); + v.push_back(16); + v.push_back(17); + + if (cb.capacity() == 0) { + + cb.insert(cb.begin(), 1); + cb.insert(cb.begin(), v.begin(), v.end()); + cb.rinsert(cb.end(), 2); + cb.rinsert(cb.end(), v.begin(), v.end()); + cb.push_back(3); + cb.push_front(4); + cb.linearize(); + + BOOST_TEST(cb.empty()); + BOOST_TEST(cb.full()); + + } else { + + cb.insert(cb.end(), 1); + BOOST_TEST(!cb.empty()); + BOOST_TEST(cb[cb.size() - 1] == 1); + + size_t size = cb.size(); + cb.rerase(cb.end() - 1, cb.end()); + BOOST_TEST(size == cb.size() + 1); + + cb.insert(cb.end(), v.begin(), v.end()); + BOOST_TEST(!cb.empty()); + BOOST_TEST(cb[cb.size() - 1] == 17); + + size = cb.size(); + cb.erase(cb.end() - 1, cb.end()); + BOOST_TEST(size == cb.size() + 1); + + size = cb.size(); + cb.rinsert(cb.begin(), 2); + BOOST_TEST(size + 1 == cb.size()); + BOOST_TEST(cb[0] == 2); + + size = cb.size(); + cb.erase(cb.begin()); + BOOST_TEST(size == cb.size() + 1); + + cb.rinsert(cb.begin(), v.begin(), v.end()); + BOOST_TEST(!cb.empty()); + BOOST_TEST(cb[0] == 11); + + size = cb.size(); + cb.pop_front(); + BOOST_TEST(size == cb.size() + 1); + + cb.push_back(3); + BOOST_TEST(!cb.empty()); + BOOST_TEST(cb[cb.size() - 1] == 3); + + size = cb.size(); + cb.pop_back(); + BOOST_TEST(size == cb.size() + 1); + + cb.push_front(4); + BOOST_TEST(!cb.empty()); + BOOST_TEST(cb[0] == 4); + + cb.linearize(); + BOOST_TEST(!cb.empty()); + BOOST_TEST(cb[0] == 4); + + size = cb.size(); + cb.rerase(cb.begin()); + BOOST_TEST(size == cb.size() + 1); + } +} + +void basic_test() { + + vector<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + v.push_back(5); + v.push_back(6); + v.push_back(7); + CB_CONTAINER<MyInteger> cb1(3, v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb2(10, v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb3(7, v.begin(), v.end()); + + BOOST_TEST(cb1.full()); + BOOST_TEST(cb1.capacity() == 3); + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1[0] == 5); + BOOST_TEST(cb1[2] == 7); + BOOST_TEST(!cb2.full()); + BOOST_TEST(cb2[2] == 3); + BOOST_TEST(cb3.full()); + BOOST_TEST(cb3[0] == 1); + BOOST_TEST(cb3[6] == 7); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); +} + +void constructor_and_element_access_test() { + + CB_CONTAINER<int> cb(5, 3); + cb[1] = 10; + + BOOST_TEST(cb.full()); + BOOST_TEST(cb[1] == 10); + BOOST_TEST(cb[4] == 3); +} + +void size_test() { + + CB_CONTAINER<MyInteger> cb1(3); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + CB_CONTAINER<MyInteger> cb2(5); + + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb2.size() == 0); + BOOST_TEST(cb1.max_size() == cb2.max_size()); + + generic_test(cb1); + generic_test(cb2); +} + +template<class T> +class my_allocator { +public: + typedef T value_type; + + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + +private: + template<class U> + struct const_pointer_; + + template<class U> + struct pointer_ { + pointer_() : hidden_ptr_(0) {} + pointer_(void* p) : hidden_ptr_(static_cast<U*>(p)) {} + difference_type operator-(const const_pointer_<U>& rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; } + difference_type operator-(pointer_ rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; } + pointer_ operator-(size_type rhs) const { return hidden_ptr_ - rhs; } + bool operator == (pointer_ rhs) const { return hidden_ptr_ == rhs.hidden_ptr_; } + bool operator != (pointer_ rhs) const { return hidden_ptr_ != rhs.hidden_ptr_; } + bool operator < (pointer_ rhs) const { return hidden_ptr_ < rhs.hidden_ptr_; } + bool operator >= (pointer_ rhs) const { return hidden_ptr_ >= rhs.hidden_ptr_; } + pointer_& operator++() { ++hidden_ptr_; return *this; } + pointer_& operator--() { --hidden_ptr_; return *this; } + pointer_& operator+=(size_type s) { hidden_ptr_ += s; return *this; } + pointer_ operator+(size_type s) const { return hidden_ptr_ + s; } + pointer_ operator++(int) { pointer_ p = *this; ++hidden_ptr_; return p; } + pointer_ operator--(int) { pointer_ p = *this; --hidden_ptr_; return p; } + U& operator*() const { return *hidden_ptr_; } + U* operator->() const { return hidden_ptr_; } + + U* hidden_ptr_; + }; + + template<class U> + struct const_pointer_ { + const_pointer_() : hidden_ptr_(0) {} + const_pointer_(pointer_<U> p) : hidden_ptr_(p.hidden_ptr_) {} + const_pointer_(const void* p) : hidden_ptr_(static_cast<const U*>(p)) {} + difference_type operator-(pointer_<U> rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; } + difference_type operator-(const_pointer_ rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; } + const_pointer_ operator-(size_type rhs) const { return hidden_ptr_ - rhs; } + bool operator == (const_pointer_ rhs) const { return hidden_ptr_ == rhs.hidden_ptr_; } + bool operator != (const_pointer_ rhs) const { return hidden_ptr_ != rhs.hidden_ptr_; } + bool operator < (const_pointer_ rhs) const { return hidden_ptr_ < rhs.hidden_ptr_; } + bool operator >= (const_pointer_ rhs) const { return hidden_ptr_ >= rhs.hidden_ptr_; } + const_pointer_& operator++() { ++hidden_ptr_; return *this; } + const_pointer_& operator--() { --hidden_ptr_; return *this; } + const_pointer_& operator+=(size_type s) { hidden_ptr_ += s; return hidden_ptr_; } + const_pointer_ operator+(size_type s) const { return hidden_ptr_ + s; } + const_pointer_ operator++(int) { const_pointer_ p = *this; ++hidden_ptr_; return p; } + const_pointer_ operator--(int) { const_pointer_ p = *this; --hidden_ptr_; return p; } + const U& operator*() const { return *hidden_ptr_; } + + const U* hidden_ptr_; + }; + +public: + typedef pointer_<T> pointer; + typedef const_pointer_<T> const_pointer; + + template<class T2> + struct rebind + { + typedef my_allocator<T2> other; + }; + + pointer allocate(size_type count) { + return pointer(::operator new(count * sizeof(value_type))); + } + + void deallocate(const pointer& ptr, size_type) + { ::operator delete(ptr.hidden_ptr_); } + + template<class P> + void construct(value_type* ptr, BOOST_FWD_REF(P) p) + { ::new((void*)ptr) value_type(::boost::forward<P>(p)); } + + void destroy(value_type* ptr) + { ptr->~value_type(); } + + size_type max_size() const { + return ~static_cast<size_type>(0) / sizeof(size_type); + } +}; + +void allocator_test() { + + CB_CONTAINER<MyInteger> cb1(10, 0); + const CB_CONTAINER<MyInteger> cb2(10, 0); + CB_CONTAINER<MyInteger>::allocator_type& alloc_ref = cb1.get_allocator(); + CB_CONTAINER<MyInteger>::allocator_type alloc = cb2.get_allocator(); + alloc_ref.max_size(); + alloc.max_size(); + + generic_test(cb1); + + + CB_CONTAINER<MyInteger, my_allocator<MyInteger> > cb_a(10, 0); + generic_test(cb_a); +} + +#if !defined(BOOST_CB_NO_CXX11_ALLOCATOR) +template<class T> +class cxx11_allocator { +public: + typedef T value_type; + + cxx11_allocator() { + } + + template<class U> + cxx11_allocator(const cxx11_allocator<U> &) { + } + + T* allocate(std::size_t n) { + return static_cast<T*>(::operator new(n * sizeof(T))); + } + + void deallocate(T * p, std::size_t n) { + ::operator delete( p ); + } +}; + +void cxx11_allocator_test() { + CB_CONTAINER<MyInteger, cxx11_allocator<MyInteger> > cb(10, 0); + generic_test(cb); +} +#endif + +void begin_and_end_test() { + + vector<int> v; + v.push_back(11); + v.push_back(12); + v.push_back(13); + + CB_CONTAINER<MyInteger> cb1(10, v.begin(), v.end()); + const CB_CONTAINER<MyInteger> cb2(10, v.begin(), v.end()); + + CB_CONTAINER<MyInteger> cb3(10); + cb3.push_back(1); + cb3.push_back(2); + cb3.insert(cb3.begin(), 3); + int i = 0; + CB_CONTAINER<MyInteger>::const_iterator it = cb3.begin(); + for (; it != cb3.end(); it++) { + i += *it; + } + CB_CONTAINER<MyInteger> cb4(20); + const CB_CONTAINER<MyInteger> cb5(20); + + BOOST_TEST(*cb1.begin() == 11); + BOOST_TEST(*cb2.begin() == 11); + BOOST_TEST(i == 6); + BOOST_TEST(cb4.begin() == cb4.end()); + BOOST_TEST(cb5.begin() == cb5.end()); + + generic_test(cb1); + generic_test(cb3); + generic_test(cb4); +} + +void rbegin_and_rend_test() { + + vector<int> v; + v.push_back(11); + v.push_back(12); + v.push_back(13); + + CB_CONTAINER<MyInteger> cb1(10, v.begin(), v.end()); + const CB_CONTAINER<MyInteger> cb2(10, v.begin(), v.end()); + + CB_CONTAINER<MyInteger> cb3(3); + cb3.push_back(1); + cb3.push_back(2); + cb3.insert(cb3.begin(), 3); + cb3.push_back(1); + int i = 0; + CB_CONTAINER<MyInteger>::reverse_iterator it = cb3.rbegin(); + for (; it != cb3.rend(); it++) { + i += *it; + } + CB_CONTAINER<MyInteger> cb4(20); + const CB_CONTAINER<MyInteger> cb5(20); + + BOOST_TEST(*cb1.rbegin() == 13); + BOOST_TEST(*cb2.rbegin() == 13); + BOOST_TEST(i == 4); + BOOST_TEST(cb4.rbegin() == cb4.rend()); + BOOST_TEST(cb5.rbegin() == cb5.rend()); + + generic_test(cb1); + generic_test(cb3); + generic_test(cb4); +} + +void element_access_and_insert_test() { + + CB_CONTAINER<MyInteger> cb(3); + cb.push_back(1); + cb.push_back(2); + cb.insert(cb.begin(), 3); + cb.push_back(4); + const CB_CONTAINER<MyInteger> ccb = cb; + + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); + BOOST_TEST(cb[2] == 4); + BOOST_TEST(ccb[2] == 4); + + generic_test(cb); +} + +void at_test() { + +#if !defined(BOOST_NO_EXCEPTIONS) + + CB_CONTAINER<MyInteger> cb(3); + cb.push_back(1); + + try { + BOOST_TEST(cb.at(0) == 1); + } + catch (out_of_range&) { + BOOST_ERROR("An unexpected exception has been thrown!"); + } + + BOOST_TEST_THROWS(cb.at(2), out_of_range); + + generic_test(cb); + +#endif // #if !defined(BOOST_NO_EXCEPTIONS) +} + +void front_and_back_test() { + + CB_CONTAINER<MyInteger> cb(1); + cb.push_back(2); + cb.push_back(3); + + BOOST_TEST(cb.front() == cb.back()); + BOOST_TEST(cb.back() == 3); + + generic_test(cb); +} + +void linearize_test() { + + vector<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + v.push_back(5); + v.push_back(6); + v.push_back(7); + v.push_back(8); + v.push_back(9); + v.push_back(10); + v.push_back(11); + v.push_back(12); + CB_CONTAINER<MyInteger> cb1(10, v.begin(), v.begin() + 10); + cb1.push_back(11); + cb1.push_back(12); + cb1.push_back(13); + CB_CONTAINER<MyInteger> cb2(10, v.begin(), v.begin() + 10); + cb2.push_back(11); + cb2.push_back(12); + cb2.push_back(13); + cb2.push_back(14); + cb2.push_back(15); + cb2.push_back(16); + cb2.push_back(17); + CB_CONTAINER<MyInteger> cb3(10, v.begin(), v.begin() + 10); + cb3.push_back(11); + cb3.push_back(12); + cb3.push_back(13); + cb3.pop_front(); + cb3.pop_front(); + CB_CONTAINER<MyInteger> cb4(5); + CB_CONTAINER<MyInteger> cb5(12, v.begin(), v.end()); + cb5.push_back(13); + cb5.push_back(14); + cb5.push_back(15); + cb5.pop_front(); + cb5.pop_front(); + cb5.pop_front(); + cb5.pop_front(); + cb5.pop_front(); + cb5.pop_front(); + CB_CONTAINER<MyInteger> cb6(6); + cb6.push_back(-2); + cb6.push_back(-1); + cb6.push_back(0); + cb6.push_back(1); + cb6.push_back(2); + cb6.push_back(3); + cb6.push_back(4); + cb6.push_back(5); + cb6.push_back(6); + cb6.pop_back(); + CB_CONTAINER<MyInteger> cb7(6); + cb7.push_back(0); + cb7.push_back(1); + cb7.push_back(2); + cb7.push_back(3); + cb7.push_back(4); + + BOOST_TEST(!cb1.is_linearized()); + BOOST_TEST(*cb1.linearize() == 4); + BOOST_TEST(cb1.is_linearized()); + BOOST_TEST(cb1.linearize() == cb1.array_one().first); + BOOST_TEST(&cb1[0] < &cb1[1] + && &cb1[1] < &cb1[2] + && &cb1[2] < &cb1[3] + && &cb1[3] < &cb1[4] + && &cb1[4] < &cb1[5] + && &cb1[5] < &cb1[6] + && &cb1[6] < &cb1[7] + && &cb1[7] < &cb1[8] + && &cb1[8] < &cb1[9]); + BOOST_TEST(*(cb1.linearize() + 1) == 5); + BOOST_TEST(*(cb1.linearize() + 2) == 6); + BOOST_TEST(*(cb1.linearize() + 3) == 7); + BOOST_TEST(*(cb1.linearize() + 4) == 8); + BOOST_TEST(*(cb1.linearize() + 5) == 9); + BOOST_TEST(*(cb1.linearize() + 6) == 10); + BOOST_TEST(*(cb1.linearize() + 7) == 11); + BOOST_TEST(*(cb1.linearize() + 8) == 12); + BOOST_TEST(*(cb1.linearize() + 9) == 13); + BOOST_TEST(!cb2.is_linearized()); + BOOST_TEST(*cb2.linearize() == 8); + BOOST_TEST(cb2.is_linearized()); + BOOST_TEST(&cb2[0] < &cb2[1] + && &cb2[1] < &cb2[2] + && &cb2[2] < &cb2[3] + && &cb2[3] < &cb2[4] + && &cb2[4] < &cb2[5] + && &cb2[5] < &cb2[6] + && &cb2[6] < &cb2[7] + && &cb2[7] < &cb2[8] + && &cb2[8] < &cb2[9]); + BOOST_TEST(*(cb2.linearize() + 1) == 9); + BOOST_TEST(*(cb2.linearize() + 2) == 10); + BOOST_TEST(*(cb2.linearize() + 3) == 11); + BOOST_TEST(*(cb2.linearize() + 4) == 12); + BOOST_TEST(*(cb2.linearize() + 5) == 13); + BOOST_TEST(*(cb2.linearize() + 6) == 14); + BOOST_TEST(*(cb2.linearize() + 7) == 15); + BOOST_TEST(*(cb2.linearize() + 8) == 16); + BOOST_TEST(*(cb2.linearize() + 9) == 17); + BOOST_TEST(cb2.is_linearized()); + BOOST_TEST(*cb3.linearize() == 6); + BOOST_TEST(cb3.is_linearized()); + BOOST_TEST(&cb3[0] < &cb3[1] + && &cb3[1] < &cb3[2] + && &cb3[2] < &cb3[3] + && &cb3[3] < &cb3[4] + && &cb3[4] < &cb3[5] + && &cb3[5] < &cb3[6] + && &cb3[6] < &cb3[7]); + BOOST_TEST(*(cb3.linearize() + 1) == 7); + BOOST_TEST(*(cb3.linearize() + 2) == 8); + BOOST_TEST(*(cb3.linearize() + 3) == 9); + BOOST_TEST(*(cb3.linearize() + 4) == 10); + BOOST_TEST(*(cb3.linearize() + 5) == 11); + BOOST_TEST(*(cb3.linearize() + 6) == 12); + BOOST_TEST(*(cb3.linearize() + 7) == 13); + BOOST_TEST(cb4.linearize() == 0); + BOOST_TEST(cb4.is_linearized()); + BOOST_TEST(*cb5.linearize() == 10); + BOOST_TEST(cb5.is_linearized()); + BOOST_TEST(&cb5[0] < &cb5[1] + && &cb5[1] < &cb5[2] + && &cb5[2] < &cb5[3] + && &cb5[3] < &cb5[4] + && &cb5[4] < &cb5[5]); + BOOST_TEST(*(cb5.linearize() + 1) == 11); + BOOST_TEST(*(cb5.linearize() + 2) == 12); + BOOST_TEST(*(cb5.linearize() + 3) == 13); + BOOST_TEST(*(cb5.linearize() + 4) == 14); + BOOST_TEST(*(cb5.linearize() + 5) == 15); + BOOST_TEST(*cb6.linearize() == 1); + BOOST_TEST(cb6.is_linearized()); + BOOST_TEST(&cb6[0] < &cb6[1] + && &cb6[1] < &cb6[2] + && &cb6[2] < &cb6[3] + && &cb6[3] < &cb6[4]); + BOOST_TEST(*(cb6.linearize() + 1) == 2); + BOOST_TEST(*(cb6.linearize() + 2) == 3); + BOOST_TEST(*(cb6.linearize() + 3) == 4); + BOOST_TEST(*(cb6.linearize() + 4) == 5); + BOOST_TEST(cb7.is_linearized()); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); + generic_test(cb5); + generic_test(cb6); + generic_test(cb7); +} + +void array_range_test() { + + CB_CONTAINER<MyInteger> cb(7); + CB_CONTAINER<MyInteger>::array_range a1 = cb.array_one(); + CB_CONTAINER<MyInteger>::array_range a2 = cb.array_two(); + CB_CONTAINER<MyInteger>::const_array_range ca1 = cb.array_one(); + CB_CONTAINER<MyInteger>::const_array_range ca2 = cb.array_two(); + + BOOST_TEST(a1.second == 0); + BOOST_TEST(a2.second == 0); + BOOST_TEST(ca1.second == 0); + BOOST_TEST(ca2.second == 0); + + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + a1 = cb.array_one(); + a2 = cb.array_two(); + ca1 = cb.array_one(); + ca2 = cb.array_two(); + + BOOST_TEST(a1.first[0] == 1); + BOOST_TEST(a1.first[2] == 3); + BOOST_TEST(ca1.first[0] == 1); + BOOST_TEST(ca1.first[2] == 3); + BOOST_TEST(a1.second == 3); + BOOST_TEST(a2.second == 0); + BOOST_TEST(ca1.second == 3); + BOOST_TEST(ca2.second == 0); + + cb.push_back(4); + cb.push_back(5); + cb.push_back(6); + cb.push_back(7); + cb.push_back(8); + cb.push_back(9); + cb.push_back(10); + a1 = cb.array_one(); + a2 = cb.array_two(); + ca1 = cb.array_one(); + ca2 = cb.array_two(); + + BOOST_TEST(a1.first[0] == 4); + BOOST_TEST(a1.first[3] == 7); + BOOST_TEST(a2.first[0] == 8); + BOOST_TEST(a2.first[2] == 10); + BOOST_TEST(ca1.first[0] == 4); + BOOST_TEST(ca1.first[3] == 7); + BOOST_TEST(ca2.first[0] == 8); + BOOST_TEST(ca2.first[2] == 10); + BOOST_TEST(a1.second == 4); + BOOST_TEST(a2.second == 3); + BOOST_TEST(ca1.second == 4); + BOOST_TEST(ca2.second == 3); + + cb.pop_front(); + cb.pop_back(); + a1 = cb.array_one(); + a2 = cb.array_two(); + ca1 = cb.array_one(); + ca2 = cb.array_two(); + + BOOST_TEST(a1.first[0] == 5); + BOOST_TEST(a1.first[2] == 7); + BOOST_TEST(a2.first[0] == 8); + BOOST_TEST(a2.first[1] == 9); + BOOST_TEST(ca1.first[0] == 5); + BOOST_TEST(ca1.first[2] == 7); + BOOST_TEST(ca2.first[0] == 8); + BOOST_TEST(ca2.first[1] == 9); + BOOST_TEST(a1.second == 3); + BOOST_TEST(a2.second == 2); + BOOST_TEST(ca1.second == 3); + BOOST_TEST(ca2.second == 2); + + cb.pop_back(); + cb.pop_back(); + cb.pop_back(); + a1 = cb.array_one(); + a2 = cb.array_two(); + ca1 = cb.array_one(); + ca2 = cb.array_two(); + + BOOST_TEST(a1.first[0] == 5); + BOOST_TEST(a1.first[1] == 6); + BOOST_TEST(ca1.first[0] == 5); + BOOST_TEST(ca1.first[1] == 6); + BOOST_TEST(a1.second == 2); + BOOST_TEST(a2.second == 0); + BOOST_TEST(ca1.second == 2); + BOOST_TEST(ca2.second == 0); + + CB_CONTAINER<MyInteger> cb0(0); + a1 = cb0.array_one(); + a2 = cb0.array_two(); + + BOOST_TEST(a1.second == 0); + BOOST_TEST(a2.second == 0); + + const CB_CONTAINER<MyInteger> ccb(10, 1); + ca1 = ccb.array_one(); + ca2 = ccb.array_two(); + + BOOST_TEST(ca1.second == 10); + BOOST_TEST(*(ca1.first) == 1); + BOOST_TEST(ca2.second == 0); + + generic_test(cb); + generic_test(cb0); +} + +void capacity_and_reserve_test() { + + CB_CONTAINER<MyInteger> cb1(0); + CB_CONTAINER<MyInteger> cb2(10); + + BOOST_TEST(cb1.capacity() == 0); + BOOST_TEST(cb1.size() == 0); + BOOST_TEST(cb1.reserve() == 0); + BOOST_TEST(cb1.full()); + BOOST_TEST(cb1.empty()); + BOOST_TEST(cb1.reserve() == cb1.capacity() - cb1.size()); + BOOST_TEST(cb2.capacity() == 10); + BOOST_TEST(cb2.size() == 0); + BOOST_TEST(cb2.reserve() == 10); + BOOST_TEST(cb2.reserve() == cb2.capacity() - cb2.size()); + + cb1.push_back(1); + cb2.push_back(2); + cb2.push_back(2); + cb2.push_back(2); + + BOOST_TEST(cb1.capacity() == 0); + BOOST_TEST(cb1.size() == 0); + BOOST_TEST(cb1.reserve() == 0); + BOOST_TEST(cb1.full()); + BOOST_TEST(cb1.empty()); + BOOST_TEST(cb1.reserve() == cb1.capacity() - cb1.size()); + BOOST_TEST(cb2.capacity() == 10); + BOOST_TEST(cb2.size() == 3); + BOOST_TEST(cb2.reserve() == 7); + BOOST_TEST(cb2.reserve() == cb2.capacity() - cb2.size()); + + generic_test(cb1); + generic_test(cb2); +} + +void full_and_empty_test() { + + CB_CONTAINER<MyInteger> cb1(10); + CB_CONTAINER<MyInteger> cb2(3); + CB_CONTAINER<MyInteger> cb3(2); + CB_CONTAINER<MyInteger> cb4(2); + cb2.push_back(1); + cb2.push_back(3); + cb2.push_back(1); + cb2.push_back(1); + cb2.push_back(1); + cb3.push_back(3); + cb3.push_back(1); + cb4.push_back(1); + + BOOST_TEST(cb1.empty()); + BOOST_TEST(cb2.full()); + BOOST_TEST(cb3.full()); + BOOST_TEST(!cb4.empty()); + BOOST_TEST(!cb4.full()); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); +} + +void set_capacity_test() { + + CB_CONTAINER<MyInteger> cb1(10); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(1); + cb1.set_capacity(5); + CB_CONTAINER<MyInteger> cb2(3); + cb2.push_back(2); + cb2.push_back(3); + cb2.push_back(1); + cb2.set_capacity(10); + CB_CONTAINER<MyInteger> cb3(5); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(1); + cb3.set_capacity(2); + + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1[0] == 2); + BOOST_TEST(cb1[2] == 1); + BOOST_TEST(cb1.capacity() == 5); + BOOST_TEST(cb2.size() == 3); + BOOST_TEST(cb2[0] == 2); + BOOST_TEST(cb2[2] == 1); + BOOST_TEST(cb2.capacity() == 10); + BOOST_TEST(cb3.size() == 2); + BOOST_TEST(cb3[0] == 2); + BOOST_TEST(cb3[1] == 3); + BOOST_TEST(cb3.capacity() == 2); + + cb3.set_capacity(2); + + BOOST_TEST(cb3.size() == 2); + BOOST_TEST(cb3[0] == 2); + BOOST_TEST(cb3[1] == 3); + BOOST_TEST(cb3.capacity() == 2); + + cb3.set_capacity(0); + + BOOST_TEST(cb3.size() == 0); + BOOST_TEST(cb3.capacity() == 0); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); +} + +void rset_capacity_test() { + + CB_CONTAINER<MyInteger> cb1(10); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(1); + cb1.rset_capacity(5); + CB_CONTAINER<MyInteger> cb2(3); + cb2.push_back(2); + cb2.push_back(3); + cb2.push_back(1); + cb2.rset_capacity(10); + CB_CONTAINER<MyInteger> cb3(5); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(1); + cb3.rset_capacity(2); + + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1[0] == 2); + BOOST_TEST(cb1[2] == 1); + BOOST_TEST(cb1.capacity() == 5); + BOOST_TEST(cb2.size() == 3); + BOOST_TEST(cb2[0] == 2); + BOOST_TEST(cb2[2] == 1); + BOOST_TEST(cb2.capacity() == 10); + BOOST_TEST(cb3.size() == 2); + BOOST_TEST(cb3[0] == 3); + BOOST_TEST(cb3[1] == 1); + BOOST_TEST(cb3.capacity() == 2); + + cb3.rset_capacity(2); + + BOOST_TEST(cb3.size() == 2); + BOOST_TEST(cb3[0] == 3); + BOOST_TEST(cb3[1] == 1); + BOOST_TEST(cb3.capacity() == 2); + + cb3.rset_capacity(0); + + BOOST_TEST(cb3.size() == 0); + BOOST_TEST(cb3.capacity() == 0); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); +} + +void resize_test() { + + CB_CONTAINER<MyInteger> cb1(10); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.resize(20, 5); + CB_CONTAINER<MyInteger> cb2(10); + cb2.push_back(1); + cb2.push_back(2); + cb2.push_back(3); + cb2.push_back(4); + cb2.resize(2); + CB_CONTAINER<MyInteger> cb3(10, 1); + cb3.resize(0); + CB_CONTAINER<MyInteger> cb4(10, 1); + cb4.resize(10); + + BOOST_TEST(cb1.size() == 20); + BOOST_TEST(cb1.capacity() == 20); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[3] == 4); + BOOST_TEST(cb1[4] == 5); + BOOST_TEST(cb1[19] == 5); + BOOST_TEST(cb2.size() == 2); + BOOST_TEST(cb2.capacity() == 10); + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2[1] == 2); + BOOST_TEST(cb3.size() == 0); + BOOST_TEST(cb3.capacity() == 10); + BOOST_TEST(cb4.size() == 10); + BOOST_TEST(cb4.capacity() == 10); + BOOST_TEST(cb4[0] == 1); + BOOST_TEST(cb4[9] == 1); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); +} + +void rresize_test() { + + CB_CONTAINER<MyInteger> cb1(10); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.rresize(20, 5); + CB_CONTAINER<MyInteger> cb2(10); + cb2.push_back(1); + cb2.push_back(2); + cb2.push_back(3); + cb2.push_back(4); + cb2.rresize(2); + CB_CONTAINER<MyInteger> cb3(10, 1); + cb3.rresize(0); + CB_CONTAINER<MyInteger> cb4(10, 1); + cb4.rresize(10); + + BOOST_TEST(cb1.size() == 20); + BOOST_TEST(cb1.capacity() == 20); + BOOST_TEST(cb1[0] == 5); + BOOST_TEST(cb1[15] == 5); + BOOST_TEST(cb1[16] == 1); + BOOST_TEST(cb1[19] == 4); + BOOST_TEST(cb2.size() == 2); + BOOST_TEST(cb2.capacity() == 10); + BOOST_TEST(cb2[0] == 3); + BOOST_TEST(cb2[1] == 4); + BOOST_TEST(cb3.size() == 0); + BOOST_TEST(cb3.capacity() == 10); + BOOST_TEST(cb4.size() == 10); + BOOST_TEST(cb4.capacity() == 10); + BOOST_TEST(cb4[0] == 1); + BOOST_TEST(cb4[9] == 1); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); +} + +void constructor_test() { + + CB_CONTAINER<MyInteger> cb0; + BOOST_TEST(cb0.capacity() == 0); + BOOST_TEST(cb0.size() == 0); + + cb0.push_back(1); + cb0.push_back(2); + cb0.push_back(3); + + BOOST_TEST(cb0.size() == 0); + BOOST_TEST(cb0.capacity() == 0); + + CB_CONTAINER<MyInteger> cb1(3); + CB_CONTAINER<MyInteger> cb2(3, 2); + vector<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + v.push_back(5); + CB_CONTAINER<MyInteger> cb3(v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb4(3, v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb5(10, v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb6(10, 3, MyInteger(2)); + + BOOST_TEST(cb1.size() == 0); + BOOST_TEST(cb1.capacity() == 3); + BOOST_TEST(cb2[0] == 2); + BOOST_TEST(cb2.full()); + BOOST_TEST(cb2[0] == 2); + BOOST_TEST(cb2[1] == 2); + BOOST_TEST(cb2[2] == 2); + BOOST_TEST(cb3.size() == 5); + BOOST_TEST(cb3.capacity() == 5); + BOOST_TEST(cb3.full()); + BOOST_TEST(cb3[0] == 1); + BOOST_TEST(cb3[4] == 5); + BOOST_TEST(cb4.size() == 3); + BOOST_TEST(cb4.capacity() == 3); + BOOST_TEST(cb4.full()); + BOOST_TEST(cb4[0] == 3); + BOOST_TEST(cb4[2] == 5); + BOOST_TEST(cb5.size() == 5); + BOOST_TEST(cb5.capacity() == 10); + BOOST_TEST(!cb5.full()); + BOOST_TEST(cb5[0] == 1); + BOOST_TEST(cb5[4] == 5); + BOOST_TEST(cb6.size() == 3); + BOOST_TEST(cb6.capacity() == 10); + BOOST_TEST(!cb6.full()); + BOOST_TEST(cb6[0] == 2); + BOOST_TEST(cb6[2] == 2); + + cb5.push_back(6); + cb6.push_back(6); + + BOOST_TEST(cb5[5] == 6); + BOOST_TEST(cb5[0] == 1); + BOOST_TEST(cb5.size() == 6); + BOOST_TEST(cb6[3] == 6); + BOOST_TEST(cb6.size() == 4); + BOOST_TEST(cb6[0] == 2); + +#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + + CB_CONTAINER<int> cb7(MyInputIterator(v.begin()), MyInputIterator(v.end())); + CB_CONTAINER<int> cb8(3, MyInputIterator(v.begin()), MyInputIterator(v.end())); + + BOOST_TEST(cb7.capacity() == 5); + BOOST_TEST(cb8.capacity() == 3); + +#endif // #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); + generic_test(cb5); + generic_test(cb6); +} + +void assign_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.push_back(5); + cb1.assign(3, 8); + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1.capacity() == 3); + BOOST_TEST(cb1[0] == 8); + BOOST_TEST(cb1[2] == 8); + + cb1.assign(6, 7); + BOOST_TEST(cb1.size() == 6); + BOOST_TEST(cb1.capacity() == 6); + BOOST_TEST(cb1[0] == 7); + BOOST_TEST(cb1[5] == 7); + + CB_CONTAINER<float> cb2(4); + cb2.assign(3, 1.1f); + BOOST_TEST(cb2[0] == 1.1f); + + CB_CONTAINER<MyInteger> cb3(5); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + cb3.assign((size_t)10, 1); // The size_t cast is not needed. It is present here just because of testing purposes. + BOOST_TEST(cb3[0] == 1); + BOOST_TEST(cb3[9] == 1); + BOOST_TEST(cb3.size() == 10); + BOOST_TEST(cb3.capacity() == 10); + +#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + + vector<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + v.push_back(5); + + CB_CONTAINER<int> cb4(3); + cb4.assign(MyInputIterator(v.begin()), MyInputIterator(v.end())); + CB_CONTAINER<int> cb5(3); + cb5.assign(4, MyInputIterator(v.begin()), MyInputIterator(v.end())); + + BOOST_TEST(cb4.capacity() == 5); + BOOST_TEST(cb5.capacity() == 4); + +#endif // #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + + generic_test(cb1); + generic_test(cb3); +} + +void copy_constructor_and_assign_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.push_back(5); + CB_CONTAINER<MyInteger> cb2 = cb1; + + BOOST_TEST(cb1 == cb2); + BOOST_TEST(cb2.capacity() == 4); + BOOST_TEST(cb2[0] == 2); + BOOST_TEST(cb2[3] == 5); + + CB_CONTAINER<MyInteger> cb3(20); + cb1.pop_back(); + CB_CONTAINER<MyInteger> cb4(3); + cb3 = cb2; + cb3 = cb3; + cb4 = cb1; + CB_CONTAINER<MyInteger> cb5 = cb1; + + BOOST_TEST(cb3 == cb2); + BOOST_TEST(cb4 == cb1); + BOOST_TEST(cb2.full()); + BOOST_TEST(cb2[0] == 2); + BOOST_TEST(cb3.full()); + BOOST_TEST(cb3.capacity() == 4); + BOOST_TEST(cb4.capacity() == 4); + BOOST_TEST(!cb4.full()); + BOOST_TEST(*(cb4.end() - 1) == 4); + BOOST_TEST(cb1 == cb5); + BOOST_TEST(cb5.capacity() == 4); + BOOST_TEST(cb2[0] == 2); + BOOST_TEST(cb2[2] == 4); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); + generic_test(cb5); +} + +void swap_test() { + + CB_CONTAINER<MyInteger> cb1(2); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + CB_CONTAINER<MyInteger> cb2(5); + cb2.push_back(8); + cb2.swap(cb1); + cb2.swap(cb2); + + BOOST_TEST(cb2.capacity() == 2); + BOOST_TEST(cb2[0] == 2); + BOOST_TEST(cb2.full()); + BOOST_TEST(cb1.capacity() == 5); + BOOST_TEST(cb1[0] == 8); + BOOST_TEST(cb1.size() == 1); + + generic_test(cb1); + generic_test(cb2); +} + +void push_back_test() { + + CB_CONTAINER<MyDefaultConstructible> cb1(5); + cb1.push_back(); + cb1.push_back(MyDefaultConstructible(2)); + BOOST_TEST(cb1[0].m_n == 1); + BOOST_TEST(cb1[1].m_n == 2); + + CB_CONTAINER<MyInteger> cb2(5); + cb2.push_back(); + BOOST_TEST(cb2.back() == CB_CONTAINER<MyInteger>::value_type()); + + cb2.push_back(1); + BOOST_TEST(cb2.back() == 1); + + generic_test(cb2); +} + +void pop_back_test() { + + CB_CONTAINER<MyInteger> cb(4); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + cb.push_back(4); + cb.push_back(5); + cb.pop_back(); + + BOOST_TEST(cb.size() == 3); + BOOST_TEST(!cb.full()); + BOOST_TEST(cb[0] == 2); + + generic_test(cb); +} + +void insert_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + CB_CONTAINER<MyInteger>::iterator it1 = cb1.begin() + 1; + it1 = cb1.insert(it1, 10); + CB_CONTAINER<MyInteger> cb2(4); + cb2.push_back(1); + cb2.insert(cb2.begin()); + cb2.insert(cb2.begin(), -1); + CB_CONTAINER<MyInteger>::iterator it2 = cb2.begin() + 1; + it2 = cb2.insert(it2, 5); + CB_CONTAINER<MyInteger> cb3(2); + cb3.insert(cb3.end(), 10); + cb3.insert(cb3.end(), 20); + cb3.insert(cb3.begin(), 30); + cb3.insert(cb3.end(), 40); + + BOOST_TEST(cb1[1] == 10); + BOOST_TEST(*it1 == 10); + BOOST_TEST(cb1.full()); + BOOST_TEST(cb2[1] == 5); + BOOST_TEST(*it2 == 5); + BOOST_TEST(cb2.full()); + BOOST_TEST(cb3[0] == 20); + BOOST_TEST(cb3[1] == 40); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); +} + +void insert_n_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.insert(cb1.begin() + 1, 2, 10); + CB_CONTAINER<MyInteger> cb2(2, 3); + cb2.insert(cb2.begin(), 10, 5); + CB_CONTAINER<MyInteger> cb3(4); + cb3.insert(cb3.end(), 1, 6); + CB_CONTAINER<MyInteger> cb4(6); + cb4.push_back(1); + cb4.push_back(2); + cb4.push_back(3); + cb4.push_back(4); + cb4.insert(cb4.begin() + 2, 5, 6); + cb4.insert(cb4.begin() + 2, 0, 7); + CB_CONTAINER<MyInteger> cb5(3); + cb5.push_back(1); + cb5.push_back(2); + cb5.pop_front(); + cb5.insert(cb5.begin(), 2, 3); + + BOOST_TEST(cb1.full()); + BOOST_TEST(cb1[0] == 10); + BOOST_TEST(cb1[1] == 10); + BOOST_TEST(cb1[2] == 2); + BOOST_TEST(cb1[3] == 3); + BOOST_TEST(cb2[0] == 3); + BOOST_TEST(cb2[1] == 3); + BOOST_TEST(cb3[0] == 6); + BOOST_TEST(cb3.size() == 1); + BOOST_TEST(cb4.size() == 6); + BOOST_TEST(cb4[0] == 6); + BOOST_TEST(cb4[1] == 6); + BOOST_TEST(cb4[2] == 6); + BOOST_TEST(cb4[3] == 6); + BOOST_TEST(cb4[4] == 3); + BOOST_TEST(cb4[5] == 4); + BOOST_TEST(cb5.size() == 3); + BOOST_TEST(cb5[0] == 3); + BOOST_TEST(cb5[1] == 3); + BOOST_TEST(cb5[2] == 2); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); + generic_test(cb5); +} + +void insert_range_test() { + + vector<int> v; + v.push_back(11); + v.push_back(12); + v.push_back(13); + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.insert(cb1.begin() + 1, v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb2(2, 2); + cb2.insert(cb2.end(), v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb3(5); + cb3.insert(cb3.end(), v.end(), v.end()); + CB_CONTAINER<MyInteger> cb4(5); + cb4.insert(cb4.end(), v.begin(), v.begin() + 1); + MyInteger array[] = { 5, 6, 7, 8, 9 }; + CB_CONTAINER<MyInteger> cb5(6); + cb5.push_back(1); + cb5.push_back(2); + cb5.push_back(3); + cb5.push_back(4); + cb5.insert(cb5.begin() + 2, array, array + 5); + cb5.insert(cb5.begin(), array, array + 5); + + BOOST_TEST(cb1.full()); + BOOST_TEST(cb1[0] == 12); + BOOST_TEST(cb1[1] == 13); + BOOST_TEST(cb1[2] == 2); + BOOST_TEST(cb1[3] == 3); + BOOST_TEST(cb2[0] == 12); + BOOST_TEST(cb2[1] == 13); + BOOST_TEST(cb3.empty()); + BOOST_TEST(cb4[0] == 11); + BOOST_TEST(cb4.size() == 1); + BOOST_TEST(cb5.size() == 6); + BOOST_TEST(cb5[0] == 6); + BOOST_TEST(cb5[1] == 7); + BOOST_TEST(cb5[2] == 8); + BOOST_TEST(cb5[3] == 9); + BOOST_TEST(cb5[4] == 3); + BOOST_TEST(cb5[5] == 4); + +#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + + v.clear(); + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + v.push_back(5); + + CB_CONTAINER<int> cb6(4); + cb6.push_back(0); + cb6.push_back(-1); + cb6.push_back(-2); + cb6.insert(cb6.begin() + 1, MyInputIterator(v.begin()), MyInputIterator(v.end())); + v.clear(); + v.push_back(11); + v.push_back(12); + v.push_back(13); + CB_CONTAINER<int> cb7(4); + cb7.push_back(1); + cb7.push_back(2); + cb7.push_back(3); + cb7.insert(cb7.begin() + 1, MyInputIterator(v.begin()), MyInputIterator(v.end())); + CB_CONTAINER<int> cb8(2, 2); + cb8.insert(cb8.end(), MyInputIterator(v.begin()), MyInputIterator(v.end())); + CB_CONTAINER<int> cb9(5); + cb9.insert(cb9.end(), MyInputIterator(v.end()), MyInputIterator(v.end())); + CB_CONTAINER<int> cb10(5); + cb10.insert(cb10.end(), MyInputIterator(v.begin()), MyInputIterator(v.begin() + 1)); + v.clear(); + v.push_back(5); + v.push_back(6); + v.push_back(7); + v.push_back(8); + v.push_back(9); + CB_CONTAINER<int> cb11(6); + cb11.push_back(1); + cb11.push_back(2); + cb11.push_back(3); + cb11.push_back(4); + cb11.insert(cb11.begin() + 2, MyInputIterator(v.begin()), MyInputIterator(v.begin() + 5)); + cb11.insert(cb11.begin(), MyInputIterator(v.begin()), MyInputIterator(v.begin() + 5)); + + BOOST_TEST(cb6.capacity() == 4); + BOOST_TEST(cb6[0] == 4); + BOOST_TEST(cb6[3] == -2); + BOOST_TEST(cb7.full()); + BOOST_TEST(cb7[0] == 12); + BOOST_TEST(cb7[1] == 13); + BOOST_TEST(cb7[2] == 2); + BOOST_TEST(cb7[3] == 3); + BOOST_TEST(cb8[0] == 12); + BOOST_TEST(cb8[1] == 13); + BOOST_TEST(cb9.empty()); + BOOST_TEST(cb10[0] == 11); + BOOST_TEST(cb10.size() == 1); + BOOST_TEST(cb11.size() == 6); + BOOST_TEST(cb11[0] == 6); + BOOST_TEST(cb11[1] == 7); + BOOST_TEST(cb11[2] == 8); + BOOST_TEST(cb11[3] == 9); + BOOST_TEST(cb11[4] == 3); + BOOST_TEST(cb11[5] == 4); + +#endif // #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); + generic_test(cb5); +} + +void push_front_test() { + + CB_CONTAINER<MyDefaultConstructible> cb1(5); + cb1.push_front(); + cb1.push_front(MyDefaultConstructible(2)); + BOOST_TEST(cb1[0].m_n == 2); + BOOST_TEST(cb1[1].m_n == 1); + + CB_CONTAINER<MyInteger> cb2(5); + cb2.push_front(); + BOOST_TEST(cb2.front() == CB_CONTAINER<MyInteger>::value_type()); + + cb2.push_front(1); + BOOST_TEST(cb2.front() == 1); + + CB_CONTAINER<MyInteger> cb3(0); + cb3.push_front(10); + BOOST_TEST(cb3.empty()); + + generic_test(cb2); + generic_test(cb3); +} + +void pop_front_test() { + + CB_CONTAINER<MyInteger> cb(4); + cb.push_front(1); + cb.push_front(2); + cb.push_front(3); + cb.push_front(4); + cb.push_front(5); + cb.pop_front(); + + BOOST_TEST(cb.size() == 3); + BOOST_TEST(!cb.full()); + BOOST_TEST(cb[0] == 4); + + generic_test(cb); +} + +void rinsert_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_front(1); + cb1.push_front(2); + cb1.push_front(3); + CB_CONTAINER<MyInteger>::iterator it1 = cb1.begin() + 1; + it1 = cb1.rinsert(it1, 10); + CB_CONTAINER<MyInteger> cb2(4); + cb2.push_front(1); + cb2.rinsert(cb2.begin()); + cb2.rinsert(cb2.begin(), -1); + CB_CONTAINER<MyInteger>::iterator it2 = cb2.end() - 2; + it2 = cb2.rinsert(it2, 5); + CB_CONTAINER<MyInteger> cb3(2); + cb3.rinsert(cb3.begin(), 10); + cb3.rinsert(cb3.begin(), 20); + cb3.rinsert(cb3.end(), 30); + cb3.rinsert(cb3.begin(), 40); + CB_CONTAINER<MyInteger> cb4(4); + cb4.push_back(1); + cb4.push_back(2); + cb4.push_back(3); + CB_CONTAINER<MyInteger>::iterator it3 = cb4.begin() + 1; + it3 = cb4.rinsert(it3, 10); + CB_CONTAINER<MyInteger> cb5(4); + cb5.push_back(1); + cb5.rinsert(cb5.begin(), 0); + cb5.rinsert(cb5.begin(), -1); + CB_CONTAINER<MyInteger>::iterator it4 = cb5.begin() + 1; + it4 = cb5.rinsert(it4, 5); + CB_CONTAINER<MyInteger> cb6(2); + cb6.rinsert(cb6.end(), 10); + cb6.rinsert(cb6.end(), 20); + cb6.rinsert(cb6.begin(), 30); + cb6.rinsert(cb6.end(), 40); + CB_CONTAINER<MyInteger> cb7(6); + cb7.push_back(1); + cb7.push_back(2); + cb7.push_back(3); + cb7.push_back(4); + cb7.rinsert(cb7.begin() + 2, 5, 6); + + BOOST_TEST(cb1[1] == 10); + BOOST_TEST(*it1 == 10); + BOOST_TEST(cb1.full()); + BOOST_TEST(cb2[1] == 5); + BOOST_TEST(*it2 == 5); + BOOST_TEST(cb2.full()); + BOOST_TEST(cb2[3] == 1); + BOOST_TEST(cb3[0] == 40); + BOOST_TEST(cb3[1] == 20); + BOOST_TEST(cb4[1] == 10); + BOOST_TEST(*it3 == 10); + BOOST_TEST(cb4.full()); + BOOST_TEST(cb5[1] == 5); + BOOST_TEST(*it4 == 5); + BOOST_TEST(cb5.full()); + BOOST_TEST(cb6[0] == 30); + BOOST_TEST(cb6[1] == 10); + BOOST_TEST(cb7.size() == 6); + BOOST_TEST(cb7[0] == 1); + BOOST_TEST(cb7[1] == 2); + BOOST_TEST(cb7[2] == 6); + BOOST_TEST(cb7[3] == 6); + BOOST_TEST(cb7[4] == 6); + BOOST_TEST(cb7[5] == 6); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); + generic_test(cb5); + generic_test(cb6); + generic_test(cb7); +} + +void rinsert_n_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_front(1); + cb1.push_front(2); + cb1.push_front(3); + cb1.rinsert(cb1.begin() + 1, 2, 10); + CB_CONTAINER<MyInteger> cb2(2, 3); + cb2.rinsert(cb2.begin(), 10, 5); + CB_CONTAINER<MyInteger> cb3(4); + cb3.rinsert(cb3.end(), 1, 6); + CB_CONTAINER<MyInteger> cb4(4); + cb4.push_back(1); + cb4.push_back(2); + cb4.push_back(3); + cb4.rinsert(cb4.begin() + 1, 2, 10); + MyInteger array[] = { 5, 6, 7, 8, 9 }; + CB_CONTAINER<MyInteger> cb5(6); + cb5.push_back(1); + cb5.push_back(2); + cb5.push_back(3); + cb5.push_back(4); + cb5.rinsert(cb5.begin() + 2, array, array + 5); + cb5.rinsert(cb5.end(), array, array + 5); + + BOOST_TEST(cb1.full()); + BOOST_TEST(cb1[0] == 3); + BOOST_TEST(cb1[1] == 10); + BOOST_TEST(cb1[2] == 10); + BOOST_TEST(cb1[3] == 2); + BOOST_TEST(cb2[0] == 5); + BOOST_TEST(cb2[1] == 5); + BOOST_TEST(cb3[0] == 6); + BOOST_TEST(cb3.size() == 1); + BOOST_TEST(cb4.full()); + BOOST_TEST(cb4[0] == 1); + BOOST_TEST(cb4[1] == 10); + BOOST_TEST(cb4[2] == 10); + BOOST_TEST(cb4[3] == 2); + BOOST_TEST(cb5.size() == 6); + BOOST_TEST(cb5[0] == 1); + BOOST_TEST(cb5[1] == 2); + BOOST_TEST(cb5[2] == 5); + BOOST_TEST(cb5[3] == 6); + BOOST_TEST(cb5[4] == 7); + BOOST_TEST(cb5[5] == 8); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); + generic_test(cb5); +} + +void rinsert_range_test() { + + vector<int> v; + v.push_back(11); + v.push_back(12); + v.push_back(13); + v.push_back(14); + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.rinsert(cb1.begin() + 1, v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb2(2, 2); + cb2.rinsert(cb2.begin(), v.begin(), v.end()); + CB_CONTAINER<MyInteger> cb3(5); + cb3.rinsert(cb3.begin(), v.end(), v.end()); + CB_CONTAINER<MyInteger> cb4(5); + cb4.rinsert(cb4.begin(), v.begin(), v.begin() + 1); + + BOOST_TEST(cb1.full()); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 11); + BOOST_TEST(cb1[2] == 12); + BOOST_TEST(cb1[3] == 13); + BOOST_TEST(cb2[0] == 11); + BOOST_TEST(cb2[1] == 12); + BOOST_TEST(cb3.empty()); + BOOST_TEST(cb4[0] == 11); + BOOST_TEST(cb4.size() == 1); + +#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + + v.clear(); + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + v.push_back(5); + + CB_CONTAINER<int> cb10(4); + cb10.push_back(0); + cb10.push_back(-1); + cb10.push_back(-2); + cb10.rinsert(cb10.begin() + 1, MyInputIterator(v.begin()), MyInputIterator(v.end())); + v.clear(); + v.push_back(11); + v.push_back(12); + v.push_back(13); + v.push_back(14); + CB_CONTAINER<int> cb11(4); + cb11.push_back(1); + cb11.push_back(2); + cb11.push_back(3); + cb11.rinsert(cb11.begin() + 1, MyInputIterator(v.begin()), MyInputIterator(v.end())); + CB_CONTAINER<int> cb12(2, 2); + cb12.rinsert(cb12.begin(), MyInputIterator(v.begin()), MyInputIterator(v.end())); + CB_CONTAINER<int> cb13(5); + cb13.rinsert(cb13.begin(), MyInputIterator(v.end()), MyInputIterator(v.end())); + CB_CONTAINER<int> cb14(5); + cb14.rinsert(cb14.begin(), MyInputIterator(v.begin()), MyInputIterator(v.begin() + 1)); + + BOOST_TEST(cb10.capacity() == 4); + BOOST_TEST(cb10[0] == 0); + BOOST_TEST(cb10[3] == 3); + BOOST_TEST(cb11.full()); + BOOST_TEST(cb11[0] == 1); + BOOST_TEST(cb11[1] == 11); + BOOST_TEST(cb11[2] == 12); + BOOST_TEST(cb11[3] == 13); + BOOST_TEST(cb12[0] == 11); + BOOST_TEST(cb12[1] == 12); + BOOST_TEST(cb13.empty()); + BOOST_TEST(cb14[0] == 11); + BOOST_TEST(cb14.size() == 1); + +#endif // #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); +} + +void erase_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + CB_CONTAINER<MyInteger>::iterator it1 = cb1.erase(cb1.begin() + 1); + + CB_CONTAINER<MyInteger> cb2(1, 1); + CB_CONTAINER<MyInteger>::iterator it2 = cb2.erase(cb2.begin()); + + CB_CONTAINER<MyInteger> cb3(4); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + CB_CONTAINER<MyInteger>::iterator it3 = cb3.erase(cb3.begin() + 2); + + BOOST_TEST(cb1.size() == 2); + BOOST_TEST(cb1.capacity() == 4); + BOOST_TEST(*it1 == 3); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 3); + BOOST_TEST(cb2.size() == 0); + BOOST_TEST(cb2.capacity() == 1); + BOOST_TEST(it2 == cb2.end()); + BOOST_TEST(cb3.size() == 2); + BOOST_TEST(cb3.capacity() == 4); + BOOST_TEST(it3 == cb3.end()); + BOOST_TEST(cb3[0] == 1); + BOOST_TEST(cb3[1] == 2); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); +} + +void erase_range_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + CB_CONTAINER<MyInteger>::iterator it1 = cb1.erase(cb1.begin() + 1, cb1.begin() + 3); + + CB_CONTAINER<MyInteger> cb2(4); + cb2.push_back(1); + cb2.push_back(2); + cb2.push_back(3); + cb2.push_back(4); + CB_CONTAINER<MyInteger>::iterator it2 = cb2.erase(cb2.begin(), cb2.begin()); + + CB_CONTAINER<MyInteger> cb3(4); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(4); + CB_CONTAINER<MyInteger>::iterator it3 = cb3.erase(cb3.begin() + 2, cb3.end()); + + CB_CONTAINER<MyInteger> cb4(10, 1); + CB_CONTAINER<MyInteger>::iterator it4 = cb4.erase(cb4.begin(), cb4.end()); + + BOOST_TEST(cb1.size() == 2); + BOOST_TEST(cb1.capacity() == 4); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 4); + BOOST_TEST(*it1 == 4); + BOOST_TEST(cb2.size() == 4); + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2[3] == 4); + BOOST_TEST(*it2 == 1); + BOOST_TEST(cb3.size() == 2); + BOOST_TEST(cb3.capacity() == 4); + BOOST_TEST(cb3[0] == 1); + BOOST_TEST(cb3[1] == 2); + BOOST_TEST(it3 == cb3.end()); + BOOST_TEST(cb4.size() == 0); + BOOST_TEST(cb4.capacity() == 10); + BOOST_TEST(it4 == cb4.end()); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); +} + +void rerase_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + CB_CONTAINER<MyInteger>::iterator it1 = cb1.rerase(cb1.begin() + 1); + + CB_CONTAINER<MyInteger> cb2(1, 1); + CB_CONTAINER<MyInteger>::iterator it2 = cb2.rerase(cb2.begin()); + + CB_CONTAINER<MyInteger> cb3(4); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + CB_CONTAINER<MyInteger>::iterator it3 = cb3.rerase(cb3.begin()); + + BOOST_TEST(cb1.size() == 2); + BOOST_TEST(cb1.capacity() == 4); + BOOST_TEST(*it1 == 1); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 3); + BOOST_TEST(cb2.size() == 0); + BOOST_TEST(cb2.capacity() == 1); + BOOST_TEST(it2 == cb2.begin()); + BOOST_TEST(cb3.size() == 2); + BOOST_TEST(cb3.capacity() == 4); + BOOST_TEST(it3 == cb3.begin()); + BOOST_TEST(*it3 == 2); + BOOST_TEST(cb3[0] == 2); + BOOST_TEST(cb3[1] == 3); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); +} + +void rerase_range_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + CB_CONTAINER<MyInteger>::iterator it1 = cb1.rerase(cb1.begin() + 1, cb1.begin() + 3); + + CB_CONTAINER<MyInteger> cb2(4); + cb2.push_back(1); + cb2.push_back(2); + cb2.push_back(3); + cb2.push_back(4); + CB_CONTAINER<MyInteger>::iterator it2 = cb2.rerase(cb2.begin(), cb2.begin()); + + CB_CONTAINER<MyInteger> cb3(4); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(4); + CB_CONTAINER<MyInteger>::iterator it3 = cb3.rerase(cb3.begin(), cb3.begin() + 2); + + CB_CONTAINER<MyInteger> cb4(10, 1); + CB_CONTAINER<MyInteger>::iterator it4 = cb4.rerase(cb4.begin(), cb4.end()); + + BOOST_TEST(cb1.size() == 2); + BOOST_TEST(cb1.capacity() == 4); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 4); + BOOST_TEST(*it1 == 1); + BOOST_TEST(cb2.size() == 4); + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2[3] == 4); + BOOST_TEST(*it2 == 1); + BOOST_TEST(cb3.size() == 2); + BOOST_TEST(cb3.capacity() == 4); + BOOST_TEST(cb3[0] == 3); + BOOST_TEST(cb3[1] == 4); + BOOST_TEST(it3 == cb3.begin()); + BOOST_TEST(cb4.size() == 0); + BOOST_TEST(cb4.capacity() == 10); + BOOST_TEST(it4 == cb4.begin()); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); +} + +void clear_test() { + + CB_CONTAINER<MyInteger> cb(4); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + cb.push_back(4); + cb.clear(); + + BOOST_TEST(cb.empty()); + + generic_test(cb); +} + +void equality_test() { + + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + CB_CONTAINER<MyInteger> cb2(10); + cb2.push_back(1); + cb2.push_back(2); + cb2.push_back(3); + cb2.push_back(4); + + BOOST_TEST(cb1 == cb2); + BOOST_TEST(!(cb2 != cb1)); + + generic_test(cb1); + generic_test(cb2); +} + +void lexicographical_comparison_test() { + + CB_CONTAINER<char> cb1(10); + cb1.push_back('a'); + cb1.push_back('d'); + cb1.push_back('a'); + cb1.push_back('m'); + CB_CONTAINER<char> cb2(5); + cb2.push_back('j'); + cb2.push_back('o'); + cb2.push_back('h'); + cb2.push_back('n'); + + BOOST_TEST(cb2 > cb1); + BOOST_TEST(cb1 < cb2); +} + +void assign_range_test() { + + vector<int> v; + v.push_back(11); + v.push_back(12); + v.push_back(13); + CB_CONTAINER<MyInteger> cb1(4); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.assign(v.begin() + 1, v.end()); + CB_CONTAINER<MyInteger> cb2(2); + cb2.push_back(1); + cb2.push_back(2); + cb2.assign(v.begin(), v.end()); + + BOOST_TEST(cb1.capacity() == 2); + BOOST_TEST(cb1[0] == 12); + BOOST_TEST(cb1[1] == 13); + BOOST_TEST(cb2.full()); + BOOST_TEST(cb2.capacity() == 3); + BOOST_TEST(cb2[0] == 11); + BOOST_TEST(cb2[1] == 12); + BOOST_TEST(cb2[2] == 13); + BOOST_TEST(cb2.size() == (size_t)distance(v.begin(), v.end())); + + generic_test(cb1); + generic_test(cb2); +} + +// test of the example (introduced in the documentation) +void example_test() { + + CB_CONTAINER<int> cb1(3); + cb1.push_back(1); + cb1.push_back(2); + + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 2); + BOOST_TEST(!cb1.full()); + BOOST_TEST(cb1.size() == 2); + BOOST_TEST(cb1.capacity() == 3); + + cb1.push_back(3); + cb1.push_back(4); + int sum = accumulate(cb1.begin(), cb1.end(), 0); + + BOOST_TEST(cb1[0] == 2); + BOOST_TEST(cb1[1] == 3); + BOOST_TEST(cb1[2] == 4); + BOOST_TEST(*cb1.begin() == 2); + BOOST_TEST(cb1.front() == 2); + BOOST_TEST(cb1.back() == 4); + BOOST_TEST(sum == 9); + BOOST_TEST(cb1.full()); + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1.capacity() == 3); + + CB_CONTAINER<int> cb2(5, 1); + cb2.insert(cb2.begin(), 2); + + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2[1] == 1); + BOOST_TEST(cb2[2] == 1); + BOOST_TEST(cb2[3] == 1); + BOOST_TEST(cb2[4] == 1); + + vector<int> v; + v.push_back(100); + v.push_back(200); + v.push_back(300); + cb2.insert(cb2.begin() + 1, v.begin(), v.end()); + + BOOST_TEST(cb2[0] == 300); + BOOST_TEST(cb2[1] == 1); + BOOST_TEST(cb2[2] == 1); + BOOST_TEST(cb2[3] == 1); + BOOST_TEST(cb2[4] == 1); + + CB_CONTAINER<int> cb3(3); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + + BOOST_TEST(cb3[0] == 1); + BOOST_TEST(cb3[1] == 2); + BOOST_TEST(cb3[2] == 3); + + cb3.push_back(4); + cb3.push_back(5); + + BOOST_TEST(cb3[0] == 3); + BOOST_TEST(cb3[1] == 4); + BOOST_TEST(cb3[2] == 5); + + cb3.pop_back(); + cb3.pop_front(); + + BOOST_TEST(cb3[0] == 4); +} + +void element_destruction_test() { + + CB_CONTAINER<InstanceCounter> cb(5); + cb.push_back(InstanceCounter()); + cb.push_back(InstanceCounter()); + cb.push_back(InstanceCounter()); + int prevCount = InstanceCounter::count(); + cb.clear(); + + BOOST_TEST(cb.empty()); + BOOST_TEST(prevCount == 3); + BOOST_TEST(InstanceCounter::count() == 0); +} + +void const_methods_test() { + + vector<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + v.push_back(5); + const CB_CONTAINER<MyInteger> cb(5, v.begin(), v.end()); + + BOOST_TEST(*cb.begin() == 1); + BOOST_TEST(*(cb.end() - 1) == 5); + BOOST_TEST(*cb.rbegin() == 5); + BOOST_TEST(*(cb.rend() - 1) == 1); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb.at(1) == 2); + BOOST_TEST(cb.front() == 1); + BOOST_TEST(cb.back() == 5); +} + +void rotate_test() { + + CB_CONTAINER<MyInteger> cb1(10); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.push_back(5); + cb1.push_back(6); + cb1.push_back(7); + CB_CONTAINER<MyInteger> cb2 = cb1; + CB_CONTAINER<MyInteger>::iterator it1 = cb1.begin() + 2; + int v1_0 = *it1; + int v1_1 = *(it1 + 1); + int v1_2 = *(it1 + 2); + int v1_3 = *(it1 + 3); + int v1_4 = *(it1 + 4); + int v1_r1 = *(it1 - 1); + int v1_r2 = *(it1 - 2); + cb1.rotate(it1); + rotate(cb2.begin(), cb2.begin() + 2, cb2.end()); + + CB_CONTAINER<MyInteger> cb3(7); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(4); + cb3.push_back(5); + cb3.push_back(6); + cb3.push_back(7); + cb3.push_back(8); + cb3.push_back(9); + CB_CONTAINER<MyInteger> cb4 = cb3; + CB_CONTAINER<MyInteger>::iterator it2 = cb3.begin() + 1; + int v2_0 = *it2; + int v2_1 = *(it2 + 1); + int v2_2 = *(it2 + 2); + int v2_3 = *(it2 + 3); + int v2_4 = *(it2 + 4); + int v2_5 = *(it2 + 5); + int v2_r1 = *(it2 - 1); + cb3.rotate(it2); + rotate(cb4.begin(), cb4.begin() + 1, cb4.end()); + + CB_CONTAINER<MyInteger> cb5(10); + cb5.push_back(1); + cb5.push_back(2); + cb5.push_back(3); + cb5.push_back(4); + cb5.push_back(5); + cb5.push_back(6); + cb5.push_back(7); + CB_CONTAINER<MyInteger> cb6 = cb5; + CB_CONTAINER<MyInteger>::iterator it3 = cb5.begin() + 5; + int v3_0 = *it3; + int v3_1 = *(it3 + 1); + int v3_r1 = *(it3 - 1); + int v3_r2 = *(it3 - 2); + int v3_r3 = *(it3 - 3); + int v3_r4 = *(it3 - 4); + int v3_r5 = *(it3 - 5); + cb5.rotate(it3); + rotate(cb6.begin(), cb6.begin() + 5, cb6.end()); + + BOOST_TEST(!cb1.full()); + BOOST_TEST(cb1 == cb2); + BOOST_TEST(v1_0 == *it1); + BOOST_TEST(v1_1 == *(it1 + 1)); + BOOST_TEST(v1_2 == *(it1 + 2)); + BOOST_TEST(v1_3 == *(it1 + 3)); + BOOST_TEST(v1_4 == *(it1 + 4)); + BOOST_TEST(v1_r1 == *(it1 + 6)); + BOOST_TEST(v1_r2 == *(it1 + 5)); + BOOST_TEST(cb1.begin() == it1); + BOOST_TEST(v1_0 == cb1[0]); + BOOST_TEST(v1_1 == cb1[1]); + BOOST_TEST(v1_2 == cb1[2]); + BOOST_TEST(v1_3 == cb1[3]); + BOOST_TEST(v1_4 == cb1[4]); + BOOST_TEST(v1_r1 == cb1[6]); + BOOST_TEST(v1_r2 == cb1[5]); + BOOST_TEST(cb3.full()); + BOOST_TEST(cb3 == cb4); + BOOST_TEST(v2_0 == *it2); + BOOST_TEST(v2_1 == *(it2 + 1)); + BOOST_TEST(v2_2 == *(it2 + 2)); + BOOST_TEST(v2_3 == *(it2 + 3)); + BOOST_TEST(v2_4 == *(it2 + 4)); + BOOST_TEST(v2_5 == *(it2 + 5)); + BOOST_TEST(v2_r1 == *(it2 + 6)); + BOOST_TEST(cb3.begin() == it2); + BOOST_TEST(v2_0 == cb3[0]); + BOOST_TEST(v2_1 == cb3[1]); + BOOST_TEST(v2_2 == cb3[2]); + BOOST_TEST(v2_3 == cb3[3]); + BOOST_TEST(v2_4 == cb3[4]); + BOOST_TEST(v2_5 == cb3[5]); + BOOST_TEST(v2_r1 == cb3[6]); + BOOST_TEST(!cb5.full()); + BOOST_TEST(cb5 == cb6); + BOOST_TEST(v3_0 == cb5[0]); + BOOST_TEST(v3_1 == cb5[1]); + BOOST_TEST(v3_r1 == cb5[6]); + BOOST_TEST(v3_r2 == cb5[5]); + BOOST_TEST(v3_r3 == cb5[4]); + BOOST_TEST(v3_r4 == cb5[3]); + BOOST_TEST(v3_r5 == cb5[2]); + + generic_test(cb1); + generic_test(cb2); + generic_test(cb3); + generic_test(cb4); + generic_test(cb5); + generic_test(cb6); +} + +int MyInteger::ms_exception_trigger = 0; +int InstanceCounter::ms_count = 0; + +void move_container_on_cpp11() { +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + CB_CONTAINER<MyInteger> cb1(10); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.push_back(5); + cb1.push_back(6); + + // Checking move constructor + CB_CONTAINER<MyInteger> cb2(static_cast<CB_CONTAINER<MyInteger>&& >(cb1)); + CB_CONTAINER<MyInteger>::iterator it2 = cb2.begin() + 1; + + BOOST_TEST(cb1.empty()); + BOOST_TEST(!cb2.empty()); + BOOST_TEST(it2[0] == 2); + BOOST_TEST(it2[-1] == 1); + BOOST_TEST(it2[2] == 4); + + // Checking move assignment + cb1 = static_cast<CB_CONTAINER<MyInteger>&& >(cb2); + CB_CONTAINER<MyInteger>::iterator it1 = cb1.begin() + 1; + + BOOST_TEST(!cb1.empty()); + BOOST_TEST(cb2.empty()); + BOOST_TEST(it1[0] == 2); + BOOST_TEST(it1[-1] == 1); + BOOST_TEST(it1[2] == 4); +#endif +} + + +struct noncopyable_movable_except_t +{ +private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(noncopyable_movable_except_t) + bool is_moved_; + int value_; +public: + static int next_value; + + explicit noncopyable_movable_except_t() + : is_moved_(false) + , value_(next_value ++) + {} + + noncopyable_movable_except_t(BOOST_RV_REF(noncopyable_movable_except_t) x) { + is_moved_ = x.is_moved_; + value_ = x.value_; + x.is_moved_ = true; + } + + noncopyable_movable_except_t& operator=(BOOST_RV_REF(noncopyable_movable_except_t) x) { + is_moved_ = x.is_moved_; + value_ = x.value_; + x.is_moved_ = true; + return *this; + } + + bool is_moved() const { + return is_moved_; + } + + int value() const { + return value_; + } + + void reinit() { is_moved_ = false; value_ = next_value ++; } +}; + +struct noncopyable_movable_noexcept_t +{ +private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(noncopyable_movable_noexcept_t) + bool is_moved_; + int value_; +public: + static int next_value; + + explicit noncopyable_movable_noexcept_t() + : is_moved_(false) + , value_(next_value ++) + {} + + noncopyable_movable_noexcept_t(BOOST_RV_REF(noncopyable_movable_noexcept_t) x) BOOST_NOEXCEPT { + is_moved_ = x.is_moved_; + value_ = x.value_; + x.is_moved_ = true; + } + + noncopyable_movable_noexcept_t& operator=(BOOST_RV_REF(noncopyable_movable_noexcept_t) x) BOOST_NOEXCEPT { + is_moved_ = x.is_moved_; + value_ = x.value_; + x.is_moved_ = true; + return *this; + } + + bool is_moved() const { + return is_moved_; + } + + int value() const { + return value_; + } + + void reinit() { is_moved_ = false; value_ = next_value ++; } +}; + +#if defined(BOOST_NO_CXX11_NOEXCEPT) || !defined(BOOST_IS_NOTHROW_MOVE_CONSTRUCT) +namespace boost { + template <> + struct is_nothrow_move_constructible<noncopyable_movable_noexcept_t> + : boost::true_type + {}; +} +#endif + +int noncopyable_movable_noexcept_t::next_value = 1; +int noncopyable_movable_except_t::next_value = 1; + +template <class T> +void move_container_values_impl() { + typedef T noncopyable_movable_test_t; + noncopyable_movable_test_t::next_value = 1; + + CB_CONTAINER<noncopyable_movable_test_t> cb1(40); + noncopyable_movable_test_t var; + cb1.push_back(boost::move(var)); + BOOST_TEST(!cb1.back().is_moved()); + BOOST_TEST(cb1.back().value() == 1); + BOOST_TEST(var.is_moved()); + BOOST_TEST(cb1.size() == 1); + + var.reinit(); + cb1.push_front(boost::move(var)); + BOOST_TEST(!cb1.front().is_moved()); + BOOST_TEST(cb1.front().value() == 2); + BOOST_TEST(var.is_moved()); + BOOST_TEST(cb1.size() == 2); + + cb1.push_back(); + BOOST_TEST(!cb1.back().is_moved()); + BOOST_TEST(cb1.back().value() == 3); + BOOST_TEST(cb1.size() == 3); + + cb1.push_front(); + BOOST_TEST(!cb1.front().is_moved()); + BOOST_TEST(cb1.front().value() == 4); + BOOST_TEST(cb1.size() == 4); + + cb1.insert(cb1.begin()); + BOOST_TEST(!cb1.front().is_moved()); + BOOST_TEST(cb1.front().value() == 5); + BOOST_TEST(cb1.size() == 5); + + var.reinit(); + cb1.insert(cb1.begin(), boost::move(var)); + BOOST_TEST(!cb1.front().is_moved()); + BOOST_TEST(cb1.front().value() == 6); + BOOST_TEST(cb1.size() == 6); + + cb1.rinsert(cb1.begin()); + BOOST_TEST(!cb1.front().is_moved()); + BOOST_TEST(cb1.front().value() == 7); + BOOST_TEST(cb1.size() == 7); + + var.reinit(); + cb1.rinsert(cb1.begin(), boost::move(var)); + BOOST_TEST(!cb1.front().is_moved()); + BOOST_TEST(cb1.front().value() == 8); + BOOST_TEST(cb1.size() == 8); + + + BOOST_TEST(cb1[0].value() == 8); + BOOST_TEST(cb1[1].value() == 7); + BOOST_TEST(cb1[2].value() == 6); + BOOST_TEST(cb1[3].value() == 5); + BOOST_TEST(cb1[4].value() == 4); + BOOST_TEST(cb1[5].value() == 2); + BOOST_TEST(cb1[6].value() == 1); + BOOST_TEST(cb1[7].value() == 3); + cb1.rotate(cb1.begin() + 2); + BOOST_TEST(cb1[0].value() == 6); + BOOST_TEST(cb1[1].value() == 5); + BOOST_TEST(cb1[2].value() == 4); + BOOST_TEST(cb1[3].value() == 2); + BOOST_TEST(cb1[4].value() == 1); + BOOST_TEST(cb1[5].value() == 3); + BOOST_TEST(cb1[6].value() == 8); + BOOST_TEST(cb1[7].value() == 7); + + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(!cb1[2].is_moved()); + BOOST_TEST(!cb1[3].is_moved()); + BOOST_TEST(!cb1[4].is_moved()); + BOOST_TEST(!cb1[5].is_moved()); + BOOST_TEST(!cb1[6].is_moved()); + BOOST_TEST(!cb1[7].is_moved()); + + cb1.linearize(); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(!cb1[2].is_moved()); + BOOST_TEST(!cb1[3].is_moved()); + BOOST_TEST(!cb1[4].is_moved()); + BOOST_TEST(!cb1[5].is_moved()); + BOOST_TEST(!cb1[6].is_moved()); + BOOST_TEST(!cb1[7].is_moved()); + BOOST_TEST(cb1[0].value() == 6); + BOOST_TEST(cb1[1].value() == 5); + BOOST_TEST(cb1[2].value() == 4); + BOOST_TEST(cb1[3].value() == 2); + BOOST_TEST(cb1[4].value() == 1); + BOOST_TEST(cb1[5].value() == 3); + BOOST_TEST(cb1[6].value() == 8); + BOOST_TEST(cb1[7].value() == 7); + + cb1.erase(cb1.begin()); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(!cb1[2].is_moved()); + BOOST_TEST(!cb1[3].is_moved()); + BOOST_TEST(!cb1[4].is_moved()); + BOOST_TEST(!cb1[5].is_moved()); + BOOST_TEST(!cb1[6].is_moved()); + BOOST_TEST(cb1[0].value() == 5); + BOOST_TEST(cb1[1].value() == 4); + BOOST_TEST(cb1[2].value() == 2); + BOOST_TEST(cb1[3].value() == 1); + BOOST_TEST(cb1[4].value() == 3); + BOOST_TEST(cb1[5].value() == 8); + BOOST_TEST(cb1[6].value() == 7); + + cb1.rerase(cb1.begin()); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(!cb1[2].is_moved()); + BOOST_TEST(!cb1[3].is_moved()); + BOOST_TEST(!cb1[4].is_moved()); + BOOST_TEST(!cb1[5].is_moved()); + BOOST_TEST(cb1[0].value() == 4); + BOOST_TEST(cb1[1].value() == 2); + BOOST_TEST(cb1[2].value() == 1); + BOOST_TEST(cb1[3].value() == 3); + BOOST_TEST(cb1[4].value() == 8); + BOOST_TEST(cb1[5].value() == 7); + + cb1.erase(cb1.begin(), cb1.begin() + 1); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(!cb1[2].is_moved()); + BOOST_TEST(!cb1[3].is_moved()); + BOOST_TEST(!cb1[4].is_moved()); + BOOST_TEST(cb1[0].value() == 2); + BOOST_TEST(cb1[1].value() == 1); + BOOST_TEST(cb1[2].value() == 3); + BOOST_TEST(cb1[3].value() == 8); + BOOST_TEST(cb1[4].value() == 7); + + cb1.rerase(cb1.begin(), cb1.begin() + 1); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(!cb1[2].is_moved()); + BOOST_TEST(!cb1[3].is_moved()); + BOOST_TEST(cb1[0].value() == 1); + BOOST_TEST(cb1[1].value() == 3); + BOOST_TEST(cb1[2].value() == 8); + BOOST_TEST(cb1[3].value() == 7); +} + +void move_container_values_noexcept() { + move_container_values_impl<noncopyable_movable_noexcept_t>(); + + typedef noncopyable_movable_noexcept_t noncopyable_movable_test_t; + noncopyable_movable_test_t::next_value = 1; + CB_CONTAINER<noncopyable_movable_test_t> cb1(40); + cb1.push_back(); + cb1.push_back(); + cb1.push_back(); + cb1.push_back(); + cb1.push_back(); + cb1.push_back(); + cb1.push_back(); + cb1.push_back(); + + cb1.set_capacity(100); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(!cb1[2].is_moved()); + BOOST_TEST(!cb1[3].is_moved()); + BOOST_TEST(!cb1[4].is_moved()); + BOOST_TEST(!cb1[5].is_moved()); + BOOST_TEST(!cb1[6].is_moved()); + BOOST_TEST(!cb1[7].is_moved()); + BOOST_TEST(cb1[0].value() == 1); + BOOST_TEST(cb1[1].value() == 2); + BOOST_TEST(cb1[2].value() == 3); + BOOST_TEST(cb1[3].value() == 4); + BOOST_TEST(cb1[4].value() == 5); + BOOST_TEST(cb1[5].value() == 6); + BOOST_TEST(cb1[6].value() == 7); + BOOST_TEST(cb1[7].value() == 8); + + cb1.rset_capacity(101); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(!cb1[2].is_moved()); + BOOST_TEST(!cb1[3].is_moved()); + BOOST_TEST(!cb1[4].is_moved()); + BOOST_TEST(!cb1[5].is_moved()); + BOOST_TEST(!cb1[6].is_moved()); + BOOST_TEST(!cb1[7].is_moved()); + BOOST_TEST(cb1[0].value() == 1); + BOOST_TEST(cb1[1].value() == 2); + BOOST_TEST(cb1[2].value() == 3); + BOOST_TEST(cb1[3].value() == 4); + BOOST_TEST(cb1[4].value() == 5); + BOOST_TEST(cb1[5].value() == 6); + BOOST_TEST(cb1[6].value() == 7); + BOOST_TEST(cb1[7].value() == 8); + + cb1.set_capacity(2); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(!cb1[1].is_moved()); + BOOST_TEST(cb1[0].value() == 1); + BOOST_TEST(cb1[1].value() == 2); + + cb1.rset_capacity(1); + BOOST_TEST(!cb1[0].is_moved()); + BOOST_TEST(cb1[0].value() == 2); +} + +void check_containers_exception_specifications() { +#ifndef BOOST_NO_CXX11_NOEXCEPT +#ifndef BOOST_CLANG + // Clang has an error in __has_nothrow_constructor implementation: + // http://llvm.org/bugs/show_bug.cgi?id=16627 + BOOST_TEST(boost::has_nothrow_constructor<CB_CONTAINER<int> >::value); +#endif + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifdef BOOST_IS_NOTHROW_MOVE_ASSIGN + BOOST_TEST(boost::is_nothrow_move_assignable<CB_CONTAINER<int> >::value); +#endif +#ifdef BOOST_IS_NOTHROW_MOVE_CONSTRUCT + BOOST_TEST(boost::is_nothrow_move_constructible<CB_CONTAINER<int> >::value); +#endif +#endif +#endif // BOOST_NO_CXX11_NOEXCEPT +} + +// add common tests into a test suite +void run_common_tests() +{ + basic_test(); + constructor_and_element_access_test(); + size_test(); + allocator_test(); + begin_and_end_test(); + rbegin_and_rend_test(); + element_access_and_insert_test(); + at_test(); + front_and_back_test(); + linearize_test(); + array_range_test(); + capacity_and_reserve_test(); + full_and_empty_test(); + set_capacity_test(); + rset_capacity_test(); + resize_test(); + rresize_test(); + constructor_test(); + assign_test(); + copy_constructor_and_assign_test(); + swap_test(); + push_back_test(); + pop_back_test(); + insert_test(); + insert_n_test(); + insert_range_test(); + push_front_test(); + pop_front_test(); + rinsert_test(); + rinsert_n_test(); + rinsert_range_test(); + erase_test(); + erase_range_test(); + rerase_test(); + rerase_range_test(); + clear_test(); + equality_test(); + lexicographical_comparison_test(); + assign_range_test(); + example_test(); + element_destruction_test(); + const_methods_test(); + rotate_test(); + move_container_on_cpp11(); + move_container_values_noexcept(); + check_containers_exception_specifications(); +#if !defined(BOOST_CB_NO_CXX11_ALLOCATOR) + cxx11_allocator_test(); +#endif +} + diff --git a/src/boost/libs/circular_buffer/test/constant_erase_test.cpp b/src/boost/libs/circular_buffer/test/constant_erase_test.cpp new file mode 100644 index 000000000..e2431be2a --- /dev/null +++ b/src/boost/libs/circular_buffer/test/constant_erase_test.cpp @@ -0,0 +1,182 @@ +// Special tests for erase_begin, erase_end and clear methods. + +// Copyright (c) 2009 Jan Gaspar + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "test.hpp" + +int MyInteger::ms_exception_trigger = 0; +int InstanceCounter::ms_count = 0; + +void erase_begin_test() { + + circular_buffer<int> cb1(5); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.push_back(5); + cb1.push_back(6); + + circular_buffer<int>::pointer p = &cb1[0]; + + cb1.erase_begin(2); + + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1[0] == 4); + BOOST_TEST(cb1[1] == 5); + BOOST_TEST(cb1[2] == 6); + + cb1.erase_begin(3); + BOOST_TEST(cb1.empty()); + BOOST_TEST(*p == 2); + BOOST_TEST(*(p + 1) == 3); + BOOST_TEST(*(p + 2) == 4); + + cb1.push_back(10); + cb1.push_back(11); + cb1.push_back(12); + + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1[0] == 10); + BOOST_TEST(cb1[1] == 11); + BOOST_TEST(cb1[2] == 12); + + circular_buffer<InstanceCounter> cb2(5, InstanceCounter()); + + BOOST_TEST(cb2.size() == 5); + BOOST_TEST(InstanceCounter::count() == 5); + + cb2.erase_begin(2); + + BOOST_TEST(cb2.size() == 3); + BOOST_TEST(InstanceCounter::count() == 3); + + circular_buffer<MyInteger> cb3(5); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(4); + cb3.push_back(5); + cb3.push_back(6); + cb3.erase_begin(2); + + BOOST_TEST(cb3.size() == 3); + BOOST_TEST(cb3[0] == 4); + BOOST_TEST(cb3[1] == 5); + BOOST_TEST(cb3[2] == 6); +} + +void erase_end_test() { + + circular_buffer<int> cb1(5); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.push_back(5); + cb1.push_back(6); + + circular_buffer<int>::pointer p = &cb1[3]; + + cb1.erase_end(2); + + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1[0] == 2); + BOOST_TEST(cb1[1] == 3); + BOOST_TEST(cb1[2] ==4); + + cb1.erase_end(3); + BOOST_TEST(cb1.empty()); + BOOST_TEST(*p == 5); + BOOST_TEST(*(p - 1) == 4); + BOOST_TEST(*(p - 2) == 3); + + cb1.push_back(10); + cb1.push_back(11); + cb1.push_back(12); + + BOOST_TEST(cb1.size() == 3); + BOOST_TEST(cb1[0] == 10); + BOOST_TEST(cb1[1] == 11); + BOOST_TEST(cb1[2] == 12); + + circular_buffer<InstanceCounter> cb2(5, InstanceCounter()); + + BOOST_TEST(cb2.size() == 5); + BOOST_TEST(InstanceCounter::count() == 5); + + cb2.erase_end(2); + + BOOST_TEST(cb2.size() == 3); + BOOST_TEST(InstanceCounter::count() == 3); + + circular_buffer<MyInteger> cb3(5); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(4); + cb3.push_back(5); + cb3.push_back(6); + cb3.erase_end(2); + + BOOST_TEST(cb3.size() == 3); + BOOST_TEST(cb3[0] == 2); + BOOST_TEST(cb3[1] == 3); + BOOST_TEST(cb3[2] == 4); +} + +void clear_test() { + + circular_buffer<int> cb1(5); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb1.push_back(5); + cb1.push_back(6); + + circular_buffer<int>::pointer p = &cb1[0]; + + cb1.clear(); + + BOOST_TEST(cb1.empty()); + BOOST_TEST(*p == 2); + BOOST_TEST(*(p + 1) == 3); + BOOST_TEST(*(p + 2) == 4); + BOOST_TEST(*(p + 3) == 5); + BOOST_TEST(*(p - 1) == 6); + + circular_buffer<InstanceCounter> cb2(5, InstanceCounter()); + + BOOST_TEST(cb2.size() == 5); + BOOST_TEST(InstanceCounter::count() == 5); + + cb2.clear(); + + BOOST_TEST(cb2.empty()); + BOOST_TEST(InstanceCounter::count() == 0); + + circular_buffer<MyInteger> cb3(5); + cb3.push_back(1); + cb3.push_back(2); + cb3.push_back(3); + cb3.push_back(4); + cb3.push_back(5); + cb3.push_back(6); + cb3.clear(); + + BOOST_TEST(cb3.empty()); +} + +// test main +int main() +{ + erase_begin_test(); + erase_end_test(); + clear_test(); + return boost::report_errors(); +} diff --git a/src/boost/libs/circular_buffer/test/soft_iterator_invalidation.cpp b/src/boost/libs/circular_buffer/test/soft_iterator_invalidation.cpp new file mode 100644 index 000000000..c266c9c93 --- /dev/null +++ b/src/boost/libs/circular_buffer/test/soft_iterator_invalidation.cpp @@ -0,0 +1,742 @@ +// Demonstration of rules when an iterator is considered to be valid if the soft +// iterator invalidation definition is applied. +// Note: The soft iterator invalidation definition CAN NOT be applied +// to the space optimized circular buffer. + +// Copyright (c) 2003-2008 Jan Gaspar + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "test.hpp" + +// test of the example (introduced in the documentation) +void validity_example_test() { + + circular_buffer<int> cb(3); + + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + circular_buffer<int>::iterator it = cb.begin(); + + BOOST_TEST(*it == 1); + + cb.push_back(4); + + BOOST_TEST(*it == 4); +} + +void validity_insert_test() { + + int array[] = { 1, 2, 3 }; + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(4, array, array + 3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + + cb.insert(cb.begin() + 1, 4); + + // memory placement: { 1, 4, 2, 3 } + // circular buffer: { 1, 4, 2, 3 } + BOOST_TEST(*it1 == 1); + BOOST_TEST(*it2 == 4); + BOOST_TEST(*it3 == 2); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 4); + BOOST_TEST(cb[2] == 2); + BOOST_TEST(cb[3] == 3); + + // it4 -> 3 + circular_buffer<int>::iterator it4 = it1 + 3; + + cb.insert(cb.begin() + 1, 5); + + // memory placement: { 3, 5, 4, 2 } + // circular buffer: { 5, 4, 2, 3 } + BOOST_TEST(*it1 == 3); + BOOST_TEST(*it2 == 5); + BOOST_TEST(*it3 == 4); + BOOST_TEST(*it4 == 2); + BOOST_TEST(cb[0] == 5); + BOOST_TEST(cb[1] == 4); + BOOST_TEST(cb[2] == 2); + BOOST_TEST(cb[3] == 3); +} + +void validity_insert_n_test() { + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(5); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + + cb.insert(cb.begin() + 1, 2, 4); + + // memory placement: { 1, 4, 4, 2, 3 } + // circular buffer: { 1, 4, 4, 2, 3 } + BOOST_TEST(*it1 == 1); + BOOST_TEST(*it2 == 4); + BOOST_TEST(*it3 == 4); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 4); + BOOST_TEST(cb[2] == 4); + BOOST_TEST(cb[3] == 2); + BOOST_TEST(cb[4] == 3); + + // it4 -> 2, it5 -> 3 + circular_buffer<int>::iterator it4 = it1 + 3; + circular_buffer<int>::iterator it5 = it1 + 4; + + cb.insert(cb.begin() + 1, 2, 5); + + // memory placement: { 3, 5, 4, 4, 2 } - 5 inserted only once + // circular buffer: { 5, 4, 4, 2, 3 } + BOOST_TEST(*it1 == 3); + BOOST_TEST(*it2 == 5); + BOOST_TEST(*it3 == 4); + BOOST_TEST(*it4 == 4); + BOOST_TEST(*it5 == 2); + BOOST_TEST(cb[0] == 5); + BOOST_TEST(cb[1] == 4); + BOOST_TEST(cb[2] == 4); + BOOST_TEST(cb[3] == 2); + BOOST_TEST(cb[4] == 3); +} + +void validity_insert_range_test() { + + vector<int> v1; + v1.push_back(4); + v1.push_back(5); + + vector<int> v2; + v2.push_back(6); + v2.push_back(7); + + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb1(5); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + + // it11 -> 1, it12 -> 2, it13 -> 3 + circular_buffer<int>::iterator it11 = cb1.begin(); + circular_buffer<int>::iterator it12 = cb1.begin() + 1; + circular_buffer<int>::iterator it13 = cb1.begin() + 2; + + cb1.insert(cb1.begin() + 1, v1.begin(), v1.end()); + + // memory placement: { 1, 4, 5, 2, 3 } + // circular buffer: { 1, 4, 5, 2, 3 } + BOOST_TEST(*it11 == 1); + BOOST_TEST(*it12 == 4); + BOOST_TEST(*it13 == 5); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 4); + BOOST_TEST(cb1[2] == 5); + BOOST_TEST(cb1[3] == 2); + BOOST_TEST(cb1[4] == 3); + + // it14 -> 2, it15 -> 3 + circular_buffer<int>::iterator it14 = it11 + 3; + circular_buffer<int>::iterator it15 = it11 + 4; + + cb1.insert(cb1.begin() + 1, v2.begin(), v2.end()); + + // memory placement: { 3, 7, 4, 5, 2 } - 7 inserted only + // circular buffer: { 7, 4, 5, 2, 3 } + BOOST_TEST(*it11 == 3); + BOOST_TEST(*it12 == 7); + BOOST_TEST(*it13 == 4); + BOOST_TEST(*it14 == 5); + BOOST_TEST(*it15 == 2); + BOOST_TEST(cb1[0] == 7); + BOOST_TEST(cb1[1] == 4); + BOOST_TEST(cb1[2] == 5); + BOOST_TEST(cb1[3] == 2); + BOOST_TEST(cb1[4] == 3); + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb2(5); + cb2.push_back(1); + cb2.push_back(2); + cb2.push_back(3); + + // it21 -> 1, it22 -> 2, it23 -> 3 + circular_buffer<int>::iterator it21 = cb2.begin(); + circular_buffer<int>::iterator it22 = cb2.begin() + 1; + circular_buffer<int>::iterator it23 = cb2.begin() + 2; + + cb2.insert(cb2.begin() + 1, MyInputIterator(v1.begin()), MyInputIterator(v1.end())); + + // memory placement: { 1, 4, 5, 2, 3 } + // circular buffer: { 1, 4, 5, 2, 3 } + BOOST_TEST(*it21 == 1); + BOOST_TEST(*it22 == 4); + BOOST_TEST(*it23 == 5); + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2[1] == 4); + BOOST_TEST(cb2[2] == 5); + BOOST_TEST(cb2[3] == 2); + BOOST_TEST(cb2[4] == 3); + + // it24 -> 2, it25 -> 3 + circular_buffer<int>::iterator it24 = it21 + 3; + circular_buffer<int>::iterator it25 = it21 + 4; + + cb2.insert(cb2.begin() + 1, MyInputIterator(v2.begin()), MyInputIterator(v2.end())); + + // memory placement: { 2, 3, 7, 4, 5 } - using input iterator inserts all items even if they are later replaced + // circular buffer: { 7, 4, 5, 2, 3 } + BOOST_TEST(*it21 == 2); + BOOST_TEST(*it22 == 3); + BOOST_TEST(*it23 == 7); + BOOST_TEST(*it24 == 4); + BOOST_TEST(*it25 == 5); + BOOST_TEST(cb2[0] == 7); + BOOST_TEST(cb2[1] == 4); + BOOST_TEST(cb2[2] == 5); + BOOST_TEST(cb2[3] == 2); + BOOST_TEST(cb2[4] == 3); +} + +void validity_rinsert_test() { + + int array[] = { 1, 2, 3 }; + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(4, array, array + 3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + + cb.rinsert(cb.begin() + 2, 4); + + // memory placement: { 2, 4, 3, 1 } + // circular buffer: { 1, 2, 4, 3 } + BOOST_TEST(*it1 == 2); + BOOST_TEST(*it2 == 4); + BOOST_TEST(*it3 == 3); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); + BOOST_TEST(cb[2] == 4); + BOOST_TEST(cb[3] == 3); + + // it4 -> 1 + circular_buffer<int>::iterator it4 = it1 - 1; + + cb.rinsert(cb.begin() + 2, 5); + + // memory placement: { 5, 4, 1, 2 } + // circular buffer: { 1, 2, 5, 4 } + BOOST_TEST(*it1 == 5); + BOOST_TEST(*it2 == 4); + BOOST_TEST(*it3 == 1); + BOOST_TEST(*it4 == 2); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); + BOOST_TEST(cb[2] == 5); + BOOST_TEST(cb[3] == 4); +} + +void validity_rinsert_n_test() { + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(5); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + + cb.rinsert(cb.begin() + 2, 2, 4); + + // memory placement: { 4, 4, 3, 1, 2 } + // circular buffer: { 1, 2, 4, 4, 3 } + BOOST_TEST(*it1 == 4); + BOOST_TEST(*it2 == 4); + BOOST_TEST(*it3 == 3); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); + BOOST_TEST(cb[2] == 4); + BOOST_TEST(cb[3] == 4); + BOOST_TEST(cb[4] == 3); + + // it4 -> 1, it5 -> 2 + circular_buffer<int>::iterator it4 = it1 - 2; + circular_buffer<int>::iterator it5 = it1 - 1; + + cb.rinsert(cb.begin() + 4, 2, 5); + + // memory placement: { 4, 5, 1, 2, 4 } - 5 inserted only once + // circular buffer: { 1, 2, 4, 4, 5 } + BOOST_TEST(*it1 == 4); + BOOST_TEST(*it2 == 5); + BOOST_TEST(*it3 == 1); + BOOST_TEST(*it4 == 2); + BOOST_TEST(*it5 == 4); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); + BOOST_TEST(cb[2] == 4); + BOOST_TEST(cb[3] == 4); + BOOST_TEST(cb[4] == 5); +} + +void validity_rinsert_range_test() { + + vector<int> v1; + v1.push_back(4); + v1.push_back(5); + + vector<int> v2; + v2.push_back(6); + v2.push_back(7); + + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb1(5); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it11 = cb1.begin(); + circular_buffer<int>::iterator it12 = cb1.begin() + 1; + circular_buffer<int>::iterator it13 = cb1.begin() + 2; + + cb1.rinsert(cb1.begin() + 2, v1.begin(), v1.end()); + + // memory placement: { 4, 5, 3, 1, 2 } + // circular buffer: { 1, 2, 4, 5, 3 } + BOOST_TEST(*it11 == 4); + BOOST_TEST(*it12 == 5); + BOOST_TEST(*it13 == 3); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 2); + BOOST_TEST(cb1[2] == 4); + BOOST_TEST(cb1[3] == 5); + BOOST_TEST(cb1[4] == 3); + + // it14 -> 1, it15 -> 2 + circular_buffer<int>::iterator it14 = it11 - 2; + circular_buffer<int>::iterator it15 = it11 - 1; + + cb1.rinsert(cb1.begin() + 4, v2.begin(), v2.end()); + + // memory placement: { 5, 6, 1, 2, 4 } - 6 inserted only + // circular buffer: { 1, 2, 4, 5, 6 } + BOOST_TEST(*it11 == 5); + BOOST_TEST(*it12 == 6); + BOOST_TEST(*it13 == 1); + BOOST_TEST(*it14 == 2); + BOOST_TEST(*it15 == 4); + BOOST_TEST(cb1[0] == 1); + BOOST_TEST(cb1[1] == 2); + BOOST_TEST(cb1[2] == 4); + BOOST_TEST(cb1[3] == 5); + BOOST_TEST(cb1[4] == 6); + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb2(5); + cb2.push_back(1); + cb2.push_back(2); + cb2.push_back(3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it21 = cb2.begin(); + circular_buffer<int>::iterator it22 = cb2.begin() + 1; + circular_buffer<int>::iterator it23 = cb2.begin() + 2; + + cb2.rinsert(cb2.begin() + 2, MyInputIterator(v1.begin()), MyInputIterator(v1.end())); + + // memory placement: { 4, 5, 3, 1, 2 } + // circular buffer: { 1, 2, 4, 5, 3 } + BOOST_TEST(*it21 == 4); + BOOST_TEST(*it22 == 5); + BOOST_TEST(*it23 == 3); + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2[1] == 2); + BOOST_TEST(cb2[2] == 4); + BOOST_TEST(cb2[3] == 5); + BOOST_TEST(cb2[4] == 3); + + // it24 -> 1, it25 -> 2 + circular_buffer<int>::iterator it24 = it21 - 2; + circular_buffer<int>::iterator it25 = it21 - 1; + + cb2.rinsert(cb2.begin() + 4, MyInputIterator(v2.begin()), MyInputIterator(v2.end())); + + // memory placement: { 5, 6, 1, 2, 4 } + // circular buffer: { 1, 2, 4, 5, 6 } + BOOST_TEST(*it21 == 5); + BOOST_TEST(*it22 == 6); + BOOST_TEST(*it23 == 1); + BOOST_TEST(*it24 == 2); + BOOST_TEST(*it25 == 4); + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2[1] == 2); + BOOST_TEST(cb2[2] == 4); + BOOST_TEST(cb2[3] == 5); + BOOST_TEST(cb2[4] == 6); +} + +void validity_erase_test() { + + // memory placement: { 4, 5, 1, 2, 3 } + // circular buffer: { 1, 2, 3, 4, 5 } + circular_buffer<int> cb(5); + cb.push_back(-1); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + cb.push_back(4); + cb.push_back(5); + + // it1 -> 1, it2 -> 2, it3 -> 3, it4 -> 4 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + circular_buffer<int>::iterator it4 = cb.begin() + 3; + + cb.erase(cb.begin() + 1); + + // memory placement: { 5, X, 1, 3, 4 } + // circular buffer: { 1, 3, 4, 5 } + BOOST_TEST(*it1 == 1); + BOOST_TEST(*it2 == 3); + BOOST_TEST(*it3 == 4); + BOOST_TEST(*it4 == 5); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 3); + BOOST_TEST(cb[2] == 4); + BOOST_TEST(cb[3] == 5); +} + +void validity_erase_range_test() { + + // memory placement: { 4, 5, 6, 1, 2, 3 } + // circular buffer: { 1, 2, 3, 4, 5, 6 } + circular_buffer<int> cb(6); + cb.push_back(-2); + cb.push_back(-1); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + cb.push_back(4); + cb.push_back(5); + cb.push_back(6); + + // it1 -> 1, it2 -> 2, it3 -> 3, it4 -> 4 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + circular_buffer<int>::iterator it4 = cb.begin() + 3; + + cb.erase(cb.begin() + 2, cb.begin() + 4); + + // memory placement: { 6, X, X, 1, 2, 5 } + // circular buffer: { 1, 2, 5, 6 } + BOOST_TEST(*it1 == 1); + BOOST_TEST(*it2 == 2); + BOOST_TEST(*it3 == 5); + BOOST_TEST(*it4 == 6); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); + BOOST_TEST(cb[2] == 5); + BOOST_TEST(cb[3] == 6); +} + +void validity_rerase_test() { + + // memory placement: { 4, 5, 1, 2, 3 } + // circular buffer: { 1, 2, 3, 4, 5 } + circular_buffer<int> cb(5); + cb.push_back(-1); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + cb.push_back(4); + cb.push_back(5); + + // it1 -> 2, it2 -> 3, it3 -> 4, it4 -> 5 + circular_buffer<int>::iterator it1 = cb.begin() + 1; + circular_buffer<int>::iterator it2 = cb.begin() + 2; + circular_buffer<int>::iterator it3 = cb.begin() + 3; + circular_buffer<int>::iterator it4 = cb.begin() + 4; + + cb.rerase(cb.begin() + 1); + + // memory placement: { 4, 5, X, 1, 3 } + // circular buffer: { 1, 3, 4, 5 } + BOOST_TEST(*it1 == 1); + BOOST_TEST(*it2 == 3); + BOOST_TEST(*it3 == 4); + BOOST_TEST(*it4 == 5); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 3); + BOOST_TEST(cb[2] == 4); + BOOST_TEST(cb[3] == 5); +} + +void validity_rerase_range_test() { + + // memory placement: { 4, 5, 6, 1, 2, 3 } + // circular buffer: { 1, 2, 3, 4, 5, 6 } + circular_buffer<int> cb(6); + cb.push_back(-2); + cb.push_back(-1); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + cb.push_back(4); + cb.push_back(5); + cb.push_back(6); + + // it1 -> 3, it2 -> 4, it3 -> 5, it4 -> 6 + circular_buffer<int>::iterator it1 = cb.begin() + 2; + circular_buffer<int>::iterator it2 = cb.begin() + 3; + circular_buffer<int>::iterator it3 = cb.begin() + 4; + circular_buffer<int>::iterator it4 = cb.begin() + 5; + + cb.rerase(cb.begin() + 2, cb.begin() + 4); + + // memory placement: { 2, 5, 6, X, X, 1 } + // circular buffer: { 1, 2, 5, 6 } + BOOST_TEST(*it1 == 1); + BOOST_TEST(*it2 == 2); + BOOST_TEST(*it3 == 5); + BOOST_TEST(*it4 == 6); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); + BOOST_TEST(cb[2] == 5); + BOOST_TEST(cb[3] == 6); +} + +void validity_linearize_test() { + + // memory placement: { 3, 1, 2 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(3); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + + cb.linearize(); + + // memory placement: { 1, 2, 3 } + // circular buffer: { 1, 2, 3 } + BOOST_TEST(*it1 == 2); + BOOST_TEST(*it2 == 3); + BOOST_TEST(*it3 == 1); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); + BOOST_TEST(cb[2] == 3); +} + +void validity_swap_test() { + + // memory placement: { 3, 1, 2 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb1(3); + cb1.push_back(0); + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + + // it11 -> 1, it12 -> 2, it13 -> 3 + circular_buffer<int>::iterator it11 = cb1.begin(); + circular_buffer<int>::iterator it12 = cb1.begin() + 1; + circular_buffer<int>::iterator it13 = cb1.begin() + 2; + + // memory placement: { 4, 5, 6 } + // circular buffer: { 4, 5, 6 } + circular_buffer<int> cb2(5); + cb2.push_back(4); + cb2.push_back(5); + cb2.push_back(6); + + // it21 -> 4, it22 -> 5, it23 -> 6 + circular_buffer<int>::iterator it21 = cb2.begin(); + circular_buffer<int>::iterator it22 = cb2.begin() + 1; + circular_buffer<int>::iterator it23 = cb2.begin() + 2; + + cb1.swap(cb2); + + // Although iterators refer to the original elements, + // their internal state is inconsistent and no other operation + // (except dereferencing) can be invoked on them any more. + BOOST_TEST(*it11 == 1); + BOOST_TEST(*it12 == 2); + BOOST_TEST(*it13 == 3); + BOOST_TEST(*it21 == 4); + BOOST_TEST(*it22 == 5); + BOOST_TEST(*it23 == 6); + BOOST_TEST(cb1[0] == 4); + BOOST_TEST(cb1[1] == 5); + BOOST_TEST(cb1[2] == 6); + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2[1] == 2); + BOOST_TEST(cb2[2] == 3); +} + +void validity_push_back_test() { + + // memory placement: { 3, 1, 2 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(3); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + + cb.push_back(4); + + // memory placement: { 3, 4, 2 } + // circular buffer: { 2, 3, 4 } + BOOST_TEST(*it1 == 4); + BOOST_TEST(*it2 == 2); + BOOST_TEST(*it3 == 3); + BOOST_TEST(cb[0] == 2); + BOOST_TEST(cb[1] == 3); + BOOST_TEST(cb[2] == 4); +} + +void validity_push_front_test() { + + // memory placement: { 3, 1, 2 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(3); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + // it1 -> 1, it2 -> 2, it3 -> 3 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + circular_buffer<int>::iterator it3 = cb.begin() + 2; + + cb.push_front(4); + + // memory placement: { 4, 1, 2 } + // circular buffer: { 4, 1, 2 } + BOOST_TEST(*it1 == 1); + BOOST_TEST(*it2 == 2); + BOOST_TEST(*it3 == 4); + BOOST_TEST(cb[0] == 4); + BOOST_TEST(cb[1] == 1); + BOOST_TEST(cb[2] == 2); +} + +void validity_pop_back_test() { + + // memory placement: { 3, 1, 2 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(3); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + // it1 -> 1, it2 -> 2 + circular_buffer<int>::iterator it1 = cb.begin(); + circular_buffer<int>::iterator it2 = cb.begin() + 1; + + cb.pop_back(); + + // memory placement: { X, 1, 2 } + // circular buffer: { 1, 2 } + BOOST_TEST(*it1 == 1); + BOOST_TEST(*it2 == 2); + BOOST_TEST(cb[0] == 1); + BOOST_TEST(cb[1] == 2); +} + +void validity_pop_front_test() { + + // memory placement: { 3, 1, 2 } + // circular buffer: { 1, 2, 3 } + circular_buffer<int> cb(3); + cb.push_back(0); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + // it1 -> 2, it2 -> 3 + circular_buffer<int>::iterator it1 = cb.begin() + 1; + circular_buffer<int>::iterator it2 = cb.begin() + 2; + + cb.pop_front(); + + // memory placement: { 3, X, 2 } + // circular buffer: { 2, 3 } + BOOST_TEST(*it1 == 2); + BOOST_TEST(*it2 == 3); + BOOST_TEST(cb[0] == 2); + BOOST_TEST(cb[1] == 3); +} + +// test main +int main() +{ + validity_example_test(); + validity_insert_test(); + validity_insert_n_test(); + validity_insert_range_test(); + validity_rinsert_test(); + validity_rinsert_n_test(); + validity_rinsert_range_test(); + validity_erase_test(); + validity_erase_range_test(); + validity_rerase_test(); + validity_rerase_range_test(); + validity_linearize_test(); + validity_swap_test(); + validity_push_back_test(); + validity_push_front_test(); + validity_pop_back_test(); + validity_pop_front_test(); + return boost::report_errors(); +} diff --git a/src/boost/libs/circular_buffer/test/space_optimized_test.cpp b/src/boost/libs/circular_buffer/test/space_optimized_test.cpp new file mode 100644 index 000000000..8694fcdb7 --- /dev/null +++ b/src/boost/libs/circular_buffer/test/space_optimized_test.cpp @@ -0,0 +1,193 @@ +// Test of the space optimized adaptor of the circular buffer. + +// Copyright (c) 2003-2008 Jan Gaspar + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "test.hpp" + +#define CB_CONTAINER circular_buffer_space_optimized + +#include "common.ipp" + +typedef circular_buffer_space_optimized<MyInteger> cb_space_optimized; +typedef cb_space_optimized::capacity_type capacity_ctrl; + +// min_capacity test (it is useful to use a debug tool) +void min_capacity_test() { + + vector<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + v.push_back(4); + v.push_back(5); + + cb_space_optimized cb1(capacity_ctrl(10, 10)); + cb_space_optimized cb2(capacity_ctrl(10, 5), 1); + cb_space_optimized cb3(capacity_ctrl(20, 10), v.begin(), v.end()); + + BOOST_TEST(cb1.size() == 0); + BOOST_TEST(cb1.capacity().capacity() == 10); + BOOST_TEST(cb1.capacity().min_capacity() == 10); + BOOST_TEST(cb2[0] == 1); + BOOST_TEST(cb2.size() == 10); + BOOST_TEST(cb2.capacity() == 10); + BOOST_TEST(cb2.capacity().min_capacity() == 5); + BOOST_TEST(cb3[0] == 1); + BOOST_TEST(cb3.size() == 5); + BOOST_TEST(cb3.capacity() == 20); + BOOST_TEST(cb3.capacity().min_capacity() == 10); + BOOST_TEST(cb1.capacity().min_capacity() <= cb1.internal_capacity()); + BOOST_TEST(cb2.capacity().min_capacity() <= cb2.internal_capacity()); + BOOST_TEST(cb3.capacity().min_capacity() <= cb3.internal_capacity()); + + cb2.erase(cb2.begin() + 2, cb2.end()); + + BOOST_TEST(cb2.size() == 2); + BOOST_TEST(cb2.capacity().min_capacity() <= cb2.internal_capacity()); + + cb2.clear(); + cb3.clear(); + + BOOST_TEST(cb2.empty()); + BOOST_TEST(cb3.empty()); + BOOST_TEST(cb2.capacity().min_capacity() <= cb2.internal_capacity()); + BOOST_TEST(cb3.capacity().min_capacity() <= cb3.internal_capacity()); +} + +void capacity_control_test() { + + circular_buffer_space_optimized<int>::capacity_type c1 = 10; + circular_buffer_space_optimized<int>::capacity_type c2 = + circular_buffer_space_optimized<int>::capacity_type(20, 5); + circular_buffer_space_optimized<int>::capacity_type c3 = c2; + + BOOST_TEST(c1.capacity() == 10); + BOOST_TEST(c1.min_capacity() == 0); + BOOST_TEST(c2.capacity() == 20); + BOOST_TEST(c2.min_capacity() == 5); + BOOST_TEST(c3.capacity() == 20); + BOOST_TEST(c3.min_capacity() == 5); + + c1 = c2; + + BOOST_TEST(c1.capacity() == 20); + BOOST_TEST(c1.min_capacity() == 5); +} + +void specific_constructors_test() { + + cb_space_optimized cb1; + BOOST_TEST(cb1.capacity() == 0); + BOOST_TEST(cb1.capacity().min_capacity() == 0); + BOOST_TEST(cb1.internal_capacity() == 0); + BOOST_TEST(cb1.size() == 0); + + cb1.push_back(1); + cb1.push_back(2); + cb1.push_back(3); + + BOOST_TEST(cb1.size() == 0); + BOOST_TEST(cb1.capacity() == 0); + + vector<int> v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + + cb_space_optimized cb2(v.begin(), v.end()); + + BOOST_TEST(cb2.capacity() == 3); + BOOST_TEST(cb2.capacity().min_capacity() == 0); + BOOST_TEST(cb2.size() == 3); +} + +void shrink_to_fit_test() { + + cb_space_optimized cb(1000); + cb.push_back(1); + cb.push_back(2); + cb.push_back(3); + + BOOST_TEST(cb.size() == 3); + BOOST_TEST(cb.capacity() == 1000); + + size_t internal_capacity = cb.internal_capacity(); + cb_space_optimized(cb).swap(cb); + + BOOST_TEST(cb.size() == 3); + BOOST_TEST(cb.capacity() == 1000); + BOOST_TEST(internal_capacity >= cb.internal_capacity()); +} + +void iterator_invalidation_test() { + +#if BOOST_CB_ENABLE_DEBUG + + cb_space_optimized cb1(10, 1); + cb1.push_back(2); + cb1.push_back(3); + cb1.push_back(4); + cb_space_optimized::iterator it1 = cb1.end(); + cb_space_optimized::const_iterator it2 = cb1.begin(); + cb_space_optimized::iterator it3 = cb1.begin() + 6; + + cb1.set_capacity(10); + BOOST_TEST(it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb1)); + BOOST_TEST(!it3.is_valid(&cb1)); + + it1 = cb1.end(); + it2 = cb1.begin(); + it3 = cb1.begin() + 6; + cb1.rset_capacity(10); + BOOST_TEST(it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb1)); + BOOST_TEST(!it3.is_valid(&cb1)); + + it1 = cb1.end(); + it2 = cb1.begin(); + it3 = cb1.begin() + 6; + cb1.resize(10); + BOOST_TEST(it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb1)); + BOOST_TEST(!it3.is_valid(&cb1)); + + it1 = cb1.end(); + it2 = cb1.begin(); + it3 = cb1.begin() + 6; + cb1.rresize(10); + BOOST_TEST(it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb1)); + BOOST_TEST(!it3.is_valid(&cb1)); + + { + cb_space_optimized cb2(10, 1); + cb2.push_back(2); + cb2.push_back(3); + cb2.push_back(4); + it1 = cb2.end(); + it2 = cb2.begin(); + it3 = cb2.begin() + 6; + } + BOOST_TEST(!it1.is_valid(&cb1)); + BOOST_TEST(!it2.is_valid(&cb1)); + BOOST_TEST(!it3.is_valid(&cb1)); + +#endif // #if BOOST_CB_ENABLE_DEBUG +} + +// test main +int main() +{ + run_common_tests(); + min_capacity_test(); + capacity_control_test(); + specific_constructors_test(); + shrink_to_fit_test(); + iterator_invalidation_test(); + return boost::report_errors(); +} diff --git a/src/boost/libs/circular_buffer/test/test.hpp b/src/boost/libs/circular_buffer/test/test.hpp new file mode 100644 index 000000000..bbcc770ed --- /dev/null +++ b/src/boost/libs/circular_buffer/test/test.hpp @@ -0,0 +1,145 @@ +// Header file for the test of the circular buffer library. + +// Copyright (c) 2003-2008 Jan Gaspar + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_CIRCULAR_BUFFER_TEST_HPP) +#define BOOST_CIRCULAR_BUFFER_TEST_HPP + +#if defined(_MSC_VER) && _MSC_VER >= 1200 + #pragma once +#endif + +#define BOOST_CB_TEST + +#include <boost/circular_buffer.hpp> +#include <boost/core/lightweight_test.hpp> +#include <iterator> +#include <numeric> +#include <vector> +#if !defined(BOOST_NO_EXCEPTIONS) + #include <exception> +#endif + +// Integer (substitute for int) - more appropriate for testing +class MyInteger { +private: + int* m_pValue; + static int ms_exception_trigger; + void check_exception() { + if (ms_exception_trigger > 0) { + if (--ms_exception_trigger == 0) { + delete m_pValue; + m_pValue = 0; +#if !defined(BOOST_NO_EXCEPTIONS) + throw std::exception(); +#endif + } + } + } +public: + MyInteger() : m_pValue(new int(0)) { check_exception(); } + MyInteger(int i) : m_pValue(new int(i)) { check_exception(); } + MyInteger(const MyInteger& src) : m_pValue(new int(src)) { check_exception(); } + ~MyInteger() { delete m_pValue; } + MyInteger& operator = (const MyInteger& src) { + if (this == &src) + return *this; + check_exception(); + delete m_pValue; + m_pValue = new int(src); + return *this; + } + operator int () const { return *m_pValue; } + static void set_exception_trigger(int n) { ms_exception_trigger = n; } +}; + +// default constructible class +class MyDefaultConstructible +{ +public: + MyDefaultConstructible() : m_n(1) {} + MyDefaultConstructible(int n) : m_n(n) {} + int m_n; +}; + +// class counting instances of self +class InstanceCounter { +public: + InstanceCounter() { increment(); } + InstanceCounter(const InstanceCounter& y) { y.increment(); } + ~InstanceCounter() { decrement(); } + static int count() { return ms_count; } +private: + void increment() const { ++ms_count; } + void decrement() const { --ms_count; } + static int ms_count; +}; + +// dummy class suitable for iterator referencing test +class Dummy { +public: + enum DummyEnum { + eVar, + eFnc, + eConst, + eVirtual + }; + Dummy() : m_n(eVar) {} + virtual ~Dummy() {} + DummyEnum fnc() { return eFnc; } + DummyEnum const_fnc() const { return eConst; } + virtual DummyEnum virtual_fnc() { return eVirtual; } + DummyEnum m_n; +}; + +// simulator of an input iterator +struct MyInputIterator { + typedef std::vector<int>::iterator vector_iterator; + typedef std::input_iterator_tag iterator_category; + typedef int value_type; + typedef int* pointer; + typedef int& reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + explicit MyInputIterator(const vector_iterator& it) : m_it(it) {} + MyInputIterator& operator = (const MyInputIterator& it) { + if (this == &it) + return *this; + m_it = it.m_it; + return *this; + } + reference operator * () const { return *m_it; } + pointer operator -> () const { return &(operator*()); } + MyInputIterator& operator ++ () { + ++m_it; + return *this; + } + MyInputIterator operator ++ (int) { + MyInputIterator tmp = *this; + ++*this; + return tmp; + } + bool operator == (const MyInputIterator& it) const { return m_it == it.m_it; } + bool operator != (const MyInputIterator& it) const { return m_it != it.m_it; } +private: + vector_iterator m_it; +}; + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) + +inline std::input_iterator_tag iterator_category(const MyInputIterator&) { + return std::input_iterator_tag(); +} +inline int* value_type(const MyInputIterator&) { return 0; } +inline ptrdiff_t* distance_type(const MyInputIterator&) { return 0; } + +#endif // #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) + +using namespace boost; +using namespace std; + +#endif // #if !defined(BOOST_CIRCULAR_BUFFER_TEST_HPP) |