Compare commits

...

58 Commits

Author SHA1 Message Date
Glen Fernandes
d1e113f441 Merge branch 'develop' 2018-10-27 18:03:10 -04:00
Glen Fernandes
c084535786 Give the unit test Dummy class a virtual destructor 2018-10-27 17:59:07 -04:00
Glen Fernandes
2433adc0ec Add variadic construct to cb_details::allocator_traits 2018-10-02 06:08:26 -04:00
Glen Fernandes
f10876014a Merge pull request #19 from luzpaz/circular_buffer-misc-typos
circular_buffer: misc-typos
2018-10-01 21:23:19 -04:00
luz.paz
187f4db314 circular_buffer: misc-typos
Found via `codespell -q 3 -L tim`
2018-09-23 15:35:26 -04:00
Glen Fernandes
37a7b2c0d5 Add minimal CMakeLists.txt 2018-09-20 08:59:12 -04:00
Glen Fernandes
2b7cb8fe8b Merge branch 'develop' 2018-09-07 08:27:10 -04:00
Glen Fernandes
fc3e2cd1bc Drop dependency on Boost.Iterator 2018-09-07 08:10:50 -04:00
Glen Fernandes
28e32ba5e8 Remove or replace unnecessary or obsolete header includes 2018-09-07 00:45:01 -04:00
Glen Fernandes
ca3d6678ee In pre-C++11 use our own allocator_traits implementation
Drops dependency on Boost.Container.
2018-09-07 00:44:52 -04:00
Glen Fernandes
c0b613f8bb Fix custom allocator and custom pointer in unit test 2018-09-06 23:54:58 -04:00
Glen Fernandes
97ef4e0e19 Update tests for GCC 4.6 in C++0x mode 2018-09-06 22:41:51 -04:00
Adam Shapiro
a3317ecd15 Removed unnecessary include of call_traits.hpp. 2018-09-06 20:36:27 -04:00
Adam Shapiro
7572374d3b Corrected no_exceptions_support.hpp include. 2018-09-06 20:36:09 -04:00
Glen Fernandes
f66c723e1e Run tests on Travis and Appveyor 2018-09-06 14:08:12 -04:00
Glen Fernandes
bad3f6a8ec Use the empty base optimization for the Allocator 2018-09-05 23:43:32 -04:00
Glen Fernandes
78735e27a0 Merge pull request #16 from DanielaE/fix/no-iterator-inheritance
Inheriting std::iterator is deprecated in c++17.
2018-09-05 23:42:37 -04:00
Glen Fernandes
4ef6e8d1f6 Merge branch 'develop' 2018-02-04 23:13:19 -05:00
Daniela Engert
14b50f574a Inheriting std::iterator is deprecated in c++17.
Boost's iterator.hpp is deprecated, too. Therefore get rid of all of that and replace inheritance by lifting std::iterator's members into the derived class.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-12-28 10:44:23 +01:00
Glen Fernandes
5c5bef6cee Use to_address free function instead of pointer_traits member 2017-11-23 23:21:39 -05:00
Glen Fernandes
2a3e26ff63 Merge pull request #14 from rarevans/spelling
correct spelling in comments for circular_buffer example
2017-10-06 08:19:23 -04:00
Richard Evans
e655fa6c4d correct spelling in comments for circular_buffer example 2017-10-06 12:44:29 +10:00
Glen Fernandes
70664ea403 Merge branch 'develop' 2017-06-04 10:41:13 -04:00
Glen Fernandes
a2a85b57d4 Merge pull request #13 from glenfe/develop
Use pointer_traits.to_address instead of addressof(*p)
2017-05-29 18:41:47 -04:00
Glen Fernandes
ef8c59c4a6 Use pointer_traits.to_address instead of addressof(*p) 2017-05-29 18:39:33 -04:00
Rene Rivera
0b9a59f270 Add, and update, documentation build targets. 2016-10-10 11:39:47 -05:00
Rene Rivera
31aa9939b3 Add, and update, documentation build targets. 2016-10-07 23:07:33 -05:00
Glen Fernandes
99c93337d7 Merge pull request #10 from boostorg/develop
Synchronize master with develop
2016-08-18 21:55:24 -04:00
Glen Fernandes
12b896d57f Merge pull request #9 from Lastique/disable_debug_by_default
Disable debug implementation by default
2016-08-11 19:50:08 -04:00
Andrey Semashev
ea60799f31 Disable debug implementation by default
The debug implementation is not thread-safe, even if different threads are using separate iterators for reading elements of the container. BOOST_CB_DISABLE_DEBUG macro is no longer used, BOOST_CB_ENABLE_DEBUG=1 should be defined instead to enable debug support.

Fixes https://svn.boost.org/trac/boost/ticket/6277.
2016-04-29 00:56:06 +03:00
Glen Fernandes
d49044344f Merge pull request #8 from MarcelRaad/patch-1
Remove deprecated include
2015-09-12 06:53:50 -04:00
Marcel Raad
45c5d05b1d Remove deprecated include
All that boost/iterator.hpp does is pull std::iterator into namespace boost. A comment in that header mentions: "This header is obsolete and will be deprecated."
2015-09-11 16:30:17 +02:00
Antony Polukhin
9cf5fbb0fe Merge pull request #7 from amerry/adl_swap
Use boost/move/adl_move_swap.hpp to perform swaps.
2015-04-21 22:43:21 +04:00
Alexander Merry
2c88fa2f27 Use boost/move/adl_move_swap.hpp to perform swaps. 2015-04-21 09:02:26 +01:00
Alex Henrie
ce9a8538f2 Correct spelling of "suppress" 2015-01-30 15:28:08 -07:00
Antony Polukhin
5136d09e0a Merge branch 'master' into develop 2014-10-14 13:54:40 +04:00
Antony Polukhin
8a35c1deb0 Merge pull request #4 from danieljames/metadata
Create metadata file.
2014-08-18 19:55:51 +04:00
Daniel James
a54ccf9962 Add metadata file. 2014-08-18 14:57:42 +01:00
Antony Polukhin
d48b479c6a Use move_if_noexcept from Boost.Move 2014-08-18 12:08:23 +04:00
Glen Fernandes
8ba2c24454 Merge pull request #2 from jzmaddock/patch-1
Update jamfile.v2
2014-08-14 12:28:36 -07:00
Glen Fernandes
05a6e6e0d5 Merge pull request #3 from jzmaddock/patch-2
Update jamfile.v2
2014-08-14 12:26:40 -07:00
jzmaddock
483a1bdc2d Update jamfile.v2
Fix image location for PDF builds.
Use SVG for admon graphics (default path works OK for these).
Change name of pdf install target as current Boost.Build chokes over targets with hyphens in them.
2014-08-14 17:33:00 +01:00
jzmaddock
cfdf5c063b Update jamfile.v2
Fix image location for PDF builds.
Use SVG for admon graphics (default path works OK for these).
Change name of pdf install target as current Boost.Build chokes over targets with hyphens in them.
2014-08-14 17:31:43 +01:00
Antony Polukhin
f02cbb939c Finished sync of develop and master branches 2014-08-12 20:50:49 +04:00
Antony Polukhin
d18e2283a4 Merge branch 'master' into develop 2014-08-12 20:47:16 +04:00
Glen Fernandes
7e233f7b41 Merge branch 'develop' 2014-05-04 07:42:32 -07:00
Glen Fernandes
689e79abd9 Correct unit test custom pointer dereference operator 2014-05-02 22:06:39 -07:00
Glen Fernandes
002f351a9f Merge pull request #1 from glenfe/develop
Add C++11 allocator model support
2014-05-02 13:20:22 -07:00
Glen Fernandes
18306aee33 Eliminate need for do_construct helper 2014-05-02 10:26:11 -07:00
Glen Fernandes
c4b62627e7 Add C++11 allocator model support 2014-05-01 23:50:44 -07:00
Antony Polukhin
f5303c70d8 Merge branch 'develop' 2014-01-19 12:02:44 +04:00
Antony Polukhin
b896ace67c Create first merge point for Git 2014-01-01 15:35:13 +04:00
Antony Polukhin
62233c53bb Removed some whitespaces 2013-12-09 11:13:34 +04:00
Antony Polukhin
fc1d341a26 Fixed setting memory to '0xcc' in debug mode for non-pointer allocator::pointer types 2013-12-09 11:13:34 +04:00
Antony Polukhin
ece1277965 Fixed issues with allocators that do not return pointers, added tes case for such situations (refs #9334) 2013-12-09 11:13:34 +04:00
Antony Polukhin
33cfe492d9 Merge circular_buffer from trunk:
* dropped support of antique compilers (thanks to Stephen Kelly for doing it all around the boost!)

[SVN r86677]
2013-11-13 13:30:10 +00:00
Stephen Kelly
f9694e2dcb Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
These evaded scripting.

[SVN r86249]
2013-10-11 23:22:36 +00:00
Daniel James
783ea198b9 Final (hopefully?) fixed link.
[SVN r86197]
2013-10-07 23:06:58 +00:00
25 changed files with 785 additions and 327 deletions

234
.travis.yml Normal file
View File

@@ -0,0 +1,234 @@
# Copyright 2018 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
language: cpp
sudo: false
python: "2.7"
branches:
only:
- master
- develop
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
- os: linux
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
- os: linux
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- cd ..
- git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost
- cd boost
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- mkdir -p libs/circular_buffer
- cp -r $TRAVIS_BUILD_DIR/* libs/circular_buffer
- python tools/boostdep/depinst/depinst.py circular_buffer
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- ./b2 -j 3 libs/circular_buffer/test toolset=$TOOLSET cxxstd=$CXXSTD
notifications:
email:
on_success: always

25
CMakeLists.txt Normal file
View File

@@ -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)

48
appveyor.yml Normal file
View File

@@ -0,0 +1,48 @@
# Copyright 2018 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-9.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-10.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-11.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-12.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
install:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% https://github.com/boostorg/boost.git boost
- cd boost
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\circular_buffer\
- python tools/boostdep/depinst/depinst.py circular_buffer
- cmd /c bootstrap
- b2 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- b2 -j 3 libs/circular_buffer/test toolset=%TOOLSET% %CXXSTD%

View File

@@ -46,7 +46,7 @@
[def __min_capacity [memberref boost::circular_buffer_space_optimized::min_capacity() min_capacity]]
[def __capacity_control [memberref boost::circular_buffer_space_optimized::capacity_control () capacity_control ]]
[def __debug_support [link circular_buffer.implmentation.debug_support debug support]]
[def __debug_support [link circular_buffer.implementation.debug_support debug support]]
[include ../../../tools/auto_index/include/auto_index_helpers.qbk]
[/ Must be first included file!]
@@ -114,7 +114,7 @@ Here is a simple example to introduce the class __cb.
[circular_buffer_example_1]
This example shows contruction, inserting elements, overwriting and popping.
This example shows construction, inserting elements, overwriting and popping.
[circular_buffer_example_2]
@@ -334,9 +334,9 @@ so for example: iterators `(begin() - 1)` and `(end() + 1)` are both invalid.
[h3 Debug Support]
In order to help a programmer to avoid and find common bugs,
the __cb contains a kind of debug support.
the __cb can be enabled to provide a kind of debug support.
The __cb maintains a list of valid iterators.
When the debugging functionality is enabled, the __cb maintains a list of valid iterators.
As soon as any element gets destroyed all iterators pointing to this element
are removed from this list and explicitly invalidated (an invalidation flag is set).
The debug support also consists of many assertions (`BOOST_ASSERT` macros)
@@ -349,9 +349,13 @@ Moreover, the uninitialized memory allocated by __cb is filled with the value `0
When debugging the code, this can help the programmer to recognize the initialized memory from the uninitialized.
For details refer the source code [@boost:boost/circular_buffer/debug.hpp circular_buffer/debug.hpp].
The debug support is enabled only in the debug mode (when the `NDEBUG` is not defined).
It can also be explicitly disabled (only for __cb)
by defining macro BOOST_CB_DISABLE_DEBUG.
[caution Since the debugging code makes __cb and its iterators more interconnected, thread safety guarantees of __cb
are different when debug support is enabled. In addition to the container itself, all iterators tracked by the container
(including any copies thereof) must be protected from concurrent access. In particular, this includes copying, destroying or
obtaining iterators from the container, even if for read-only access.]
The debug support is disabled by default. To enable it, one has to define `BOOST_CB_ENABLE_DEBUG` macro with the value of 1
while compiling the code using __cb.
[h3 Compatibility with Interprocess library]
@@ -359,8 +363,8 @@ The __cb is compatible with the [@boost:libs/interprocess/index.html Boost.Inte
[/ This should be in @boost:libs/interprocess/doc/index.html ]
library used for interprocess communication.
Considering that the circular_buffer's debug support relies on 'raw' pointers
(which is not permited by the Interprocess library)
the code has to compiled with `-DBOOST_CB_DISABLE_DEBUG` or `-DNDEBUG` (which disables the Debug Support).
(which is not permitted by the Interprocess library)
the code has to compiled with debug support disabled (i.e. with `BOOST_CB_ENABLE_DEBUG` macro not defined or defined to 0).
Not doing that will cause the compilation to fail.
[endsect] [/section:implementation Implementation ]
@@ -532,6 +536,10 @@ Type: Patches
[section:release Release Notes]
[h4 Boost 1.56]
* C++11 allocator model support implemented by Glen Fernandes.
[h4 Boost 1.55]
* Documentation refactored by Paul A. Bristow using Quickbook, Doxygen and Autoindexing.

View File

@@ -11,7 +11,7 @@
path-constant nav_images : html/images/ ; # png and svg images for home, next, note, tip...
path-constant images_location : html/images ; # location of my SVG and PNG images referenced by Quickbook.
path-constant pdf_images_location : html ; # location of SVG and PNG images referenced by pdf.
path-constant pdf_images_location : .. ; # location of SVG and PNG images referenced by pdf.
path-constant here : . ; # location of /doc folder.
# echo "nav_images = " $(nav_images) ; # "nav_images = I:\boost-trunk\libs\circular_buffer\doc\html\images
@@ -83,8 +83,8 @@ doxygen autodoc
# The syntax hoops to jump through are 'interesting' for more than one PREDEFINED,
# and to permit spaces within definitions (use double quotes).
# Don't forget that every double quote " needs a preceeding \trip character!
# and that each trailing continuation \ needs a preceeding \trip character too!
# Don't forget that every double quote " needs a preceding \trip character!
# and that each trailing continuation \ needs a preceding \trip character too!
# And finally that if more than one item is included (as here) the whole is
# enclosed in "PREDEFINED=... ", but without a leading \. Go figure...
@@ -181,14 +181,15 @@ boostbook standalone
# Set these one for PDF generation *only*:
# default png graphics are awful in PDF form,
# better use SVG instead:
#<format>pdf:<xsl:param>admon.graphics.extension=".svg"
<format>pdf:<xsl:param>admon.graphics.extension=".png" # Only png images are available.
<format>pdf:<xsl:param>admon.graphics.path=$(nav_images)/ # next, prev, note, tip ... for pdf.
<format>pdf:<xsl:param>admon.graphics.extension=".svg"
#<format>pdf:<xsl:param>admon.graphics.extension=".png" # Only png images are available.
# Don't need this, default path works OK:
#<format>pdf:<xsl:param>admon.graphics.path=$(nav_images)/ # next, prev, note, tip ... for pdf.
<format>pdf:<xsl:param>use.role.for.mediaobject=1
<format>pdf:<xsl:param>preferred.mediaobject.role=print
<format>pdf:<xsl:param>img.src.path=$(pdf_images_location)/ # graphics (diagrams) for pdf.
<format>pdf:<xsl:param>img.src.path=$(pdf_images_location)/ # graphics (diagrams) for pdf.
<format>pdf:<xsl:param>draft.mode="no"
<format>pdf:<xsl:param>boost.url.prefix=../../../..
<format>pdf:<xsl:param>boost.url.prefix=../../../..
<dependency>autodoc #
<dependency>png_install
@@ -205,7 +206,14 @@ install png_install : [ glob $(here)/*.png ] : <location>$(here)/../../../doc/ht
# because a modified pdf file is created, so this command
# will rename the file to the expected filename, here circular_buffer.pdf.
install pdf-install : standalone : <install-type>PDF <location>. <name>circular_buffer.pdf ;
install pdfinstall : standalone : <install-type>PDF <location>. <name>circular_buffer.pdf ;
###############################################################################
alias boostdoc
: standalone/<format>docbook
:
:
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;

View File

@@ -7,8 +7,6 @@
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CB_DISABLE_DEBUG
#include <boost/circular_buffer.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>

View File

@@ -20,7 +20,7 @@
// Create a circular buffer with a capacity for 3 integers.
boost::circular_buffer<int> cb(3);
// Insert threee elements into the buffer.
// Insert three elements into the buffer.
cb.push_back(1);
cb.push_back(2);
cb.push_back(3);

View File

@@ -1,5 +1,5 @@
echo off
rem quickbook doxgen auto-index docs template circular_buffer_html_index.bat
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

View File

@@ -5,11 +5,13 @@
// (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_DISABLE_DEBUG // The Debug Support has to be disabled, otherwise the code produces a runtime error.
#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>
@@ -34,5 +36,5 @@ int main(int /*argc*/, char* /*argv*/[])
return 0;
}
//] [/circular_buffer_iter_example_1]
//] [/circular_buffer_iter_example_1]

View File

@@ -11,18 +11,17 @@
#if !defined(BOOST_CIRCULAR_BUFFER_HPP)
#define BOOST_CIRCULAR_BUFFER_HPP
#if defined(_MSC_VER) && _MSC_VER >= 1200
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/circular_buffer_fwd.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
#include <boost/static_assert.hpp>
// BOOST_CB_ENABLE_DEBUG: Debug support control.
#if defined(NDEBUG) || defined(BOOST_CB_DISABLE_DEBUG)
#if !defined(BOOST_CB_ENABLE_DEBUG)
#define BOOST_CB_ENABLE_DEBUG 0
#else
#define BOOST_CB_ENABLE_DEBUG 1
#endif
// BOOST_CB_ASSERT: Runtime assertion.
@@ -33,29 +32,20 @@
#define BOOST_CB_ASSERT(Expr) ((void)0)
#endif
// BOOST_CB_STATIC_ASSERT: Compile time assertion.
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define BOOST_CB_STATIC_ASSERT(Expr) ((void)0)
#else
#include <boost/static_assert.hpp>
#define BOOST_CB_STATIC_ASSERT(Expr) BOOST_STATIC_ASSERT(Expr)
#endif
// BOOST_CB_IS_CONVERTIBLE: Check if Iterator::value_type is convertible to Type.
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407) || \
BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) ((void)0)
#else
#include <boost/detail/iterator.hpp>
#include <iterator>
#include <boost/type_traits/is_convertible.hpp>
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) \
BOOST_CB_STATIC_ASSERT((is_convertible<typename detail::iterator_traits<Iterator>::value_type, Type>::value))
BOOST_STATIC_ASSERT((is_convertible<typename std::iterator_traits<Iterator>::value_type, Type>::value))
#endif
// BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS:
// Check if the STL provides templated iterator constructors for its containers.
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_CB_STATIC_ASSERT(false);
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_STATIC_ASSERT(false);
#else
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS ((void)0);
#endif
@@ -67,8 +57,6 @@
#undef BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS
#undef BOOST_CB_IS_CONVERTIBLE
#undef BOOST_CB_STATIC_ASSERT
#undef BOOST_CB_ASSERT
#undef BOOST_CB_ENABLE_DEBUG
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_HPP)

View File

@@ -0,0 +1,89 @@
// Copyright 2018 Glen Joseph Fernandes
// (glenjofe@gmail.com)
//
// 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)
#ifndef BOOST_CIRCULAR_BUFFER_ALLOCATORS_HPP
#define BOOST_CIRCULAR_BUFFER_ALLOCATORS_HPP
#include <boost/config.hpp>
#if defined(BOOST_NO_CXX11_ALLOCATOR)
#define BOOST_CB_NO_CXX11_ALLOCATOR
#elif defined(BOOST_LIBSTDCXX_VERSION) && (BOOST_LIBSTDCXX_VERSION < 40800)
#define BOOST_CB_NO_CXX11_ALLOCATOR
#endif
#include <limits>
#if !defined(BOOST_CB_NO_CXX11_ALLOCATOR)
#include <memory>
#else
#include <new>
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <utility>
#endif
namespace boost {
namespace cb_details {
#if !defined(BOOST_CB_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_traits
: std::allocator_traits<A> {
using typename std::allocator_traits<A>::value_type;
using typename std::allocator_traits<A>::size_type;
static size_type max_size(const A&) BOOST_NOEXCEPT {
return std::numeric_limits<size_type>::max() / sizeof(value_type);
}
};
#else
template<class A>
struct allocator_traits {
typedef typename A::value_type value_type;
typedef typename A::pointer pointer;
typedef typename A::const_pointer const_pointer;
typedef typename A::difference_type difference_type;
typedef typename A::size_type size_type;
static size_type max_size(const A&) BOOST_NOEXCEPT {
return std::numeric_limits<size_type>::max() / sizeof(value_type);
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class U, class... Args>
static void construct(const A&, U* ptr, Args&&... args) {
::new((void*)ptr) U(std::forward<Args>(args)...);
}
#else
template<class U, class V>
static void construct(const A&, U* ptr, V&& value) {
::new((void*)ptr) U(std::forward<V>(value));
}
#endif
#else
template<class U, class V>
static void construct(const A&, U* ptr, const V& value) {
::new((void*)ptr) U(value);
}
template<class U, class V>
static void construct(const A&, U* ptr, V& value) {
::new((void*)ptr) U(value);
}
#endif
template<class U>
static void destroy(const A&, U* ptr) {
(void)ptr;
ptr->~U();
}
};
#endif
} // cb_details
} // boost
#endif

View File

@@ -4,6 +4,8 @@
// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed.
// Copyright (c) 2013 Antony Polukhin // Move semantics implementation.
// 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
@@ -12,16 +14,15 @@
#if !defined(BOOST_CIRCULAR_BUFFER_BASE_HPP)
#define BOOST_CIRCULAR_BUFFER_BASE_HPP
#if defined(_MSC_VER) && _MSC_VER >= 1200
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/call_traits.hpp>
#include <boost/concept_check.hpp>
#include <boost/limits.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/circular_buffer/allocators.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/type_traits/is_stateless.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_scalar.hpp>
@@ -29,26 +30,18 @@
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <boost/move/move.hpp>
#include <algorithm>
#include <iterator>
#include <utility>
#include <deque>
#include <stdexcept>
#if BOOST_CB_ENABLE_DEBUG
#include <cstring>
#endif
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
#include <stddef.h>
#endif
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std {
using ::memset;
}
#endif
namespace boost {
/*!
@@ -77,12 +70,15 @@ namespace boost {
*/
template <class T, class Alloc>
class circular_buffer
:
/*! \cond */
#if BOOST_CB_ENABLE_DEBUG
: public cb_details::debug_iterator_registry
public cb_details::debug_iterator_registry,
#endif
/*! \endcond */
private empty_value<Alloc>
{
typedef empty_value<Alloc> base;
// Requirements
//BOOST_CLASS_REQUIRE(T, boost, SGIAssignableConcept);
@@ -103,31 +99,31 @@ public:
typedef circular_buffer<T, Alloc> this_type;
//! The type of elements stored in the <code>circular_buffer</code>.
typedef typename Alloc::value_type value_type;
typedef typename cb_details::allocator_traits<Alloc>::value_type value_type;
//! A pointer to an element.
typedef typename Alloc::pointer pointer;
typedef typename cb_details::allocator_traits<Alloc>::pointer pointer;
//! A const pointer to the element.
typedef typename Alloc::const_pointer const_pointer;
typedef typename cb_details::allocator_traits<Alloc>::const_pointer const_pointer;
//! A reference to an element.
typedef typename Alloc::reference reference;
typedef value_type& reference;
//! A const reference to an element.
typedef typename Alloc::const_reference const_reference;
typedef const value_type& const_reference;
//! The distance type.
/*!
(A signed integral type used to represent the distance between two iterators.)
*/
typedef typename Alloc::difference_type difference_type;
typedef typename cb_details::allocator_traits<Alloc>::difference_type difference_type;
//! The size type.
/*!
(An unsigned integral type that can represent any non-negative value of the container's distance type.)
*/
typedef typename Alloc::size_type size_type;
typedef typename cb_details::allocator_traits<Alloc>::size_type size_type;
//! The type of an allocator used in the <code>circular_buffer</code>.
typedef Alloc allocator_type;
@@ -135,16 +131,16 @@ public:
// Iterators
//! A const (random access) iterator used to iterate through the <code>circular_buffer</code>.
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::const_traits<Alloc> > const_iterator;
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::const_traits<cb_details::allocator_traits<Alloc> > > const_iterator;
//! A (random access) iterator used to iterate through the <code>circular_buffer</code>.
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::nonconst_traits<Alloc> > iterator;
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::nonconst_traits<cb_details::allocator_traits<Alloc> > > iterator;
//! A const iterator used to iterate backwards through a <code>circular_buffer</code>.
typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
//! An iterator used to iterate backwards through a <code>circular_buffer</code>.
typedef boost::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
// Container specific types
@@ -183,23 +179,6 @@ public:
typedef BOOST_RV_REF(value_type) rvalue_type;
private:
// TODO: move to Boost.Move
/*! \cond */
template <class ValT>
static inline typename boost::conditional<
((boost::is_nothrow_move_constructible<ValT>::value && boost::is_nothrow_move_assignable<ValT>::value) || !boost::is_copy_constructible<ValT>::value)
#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
&& has_move_emulation_enabled<ValT>::value
#endif
,
rvalue_type,
param_value_type
>::type move_if_noexcept(ValT& value) BOOST_NOEXCEPT {
return boost::move(value);
}
/*! \endcond */
// Member variables
//! The internal buffer used for storing elements in the circular buffer.
@@ -217,9 +196,6 @@ private:
//! The number of items currently stored in the circular buffer.
size_type m_size;
//! The allocator.
allocator_type m_alloc;
// Friends
#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
friend iterator;
@@ -243,7 +219,7 @@ public:
Constant (in the size of the <code>circular_buffer</code>).
\sa <code>get_allocator()</code> for obtaining an allocator %reference.
*/
allocator_type get_allocator() const BOOST_NOEXCEPT { return m_alloc; }
allocator_type get_allocator() const BOOST_NOEXCEPT { return alloc(); }
//! Get the allocator reference.
/*!
@@ -259,7 +235,7 @@ public:
although use of stateful allocators in STL is discouraged.
\sa <code>get_allocator() const</code>
*/
allocator_type& get_allocator() BOOST_NOEXCEPT { return m_alloc; }
allocator_type& get_allocator() BOOST_NOEXCEPT { return alloc(); }
// Element access
@@ -690,11 +666,11 @@ public:
break;
}
if (is_uninitialized(dest)) {
::new (dest) value_type(this_type::move_if_noexcept(*src));
cb_details::allocator_traits<Alloc>::construct(alloc(), boost::to_address(dest), boost::move_if_noexcept(*src));
++constructed;
} else {
value_type tmp = this_type::move_if_noexcept(*src);
replace(src, this_type::move_if_noexcept(*dest));
value_type tmp = boost::move_if_noexcept(*src);
replace(src, boost::move_if_noexcept(*dest));
replace(dest, boost::move(tmp));
}
}
@@ -769,12 +745,12 @@ public:
difference_type n = new_begin - begin();
if (m < n) {
for (; m > 0; --m) {
push_front(this_type::move_if_noexcept(back()));
push_front(boost::move_if_noexcept(back()));
pop_back();
}
} else {
for (; n > 0; --n) {
push_back(this_type::move_if_noexcept(front()));
push_back(boost::move_if_noexcept(front()));
pop_front();
}
}
@@ -811,7 +787,7 @@ public:
\sa <code>size()</code>, <code>capacity()</code>, <code>reserve()</code>
*/
size_type max_size() const BOOST_NOEXCEPT {
return (std::min<size_type>)(m_alloc.max_size(), (std::numeric_limits<difference_type>::max)());
return (std::min<size_type>)(cb_details::allocator_traits<Alloc>::max_size(alloc()), (std::numeric_limits<difference_type>::max)());
}
//! Is the <code>circular_buffer</code> empty?
@@ -902,7 +878,7 @@ public:
iterator b = begin();
BOOST_TRY {
reset(buff,
cb_details::uninitialized_move_if_noexcept<value_type>(b, b + (std::min)(new_capacity, size()), buff),
cb_details::uninitialized_move_if_noexcept(b, b + (std::min)(new_capacity, size()), buff, alloc()),
new_capacity);
} BOOST_CATCH(...) {
deallocate(buff, new_capacity);
@@ -977,8 +953,8 @@ public:
pointer buff = allocate(new_capacity);
iterator e = end();
BOOST_TRY {
reset(buff, cb_details::uninitialized_move_if_noexcept<value_type>(e - (std::min)(new_capacity, size()),
e, buff), new_capacity);
reset(buff, cb_details::uninitialized_move_if_noexcept(e - (std::min)(new_capacity, size()),
e, buff, alloc()), new_capacity);
} BOOST_CATCH(...) {
deallocate(buff, new_capacity);
BOOST_RETHROW
@@ -1044,7 +1020,7 @@ public:
<code>set_capacity(capacity_type)</code>
*/
explicit circular_buffer(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT
: m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0), m_alloc(alloc) {}
: base(boost::empty_init_t(), alloc), m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0) {}
//! Create an empty <code>circular_buffer</code> with the specified capacity.
/*!
@@ -1057,7 +1033,7 @@ public:
Constant.
*/
explicit circular_buffer(capacity_type buffer_capacity, const allocator_type& alloc = allocator_type())
: m_size(0), m_alloc(alloc) {
: base(boost::empty_init_t(), alloc), m_size(0) {
initialize_buffer(buffer_capacity);
m_first = m_last = m_buff;
}
@@ -1076,7 +1052,7 @@ public:
Linear (in the <code>n</code>).
*/
circular_buffer(size_type n, param_value_type item, const allocator_type& alloc = allocator_type())
: m_size(n), m_alloc(alloc) {
: base(boost::empty_init_t(), alloc), m_size(n) {
initialize_buffer(n, item);
m_first = m_last = m_buff;
}
@@ -1098,7 +1074,7 @@ public:
*/
circular_buffer(capacity_type buffer_capacity, size_type n, param_value_type item,
const allocator_type& alloc = allocator_type())
: m_size(n), m_alloc(alloc) {
: base(boost::empty_init_t(), alloc), m_size(n) {
BOOST_CB_ASSERT(buffer_capacity >= size()); // check for capacity lower than size
initialize_buffer(buffer_capacity, item);
m_first = m_buff;
@@ -1121,11 +1097,12 @@ public:
#if BOOST_CB_ENABLE_DEBUG
debug_iterator_registry(),
#endif
m_size(cb.size()), m_alloc(cb.get_allocator()) {
base(boost::empty_init_t(), cb.get_allocator()),
m_size(cb.size()) {
initialize_buffer(cb.capacity());
m_first = m_buff;
BOOST_TRY {
m_last = cb_details::uninitialized_copy<value_type>(cb.begin(), cb.end(), m_buff);
m_last = cb_details::uninitialized_copy(cb.begin(), cb.end(), m_buff, alloc());
} BOOST_CATCH(...) {
deallocate(m_buff, cb.capacity());
BOOST_RETHROW
@@ -1145,30 +1122,11 @@ public:
\par Constant.
*/
circular_buffer(circular_buffer<T, Alloc>&& cb) BOOST_NOEXCEPT
: m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0), m_alloc(cb.get_allocator()) {
: base(boost::empty_init_t(), cb.get_allocator()), m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0) {
cb.swap(*this);
}
#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
/*! \cond */
template <class InputIterator>
circular_buffer(InputIterator first, InputIterator last)
: m_alloc(allocator_type()) {
initialize(first, last, is_integral<InputIterator>());
}
template <class InputIterator>
circular_buffer(capacity_type capacity, InputIterator first, InputIterator last)
: m_alloc(allocator_type()) {
initialize(capacity, first, last, is_integral<InputIterator>());
}
/*! \endcond */
#else
//! Create a full <code>circular_buffer</code> filled with a copy of the range.
/*!
\pre Valid range <code>[first, last)</code>.<br>
@@ -1187,7 +1145,7 @@ public:
*/
template <class InputIterator>
circular_buffer(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())
: m_alloc(alloc) {
: base(boost::empty_init_t(), alloc) {
initialize(first, last, is_integral<InputIterator>());
}
@@ -1217,12 +1175,10 @@ public:
template <class InputIterator>
circular_buffer(capacity_type buffer_capacity, InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type())
: m_alloc(alloc) {
: base(boost::empty_init_t(), alloc) {
initialize(buffer_capacity, first, last, is_integral<InputIterator>());
}
#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
//! The destructor.
/*!
Destroys the <code>circular_buffer</code>.
@@ -1270,7 +1226,7 @@ public:
return *this;
pointer buff = allocate(cb.capacity());
BOOST_TRY {
reset(buff, cb_details::uninitialized_copy<value_type>(cb.begin(), cb.end(), buff), cb.capacity());
reset(buff, cb_details::uninitialized_copy(cb.begin(), cb.end(), buff, alloc()), cb.capacity());
} BOOST_CATCH(...) {
deallocate(buff, cb.capacity());
BOOST_RETHROW
@@ -1290,7 +1246,7 @@ public:
*/
circular_buffer<T, Alloc>& operator = (circular_buffer<T, Alloc>&& cb) BOOST_NOEXCEPT {
cb.swap(*this); // now `this` holds `cb`
circular_buffer<T, Alloc>(get_allocator()) // temprary that holds initial `cb` allocator
circular_buffer<T, Alloc>(get_allocator()) // temporary that holds initial `cb` allocator
.swap(cb); // makes `cb` empty
return *this;
}
@@ -1321,7 +1277,7 @@ public:
<code>assign(capacity_type, InputIterator, InputIterator)</code>
*/
void assign(size_type n, param_value_type item) {
assign_n(n, n, cb_details::assign_n<param_value_type, allocator_type>(n, item, m_alloc));
assign_n(n, n, cb_details::assign_n<param_value_type, allocator_type>(n, item, alloc()));
}
//! Assign <code>n</code> items into the <code>circular_buffer</code> specifying the capacity.
@@ -1351,7 +1307,7 @@ public:
*/
void assign(capacity_type buffer_capacity, size_type n, param_value_type item) {
BOOST_CB_ASSERT(buffer_capacity >= n); // check for new capacity lower than n
assign_n(buffer_capacity, n, cb_details::assign_n<param_value_type, allocator_type>(n, item, m_alloc));
assign_n(buffer_capacity, n, cb_details::assign_n<param_value_type, allocator_type>(n, item, alloc()));
}
//! Assign a copy of the range into the <code>circular_buffer</code>.
@@ -1445,11 +1401,11 @@ public:
*/
void swap(circular_buffer<T, Alloc>& cb) BOOST_NOEXCEPT {
swap_allocator(cb, is_stateless<allocator_type>());
std::swap(m_buff, cb.m_buff);
std::swap(m_end, cb.m_end);
std::swap(m_first, cb.m_first);
std::swap(m_last, cb.m_last);
std::swap(m_size, cb.m_size);
adl_move_swap(m_buff, cb.m_buff);
adl_move_swap(m_end, cb.m_end);
adl_move_swap(m_first, cb.m_first);
adl_move_swap(m_last, cb.m_last);
adl_move_swap(m_size, cb.m_size);
#if BOOST_CB_ENABLE_DEBUG
invalidate_all_iterators();
cb.invalidate_all_iterators();
@@ -1467,7 +1423,7 @@ private:
increment(m_last);
m_first = m_last;
} else {
::new (m_last) value_type(static_cast<ValT>(item));
cb_details::allocator_traits<Alloc>::construct(alloc(), boost::to_address(m_last), static_cast<ValT>(item));
increment(m_last);
++m_size;
}
@@ -1484,7 +1440,7 @@ private:
m_last = m_first;
} else {
decrement(m_first);
::new (m_first) value_type(static_cast<ValT>(item));
cb_details::allocator_traits<Alloc>::construct(alloc(), boost::to_address(m_first), static_cast<ValT>(item));
++m_size;
}
} BOOST_CATCH(...) {
@@ -1907,7 +1863,7 @@ private:
bool construct = !full();
BOOST_TRY {
while (src != pos.m_it) {
construct_or_replace(construct, dest, this_type::move_if_noexcept(*src));
construct_or_replace(construct, dest, boost::move_if_noexcept(*src));
increment(src);
increment(dest);
construct = false;
@@ -2154,7 +2110,7 @@ public:
pointer next = pos.m_it;
increment(next);
for (pointer p = pos.m_it; next != m_last; p = next, increment(next))
replace(p, this_type::move_if_noexcept(*next));
replace(p, boost::move_if_noexcept(*next));
decrement(m_last);
destroy_item(m_last);
--m_size;
@@ -2193,7 +2149,7 @@ public:
return first;
pointer p = first.m_it;
while (last.m_it != 0)
replace((first++).m_it, this_type::move_if_noexcept(*last++));
replace((first++).m_it, boost::move_if_noexcept(*last++));
do {
decrement(m_last);
destroy_item(m_last);
@@ -2218,7 +2174,7 @@ public:
the erased element (towards the beginning).
\par Complexity
Linear (in <code>std::distance(begin(), pos)</code>).
\note This method is symetric to the <code>erase(iterator)</code> method and is more effective than
\note This method is symmetric to the <code>erase(iterator)</code> method and is more effective than
<code>erase(iterator)</code> if the iterator <code>pos</code> is close to the beginning of the
<code>circular_buffer</code>. (See the <i>Complexity</i>.)
\sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
@@ -2231,7 +2187,7 @@ public:
pointer prev = pos.m_it;
pointer p = prev;
for (decrement(prev); p != m_first; p = prev, decrement(prev))
replace(p, this_type::move_if_noexcept(*prev));
replace(p, boost::move_if_noexcept(*prev));
destroy_item(m_first);
increment(m_first);
--m_size;
@@ -2259,7 +2215,7 @@ public:
the erased range (towards the beginning).
\par Complexity
Linear (in <code>std::distance(begin(), last)</code>).
\note This method is symetric to the <code>erase(iterator, iterator)</code> method and is more effective than
\note This method is symmetric to the <code>erase(iterator, iterator)</code> method and is more effective than
<code>erase(iterator, iterator)</code> if <code>std::distance(begin(), first)</code> is lower that
<code>std::distance(last, end())</code>.
\sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
@@ -2276,7 +2232,7 @@ public:
while (first.m_it != m_first) {
decrement(first.m_it);
decrement(p);
replace(p, this_type::move_if_noexcept(*first.m_it));
replace(p, boost::move_if_noexcept(*first.m_it));
}
do {
destroy_item(m_first);
@@ -2412,23 +2368,31 @@ private:
//! Map the null pointer to virtual end of circular buffer.
pointer map_pointer(pointer p) const { return p == 0 ? m_last : p; }
const Alloc& alloc() const {
return base::get();
}
Alloc& alloc() {
return base::get();
}
//! Allocate memory.
pointer allocate(size_type n) {
if (n > max_size())
throw_exception(std::length_error("circular_buffer"));
#if BOOST_CB_ENABLE_DEBUG
pointer p = (n == 0) ? 0 : m_alloc.allocate(n, 0);
std::memset(p, cb_details::UNINITIALIZED, sizeof(value_type) * n);
pointer p = (n == 0) ? 0 : alloc().allocate(n);
cb_details::do_fill_uninitialized_memory(p, sizeof(value_type) * n);
return p;
#else
return (n == 0) ? 0 : m_alloc.allocate(n, 0);
return (n == 0) ? 0 : alloc().allocate(n);
#endif
}
//! Deallocate memory.
void deallocate(pointer p, size_type n) {
if (p != 0)
m_alloc.deallocate(p, n);
alloc().deallocate(p, n);
}
//! Does the pointer point to the uninitialized memory?
@@ -2459,7 +2423,7 @@ private:
*/
void construct_or_replace(bool construct, pointer pos, param_value_type item) {
if (construct)
::new (pos) value_type(item);
cb_details::allocator_traits<Alloc>::construct(alloc(), boost::to_address(pos), item);
else
replace(pos, item);
}
@@ -2471,17 +2435,17 @@ private:
*/
void construct_or_replace(bool construct, pointer pos, rvalue_type item) {
if (construct)
::new (pos) value_type(boost::move(item));
cb_details::allocator_traits<Alloc>::construct(alloc(), boost::to_address(pos), boost::move(item));
else
replace(pos, boost::move(item));
}
//! Destroy an item.
void destroy_item(pointer p) {
m_alloc.destroy(p);
cb_details::allocator_traits<Alloc>::destroy(alloc(), boost::to_address(p));
#if BOOST_CB_ENABLE_DEBUG
invalidate_iterators(iterator(this, p));
std::memset(p, cb_details::UNINITIALIZED, sizeof(value_type));
cb_details::do_fill_uninitialized_memory(p, sizeof(value_type));
#endif
}
@@ -2533,7 +2497,7 @@ private:
void initialize_buffer(capacity_type buffer_capacity, param_value_type item) {
initialize_buffer(buffer_capacity);
BOOST_TRY {
cb_details::uninitialized_fill_n_with_alloc(m_buff, size(), item, m_alloc);
cb_details::uninitialized_fill_n_with_alloc(m_buff, size(), item, alloc());
} BOOST_CATCH(...) {
deallocate(m_buff, size());
BOOST_RETHROW
@@ -2554,9 +2518,9 @@ private:
void initialize(Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
initialize(first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
initialize(first, last, std::iterator_traits<Iterator>::iterator_category());
#else
initialize(first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
initialize(first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
#endif
}
@@ -2565,7 +2529,7 @@ private:
void initialize(InputIterator first, InputIterator last, const std::input_iterator_tag&) {
BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors
// for containers
std::deque<value_type, allocator_type> tmp(first, last, m_alloc);
std::deque<value_type, allocator_type> tmp(first, last, alloc());
size_type distance = tmp.size();
initialize(distance, boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), distance);
}
@@ -2593,9 +2557,9 @@ private:
void initialize(capacity_type buffer_capacity, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
initialize(buffer_capacity, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
initialize(buffer_capacity, first, last, std::iterator_traits<Iterator>::iterator_category());
#else
initialize(buffer_capacity, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
initialize(buffer_capacity, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
#endif
}
@@ -2611,7 +2575,7 @@ private:
if (buffer_capacity == 0)
return;
while (first != last && !full()) {
::new (m_last) value_type(*first++);
cb_details::allocator_traits<Alloc>::construct(alloc(), boost::to_address(m_last), *first++);
increment(m_last);
++m_size;
}
@@ -2647,7 +2611,7 @@ private:
m_size = distance;
}
BOOST_TRY {
m_last = cb_details::uninitialized_copy<value_type>(first, last, m_buff);
m_last = cb_details::uninitialized_copy(first, last, m_buff, alloc());
} BOOST_CATCH(...) {
deallocate(m_buff, buffer_capacity);
BOOST_RETHROW
@@ -2673,7 +2637,7 @@ private:
//! Specialized method for swapping the allocator.
void swap_allocator(circular_buffer<T, Alloc>& cb, const false_type&) {
std::swap(m_alloc, cb.m_alloc);
adl_move_swap(alloc(), cb.alloc());
}
//! Specialized assign method.
@@ -2687,9 +2651,9 @@ private:
void assign(Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
assign(first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
assign(first, last, std::iterator_traits<Iterator>::iterator_category());
#else
assign(first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
assign(first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
#endif
}
@@ -2698,11 +2662,11 @@ private:
void assign(InputIterator first, InputIterator last, const std::input_iterator_tag&) {
BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors
// for containers
std::deque<value_type, allocator_type> tmp(first, last, m_alloc);
std::deque<value_type, allocator_type> tmp(first, last, alloc());
size_type distance = tmp.size();
assign_n(distance, distance,
cb_details::make_assign_range<value_type>
(boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end())));
cb_details::make_assign_range
(boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), alloc()));
}
//! Specialized assign method.
@@ -2710,7 +2674,7 @@ private:
void assign(ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) {
BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
size_type distance = std::distance(first, last);
assign_n(distance, distance, cb_details::make_assign_range<value_type>(first, last));
assign_n(distance, distance, cb_details::make_assign_range(first, last, alloc()));
}
//! Specialized assign method.
@@ -2724,9 +2688,9 @@ private:
void assign(capacity_type new_capacity, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
assign(new_capacity, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
assign(new_capacity, first, last, std::iterator_traits<Iterator>::iterator_category());
#else
assign(new_capacity, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
assign(new_capacity, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
#endif
}
@@ -2737,12 +2701,7 @@ private:
clear();
insert(begin(), first, last);
} else {
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
circular_buffer<value_type, allocator_type> tmp(new_capacity, m_alloc);
tmp.insert(begin(), first, last);
#else
circular_buffer<value_type, allocator_type> tmp(new_capacity, first, last, m_alloc);
#endif
circular_buffer<value_type, allocator_type> tmp(new_capacity, first, last, alloc());
tmp.swap(*this);
}
}
@@ -2758,7 +2717,7 @@ private:
distance = new_capacity;
}
assign_n(new_capacity, distance,
cb_details::make_assign_range<value_type>(first, last));
cb_details::make_assign_range(first, last, alloc()));
}
//! Helper assign method.
@@ -2805,7 +2764,7 @@ private:
BOOST_TRY {
while (src != p) {
decrement(src);
construct_or_replace(construct, dest, this_type::move_if_noexcept(*src));
construct_or_replace(construct, dest, boost::move_if_noexcept(*src));
decrement(dest);
construct = false;
}
@@ -2838,9 +2797,9 @@ private:
void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
insert(pos, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
insert(pos, first, last, std::iterator_traits<Iterator>::iterator_category());
#else
insert(pos, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
insert(pos, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
#endif
}
@@ -2881,7 +2840,7 @@ private:
pointer p = m_last;
BOOST_TRY {
for (; ii < construct; ++ii, increment(p))
::new (p) value_type(*wrapper());
cb_details::allocator_traits<Alloc>::construct(alloc(), boost::to_address(p), *wrapper());
for (;ii < n; ++ii, increment(p))
replace(p, *wrapper());
} BOOST_CATCH(...) {
@@ -2929,9 +2888,9 @@ private:
void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
rinsert(pos, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
rinsert(pos, first, last, std::iterator_traits<Iterator>::iterator_category());
#else
rinsert(pos, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
rinsert(pos, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
#endif
}
@@ -2975,7 +2934,7 @@ private:
for (;ii > construct; --ii, increment(p))
replace(p, *wrapper());
for (; ii > 0; --ii, increment(p))
::new (p) value_type(*wrapper());
cb_details::allocator_traits<Alloc>::construct(alloc(), boost::to_address(p), *wrapper());
} BOOST_CATCH(...) {
size_type constructed = ii < construct ? construct - ii : 0;
m_last = add(m_last, constructed);

View File

@@ -9,10 +9,20 @@
#if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
#define BOOST_CIRCULAR_BUFFER_DEBUG_HPP
#if defined(_MSC_VER) && _MSC_VER >= 1200
#if defined(_MSC_VER)
#pragma once
#endif
#if BOOST_CB_ENABLE_DEBUG
#include <cstring>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std {
using ::memset;
}
#endif
#endif // BOOST_CB_ENABLE_DEBUG
namespace boost {
namespace cb_details {
@@ -22,6 +32,17 @@ namespace cb_details {
// The value the uninitialized memory is filled with.
const int UNINITIALIZED = 0xcc;
template <class T>
inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT {
std::memset(static_cast<void*>(data), UNINITIALIZED, size_in_bytes);
}
template <class T>
inline void do_fill_uninitialized_memory(T& /*data*/, std::size_t /*size_in_bytes*/) BOOST_NOEXCEPT {
// Do nothing
}
class debug_iterator_registry;
/*!

View File

@@ -2,6 +2,9 @@
// Copyright (c) 2003-2008 Jan Gaspar
// 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)
@@ -9,15 +12,16 @@
#if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
#define BOOST_CIRCULAR_BUFFER_DETAILS_HPP
#if defined(_MSC_VER) && _MSC_VER >= 1200
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/iterator.hpp>
#include <boost/throw_exception.hpp>
#include <boost/circular_buffer/allocators.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <iterator>
// Silence MS /W4 warnings like C4913:
@@ -38,11 +42,11 @@ template<class ForwardIterator, class Diff, class T, class Alloc>
void uninitialized_fill_n_with_alloc(
ForwardIterator first, Diff n, const T& item, Alloc& alloc);
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest);
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest);
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
/*!
\struct const_traits
@@ -53,7 +57,7 @@ struct const_traits {
// Basic types
typedef typename Traits::value_type value_type;
typedef typename Traits::const_pointer pointer;
typedef typename Traits::const_reference reference;
typedef const value_type& reference;
typedef typename Traits::size_type size_type;
typedef typename Traits::difference_type difference_type;
@@ -70,7 +74,7 @@ struct nonconst_traits {
// Basic types
typedef typename Traits::value_type value_type;
typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference;
typedef value_type& reference;
typedef typename Traits::size_type size_type;
typedef typename Traits::difference_type difference_type;
@@ -110,7 +114,7 @@ private:
*/
template <class Value, class Alloc>
struct assign_n {
typedef typename Alloc::size_type size_type;
typedef typename allocator_traits<Alloc>::size_type size_type;
size_type m_n;
Value m_item;
Alloc& m_alloc;
@@ -127,23 +131,24 @@ private:
\struct assign_range
\brief Helper functor for assigning range of items.
*/
template <class ValueType, class Iterator>
template <class Iterator, class Alloc>
struct assign_range {
Iterator m_first;
Iterator m_last;
Alloc& m_alloc;
assign_range(const Iterator& first, const Iterator& last) BOOST_NOEXCEPT
: m_first(first), m_last(last) {}
assign_range(const Iterator& first, const Iterator& last, Alloc& alloc)
: m_first(first), m_last(last), m_alloc(alloc) {}
template <class Pointer>
void operator () (Pointer p) const {
boost::cb_details::uninitialized_copy<ValueType>(m_first, m_last, p);
boost::cb_details::uninitialized_copy(m_first, m_last, p, m_alloc);
}
};
template <class ValueType, class Iterator>
inline assign_range<ValueType, Iterator> make_assign_range(const Iterator& first, const Iterator& last) {
return assign_range<ValueType, Iterator>(first, last);
template <class Iterator, class Alloc>
inline assign_range<Iterator, Alloc> make_assign_range(const Iterator& first, const Iterator& last, Alloc& a) {
return assign_range<Iterator, Alloc>(first, last, a);
}
/*!
@@ -191,46 +196,33 @@ public:
for iterating from begin() to end() of the circular buffer.
*/
template <class Buff, class Traits>
struct iterator :
public boost::iterator<
std::random_access_iterator_tag,
typename Traits::value_type,
typename Traits::difference_type,
typename Traits::pointer,
typename Traits::reference>
struct iterator
#if BOOST_CB_ENABLE_DEBUG
, public debug_iterator_base
: public debug_iterator_base
#endif // #if BOOST_CB_ENABLE_DEBUG
{
// Helper types
//! Base iterator.
typedef boost::iterator<
std::random_access_iterator_tag,
typename Traits::value_type,
typename Traits::difference_type,
typename Traits::pointer,
typename Traits::reference> base_iterator;
//! Non-const iterator.
typedef iterator<Buff, typename Traits::nonconst_self> nonconst_self;
// Basic types
typedef std::random_access_iterator_tag iterator_category;
//! The type of the elements stored in the circular buffer.
typedef typename base_iterator::value_type value_type;
typedef typename Traits::value_type value_type;
//! Pointer to the element.
typedef typename base_iterator::pointer pointer;
typedef typename Traits::pointer pointer;
//! Reference to the element.
typedef typename base_iterator::reference reference;
typedef typename Traits::reference reference;
//! Size type.
typedef typename Traits::size_type size_type;
//! Difference type.
typedef typename base_iterator::difference_type difference_type;
typedef typename Traits::difference_type difference_type;
// Member variables
@@ -423,70 +415,47 @@ operator + (typename Traits::difference_type n, const iterator<Buff, Traits>& it
return it + n;
}
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
//! Iterator category.
template <class Buff, class Traits>
inline std::random_access_iterator_tag iterator_category(const iterator<Buff, Traits>&) {
return std::random_access_iterator_tag();
}
//! The type of the elements stored in the circular buffer.
template <class Buff, class Traits>
inline typename Traits::value_type* value_type(const iterator<Buff, Traits>&) { return 0; }
//! Distance type.
template <class Buff, class Traits>
inline typename Traits::difference_type* distance_type(const iterator<Buff, Traits>&) { return 0; }
#endif // #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
/*!
\fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest)
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type.
*/
template<class ValueType, class InputIterator, class ForwardIterator>
inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) {
typedef ValueType value_type;
// We do not use allocator.construct and allocator.destroy
// because C++03 requires to take parameter by const reference but
// Boost.move requires nonconst reference
template<class InputIterator, class ForwardIterator, class Alloc>
inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
ForwardIterator next = dest;
BOOST_TRY {
for (; first != last; ++first, ++dest)
::new (dest) value_type(*first);
allocator_traits<Alloc>::construct(a, boost::to_address(dest), *first);
} BOOST_CATCH(...) {
for (; next != dest; ++next)
next->~value_type();
allocator_traits<Alloc>::destroy(a, boost::to_address(next));
BOOST_RETHROW
}
BOOST_CATCH_END
return dest;
}
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest,
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
true_type) {
for (; first != last; ++first, ++dest)
::new (dest) ValueType(boost::move(*first));
allocator_traits<Alloc>::construct(a, boost::to_address(dest), boost::move(*first));
return dest;
}
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest,
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
false_type) {
return uninitialized_copy<ValueType>(first, last, dest);
return uninitialized_copy(first, last, dest, a);
}
/*!
\fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest)
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type and moves elements if they have noexcept move constructors.
*/
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) {
typedef typename boost::is_nothrow_move_constructible<ValueType>::type tag_t;
return uninitialized_move_if_noexcept_impl<ValueType>(first, last, dest, tag_t());
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
typedef typename boost::is_nothrow_move_constructible<typename allocator_traits<Alloc>::value_type>::type tag_t;
return uninitialized_move_if_noexcept_impl(first, last, dest, a, tag_t());
}
/*!
@@ -498,10 +467,10 @@ inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const
ForwardIterator next = first;
BOOST_TRY {
for (; n > 0; ++first, --n)
alloc.construct(first, item);
allocator_traits<Alloc>::construct(alloc, boost::to_address(first), item);
} BOOST_CATCH(...) {
for (; next != first; ++next)
alloc.destroy(next);
allocator_traits<Alloc>::destroy(alloc, boost::to_address(next));
BOOST_RETHROW
}
BOOST_CATCH_END

View File

@@ -11,12 +11,12 @@
#if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)
#define BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP
#if defined(_MSC_VER) && _MSC_VER >= 1200
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/type_traits/is_same.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
namespace boost {
@@ -416,31 +416,6 @@ public:
: circular_buffer<T, Alloc>(init_capacity(capacity_ctrl, n), n, item, alloc)
, m_capacity_ctrl(capacity_ctrl) {}
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
/*! \cond */
circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
: circular_buffer<T, Alloc>(cb.begin(), cb.end())
, m_capacity_ctrl(cb.m_capacity_ctrl) {}
template <class InputIterator>
circular_buffer_space_optimized(InputIterator first, InputIterator last)
: circular_buffer<T, Alloc>(first, last)
, m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
template <class InputIterator>
circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last)
: circular_buffer<T, Alloc>(
init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
first, last)
, m_capacity_ctrl(capacity_ctrl) {
reduce_capacity(
is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
}
/*! \endcond */
#else
//! The copy constructor.
/*!
Creates a copy of the specified <code>circular_buffer_space_optimized</code>.
@@ -534,11 +509,9 @@ public:
first, last, alloc)
, m_capacity_ctrl(capacity_ctrl) {
reduce_capacity(
is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
is_same< BOOST_DEDUCED_TYPENAME std::iterator_traits<InputIterator>::iterator_category, std::input_iterator_tag >());
}
#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#if defined(BOOST_CB_NEVER_DEFINED)
// This section will never be compiled - the default destructor will be generated instead.
// Declared only for documentation purpose.
@@ -606,7 +579,7 @@ public:
*/
circular_buffer_space_optimized<T, Alloc>& operator = (circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT {
cb.swap(*this); // now `this` holds `cb`
circular_buffer<T, Alloc>(get_allocator()) // temprary that holds initial `cb` allocator
circular_buffer<T, Alloc>(get_allocator()) // temporary that holds initial `cb` allocator
.swap(cb); // makes `cb` empty
return *this;
}
@@ -767,7 +740,7 @@ public:
\par Iterator Invalidation
Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other
hand the iterators still point to the same elements but within another container. If you want to rely on
this feature you have to turn the __debug_support off by defining macro BOOST_CB_DISABLE_DEBUG,
this feature you have to turn the __debug_support off,
otherwise an assertion will report an error if such invalidated iterator is used.)
\par Complexity
Constant (in the size of the <code>circular_buffer_space_optimized</code>).
@@ -1632,10 +1605,10 @@ private:
const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
return init_capacity(capacity_ctrl, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
return init_capacity(capacity_ctrl, first, last, std::iterator_traits<Iterator>::iterator_category());
#else
return init_capacity(
capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
#endif
}

View File

@@ -11,7 +11,7 @@
#if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP)
#define BOOST_CIRCULAR_BUFFER_FWD_HPP
#if defined(_MSC_VER) && _MSC_VER >= 1200
#if defined(_MSC_VER)
#pragma once
#endif

14
meta/libraries.json Normal file
View File

@@ -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>"
]
}

View File

@@ -6,7 +6,7 @@
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Added warning supression Paul A. Bristow 25 Nov 2008
# Added warning suppression Paul A. Bristow 25 Nov 2008
# Bring in rules for testing.
import testing ;
@@ -22,9 +22,11 @@ project
;
test-suite "circular_buffer"
: [ run base_test.cpp : <threading>single : ]
[ run space_optimized_test.cpp : <threading>single : ]
[ run soft_iterator_invalidation.cpp : <threading>single : ]
[ run constant_erase_test.cpp : <threading>single : ]
: [ 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 : ]
;

View File

@@ -193,7 +193,7 @@ void iterator_comparison_test() {
void iterator_invalidation_test() {
#if !defined(NDEBUG) && !defined(BOOST_CB_DISABLE_DEBUG)
#if BOOST_CB_ENABLE_DEBUG
circular_buffer<MyInteger>::iterator it1;
circular_buffer<MyInteger>::const_iterator it2;
@@ -563,7 +563,7 @@ void iterator_invalidation_test() {
BOOST_CHECK(it3.is_valid(&cb16));
BOOST_CHECK(!it4.is_valid(&cb16));
#endif // #if !defined(NDEBUG) && !defined(BOOST_CB_DISABLE_DEBUG)
#endif // #if BOOST_CB_ENABLE_DEBUG
}
// basic exception safety test (it is useful to use any memory-leak detection tool)

View File

@@ -7,8 +7,6 @@
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CB_DISABLE_DEBUG
#include <boost/circular_buffer.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>

View File

@@ -3,6 +3,9 @@
// 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)
@@ -11,7 +14,8 @@
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include <boost/type_traits/has_nothrow_constructor.hpp>
void generic_test(CB_CONTAINER<MyInteger>& cb) {
template <class Alloc>
void generic_test(CB_CONTAINER<MyInteger, Alloc>& cb) {
vector<int> v;
v.push_back(11);
@@ -149,6 +153,91 @@ void size_test() {
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(); }
};
void allocator_test() {
CB_CONTAINER<MyInteger> cb1(10, 0);
@@ -159,8 +248,40 @@ void allocator_test() {
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;
@@ -1988,7 +2109,6 @@ void move_container_on_cpp11() {
struct noncopyable_movable_except_t
: private boost::noncopyable // required, until there will be no support for is_copy_constructible added to Boost.Move
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(noncopyable_movable_except_t)
@@ -2027,7 +2147,6 @@ public:
};
struct noncopyable_movable_noexcept_t
: private boost::noncopyable // required, until there will be no support for is_copy_constructible added to Boost.Move
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(noncopyable_movable_noexcept_t)
@@ -2065,7 +2184,7 @@ public:
void reinit() { is_moved_ = false; value_ = next_value ++; }
};
#ifdef BOOST_NO_CXX11_NOEXCEPT
#if defined(BOOST_NO_CXX11_NOEXCEPT) || !defined(BOOST_IS_NOTHROW_MOVE_CONSTRUCT)
namespace boost {
template <>
struct is_nothrow_move_constructible<noncopyable_movable_noexcept_t>
@@ -2299,9 +2418,13 @@ void check_containers_exception_specifications() {
#endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#ifdef BOOST_IS_NOTHROW_MOVE_ASSIGN
BOOST_CHECK(boost::is_nothrow_move_assignable<CB_CONTAINER<int> >::value);
#endif
#ifdef BOOST_IS_NOTHROW_MOVE_CONSTRUCT
BOOST_CHECK(boost::is_nothrow_move_constructible<CB_CONTAINER<int> >::value);
#endif
#endif
#endif // BOOST_NO_CXX11_NOEXCEPT
}
@@ -2353,5 +2476,8 @@ void add_common_tests(test_suite* tests) {
tests->add(BOOST_TEST_CASE(&move_container_on_cpp11));
tests->add(BOOST_TEST_CASE(&move_container_values_noexcept));
tests->add(BOOST_TEST_CASE(&check_containers_exception_specifications));
#if !defined(BOOST_CB_NO_CXX11_ALLOCATOR)
tests->add(BOOST_TEST_CASE(&cxx11_allocator_test));
#endif
}

View File

@@ -6,8 +6,6 @@
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CB_DISABLE_DEBUG
#include "test.hpp"
int MyInteger::ms_exception_trigger = 0;

View File

@@ -9,8 +9,6 @@
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CB_DISABLE_DEBUG
#include "test.hpp"
// test of the example (introduced in the documentation)
@@ -602,7 +600,7 @@ void validity_swap_test() {
cb1.swap(cb2);
// Although iterators refer to the original elements,
// their interal state is inconsistent and no other operation
// their internal state is inconsistent and no other operation
// (except dereferencing) can be invoked on them any more.
BOOST_CHECK(*it11 == 1);
BOOST_CHECK(*it12 == 2);

View File

@@ -125,7 +125,7 @@ void shrink_to_fit_test() {
void iterator_invalidation_test() {
#if !defined(NDEBUG) && !defined(BOOST_CB_DISABLE_DEBUG)
#if BOOST_CB_ENABLE_DEBUG
cb_space_optimized cb1(10, 1);
cb1.push_back(2);
@@ -177,7 +177,7 @@ void iterator_invalidation_test() {
BOOST_CHECK(!it2.is_valid(&cb1));
BOOST_CHECK(!it3.is_valid(&cb1));
#endif // #if !defined(NDEBUG) && !defined(BOOST_CB_DISABLE_DEBUG)
#endif // #if BOOST_CB_ENABLE_DEBUG
}
// test main

View File

@@ -17,7 +17,6 @@
#include <boost/circular_buffer.hpp>
#include <boost/test/included/unit_test.hpp>
#include <boost/iterator.hpp>
#include <iterator>
#include <numeric>
#include <vector>
@@ -90,6 +89,7 @@ public:
eVirtual
};
Dummy() : m_n(eVar) {}
virtual ~Dummy() {}
DummyEnum fnc() { return eFnc; }
DummyEnum const_fnc() const { return eConst; }
virtual DummyEnum virtual_fnc() { return eVirtual; }
@@ -97,9 +97,9 @@ public:
};
// simulator of an input iterator
struct MyInputIterator
: boost::iterator<std::input_iterator_tag, int, ptrdiff_t, int*, int&> {
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;