Squashed 'boost/' changes from d9443bc48..c27aa31f0

c27aa31f0 Updated Boost to v1.70.0 including iterator range math numeric crc circular_buffer multi_index intrusive

git-subtree-dir: boost
git-subtree-split: c27aa31f06ebf1a91b3fa3ae9df9b5efdf14ec9f
This commit is contained in:
Bill Somerville 2019-07-02 23:38:24 +01:00
parent edd0930758
commit d361e123c6
6021 changed files with 118782 additions and 872011 deletions

View File

@ -1,8 +0,0 @@
See ./index.html for information about this release. The "Getting Started"
section is a useful starting place.
---------------------------
Copyright Beman Dawes, 2008
Distributed under the Boost Software License, Version 1.0.
See ./LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt

312
Jamroot
View File

@ -1,312 +0,0 @@
# Copyright Vladimir Prus 2002-2006.
# Copyright Dave Abrahams 2005-2006.
# Copyright Rene Rivera 2005-2007.
# Copyright Douglas Gregor 2005.
#
# 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)
# Usage:
#
# b2 [options] [properties] [install|stage]
#
# Builds and installs Boost.
#
# Targets and Related Options:
#
# install Install headers and compiled library files to the
# ======= configured locations (below).
#
# --prefix=<PREFIX> Install architecture independent files here.
# Default; C:\Boost on Win32
# Default; /usr/local on Unix. Linux, etc.
#
# --exec-prefix=<EPREFIX> Install architecture dependent files here.
# Default; <PREFIX>
#
# --libdir=<DIR> Install library files here.
# Default; <EPREFIX>/lib
#
# --includedir=<HDRDIR> Install header files here.
# Default; <PREFIX>/include
#
# stage Build and install only compiled library files to the
# ===== stage directory.
#
# --stagedir=<STAGEDIR> Install library files here
# Default; ./stage
#
# Other Options:
#
# --build-type=<type> Build the specified pre-defined set of variations of
# the libraries. Note, that which variants get built
# depends on what each library supports.
#
# -- minimal -- (default) Builds a minimal set of
# variants. On Windows, these are static
# multithreaded libraries in debug and release
# modes, using shared runtime. On Linux, these are
# static and shared multithreaded libraries in
# release mode.
#
# -- complete -- Build all possible variations.
#
# --build-dir=DIR Build in this location instead of building within
# the distribution tree. Recommended!
#
# --show-libraries Display the list of Boost libraries that require
# build and installation steps, and then exit.
#
# --layout=<layout> Determine whether to choose library names and header
# locations such that multiple versions of Boost or
# multiple compilers can be used on the same system.
#
# -- versioned -- Names of boost binaries include
# the Boost version number, name and version of
# the compiler and encoded build properties. Boost
# headers are installed in a subdirectory of
# <HDRDIR> whose name contains the Boost version
# number.
#
# -- tagged -- Names of boost binaries include the
# encoded build properties such as variant and
# threading, but do not including compiler name
# and version, or Boost version. This option is
# useful if you build several variants of Boost,
# using the same compiler.
#
# -- system -- Binaries names do not include the
# Boost version number or the name and version
# number of the compiler. Boost headers are
# installed directly into <HDRDIR>. This option is
# intended for system integrators building
# distribution packages.
#
# The default value is 'versioned' on Windows, and
# 'system' on Unix.
#
# --buildid=ID Add the specified ID to the name of built libraries.
# The default is to not add anything.
#
# --python-buildid=ID Add the specified ID to the name of built libraries
# that depend on Python. The default is to not add
# anything. This ID is added in addition to --buildid.
#
# --help This message.
#
# --with-<library> Build and install the specified <library>. If this
# option is used, only libraries specified using this
# option will be built.
#
# --without-<library> Do not build, stage, or install the specified
# <library>. By default, all libraries are built.
#
# Properties:
#
# toolset=toolset Indicate the toolset to build with.
#
# variant=debug|release Select the build variant
#
# link=static|shared Whether to build static or shared libraries
#
# threading=single|multi Whether to build single or multithreaded binaries
#
# runtime-link=static|shared
# Whether to link to static or shared C and C++
# runtime.
#
# TODO:
# - handle boost version
# - handle python options such as pydebug
import boostcpp ;
import package ;
import sequence ;
import xsltproc ;
import set ;
import path ;
import link ;
path-constant BOOST_ROOT : . ;
constant BOOST_VERSION : 1.63.0 ;
constant BOOST_JAMROOT_MODULE : $(__name__) ;
boostcpp.set-version $(BOOST_VERSION) ;
use-project /boost/architecture : libs/config/checks/architecture ;
local all-headers =
[ MATCH .*libs/(.*)/include/boost : [ glob libs/*/include/boost libs/*/*/include/boost ] ] ;
for dir in $(all-headers)
{
link-directory $(dir)-headers : libs/$(dir)/include/boost : <location>. ;
explicit $(dir)-headers ;
}
if $(all-headers)
{
constant BOOST_MODULARLAYOUT : $(all-headers) ;
}
project boost
: requirements <include>.
[ boostcpp.architecture ]
[ boostcpp.address-model ]
# Disable auto-linking for all targets here, primarily because it caused
# troubles with V2.
<define>BOOST_ALL_NO_LIB=1
# Used to encode variant in target name. See the 'tag' rule below.
<tag>@$(__name__).tag
<conditional>@handle-static-runtime
# Comeau does not support shared lib
<toolset>como:<link>static
<toolset>como-linux:<define>_GNU_SOURCE=1
# When building docs within Boost, we want the standard Boost style
<xsl:param>boost.defaults=Boost
: usage-requirements <include>.
: build-dir bin.v2
;
# This rule is called by Boost.Build to determine the name of target. We use it
# to encode the build variant, compiler name and boost version in the target
# name.
#
rule tag ( name : type ? : property-set )
{
return [ boostcpp.tag $(name) : $(type) : $(property-set) ] ;
}
rule python-tag ( name : type ? : property-set )
{
return [ boostcpp.python-tag $(name) : $(type) : $(property-set) ] ;
}
rule handle-static-runtime ( properties * )
{
# Using static runtime with shared libraries is impossible on Linux, and
# dangerous on Windows. Therefore, we disallow it. This might be drastic,
# but it was disabled for a while without anybody complaining.
# For CW, static runtime is needed so that std::locale works.
if <link>shared in $(properties) && <runtime-link>static in $(properties) &&
! ( <toolset>cw in $(properties) )
{
ECHO "error: link=shared together with runtime-link=static is not allowed" ;
ECHO "error: such property combination is either impossible " ;
ECHO "error: or too dangerious to be of any use" ;
EXIT ;
}
}
all-libraries = [ MATCH .*libs/(.*)/build/.* : [ glob libs/*/build/Jamfile.v2 ]
[ glob libs/*/build/Jamfile ] ] ;
all-libraries = [ sequence.unique $(all-libraries) ] ;
# The function_types library has a Jamfile, but it's used for maintenance
# purposes, there's no library to build and install.
all-libraries = [ set.difference $(all-libraries) : function_types ] ;
# Setup convenient aliases for all libraries.
local rule explicit-alias ( id : targets + )
{
alias $(id) : $(targets) ;
explicit $(id) ;
}
# First, the complicated libraries: where the target name in Jamfile is
# different from its directory name.
explicit-alias prg_exec_monitor : libs/test/build//boost_prg_exec_monitor ;
explicit-alias test_exec_monitor : libs/test/build//boost_test_exec_monitor ;
explicit-alias unit_test_framework : libs/test/build//boost_unit_test_framework ;
explicit-alias bgl-vis : libs/graps/build//bgl-vis ;
explicit-alias serialization : libs/serialization/build//boost_serialization ;
explicit-alias wserialization : libs/serialization/build//boost_wserialization ;
for local l in $(all-libraries)
{
if ! $(l) in test graph serialization
{
explicit-alias $(l) : libs/$(l)/build//boost_$(l) ;
}
}
# Log has an additional target
explicit-alias log_setup : libs/log/build//boost_log_setup ;
alias headers : $(all-headers)-headers : : : <include>. ;
explicit headers ;
# Make project ids of all libraries known.
for local l in $(all-libraries)
{
use-project /boost/$(l) : libs/$(l)/build ;
}
if [ path.exists $(BOOST_ROOT)/tools/inspect ]
{
use-project /boost/tools/inspect : tools/inspect/build ;
}
if [ path.exists $(BOOST_ROOT)/libs/wave/tool ]
{
use-project /boost/libs/wave/tool : libs/wave/tool/build ;
}
# This rule should be called from libraries' Jamfiles and will create two
# targets, "install" and "stage", that will install or stage that library. The
# --prefix option is respected, but --with and --without options, naturally, are
# ignored.
#
# - libraries -- list of library targets to install.
#
rule boost-install ( libraries * )
{
package.install install
: <dependency>/boost//install-proper-headers $(install-requirements)
: # No binaries
: $(libraries)
: # No headers, it is handled by the dependency.
;
install stage : $(libraries) : <location>$(BOOST_STAGE_LOCATE) ;
module [ CALLER_MODULE ]
{
explicit stage ;
explicit install ;
}
}
# Creates a library target, adding autolink support and also creates
# stage and install targets via boost-install, above.
rule boost-lib ( name : sources * : requirements * : default-build * : usage-requirements * )
{
name = boost_$(name) ;
autolink = <link>shared:<define>BOOST_$(name:U)_DYN_LINK=1 ;
lib $(name)
: $(sources)
: $(requirements) $(autolink)
: $(default-build)
: $(usage-requirements) $(autolink)
;
boost-install $(name) ;
}
headers =
# The .SUNWCCh files are present in tr1 include directory and have to be
# installed (see http://lists.boost.org/Archives/boost/2007/05/121430.php).
[ path.glob-tree $(BOOST_ROOT)/boost : *.hpp *.ipp *.h *.inc *.SUNWCCh : CVS .svn ]
[ path.glob-tree $(BOOST_ROOT)/boost/compatibility/cpp_c_headers : c* : CVS .svn ]
[ path.glob boost/tr1/tr1 : * : bcc32 sun CVS .svn ]
;
# Declare special top-level targets that build and install the desired variants
# of the libraries.
boostcpp.declare-targets $(all-libraries) : $(headers) ;

View File

@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -7,11 +7,18 @@ upstream and master. To upgrade the content do the following:
```bash
git checkout upstream
mv README.md /tmp
rm -r *
# use the bcp tool to populate with the new Boost libraries
# use git add to stage any new files and directories
git commit -a -m "Updated Boost v1.63 libraries including ..."
git tag boost_1_63
mv /tmp/README.md .
# use the bcp tool to populate with the new Boost libraries from a clean boost install.
# Something like:
#
# bcp --boost=../boost_1_70_0 --unix-lines iterator range math numeric crc circular_buffer multi_index intrusive .
#
# Clean out any unwanted files and directories (e.g. libs and docs for a header only subset).
# Use git add to stage any new files and directories.
git commit -a -m "Updated Boost v1.70.0 libraries including ..."
git tag boost_1_70_0
git push origin
git checkout master
git merge upstream
@ -19,4 +26,4 @@ git push origin
```
The resulting master branch is now ready to be git-subtree merged into
any projects that need these libraries.
any projects that need these libraries.

View File

@ -1,17 +0,0 @@
# Copyright (C) 2002-2003 David Abrahams.
# Copyright (C) 2002-2003 Vladimir Prus.
# Copyright (C) 2003,2007 Rene Rivera.
# Use, modification and distribution are 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)
# This is the initial file loaded by Boost Jam when run from any Boost library
# folder. It allows us to choose which Boost Build installation to use for
# building Boost libraries. Unless explicitly selected using a command-line
# option, the version included with the Boost library distribution is used (as
# opposed to any other Boost Build version installed on the user's sytem).
BOOST_ROOT = $(.boost-build-file:D) ;
BOOST_BUILD = [ MATCH --boost-build=(.*) : $(ARGV) ] ;
BOOST_BUILD ?= tools/build/src ;
boost-build $(BOOST_BUILD) ;

View File

@ -1,66 +0,0 @@
/*=============================================================================
Copyright 2002 William E. Kempf
Distributed under the Boost Software License, Version 1.0. (See accompany-
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
H1
{
FONT-SIZE: 200%;
COLOR: #00008B;
}
H2
{
FONT-SIZE: 150%;
}
H3
{
FONT-SIZE: 125%;
}
H4
{
FONT-SIZE: 108%;
}
BODY
{
FONT-SIZE: 100%;
BACKGROUND-COLOR: #ffffff;
COLOR: #000000;
}
PRE
{
MARGIN-LEFT: 2em;
FONT-FAMILY: Courier,
monospace;
}
CODE
{
FONT-FAMILY: Courier,
monospace;
}
CODE.as_pre
{
white-space: pre;
}
.index
{
TEXT-ALIGN: left;
}
.page-index
{
TEXT-ALIGN: left;
}
.definition
{
TEXT-ALIGN: left;
}
.footnote
{
FONT-SIZE: 66%;
VERTICAL-ALIGN: super;
TEXT-DECORATION: none;
}
.function-semantics
{
CLEAR: left;
}

BIN
boost.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -27,7 +27,7 @@ namespace boost { namespace algorithm {
///
/// \note This function is part of the C++2011 standard library.
template<typename InputIterator, typename Predicate>
bool all_of ( InputIterator first, InputIterator last, Predicate p )
BOOST_CXX14_CONSTEXPR bool all_of ( InputIterator first, InputIterator last, Predicate p )
{
for ( ; first != last; ++first )
if ( !p(*first))
@ -43,7 +43,7 @@ bool all_of ( InputIterator first, InputIterator last, Predicate p )
/// \param p A predicate for testing the elements of the range
///
template<typename Range, typename Predicate>
bool all_of ( const Range &r, Predicate p )
BOOST_CXX14_CONSTEXPR bool all_of ( const Range &r, Predicate p )
{
return boost::algorithm::all_of ( boost::begin (r), boost::end (r), p );
}
@ -57,7 +57,7 @@ bool all_of ( const Range &r, Predicate p )
/// \param val A value to compare against
///
template<typename InputIterator, typename T>
bool all_of_equal ( InputIterator first, InputIterator last, const T &val )
BOOST_CXX14_CONSTEXPR bool all_of_equal ( InputIterator first, InputIterator last, const T &val )
{
for ( ; first != last; ++first )
if ( val != *first )
@ -73,7 +73,7 @@ bool all_of_equal ( InputIterator first, InputIterator last, const T &val )
/// \param val A value to compare against
///
template<typename Range, typename T>
bool all_of_equal ( const Range &r, const T &val )
BOOST_CXX14_CONSTEXPR bool all_of_equal ( const Range &r, const T &val )
{
return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val );
}

View File

@ -0,0 +1,553 @@
// (C) Copyright Herve Bronnimann 2004.
//
// 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)
/*
Revision history:
1 July 2004
Split the code into two headers to lessen dependence on
Boost.tuple. (Herve)
26 June 2004
Added the code for the boost minmax library. (Herve)
*/
#ifndef BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
#define BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
/* PROPOSED STANDARD EXTENSIONS:
*
* minmax_element(first, last)
* Effect: std::make_pair( std::min_element(first, last),
* std::max_element(first, last) );
*
* minmax_element(first, last, comp)
* Effect: std::make_pair( std::min_element(first, last, comp),
* std::max_element(first, last, comp) );
*/
#include <utility> // for std::pair and std::make_pair
namespace boost {
namespace detail { // for obtaining a uniform version of minmax_element
// that compiles with VC++ 6.0 -- avoid the iterator_traits by
// having comparison object over iterator, not over dereferenced value
template <typename Iterator>
struct less_over_iter {
bool operator()(Iterator const& it1,
Iterator const& it2) const { return *it1 < *it2; }
};
template <typename Iterator, class BinaryPredicate>
struct binary_pred_over_iter {
explicit binary_pred_over_iter(BinaryPredicate const& p ) : m_p( p ) {}
bool operator()(Iterator const& it1,
Iterator const& it2) const { return m_p(*it1, *it2); }
private:
BinaryPredicate m_p;
};
// common base for the two minmax_element overloads
template <typename ForwardIter, class Compare >
std::pair<ForwardIter,ForwardIter>
basic_minmax_element(ForwardIter first, ForwardIter last, Compare comp)
{
if (first == last)
return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
// if only one element
ForwardIter second = first; ++second;
if (second == last)
return std::make_pair(min_result, max_result);
// treat first pair separately (only one comparison for first two elements)
ForwardIter potential_min_result = last;
if (comp(first, second))
max_result = second;
else {
min_result = second;
potential_min_result = first;
}
// then each element by pairs, with at most 3 comparisons per pair
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (comp(first, min_result)) {
min_result = first;
potential_min_result = last;
}
if (comp(max_result, second))
max_result = second;
} else {
if (comp(second, min_result)) {
min_result = second;
potential_min_result = first;
}
if (comp(max_result, first))
max_result = first;
}
first = ++second;
if (first != last) ++second;
}
// if odd number of elements, treat last element
if (first != last) { // odd number of elements
if (comp(first, min_result)) {
min_result = first;
potential_min_result = last;
}
else if (comp(max_result, first))
max_result = first;
}
// resolve min_result being incorrect with one extra comparison
// (in which case potential_min_result is necessarily the correct result)
if (potential_min_result != last
&& !comp(min_result, potential_min_result))
min_result = potential_min_result;
return std::make_pair(min_result,max_result);
}
} // namespace detail
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
minmax_element(ForwardIter first, ForwardIter last)
{
return detail::basic_minmax_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
minmax_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_minmax_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
}
/* PROPOSED BOOST EXTENSIONS
* In the description below, [rfirst,rlast) denotes the reversed range
* of [first,last). Even though the iterator type of first and last may
* be only a Forward Iterator, it is possible to explain the semantics
* by assuming that it is a Bidirectional Iterator. In the sequel,
* reverse(ForwardIterator&) returns the reverse_iterator adaptor.
* This is not how the functions would be implemented!
*
* first_min_element(first, last)
* Effect: std::min_element(first, last);
*
* first_min_element(first, last, comp)
* Effect: std::min_element(first, last, comp);
*
* last_min_element(first, last)
* Effect: reverse( std::min_element(reverse(last), reverse(first)) );
*
* last_min_element(first, last, comp)
* Effect: reverse( std::min_element(reverse(last), reverse(first), comp) );
*
* first_max_element(first, last)
* Effect: std::max_element(first, last);
*
* first_max_element(first, last, comp)
* Effect: max_element(first, last);
*
* last_max_element(first, last)
* Effect: reverse( std::max_element(reverse(last), reverse(first)) );
*
* last_max_element(first, last, comp)
* Effect: reverse( std::max_element(reverse(last), reverse(first), comp) );
*
* first_min_first_max_element(first, last)
* Effect: std::make_pair( first_min_element(first, last),
* first_max_element(first, last) );
*
* first_min_first_max_element(first, last, comp)
* Effect: std::make_pair( first_min_element(first, last, comp),
* first_max_element(first, last, comp) );
*
* first_min_last_max_element(first, last)
* Effect: std::make_pair( first_min_element(first, last),
* last_max_element(first, last) );
*
* first_min_last_max_element(first, last, comp)
* Effect: std::make_pair( first_min_element(first, last, comp),
* last_max_element(first, last, comp) );
*
* last_min_first_max_element(first, last)
* Effect: std::make_pair( last_min_element(first, last),
* first_max_element(first, last) );
*
* last_min_first_max_element(first, last, comp)
* Effect: std::make_pair( last_min_element(first, last, comp),
* first_max_element(first, last, comp) );
*
* last_min_last_max_element(first, last)
* Effect: std::make_pair( last_min_element(first, last),
* last_max_element(first, last) );
*
* last_min_last_max_element(first, last, comp)
* Effect: std::make_pair( last_min_element(first, last, comp),
* last_max_element(first, last, comp) );
*/
namespace boost {
// Min_element and max_element variants
namespace detail { // common base for the overloads
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_first_min_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter min_result = first;
while (++first != last)
if (comp(first, min_result))
min_result = first;
return min_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_last_min_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter min_result = first;
while (++first != last)
if (!comp(min_result, first))
min_result = first;
return min_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter max_result = first;
while (++first != last)
if (comp(max_result, first))
max_result = first;
return max_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter max_result = first;
while (++first != last)
if (!comp(first, max_result))
max_result = first;
return max_result;
}
} // namespace detail
template <typename ForwardIter>
ForwardIter
first_min_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_min_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
first_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_first_min_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
last_min_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
last_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_last_min_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
first_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
first_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_first_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
last_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
// Minmax_element variants -- comments removed
namespace detail {
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_first_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last)
return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = ++first;
if (second == last)
return std::make_pair(min_result, max_result);
if (comp(second, min_result))
min_result = second;
else
max_result = second;
first = ++second; if (first != last) ++second;
while (second != last) {
if (!comp(second, first)) {
if (comp(first, min_result))
min_result = first;
if (!comp(second, max_result))
max_result = second;
} else {
if (comp(second, min_result))
min_result = second;
if (!comp(first, max_result))
max_result = first;
}
first = ++second; if (first != last) ++second;
}
if (first != last) {
if (comp(first, min_result))
min_result = first;
else if (!comp(first, max_result))
max_result = first;
}
return std::make_pair(min_result, max_result);
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_last_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = ++first;
if (second == last)
return std::make_pair(min_result, max_result);
if (comp(max_result, second))
max_result = second;
else
min_result = second;
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (!comp(min_result, first))
min_result = first;
if (comp(max_result, second))
max_result = second;
} else {
if (!comp(min_result, second))
min_result = second;
if (comp(max_result, first))
max_result = first;
}
first = ++second; if (first != last) ++second;
}
if (first != last) {
if (!comp(min_result, first))
min_result = first;
else if (comp(max_result, first))
max_result = first;
}
return std::make_pair(min_result, max_result);
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_last_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = first; ++second;
if (second == last)
return std::make_pair(min_result,max_result);
ForwardIter potential_max_result = last;
if (comp(first, second))
max_result = second;
else {
min_result = second;
potential_max_result = second;
}
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (!comp(min_result, first))
min_result = first;
if (!comp(second, max_result)) {
max_result = second;
potential_max_result = last;
}
} else {
if (!comp(min_result, second))
min_result = second;
if (!comp(first, max_result)) {
max_result = first;
potential_max_result = second;
}
}
first = ++second;
if (first != last) ++second;
}
if (first != last) {
if (!comp(min_result, first))
min_result = first;
if (!comp(first, max_result)) {
max_result = first;
potential_max_result = last;
}
}
if (potential_max_result != last
&& !comp(potential_max_result, max_result))
max_result = potential_max_result;
return std::make_pair(min_result,max_result);
}
} // namespace detail
template <typename ForwardIter>
inline std::pair<ForwardIter,ForwardIter>
first_min_first_max_element(ForwardIter first, ForwardIter last)
{
return minmax_element(first, last);
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
first_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return minmax_element(first, last, comp);
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
first_min_last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_min_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
first_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_first_min_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
last_min_first_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_first_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
last_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_last_min_first_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
last_min_last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
last_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_last_min_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
} // namespace boost
#endif // BOOST_ALGORITHM_MINMAX_ELEMENT_HPP

View File

@ -30,8 +30,10 @@ namespace boost {
// a tolower functor
template<typename CharT>
struct to_lowerF : public std::unary_function<CharT, CharT>
struct to_lowerF
{
typedef CharT argument_type;
typedef CharT result_type;
// Constructor
to_lowerF( const std::locale& Loc ) : m_Loc( &Loc ) {}
@ -50,8 +52,10 @@ namespace boost {
// a toupper functor
template<typename CharT>
struct to_upperF : public std::unary_function<CharT, CharT>
struct to_upperF
{
typedef CharT argument_type;
typedef CharT result_type;
// Constructor
to_upperF( const std::locale& Loc ) : m_Loc( &Loc ) {}

View File

@ -40,7 +40,7 @@ namespace boost {
// Protected construction/destruction
// Default constructor
find_iterator_base() {};
find_iterator_base() {}
// Copy construction
find_iterator_base( const find_iterator_base& Other ) :
m_Finder(Other.m_Finder) {}

View File

@ -89,9 +89,10 @@ namespace boost {
template<
typename SeqT,
typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator >
struct copy_iterator_rangeF :
public std::unary_function< iterator_range<IteratorT>, SeqT >
struct copy_iterator_rangeF
{
typedef iterator_range<IteratorT> argument_type;
typedef SeqT result_type;
SeqT operator()( const iterator_range<IteratorT>& Range ) const
{
return copy_range<SeqT>(Range);

View File

@ -43,7 +43,6 @@ namespace boost {
The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for.
\param Comp An element comparison predicate
\return An instance of the \c first_finder object
*/
template<typename RangeT>
@ -84,7 +83,6 @@ namespace boost {
The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for.
\param Comp An element comparison predicate
\return An instance of the \c last_finder object
*/
template<typename RangeT>
@ -124,7 +122,6 @@ namespace boost {
\param Search A substring to be searched for.
\param Nth An index of the match to be find
\param Comp An element comparison predicate
\return An instance of the \c nth_finder object
*/
template<typename RangeT>
@ -230,7 +227,6 @@ namespace boost {
\param Begin Beginning of the range
\param End End of the range
\param Range The range.
\return An instance of the \c range_finger object
*/
template< typename ForwardIteratorT >

View File

@ -1,20 +0,0 @@
/*
(c) 2014-2015 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGN_HPP
#define BOOST_ALIGN_ALIGN_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_STD_ALIGN)
#include <boost/align/detail/align_cxx11.hpp>
#else
#include <boost/align/detail/align.hpp>
#endif
#endif

View File

@ -1,38 +0,0 @@
/*
(c) 2014-2016 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGN_HPP
#define BOOST_ALIGN_DETAIL_ALIGN_HPP
#include <boost/align/detail/is_alignment.hpp>
#include <boost/assert.hpp>
namespace boost {
namespace alignment {
inline void* align(std::size_t alignment, std::size_t size,
void*& ptr, std::size_t& space)
{
BOOST_ASSERT(detail::is_alignment(alignment));
if (size <= space) {
char* p = (char*)(((std::size_t)ptr + alignment - 1) &
~(alignment - 1));
std::size_t n = space - (p - static_cast<char*>(ptr));
if (size <= n) {
ptr = p;
space = n;
return p;
}
}
return 0;
}
} /* .alignment */
} /* .boost */
#endif

View File

@ -1,22 +0,0 @@
/*
(c) 2014 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_ALIGN_CXX11_HPP
#define BOOST_ALIGN_DETAIL_ALIGN_CXX11_HPP
#include <memory>
namespace boost {
namespace alignment {
using std::align;
} /* .alignment */
} /* .boost */
#endif

View File

@ -1,29 +0,0 @@
/*
(c) 2014 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP
#define BOOST_ALIGN_DETAIL_IS_ALIGNMENT_HPP
#include <boost/config.hpp>
#include <cstddef>
namespace boost {
namespace alignment {
namespace detail {
BOOST_CONSTEXPR inline bool is_alignment(std::size_t value)
BOOST_NOEXCEPT
{
return (value > 0) && ((value & (value - 1)) == 0);
}
} /* .detail */
} /* .alignment */
} /* .boost */
#endif

View File

@ -12,11 +12,11 @@
// with features contributed and bugs found by
// Antony Polukhin, Ed Brey, Mark Rodgers,
// Peter Dimov, and James Curran
// when: July 2001, April 2013 - May 2013
// when: July 2001, April 2013 - 2019
#include <algorithm>
#include "boost/config.hpp"
#include <boost/config.hpp>
#include <boost/type_index.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/decay.hpp>
@ -27,9 +27,10 @@
#include <boost/throw_exception.hpp>
#include <boost/static_assert.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/core/addressof.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/conditional.hpp>
namespace boost
{
@ -108,7 +109,7 @@ namespace boost
return *this;
}
// move assignement
// move assignment
any & operator=(any&& rhs) BOOST_NOEXCEPT
{
rhs.swap(*this);
@ -148,7 +149,7 @@ namespace boost
public: // types (public so any_cast can be non-friend)
#endif
class placeholder
class BOOST_SYMBOL_VISIBLE placeholder
{
public: // structors
@ -244,7 +245,9 @@ namespace boost
ValueType * any_cast(any * operand) BOOST_NOEXCEPT
{
return operand && operand->type() == boost::typeindex::type_id<ValueType>()
? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
? boost::addressof(
static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
)
: 0;
}
@ -260,7 +263,7 @@ namespace boost
typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
nonref * result = any_cast<nonref>(&operand);
nonref * result = any_cast<nonref>(boost::addressof(operand));
if(!result)
boost::throw_exception(bad_any_cast());
@ -268,13 +271,20 @@ namespace boost
// `ValueType` is not a reference. Example:
// `static_cast<std::string>(*result);`
// which is equal to `std::string(*result);`
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
boost::is_reference<ValueType>,
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_reference<ValueType>::value,
ValueType,
BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
>::type ref_type;
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
#endif
return static_cast<ref_type>(*result);
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
}
template<typename ValueType>
@ -306,7 +316,9 @@ namespace boost
template<typename ValueType>
inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT
{
return &static_cast<any::holder<ValueType> *>(operand->content)->held;
return boost::addressof(
static_cast<any::holder<ValueType> *>(operand->content)->held
);
}
template<typename ValueType>
@ -317,6 +329,7 @@ namespace boost
}
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
// Copyright Antony Polukhin, 2013-2019.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@ -127,11 +127,11 @@ public:
}
// used for text output
operator int () const {
operator base_type () const {
return t;
}
// used for text input
operator int_least16_t &() {
operator base_type &() {
return t;
}
bool operator==(const class_id_type & rhs) const {
@ -151,7 +151,10 @@ private:
public:
object_id_type(): t(0) {};
// note: presumes that size_t >= unsigned int.
explicit object_id_type(const std::size_t & t_) : t(t_){
// use explicit cast to silence useless warning
explicit object_id_type(const std::size_t & t_) : t(static_cast<base_type>(t_)){
// make quadriple sure that we haven't lost any real integer
// precision
BOOST_ASSERT(t_ <= boost::integer_traits<base_type>::const_max);
}
object_id_type(const object_id_type & t_) :
@ -162,11 +165,11 @@ public:
return *this;
}
// used for text output
operator uint_least32_t () const {
operator base_type () const {
return t;
}
// used for text input
operator uint_least32_t & () {
operator base_type & () {
return t;
}
bool operator==(const object_id_type & rhs) const {

View File

@ -102,17 +102,29 @@ protected:
}
void load_override(class_id_type & t){
library_version_type lvt = this->get_library_version();
/*
* library versions:
* boost 1.39 -> 5
* boost 1.43 -> 7
* boost 1.47 -> 9
*
*
* 1) in boost 1.43 and inferior, class_id_type is always a 16bit value, with no check on the library version
* --> this means all archives with version v <= 7 are written with a 16bit class_id_type
* 2) in boost 1.44 this load_override has disappeared (and thus boost 1.44 is not backward compatible at all !!)
* 3) recent boosts reintroduced load_override with a test on the version :
* - v > 7 : this->detail_common_iarchive::load_override(t, version)
* - v > 6 : 16bit
* - other : 32bit
* --> which is obviously incorrect, see point 1
*
* the fix here decodes class_id_type on 16bit for all v <= 7, which seems to be the correct behaviour ...
*/
if(boost::archive::library_version_type(7) < lvt){
this->detail_common_iarchive::load_override(t);
}
else
if(boost::archive::library_version_type(6) < lvt){
int_least16_t x=0;
* this->This() >> x;
t = boost::archive::class_id_type(x);
}
else{
int x=0;
int_least16_t x=0;
* this->This() >> x;
t = boost::archive::class_id_type(x);
}

View File

@ -50,7 +50,7 @@ namespace std{
//#include <boost/mpl/placeholders.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/array_wrapper.hpp>
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#include <boost/archive/codecvt_null.hpp>

View File

@ -45,7 +45,7 @@ namespace std{
//#include <boost/mpl/placeholders.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/array_wrapper.hpp>
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#include <boost/archive/codecvt_null.hpp>

View File

@ -21,7 +21,7 @@
//
// note the fact that on libraries without wide characters, ostream is
// is not a specialization of basic_ostream which in fact is not defined
// in such cases. So we can't use basic_ostream<IStream::char_type> but rather
// in such cases. So we can't use basic_istream<IStream::char_type> but rather
// use two template parameters
#include <boost/config.hpp>

View File

@ -175,8 +175,6 @@ protected:
template<class T>
void save(const T & t){
boost::io::ios_flags_saver fs(os);
boost::io::ios_precision_saver ps(os);
typename is_float<T>::type tf;
save_impl(t, tf);
}

View File

@ -89,8 +89,7 @@ protected:
// leaving the archive in an undetermined state
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load_override(class_id_type & t);
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load_override(class_id_optional_type & /* t */){}
void load_override(class_id_optional_type & /* t */){}
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
load_override(object_id_type & t);
BOOST_ARCHIVE_OR_WARCHIVE_DECL void

View File

@ -18,8 +18,11 @@
#include <locale>
#include <cstddef> // NULL, size_t
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // for mbstate_t
#endif
#include <boost/config.hpp>
#include <boost/serialization/force_include.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
@ -60,9 +63,10 @@ public:
};
template<>
class BOOST_SYMBOL_VISIBLE codecvt_null<wchar_t> : public std::codecvt<wchar_t, char, std::mbstate_t>
class BOOST_WARCHIVE_DECL codecvt_null<wchar_t> :
public std::codecvt<wchar_t, char, std::mbstate_t>
{
virtual BOOST_WARCHIVE_DECL std::codecvt_base::result
virtual std::codecvt_base::result
do_out(
std::mbstate_t & state,
const wchar_t * first1,
@ -72,7 +76,7 @@ class BOOST_SYMBOL_VISIBLE codecvt_null<wchar_t> : public std::codecvt<wchar_t,
char * last2,
char * & next2
) const;
virtual BOOST_WARCHIVE_DECL std::codecvt_base::result
virtual std::codecvt_base::result
do_in(
std::mbstate_t & state,
const char * first1,
@ -92,7 +96,7 @@ public:
explicit codecvt_null(std::size_t no_locale_manage = 0) :
std::codecvt<wchar_t, char, std::mbstate_t>(no_locale_manage)
{}
virtual ~codecvt_null(){};
//virtual ~codecvt_null(){};
};
} // namespace archive

View File

@ -35,11 +35,12 @@ class extended_type_info;
// note: referred to as Curiously Recurring Template Patter (CRTP)
template<class Archive>
class BOOST_SYMBOL_VISIBLE common_iarchive :
class BOOST_SYMBOL_VISIBLE common_iarchive :
public basic_iarchive,
public interface_iarchive<Archive>
{
friend class interface_iarchive<Archive>;
friend class basic_iarchive;
private:
virtual void vload(version_type & t){
* this->This() >> t;

View File

@ -38,6 +38,7 @@ class BOOST_SYMBOL_VISIBLE common_oarchive :
public interface_oarchive<Archive>
{
friend class interface_oarchive<Archive>;
friend class basic_oarchive;
private:
virtual void vsave(const version_type t){
* this->This() << t;

View File

@ -57,11 +57,10 @@ namespace std{
#include <boost/serialization/assume_abstract.hpp>
#ifndef BOOST_MSVC
#define DONT_USE_HAS_NEW_OPERATOR ( \
BOOST_WORKAROUND(__IBMCPP__, < 1210) \
|| defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \
)
#if !defined(BOOST_MSVC) && \
(BOOST_WORKAROUND(__IBMCPP__, < 1210) || \
defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590))
#define DONT_USE_HAS_NEW_OPERATOR 1
#else
#define DONT_USE_HAS_NEW_OPERATOR 0
#endif
@ -77,10 +76,10 @@ namespace std{
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/void_cast.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/singleton.hpp>
#include <boost/serialization/wrapper.hpp>
#include <boost/serialization/array_wrapper.hpp>
// the following is need only for dynamic cast of polymorphic pointers
#include <boost/archive/archive_exception.hpp>
@ -90,6 +89,8 @@ namespace std{
#include <boost/archive/detail/archive_serializer_map.hpp>
#include <boost/archive/detail/check.hpp>
#include <boost/core/addressof.hpp>
namespace boost {
namespace serialization {
@ -122,8 +123,7 @@ private:
virtual void destroy(/*const*/ void *address) const {
boost::serialization::access::destroy(static_cast<T *>(address));
}
protected:
// protected constructor since it's always created by singleton
public:
explicit iserializer() :
basic_iserializer(
boost::serialization::singleton<
@ -132,7 +132,6 @@ protected:
>::get_const_instance()
)
{}
public:
virtual BOOST_DLLEXPORT void load_object_data(
basic_iarchive & ar,
void *x,
@ -234,7 +233,7 @@ struct heap_allocation {
// that the class might have class specific new with NO
// class specific delete at all. Patches (compatible with
// C++03) welcome!
delete t;
(operator delete)(t);
}
};
struct doesnt_have_new_operator {
@ -243,7 +242,7 @@ struct heap_allocation {
}
static void invoke_delete(T * t) {
// Note: I'm reliance upon automatic conversion from T * to void * here
delete t;
(operator delete)(t);
}
};
static T * invoke_new() {
@ -306,7 +305,7 @@ private:
void * x,
const unsigned int file_version
) const BOOST_USED;
protected:
public:
// this should alway be a singleton so make the constructor protected
pointer_iserializer();
~pointer_iserializer();
@ -406,7 +405,7 @@ struct load_non_pointer_type {
struct load_standard {
template<class T>
static void invoke(Archive &ar, const T & t){
void * x = & const_cast<T &>(t);
void * x = boost::addressof(const_cast<T &>(t));
ar.load_object(
x,
boost::serialization::singleton<
@ -484,7 +483,7 @@ struct load_pointer_type {
};
template<class T>
static const basic_pointer_iserializer * register_type(Archive &ar, const T & /*t*/){
static const basic_pointer_iserializer * register_type(Archive &ar, const T* const /*t*/){
// there should never be any need to load an abstract polymorphic
// class pointer. Inhibiting code generation for this
// permits abstract base classes to be used - note: exception
@ -523,7 +522,7 @@ struct load_pointer_type {
}
template<class T>
static void check_load(T & /* t */){
static void check_load(T * const /* t */){
check_pointer_level< T >();
check_pointer_tracking< T >();
}
@ -537,8 +536,8 @@ struct load_pointer_type {
template<class Tptr>
static void invoke(Archive & ar, Tptr & t){
check_load(*t);
const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t);
check_load(t);
const basic_pointer_iserializer * bpis_ptr = register_type(ar, t);
const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer(
// note major hack here !!!
// I tried every way to convert Tptr &t (where Tptr might
@ -588,7 +587,14 @@ struct load_array_type {
boost::archive::archive_exception::array_size_too_short
)
);
ar >> serialization::make_array(static_cast<value_type*>(&t[0]),count);
// explict template arguments to pass intel C++ compiler
ar >> serialization::make_array<
value_type,
boost::serialization::collection_size_type
>(
static_cast<value_type *>(&t[0]),
count
);
}
};
@ -598,7 +604,7 @@ template<class Archive, class T>
inline void load(Archive & ar, T &t){
// if this assertion trips. It means we're trying to load a
// const object with a compiler that doesn't have correct
// funtion template ordering. On other compilers, this is
// function template ordering. On other compilers, this is
// handled below.
detail::check_const_loading< T >();
typedef

View File

@ -26,6 +26,7 @@
#include <cstddef> // NULL
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
@ -56,8 +57,9 @@
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/void_cast.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/array_wrapper.hpp>
#include <boost/serialization/singleton.hpp>
#include <boost/archive/archive_exception.hpp>
@ -67,6 +69,8 @@
#include <boost/archive/detail/archive_serializer_map.hpp>
#include <boost/archive/detail/check.hpp>
#include <boost/core/addressof.hpp>
namespace boost {
namespace serialization {
@ -252,7 +256,7 @@ struct save_non_pointer_type {
template<class T>
static void invoke(Archive &ar, const T & t){
ar.save_object(
& t,
boost::addressof(t),
boost::serialization::singleton<
oserializer<Archive, T>
>::get_const_instance()
@ -260,6 +264,8 @@ struct save_non_pointer_type {
}
};
// adds class information to the archive. This includes
// serialization level and class version
struct save_conditional {
@ -337,7 +343,7 @@ struct save_pointer_type {
};
template<class T>
static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){
static const basic_pointer_oserializer * register_type(Archive &ar, T* const /*t*/){
// there should never be any need to save an abstract polymorphic
// class pointer. Inhibiting code generation for this
// permits abstract base classes to be used - note: exception
@ -404,7 +410,7 @@ struct save_pointer_type {
// if its not a pointer to a more derived type
const void *vp = static_cast<const void *>(&t);
if(*this_type == *true_type){
const basic_pointer_oserializer * bpos = register_type(ar, t);
const basic_pointer_oserializer * bpos = register_type(ar, &t);
ar.save_pointer(vp, bpos);
return;
}
@ -463,7 +469,7 @@ struct save_pointer_type {
template<class TPtr>
static void invoke(Archive &ar, const TPtr t){
register_type(ar, * t);
register_type(ar, t);
if(NULL == t){
basic_oarchive & boa
= boost::serialization::smart_cast_reference<basic_oarchive &>(ar);
@ -501,7 +507,14 @@ struct save_array_type
);
boost::serialization::collection_size_type count(c);
ar << BOOST_SERIALIZATION_NVP(count);
ar << serialization::make_array(static_cast<value_type const*>(&t[0]),count);
// explict template arguments to pass intel C++ compiler
ar << serialization::make_array<
const value_type,
boost::serialization::collection_size_type
>(
static_cast<const value_type *>(&t[0]),
count
);
}
};

View File

@ -0,0 +1,218 @@
#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP
#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_iarchive_route.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <string>
#include <ostream>
#include <cstddef>
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::size_t;
} // namespace std
#endif
#include <boost/cstdint.hpp>
#include <boost/integer_traits.hpp>
#include <boost/archive/polymorphic_iarchive.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail{
class basic_iserializer;
class basic_pointer_iserializer;
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
#endif
template<class ArchiveImplementation>
class polymorphic_iarchive_route :
public polymorphic_iarchive,
// note: gcc dynamic cross cast fails if the the derivation below is
// not public. I think this is a mistake.
public /*protected*/ ArchiveImplementation
{
private:
// these are used by the serialization library.
virtual void load_object(
void *t,
const basic_iserializer & bis
){
ArchiveImplementation::load_object(t, bis);
}
virtual const basic_pointer_iserializer * load_pointer(
void * & t,
const basic_pointer_iserializer * bpis_ptr,
const basic_pointer_iserializer * (*finder)(
const boost::serialization::extended_type_info & type
)
){
return ArchiveImplementation::load_pointer(t, bpis_ptr, finder);
}
virtual void set_library_version(library_version_type archive_library_version){
ArchiveImplementation::set_library_version(archive_library_version);
}
virtual library_version_type get_library_version() const{
return ArchiveImplementation::get_library_version();
}
virtual unsigned int get_flags() const {
return ArchiveImplementation::get_flags();
}
virtual void delete_created_pointers(){
ArchiveImplementation::delete_created_pointers();
}
virtual void reset_object_address(
const void * new_address,
const void * old_address
){
ArchiveImplementation::reset_object_address(new_address, old_address);
}
virtual void load_binary(void * t, std::size_t size){
ArchiveImplementation::load_binary(t, size);
}
// primitive types the only ones permitted by polymorphic archives
virtual void load(bool & t){
ArchiveImplementation::load(t);
}
virtual void load(char & t){
ArchiveImplementation::load(t);
}
virtual void load(signed char & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned char & t){
ArchiveImplementation::load(t);
}
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
virtual void load(wchar_t & t){
ArchiveImplementation::load(t);
}
#endif
#endif
virtual void load(short & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned short & t){
ArchiveImplementation::load(t);
}
virtual void load(int & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned int & t){
ArchiveImplementation::load(t);
}
virtual void load(long & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned long & t){
ArchiveImplementation::load(t);
}
#if defined(BOOST_HAS_LONG_LONG)
virtual void load(boost::long_long_type & t){
ArchiveImplementation::load(t);
}
virtual void load(boost::ulong_long_type & t){
ArchiveImplementation::load(t);
}
#elif defined(BOOST_HAS_MS_INT64)
virtual void load(__int64 & t){
ArchiveImplementation::load(t);
}
virtual void load(unsigned __int64 & t){
ArchiveImplementation::load(t);
}
#endif
virtual void load(float & t){
ArchiveImplementation::load(t);
}
virtual void load(double & t){
ArchiveImplementation::load(t);
}
virtual void load(std::string & t){
ArchiveImplementation::load(t);
}
#ifndef BOOST_NO_STD_WSTRING
virtual void load(std::wstring & t){
ArchiveImplementation::load(t);
}
#endif
// used for xml and other tagged formats default does nothing
virtual void load_start(const char * name){
ArchiveImplementation::load_start(name);
}
virtual void load_end(const char * name){
ArchiveImplementation::load_end(name);
}
virtual void register_basic_serializer(const basic_iserializer & bis){
ArchiveImplementation::register_basic_serializer(bis);
}
virtual helper_collection &
get_helper_collection(){
return ArchiveImplementation::get_helper_collection();
}
public:
// this can't be inheriteded because they appear in mulitple
// parents
typedef mpl::bool_<true> is_loading;
typedef mpl::bool_<false> is_saving;
// the >> operator
template<class T>
polymorphic_iarchive & operator>>(T & t){
return polymorphic_iarchive::operator>>(t);
}
// the & operator
template<class T>
polymorphic_iarchive & operator&(T & t){
return polymorphic_iarchive::operator&(t);
}
// register type function
template<class T>
const basic_pointer_iserializer *
register_type(T * t = NULL){
return ArchiveImplementation::register_type(t);
}
// all current archives take a stream as constructor argument
template <class _Elem, class _Tr>
polymorphic_iarchive_route(
std::basic_istream<_Elem, _Tr> & is,
unsigned int flags = 0
) :
ArchiveImplementation(is, flags)
{}
virtual ~polymorphic_iarchive_route(){};
};
} // namespace detail
} // namespace archive
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP

View File

@ -0,0 +1,209 @@
#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP
#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_oarchive_route.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <string>
#include <ostream>
#include <cstddef> // size_t
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::size_t;
} // namespace std
#endif
#include <boost/cstdint.hpp>
#include <boost/integer_traits.hpp>
#include <boost/archive/polymorphic_oarchive.hpp>
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
namespace serialization {
class extended_type_info;
} // namespace serialization
namespace archive {
namespace detail{
class basic_oserializer;
class basic_pointer_oserializer;
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
#endif
template<class ArchiveImplementation>
class polymorphic_oarchive_route :
public polymorphic_oarchive,
// note: gcc dynamic cross cast fails if the the derivation below is
// not public. I think this is a mistake.
public /*protected*/ ArchiveImplementation
{
private:
// these are used by the serialization library.
virtual void save_object(
const void *x,
const detail::basic_oserializer & bos
){
ArchiveImplementation::save_object(x, bos);
}
virtual void save_pointer(
const void * t,
const detail::basic_pointer_oserializer * bpos_ptr
){
ArchiveImplementation::save_pointer(t, bpos_ptr);
}
virtual void save_null_pointer(){
ArchiveImplementation::save_null_pointer();
}
// primitive types the only ones permitted by polymorphic archives
virtual void save(const bool t){
ArchiveImplementation::save(t);
}
virtual void save(const char t){
ArchiveImplementation::save(t);
}
virtual void save(const signed char t){
ArchiveImplementation::save(t);
}
virtual void save(const unsigned char t){
ArchiveImplementation::save(t);
}
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
virtual void save(const wchar_t t){
ArchiveImplementation::save(t);
}
#endif
#endif
virtual void save(const short t){
ArchiveImplementation::save(t);
}
virtual void save(const unsigned short t){
ArchiveImplementation::save(t);
}
virtual void save(const int t){
ArchiveImplementation::save(t);
}
virtual void save(const unsigned int t){
ArchiveImplementation::save(t);
}
virtual void save(const long t){
ArchiveImplementation::save(t);
}
virtual void save(const unsigned long t){
ArchiveImplementation::save(t);
}
#if defined(BOOST_HAS_LONG_LONG)
virtual void save(const boost::long_long_type t){
ArchiveImplementation::save(t);
}
virtual void save(const boost::ulong_long_type t){
ArchiveImplementation::save(t);
}
#elif defined(BOOST_HAS_MS_INT64)
virtual void save(const boost::int64_t t){
ArchiveImplementation::save(t);
}
virtual void save(const boost::uint64_t t){
ArchiveImplementation::save(t);
}
#endif
virtual void save(const float t){
ArchiveImplementation::save(t);
}
virtual void save(const double t){
ArchiveImplementation::save(t);
}
virtual void save(const std::string & t){
ArchiveImplementation::save(t);
}
#ifndef BOOST_NO_STD_WSTRING
virtual void save(const std::wstring & t){
ArchiveImplementation::save(t);
}
#endif
virtual library_version_type get_library_version() const{
return ArchiveImplementation::get_library_version();
}
virtual unsigned int get_flags() const {
return ArchiveImplementation::get_flags();
}
virtual void save_binary(const void * t, std::size_t size){
ArchiveImplementation::save_binary(t, size);
}
// used for xml and other tagged formats default does nothing
virtual void save_start(const char * name){
ArchiveImplementation::save_start(name);
}
virtual void save_end(const char * name){
ArchiveImplementation::save_end(name);
}
virtual void end_preamble(){
ArchiveImplementation::end_preamble();
}
virtual void register_basic_serializer(const detail::basic_oserializer & bos){
ArchiveImplementation::register_basic_serializer(bos);
}
virtual helper_collection &
get_helper_collection(){
return ArchiveImplementation::get_helper_collection();
}
public:
// this can't be inheriteded because they appear in mulitple
// parents
typedef mpl::bool_<false> is_loading;
typedef mpl::bool_<true> is_saving;
// the << operator
template<class T>
polymorphic_oarchive & operator<<(T & t){
return polymorphic_oarchive::operator<<(t);
}
// the & operator
template<class T>
polymorphic_oarchive & operator&(T & t){
return polymorphic_oarchive::operator&(t);
}
// register type function
template<class T>
const basic_pointer_oserializer *
register_type(T * t = NULL){
return ArchiveImplementation::register_type(t);
}
// all current archives take a stream as constructor argument
template <class _Elem, class _Tr>
polymorphic_oarchive_route(
std::basic_ostream<_Elem, _Tr> & os,
unsigned int flags = 0
) :
ArchiveImplementation(os, flags)
{}
virtual ~polymorphic_oarchive_route(){};
};
} // namespace detail
} // namespace archive
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP

View File

@ -9,26 +9,21 @@
#include <boost/config.hpp>
// std::codecvt_utf8 doesn't seem to work for msvc
// versions prior to MSVC 14.0
#ifdef BOOST_NO_STD_WSTREAMBUF
#error "wide char i/o not supported on this platform"
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900 \
|| defined( BOOST_NO_CXX11_HDR_CODECVT )
#include <boost/archive/detail/decl.hpp>
#define BOOST_UTF8_BEGIN_NAMESPACE \
namespace boost { namespace archive { namespace detail {
#define BOOST_UTF8_DECL BOOST_ARCHIVE_DECL
#define BOOST_UTF8_END_NAMESPACE }}}
// use boost's utf8 codecvt facet
#include <boost/archive/detail/decl.hpp>
#define BOOST_UTF8_BEGIN_NAMESPACE \
namespace boost { namespace archive { namespace detail {
#define BOOST_UTF8_DECL BOOST_ARCHIVE_DECL
#define BOOST_UTF8_END_NAMESPACE }}}
#include <boost/detail/utf8_codecvt_facet.hpp>
#include <boost/detail/utf8_codecvt_facet.hpp>
#undef BOOST_UTF8_END_NAMESPACE
#undef BOOST_UTF8_DECL
#undef BOOST_UTF8_BEGIN_NAMESPACE
#undef BOOST_UTF8_END_NAMESPACE
#undef BOOST_UTF8_DECL
#undef BOOST_UTF8_BEGIN_NAMESPACE
#else
#include <codecvt>
namespace boost { namespace archive { namespace detail {
typedef std::codecvt_utf8<wchar_t> utf8_codecvt_facet;
} } }
#endif // BOOST_NO_CXX11_HDR_CODECVT
#endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP

View File

@ -47,6 +47,10 @@ archive_serializer_map<Archive>::insert(const basic_serializer * bs){
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
archive_serializer_map<Archive>::erase(const basic_serializer * bs){
// note: previously this conditional was a runtime assertion with
// BOOST_ASSERT. We've changed it because we've discovered that at
// least one platform is not guaranteed to destroy singletons in
// reverse order of distruction.
if(boost::serialization::singleton<
extra_detail::map<Archive>
>::is_destroyed())

View File

@ -84,6 +84,8 @@ basic_binary_iprimitive<Archive, Elem, Tr>::init()
);
}
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::load(wchar_t * ws)
@ -93,6 +95,8 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(wchar_t * ws)
load_binary(ws, l * sizeof(wchar_t) / sizeof(char));
ws[l] = L'\0';
}
#endif
#endif
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
@ -110,7 +114,6 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(std::string & s)
load_binary(&(*s.begin()), l);
}
#ifndef BOOST_NO_CWCHAR
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_iprimitive<Archive, Elem, Tr>::load(char * s)
@ -120,7 +123,6 @@ basic_binary_iprimitive<Archive, Elem, Tr>::load(char * s)
load_binary(s, l);
s[l] = '\0';
}
#endif
#ifndef BOOST_NO_STD_WSTRING
template<class Archive, class Elem, class Tr>

View File

@ -71,6 +71,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::string &s)
}
#ifndef BOOST_NO_CWCHAR
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_binary_oprimitive<Archive, Elem, Tr>::save(const wchar_t * ws)
@ -91,6 +92,7 @@ basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::wstring &ws)
save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char));
}
#endif
#endif // BOOST_NO_CWCHAR
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL

View File

@ -64,7 +64,7 @@ namespace archive {
// XML grammar parsing
template<class CharType>
class basic_xml_grammar {
class BOOST_SYMBOL_VISIBLE basic_xml_grammar {
public:
// The following is not necessary according to DR45, but at least
// one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise.

View File

@ -56,7 +56,7 @@ text_wiarchive_impl<Archive>::load(std::string &s)
s.resize(0);
s.reserve(size);
while(size-- > 0){
int x = is.narrow(is.get(), '\0');
char x = is.narrow(is.get(), '\0');
s += x;
}
}

View File

@ -161,13 +161,13 @@ xml_wiarchive_impl<Archive>::xml_wiarchive_impl(
gimpl(new xml_wgrammar())
{
if(0 == (flags & no_codecvt)){
std::locale l = std::locale(
archive_locale = std::locale(
is_.getloc(),
new boost::archive::detail::utf8_codecvt_facet
);
// libstdc++ crashes without this
is_.sync();
is_.imbue(l);
is_.imbue(archive_locale);
}
if(0 == (flags & no_header))
init();

View File

@ -17,7 +17,9 @@
#include <cstring> // strlen
#include <cstdlib> // mbtowc
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // wcslen
#endif
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
@ -101,7 +103,6 @@ xml_woarchive_impl<Archive>::save(const char * s){
template<class Archive>
BOOST_WARCHIVE_DECL void
xml_woarchive_impl<Archive>::save(const wchar_t * ws){
os << ws;
typedef iterators::xml_escape<const wchar_t *> xmbtows;
std::copy(
xmbtows(ws),
@ -124,12 +125,12 @@ xml_woarchive_impl<Archive>::xml_woarchive_impl(
basic_xml_oarchive<Archive>(flags)
{
if(0 == (flags & no_codecvt)){
std::locale l = std::locale(
archive_locale = std::locale(
os_.getloc(),
new boost::archive::detail::utf8_codecvt_facet
);
os_.flush();
os_.imbue(l);
os_.imbue(archive_locale);
}
if(0 == (flags & no_header))
this->init();
@ -141,7 +142,7 @@ xml_woarchive_impl<Archive>::~xml_woarchive_impl(){
if(std::uncaught_exception())
return;
if(0 == (this->get_flags() & no_header)){
save(L"</boost_serialization>\n");
os << L"</boost_serialization>";
}
}

View File

@ -41,7 +41,7 @@ template<class CharType>
struct from_6_bit {
typedef CharType result_type;
CharType operator()(CharType t) const{
const char * lookup_table =
static const char * lookup_table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"

View File

@ -37,7 +37,7 @@ template<class CharType>
struct to_6_bit {
typedef CharType result_type;
CharType operator()(CharType t) const{
const signed char lookup_table[] = {
static const signed char lookup_table[] = {
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,

View File

@ -102,7 +102,8 @@ public:
super_t(base),
m_bnext(NULL),
m_bend(NULL),
m_full(false)
m_full(false),
m_current_value(0)
{
}
};

View File

@ -56,7 +56,7 @@ class istream_iterator :
//Access the value referred to
Elem dereference() const {
return m_istream->peek();
return static_cast<Elem>(m_istream->peek());
}
void increment(){
@ -75,14 +75,14 @@ public:
}
istream_iterator() :
m_istream(NULL)
m_istream(NULL),
m_current_value(NULL)
{}
istream_iterator(const istream_iterator<Elem> & rhs) :
m_istream(rhs.m_istream),
m_current_value(rhs.m_current_value)
{}
};
} // namespace iterators

View File

@ -18,14 +18,16 @@
#include <boost/assert.hpp>
#include <cstddef> // size_t
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // mbstate_t
#endif
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::mbstate_t;
} // namespace std
#endif
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
@ -84,12 +86,15 @@ class mb_from_wchar
wchar_t value = * this->base_reference();
const wchar_t *wend;
char *bend;
std::codecvt_base::result r = m_codecvt_facet.out(
m_mbs,
& value, & value + 1, wend,
m_buffer, m_buffer + sizeof(m_buffer), bend
BOOST_VERIFY(
m_codecvt_facet.out(
m_mbs,
& value, & value + 1, wend,
m_buffer, m_buffer + sizeof(m_buffer), bend
)
==
std::codecvt_base::ok
);
BOOST_ASSERT(std::codecvt_base::ok == r);
m_bnext = 0;
m_bend = bend - m_buffer;
}

View File

@ -111,6 +111,7 @@ public:
transform_width(T start) :
super_t(Base(static_cast< T >(start))),
m_buffer_out_full(false),
m_buffer_out(0),
// To disable GCC warning, but not truly necessary
//(m_buffer_in will be initialized later before being
//used because m_remaining_bits == 0)

View File

@ -19,7 +19,9 @@
#include <boost/assert.hpp>
#include <cctype>
#include <cstddef> // size_t
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // mbstate_t
#endif
#include <algorithm> // copy
#include <boost/config.hpp>

View File

@ -16,6 +16,8 @@
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/assert.hpp>
#include <boost/serialization/throw_exception.hpp>
@ -42,11 +44,11 @@ class xml_unescape
return unescape<xml_unescape<Base>, Base>::dereference();
}
public:
// workaround msvc 7.1 ICU crash
#if defined(BOOST_MSVC)
// msvc versions prior to 14.0 crash with and ICE
#if BOOST_WORKAROUND(BOOST_MSVC, < 1900)
typedef int value_type;
#else
typedef typename this_t::value_type value_type;
typedef typename super_t::value_type value_type;
#endif
void drain_residue(const char *literal);

View File

@ -0,0 +1,54 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_binary_iarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/detail/polymorphic_iarchive_route.hpp>
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
#endif
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_binary_iarchive :
public detail::polymorphic_iarchive_route<binary_iarchive>
{
public:
polymorphic_binary_iarchive(std::istream & is, unsigned int flags = 0) :
detail::polymorphic_iarchive_route<binary_iarchive>(is, flags)
{}
~polymorphic_binary_iarchive(){}
};
} // namespace archive
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_binary_iarchive
)
#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP

View File

@ -0,0 +1,45 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_binary_oarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/detail/polymorphic_oarchive_route.hpp>
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_binary_oarchive :
public detail::polymorphic_oarchive_route<binary_oarchive>
{
public:
polymorphic_binary_oarchive(std::ostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<binary_oarchive>(os, flags)
{}
~polymorphic_binary_oarchive(){}
};
} // namespace archive
} // namespace boost
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_binary_oarchive
)
#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP

View File

@ -0,0 +1,54 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_text_iarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/detail/polymorphic_iarchive_route.hpp>
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
#endif
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_text_iarchive :
public detail::polymorphic_iarchive_route<text_iarchive>
{
public:
polymorphic_text_iarchive(std::istream & is, unsigned int flags = 0) :
detail::polymorphic_iarchive_route<text_iarchive>(is, flags)
{}
~polymorphic_text_iarchive(){}
};
} // namespace archive
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_text_iarchive
)
#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP

View File

@ -0,0 +1,45 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_text_oarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/detail/polymorphic_oarchive_route.hpp>
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_text_oarchive :
public detail::polymorphic_oarchive_route<text_oarchive>
{
public:
polymorphic_text_oarchive(std::ostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<text_oarchive>(os, flags)
{}
~polymorphic_text_oarchive(){}
};
} // namespace archive
} // namespace boost
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_text_oarchive
)
#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP

View File

@ -0,0 +1,59 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_text_wiarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
#error "wide char i/o not supported on this platform"
#else
#include <boost/archive/text_wiarchive.hpp>
#include <boost/archive/detail/polymorphic_iarchive_route.hpp>
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
#endif
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_text_wiarchive :
public detail::polymorphic_iarchive_route<text_wiarchive>
{
public:
polymorphic_text_wiarchive(std::wistream & is, unsigned int flags = 0) :
detail::polymorphic_iarchive_route<text_wiarchive>(is, flags)
{}
~polymorphic_text_wiarchive(){}
};
} // namespace archive
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_text_wiarchive
)
#endif // BOOST_NO_STD_WSTREAMBUF
#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP

View File

@ -0,0 +1,50 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_text_oarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
#error "wide char i/o not supported on this platform"
#else
#include <boost/archive/text_woarchive.hpp>
#include <boost/archive/detail/polymorphic_oarchive_route.hpp>
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_text_woarchive :
public detail::polymorphic_oarchive_route<text_woarchive>
{
public:
polymorphic_text_woarchive(std::wostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<text_woarchive>(os, flags)
{}
~polymorphic_text_woarchive(){}
};
} // namespace archive
} // namespace boost
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_text_woarchive
)
#endif // BOOST_NO_STD_WSTREAMBUF
#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP

View File

@ -0,0 +1,54 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_xml_iarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/detail/polymorphic_iarchive_route.hpp>
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4511 4512)
#endif
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_xml_iarchive :
public detail::polymorphic_iarchive_route<xml_iarchive>
{
public:
polymorphic_xml_iarchive(std::istream & is, unsigned int flags = 0) :
detail::polymorphic_iarchive_route<xml_iarchive>(is, flags)
{}
~polymorphic_xml_iarchive(){}
};
} // namespace archive
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_xml_iarchive
)
#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP

View File

@ -0,0 +1,44 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_xml_oarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/detail/polymorphic_oarchive_route.hpp>
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_xml_oarchive :
public detail::polymorphic_oarchive_route<xml_oarchive>
{
public:
polymorphic_xml_oarchive(std::ostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<xml_oarchive>(os, flags)
{}
~polymorphic_xml_oarchive(){}
};
} // namespace archive
} // namespace boost
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_xml_oarchive
)
#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP

View File

@ -0,0 +1,50 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_xml_wiarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
#error "wide char i/o not supported on this platform"
#else
#include <boost/archive/xml_wiarchive.hpp>
#include <boost/archive/detail/polymorphic_iarchive_route.hpp>
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_xml_wiarchive :
public detail::polymorphic_iarchive_route<xml_wiarchive>
{
public:
polymorphic_xml_wiarchive(std::wistream & is, unsigned int flags = 0) :
detail::polymorphic_iarchive_route<xml_wiarchive>(is, flags)
{}
~polymorphic_xml_wiarchive(){}
};
} // namespace archive
} // namespace boost
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_xml_wiarchive
)
#endif // BOOST_NO_STD_WSTREAMBUF
#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP

View File

@ -0,0 +1,50 @@
#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP
#define BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// polymorphic_xml_woarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)
// See http://www.boost.org for updates, documentation, and revision history.
#include <boost/config.hpp>
#ifdef BOOST_NO_STD_WSTREAMBUF
#error "wide char i/o not supported on this platform"
#else
#include <boost/archive/xml_woarchive.hpp>
#include <boost/archive/detail/polymorphic_oarchive_route.hpp>
namespace boost {
namespace archive {
class BOOST_SYMBOL_VISIBLE polymorphic_xml_woarchive :
public detail::polymorphic_oarchive_route<xml_woarchive>
{
public:
polymorphic_xml_woarchive(std::wostream & os, unsigned int flags = 0) :
detail::polymorphic_oarchive_route<xml_woarchive>(os, flags)
{}
~polymorphic_xml_woarchive(){}
};
} // namespace archive
} // namespace boost
// required by export
BOOST_SERIALIZATION_REGISTER_ARCHIVE(
boost::archive::polymorphic_xml_woarchive
)
#endif // BOOST_NO_STD_WSTREAMBUF
#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP

View File

@ -65,10 +65,10 @@ protected:
basic_text_oprimitive<std::ostream>::save(t);
}
void save(const version_type & t){
save(static_cast<const unsigned int>(t));
save(static_cast<unsigned int>(t));
}
void save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
save(static_cast<unsigned int>(t));
}
BOOST_ARCHIVE_DECL void
save(const char * t);

View File

@ -78,10 +78,10 @@ protected:
basic_text_oprimitive<std::wostream>::save(t);
}
void save(const version_type & t){
save(static_cast<const unsigned int>(t));
save(static_cast<unsigned int>(t));
}
void save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
save(static_cast<unsigned int>(t));
}
BOOST_WARCHIVE_DECL void
save(const char * t);

View File

@ -44,7 +44,9 @@ inline std::size_t wcslen(const wchar_t * ws)
#else
#ifndef BOOST_NO_CWCHAR
#include <cwchar>
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::wcslen; }
#endif

View File

@ -65,11 +65,11 @@ protected:
}
void
save(const version_type & t){
save(static_cast<const unsigned int>(t));
save(static_cast<unsigned int>(t));
}
void
save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
save(static_cast<unsigned int>(t));
}
BOOST_ARCHIVE_DECL void
save(const char * t);

View File

@ -62,6 +62,7 @@ protected:
friend class basic_xml_iarchive<Archive>;
friend class load_access;
#endif
std::locale archive_locale;
boost::scoped_ptr<xml_wgrammar> gimpl;
std::wistream & get_is(){
return is;

View File

@ -74,11 +74,11 @@ protected:
}
void
save(const version_type & t){
save(static_cast<const unsigned int>(t));
save(static_cast<unsigned int>(t));
}
void
save(const boost::serialization::item_version_type & t){
save(static_cast<const unsigned int>(t));
save(static_cast<unsigned int>(t));
}
BOOST_WARCHIVE_DECL void
save(const char * t);

View File

@ -13,6 +13,7 @@
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* 9 Jan 2013 - (mtc) Added constexpr
* 14 Apr 2012 - (mtc) Added support for boost::hash
* 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility.
* 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group.
@ -42,12 +43,12 @@
#include <cstddef>
#include <stdexcept>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/swap.hpp>
// Handles broken standard libraries better than <iterator>
#include <boost/detail/iterator.hpp>
#include <boost/throw_exception.hpp>
#include <boost/functional/hash_fwd.hpp>
#include <algorithm>
// FIXES for broken compilers
@ -81,15 +82,9 @@ namespace boost {
const_iterator cend() const { return elems+N; }
// reverse iterator support
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
// workaround for broken reverse_iterator in VC7
typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
reference, iterator, reference> > reverse_iterator;
typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
const_reference, iterator, reference> > const_reverse_iterator;
#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
value_type, reference, iterator, difference_type> reverse_iterator;
@ -120,19 +115,17 @@ namespace boost {
// operator[]
reference operator[](size_type i)
{
BOOST_ASSERT_MSG( i < N, "out of range" );
return elems[i];
return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i];
}
const_reference operator[](size_type i) const
/*BOOST_CONSTEXPR*/ const_reference operator[](size_type i) const
{
BOOST_ASSERT_MSG( i < N, "out of range" );
return elems[i];
return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i];
}
// at() with range check
reference at(size_type i) { rangecheck(i); return elems[i]; }
const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
reference at(size_type i) { return rangecheck(i), elems[i]; }
/*BOOST_CONSTEXPR*/ const_reference at(size_type i) const { return rangecheck(i), elems[i]; }
// front() and back()
reference front()
@ -140,7 +133,7 @@ namespace boost {
return elems[0];
}
const_reference front() const
BOOST_CONSTEXPR const_reference front() const
{
return elems[0];
}
@ -150,15 +143,15 @@ namespace boost {
return elems[N-1];
}
const_reference back() const
BOOST_CONSTEXPR const_reference back() const
{
return elems[N-1];
}
// size is constant
static size_type size() { return N; }
static bool empty() { return false; }
static size_type max_size() { return N; }
static BOOST_CONSTEXPR size_type size() { return N; }
static BOOST_CONSTEXPR bool empty() { return false; }
static BOOST_CONSTEXPR size_type max_size() { return N; }
enum { static_size = N };
// swap (note: linear complexity)
@ -189,16 +182,12 @@ namespace boost {
}
// check range (may be private because it is static)
static void rangecheck (size_type i) {
if (i >= size()) {
std::out_of_range e("array<>: index out of range");
boost::throw_exception(e);
}
static BOOST_CONSTEXPR bool rangecheck (size_type i) {
return i >= size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true;
}
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template< class T >
class array< T, 0 > {
@ -222,15 +211,9 @@ namespace boost {
const_iterator cend() const { return cbegin(); }
// reverse iterator support
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
// workaround for broken reverse_iterator in VC7
typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
reference, iterator, reference> > reverse_iterator;
typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
const_reference, iterator, reference> > const_reverse_iterator;
#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
value_type, reference, iterator, difference_type> reverse_iterator;
@ -264,14 +247,14 @@ namespace boost {
return failed_rangecheck();
}
const_reference operator[](size_type /*i*/) const
/*BOOST_CONSTEXPR*/ const_reference operator[](size_type /*i*/) const
{
return failed_rangecheck();
}
// at() with range check
reference at(size_type /*i*/) { return failed_rangecheck(); }
const_reference at(size_type /*i*/) const { return failed_rangecheck(); }
/*BOOST_CONSTEXPR*/ const_reference at(size_type /*i*/) const { return failed_rangecheck(); }
// front() and back()
reference front()
@ -279,7 +262,7 @@ namespace boost {
return failed_rangecheck();
}
const_reference front() const
BOOST_CONSTEXPR const_reference front() const
{
return failed_rangecheck();
}
@ -289,15 +272,15 @@ namespace boost {
return failed_rangecheck();
}
const_reference back() const
BOOST_CONSTEXPR const_reference back() const
{
return failed_rangecheck();
}
// size is constant
static size_type size() { return 0; }
static bool empty() { return true; }
static size_type max_size() { return 0; }
static BOOST_CONSTEXPR size_type size() { return 0; }
static BOOST_CONSTEXPR bool empty() { return true; }
static BOOST_CONSTEXPR size_type max_size() { return 0; }
enum { static_size = 0 };
void swap (array<T,0>& /*y*/) {
@ -335,7 +318,6 @@ namespace boost {
#endif
}
};
#endif
// comparisons
template<class T, std::size_t N>
@ -391,7 +373,7 @@ namespace boost {
// Specific for boost::array: simply returns its elems data member.
template <typename T, std::size_t N>
typename const detail::c_array<T,N>::type& get_c_array(const boost::array<T,N>& arg)
typename detail::c_array<T,N>::type const& get_c_array(const boost::array<T,N>& arg)
{
return arg.elems;
}
@ -429,6 +411,7 @@ namespace boost {
}
#endif
template <class It> std::size_t hash_range(It, It);
template<class T, std::size_t N>
std::size_t hash_value(const array<T,N>& arr)
@ -436,8 +419,36 @@ namespace boost {
return boost::hash_range(arr.begin(), arr.end());
}
template <size_t Idx, typename T, size_t N>
T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" );
return arr[Idx];
}
template <size_t Idx, typename T, size_t N>
const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" );
return arr[Idx];
}
} /* namespace boost */
#ifndef BOOST_NO_CXX11_HDR_ARRAY
// If we don't have std::array, I'm assuming that we don't have std::get
namespace std {
template <size_t Idx, typename T, size_t N>
T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" );
return arr[Idx];
}
template <size_t Idx, typename T, size_t N>
const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" );
return arr[Idx];
}
}
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)

View File

@ -12,12 +12,13 @@
#ifndef BOOST_ASSIGN_ASSIGNMENT_EXCEPTION_HPP
#define BOOST_ASSIGN_ASSIGNMENT_EXCEPTION_HPP
#if defined(_MSC_VER)
#include <boost/config.hpp>
#include <exception>
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <exception>
namespace boost
{
namespace assign
@ -28,12 +29,12 @@ namespace boost
assignment_exception( const char* _what )
: what_( _what )
{ }
virtual const char* what() const throw()
virtual const char* what() const BOOST_NOEXCEPT_OR_NOTHROW
{
return what_;
}
private:
const char* what_;
};

View File

@ -22,14 +22,19 @@
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/config.hpp>
#include <boost/move/utility.hpp>
#include <cstddef>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#endif
namespace boost
{
namespace assign_detail
@ -53,7 +58,18 @@ namespace assign_detail
fun_repeater( std::size_t sz_, Fun r ) : sz( sz_ ), val( r )
{ }
};
template< class T >
struct is_repeater : boost::false_type {};
template< class T >
struct is_repeater< boost::assign_detail::repeater<T> > : boost::true_type{};
template< class Fun >
struct is_repeater< boost::assign_detail::fun_repeater<Fun> > : boost::true_type{};
template< class C >
class call_push_back
{
@ -62,11 +78,19 @@ namespace assign_detail
call_push_back( C& c ) : c_( c )
{ }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class T >
void operator()( T r )
{
c_.push_back( r );
}
#else
template< class T >
void operator()(T&& r)
{
c_.push_back(boost::forward<T>(r));
}
#endif
};
template< class C >
@ -76,12 +100,20 @@ namespace assign_detail
public:
call_push_front( C& c ) : c_( c )
{ }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class T >
void operator()( T r )
{
c_.push_front( r );
}
#else
template< class T >
void operator()(T&& r)
{
c_.push_front(boost::forward<T>(r));
}
#endif
};
template< class C >
@ -92,11 +124,19 @@ namespace assign_detail
call_push( C& c ) : c_( c )
{ }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class T >
void operator()( T r )
{
c_.push( r );
}
#else
template< class T >
void operator()(T&& r)
{
c_.push(boost::forward<T>(r));
}
#endif
};
template< class C >
@ -106,12 +146,20 @@ namespace assign_detail
public:
call_insert( C& c ) : c_( c )
{ }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class T >
void operator()( T r )
{
c_.insert( r );
}
#else
template< class T >
void operator()(T&& r)
{
c_.insert(boost::forward<T>(r));
}
#endif
};
template< class C >
@ -161,8 +209,9 @@ namespace assign
template< class Function, class Argument = assign_detail::forward_n_arguments >
class list_inserter
{
struct single_arg_type {};
struct n_arg_type {};
struct single_arg_type {};
struct n_arg_type {};
struct repeater_arg_type {};
typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_same<Argument,assign_detail::forward_n_arguments>::value,
n_arg_type,
@ -186,14 +235,15 @@ namespace assign
insert_( Argument() );
return *this;
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class T >
list_inserter& operator=( const T& r )
{
insert_( r );
return *this;
}
template< class T >
list_inserter& operator=( assign_detail::repeater<T> r )
{
@ -232,6 +282,38 @@ namespace assign
{
return repeat_fun( r.sz, r.val );
}
#else
// BOOST_NO_CXX11_RVALUE_REFERENCES
template< class T >
list_inserter& operator=(T&& r)
{
return operator,(boost::forward<T>(r));
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template< class T >
list_inserter& operator,(T&& r)
{
typedef BOOST_DEDUCED_TYPENAME mpl::if_c< assign_detail::is_repeater< T >::value,
repeater_arg_type,
arg_type >::type tag;
insert(boost::forward<T>(r), tag());
return *this;
}
#else
// we add the tag as the first argument when using variadic templates
template< class T >
list_inserter& operator,(T&& r)
{
typedef BOOST_DEDUCED_TYPENAME mpl::if_c< assign_detail::is_repeater< T >::value,
repeater_arg_type,
arg_type >::type tag;
insert(tag(), boost::forward<T>(r));
return *this;
}
#endif
#endif
template< class T >
list_inserter& repeat( std::size_t sz, T r )
@ -266,6 +348,7 @@ namespace assign
return range( boost::begin(r), boost::end(r) );
}
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class T >
list_inserter& operator()( const T& t )
{
@ -316,7 +399,72 @@ namespace assign
#include BOOST_PP_LOCAL_ITERATE()
#else
template< class... Ts >
list_inserter& operator()(Ts&&... ts)
{
insert(arg_type(), boost::forward<Ts>(ts)...);
return *this;
}
template< class T >
void insert(single_arg_type, T&& t)
{
// Special implementation for single argument overload to prevent accidental casts (type-cast using functional notation)
insert_(boost::forward<T>(t));
}
template< class T1, class T2, class... Ts >
void insert(single_arg_type, T1&& t1, T2&& t2, Ts&&... ts)
{
insert_(Argument(boost::forward<T1>(t1), boost::forward<T2>(t2), boost::forward<Ts>(ts)...));
}
template< class... Ts >
void insert(n_arg_type, Ts&&... ts)
{
insert_(boost::forward<Ts>(ts)...);
}
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template< class T >
void insert( T&& r, arg_type)
{
insert_( boost::forward<T>(r) );
}
template< class T >
void insert(assign_detail::repeater<T> r, repeater_arg_type)
{
repeat(r.sz, r.val);
}
template< class Nullary_function >
void insert(const assign_detail::fun_repeater<Nullary_function>& r, repeater_arg_type)
{
repeat_fun(r.sz, r.val);
}
#else
template< class T >
void insert(repeater_arg_type, assign_detail::repeater<T> r)
{
repeat(r.sz, r.val);
}
template< class Nullary_function >
void insert(repeater_arg_type, const assign_detail::fun_repeater<Nullary_function>& r)
{
repeat_fun(r.sz, r.val);
}
#endif
#endif
Function fun_private() const
{
return insert_;
@ -392,9 +540,13 @@ namespace assign
} // namespace 'assign'
} // namespace 'boost'
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#undef BOOST_ASSIGN_PARAMS1
#undef BOOST_ASSIGN_PARAMS2
#undef BOOST_ASSIGN_PARAMS3
#undef BOOST_ASSIGN_MAX_PARAMETERS
#endif
#endif

View File

@ -24,18 +24,38 @@
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/declval.hpp>
#include <boost/mpl/if.hpp>
#include <boost/move/utility.hpp>
#include <deque>
#include <cstddef>
#include <utility>
#ifndef BOOST_NO_CXX11_HDR_ARRAY
#include <array>
#endif
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
// some gcc < 4.7 do not support all of the variadic features required for boost::assign
#if !(defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_WORKAROUND(BOOST_GCC, < 40700) \
|| defined(BOOST_NO_CXX11_RVALUE_REFERENCES))
# define BOOST_ASSIGN_USE_VARIADIC_TEMPLATES
#endif
#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#endif
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// BCB requires full type definition for is_array<> to work correctly.
#include <boost/array.hpp>
@ -48,8 +68,8 @@ namespace boost
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template< class T, std::size_t sz >
class array;
#endif
#endif
namespace assign_detail
{
/////////////////////////////////////////////////////////////////////////
@ -68,16 +88,20 @@ namespace assign_detail
::boost::decay<const T>,
::boost::decay<T> >::type type;
};
template< class T, std::size_t sz >
type_traits::yes_type assign_is_array( const array<T,sz>* );
#ifndef BOOST_NO_CXX11_HDR_ARRAY
template< class T, std::size_t sz >
type_traits::yes_type assign_is_array( const std::array<T, sz>* );
#endif
type_traits::no_type assign_is_array( ... );
template< class T, class U >
type_traits::yes_type assign_is_pair( const std::pair<T,U>* );
type_traits::no_type assign_is_pair( ... );
type_traits::no_type assign_is_pair( ... );
struct array_type_tag
{
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
@ -107,16 +131,22 @@ namespace assign_detail
#endif
};
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
template< class C >
struct is_initializer_list : boost::false_type {};
template< class E >
struct is_initializer_list< std::initializer_list<E> > : boost::true_type {};
#endif
template< class DerivedTAssign, class Iterator >
class converter
{
public: // Range operations
typedef Iterator iterator;
typedef Iterator const_iterator;
iterator begin() const
iterator begin() const
{
return static_cast<const DerivedTAssign*>(this)->begin();
}
@ -125,14 +155,14 @@ namespace assign_detail
{
return static_cast<const DerivedTAssign*>(this)->end();
}
public:
template< class Container >
Container convert_to_container() const
{
static Container* c = 0;
BOOST_STATIC_CONSTANT( bool, is_array_flag = sizeof( assign_detail::assign_is_array( c ) )
BOOST_STATIC_CONSTANT( bool, is_array_flag = sizeof( assign_detail::assign_is_array( c ) )
== sizeof( type_traits::yes_type ) );
typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_array_flag,
@ -141,9 +171,9 @@ namespace assign_detail
return convert<Container>( c, tag_type() );
}
private:
template< class Container >
Container convert( const Container*, default_type_tag ) const
{
@ -151,7 +181,7 @@ namespace assign_detail
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
// old Dinkumware doesn't support iterator type as template
Container result;
iterator it = begin(),
iterator it = begin(),
e = end();
while( it != e )
{
@ -169,29 +199,29 @@ namespace assign_detail
{
typedef BOOST_DEDUCED_TYPENAME Array::value_type value_type;
#if BOOST_WORKAROUND(BOOST_INTEL, <= 910 ) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580 )
#if BOOST_WORKAROUND(BOOST_INTEL, <= 910 ) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5100 )
BOOST_DEDUCED_TYPENAME remove_const<Array>::type ar;
#else
Array ar;
#endif
#endif
const std::size_t sz = ar.size();
if( sz < static_cast<const DerivedTAssign*>(this)->size() )
throw assign::assignment_exception( "array initialized with too many elements" );
std::size_t n = 0;
iterator i = begin(),
BOOST_THROW_EXCEPTION( assign::assignment_exception( "array initialized with too many elements" ) );
std::size_t n = 0;
iterator i = begin(),
e = end();
for( ; i != e; ++i, ++n )
ar[n] = *i;
for( ; n < sz; ++n )
ar[n] = value_type();
return ar;
return ar;
}
template< class Adapter >
Adapter convert_to_adapter( const Adapter* = 0 ) const
{
Adapter a;
iterator i = begin(),
iterator i = begin(),
e = end();
for( ; i != e; ++i )
a.push( *i );
@ -208,7 +238,7 @@ namespace assign_detail
adapter_converter( const converter& this_ ) : gl( this_ )
{}
adapter_converter( const adapter_converter& r )
adapter_converter( const adapter_converter& r )
: gl( r.gl )
{ }
@ -219,11 +249,11 @@ namespace assign_detail
}
};
public:
public:
template< class Container >
Container to_container( Container& c ) const
{
return convert( &c, default_type_tag() );
return convert( &c, default_type_tag() );
}
adapter_converter to_adapter() const
@ -234,7 +264,7 @@ namespace assign_detail
template< class Adapter >
Adapter to_adapter( Adapter& a ) const
{
return this->convert_to_adapter( &a );
return this->convert_to_adapter( &a );
}
template< class Array >
@ -261,7 +291,7 @@ namespace assign_detail
{
return !( l == r );
}
template< class T, class I, class Range >
inline bool operator!=( const Range& l, const converter<T,I>& r )
{
@ -303,7 +333,7 @@ namespace assign_detail
{
return !( l > r );
}
template< class T, class I, class Range >
inline bool operator>=( const converter<T,I>& l, const Range& r )
{
@ -317,67 +347,89 @@ namespace assign_detail
}
template< class T, class I, class Elem, class Traits >
inline std::basic_ostream<Elem,Traits>&
inline std::basic_ostream<Elem,Traits>&
operator<<( std::basic_ostream<Elem, Traits>& Os,
const converter<T,I>& r )
{
return Os << ::boost::make_iterator_range( r.begin(), r.end() );
}
/////////////////////////////////////////////////////////////////////////
// Part 1: flexible, but inefficient interface
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
template< class T >
class generic_list :
template< class T >
class generic_list :
public converter< generic_list< BOOST_DEDUCED_TYPENAME assign_decay<T>::type >,
BOOST_DEDUCED_TYPENAME std::deque<BOOST_DEDUCED_TYPENAME
BOOST_DEDUCED_TYPENAME std::deque<BOOST_DEDUCED_TYPENAME
assign_decay<T>::type>::iterator >
{
typedef BOOST_DEDUCED_TYPENAME assign_decay<T>::type Ty;
typedef std::deque<Ty> impl_type;
mutable impl_type values_;
public:
typedef BOOST_DEDUCED_TYPENAME impl_type::iterator iterator;
typedef iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME impl_type::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME impl_type::size_type size_type;
typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type difference_type;
public:
iterator begin() const { return values_.begin(); }
iterator end() const { return values_.end(); }
bool empty() const { return values_.empty(); }
size_type size() const { return values_.size(); }
private:
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
void push_back( value_type r ) { values_.push_back( r ); }
#else
void push_back( const value_type& r ) { values_.push_back( r ); }
void push_back( value_type&& r ) { values_.push_back( boost::move( r ) ); }
#endif
public:
generic_list& operator,( const Ty& u )
{
this->push_back( u );
this->push_back( u );
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
generic_list& operator,( Ty&& u )
{
this->push_back( boost::move(u) );
return *this;
}
#endif
generic_list& operator()( const Ty& u )
{
this->push_back( u );
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
generic_list& operator()(Ty&& u)
{
this->push_back( boost::move(u) );
return *this;
}
#endif
generic_list& operator()()
{
this->push_back( Ty() );
return *this;
}
generic_list& operator()( const Ty& u )
{
this->push_back( u );
return *this;
}
#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
#ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
#define BOOST_ASSIGN_MAX_PARAMS 5
#endif
#define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
#endif
#define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
#define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class U)
#define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, const& u)
#define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, u)
@ -393,10 +445,18 @@ namespace assign_detail
return *this; \
} \
/**/
#include BOOST_PP_LOCAL_ITERATE()
#else
template< class U0, class U1, class... Us >
generic_list& operator()(U0&& u0, U1&& u1, Us&&... us)
{
this->push_back(Ty(boost::forward<U0>(u0), boost::forward<U1>(u1), boost::forward<Us>(us)...));
return *this;
}
#endif
template< class U >
generic_list& repeat( std::size_t sz, U u )
{
@ -405,7 +465,7 @@ namespace assign_detail
this->push_back( u );
return *this;
}
template< class Nullary_function >
generic_list& repeat_fun( std::size_t sz, Nullary_function fun )
{
@ -416,27 +476,59 @@ namespace assign_detail
}
template< class SinglePassIterator >
generic_list& range( SinglePassIterator first,
generic_list& range( SinglePassIterator first,
SinglePassIterator last )
{
for( ; first != last; ++first )
this->push_back( *first );
return *this;
}
template< class SinglePassRange >
generic_list& range( const SinglePassRange& r )
{
return range( boost::begin(r), boost::end(r) );
}
#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
template< class Container,
class = decltype(Container(
boost::declval<BOOST_DEDUCED_TYPENAME std::deque<BOOST_DEDUCED_TYPENAME assign_decay<T>::type>::iterator>(),
boost::declval<BOOST_DEDUCED_TYPENAME std::deque<BOOST_DEDUCED_TYPENAME assign_decay<T>::type>::iterator>()
))
>
operator Container() const
{
return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
}
template< class Container,
class = typename boost::enable_if< boost::is_same< boost::type_traits::yes_type, decltype(assign_is_array((Container*)0))> >::type,
class = void
>
operator Container() const
{
return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
}
#elif !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
template< class Container
# if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
, class = typename boost::disable_if< is_initializer_list<Container> >::type
# endif
, class = typename Container::iterator
>
operator Container() const
{
return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
}
#else
template< class Container >
operator Container() const
{
return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
}
#endif
};
/////////////////////////////////////////////////////////////////////////
// Part 2: efficient, but inconvenient interface
/////////////////////////////////////////////////////////////////////////
@ -444,7 +536,7 @@ namespace assign_detail
template< class T >
struct assign_reference
{
assign_reference()
assign_reference() : ref_(0)
{ /* intentionally empty */ }
assign_reference( T& r ) : ref_(&r)
@ -469,14 +561,14 @@ namespace assign_detail
{
return *ref_;
}
private:
T* ref_;
};
template< class T >
inline bool operator<( const assign_reference<T>& l,
inline bool operator<( const assign_reference<T>& l,
const assign_reference<T>& r )
{
return l.get_ref() < r.get_ref();
@ -490,16 +582,16 @@ namespace assign_detail
}
template< class T >
inline void swap( assign_reference<T>& l,
inline void swap( assign_reference<T>& l,
assign_reference<T>& r )
{
l.swap( r );
}
template< class T, int N >
struct static_generic_list :
struct static_generic_list :
public converter< static_generic_list<T,N>, assign_reference<T>* >
{
private:
@ -512,7 +604,7 @@ namespace assign_detail
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
static_generic_list( T& r ) :
current_(1)
{
@ -525,7 +617,7 @@ namespace assign_detail
return *this;
}
iterator begin() const
iterator begin() const
{
return &refs_[0];
}
@ -537,7 +629,7 @@ namespace assign_detail
size_type size() const
{
return static_cast<size_type>( current_ );
return static_cast<size_type>( current_ );
}
bool empty() const
@ -546,7 +638,7 @@ namespace assign_detail
}
template< class ForwardIterator >
static_generic_list& range( ForwardIterator first,
static_generic_list& range( ForwardIterator first,
ForwardIterator last )
{
for( ; first != last; ++first )
@ -566,11 +658,41 @@ namespace assign_detail
return range( boost::begin(r), boost::end(r) );
}
#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
template< class Container,
class = decltype(Container(boost::declval<assign_reference<T>*>(), boost::declval<assign_reference<T>*>()))
>
operator Container() const
{
return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
}
template< class Container,
class = typename boost::enable_if< boost::is_same< boost::type_traits::yes_type, decltype(assign_is_array((Container*)0))> >::type,
class = void
>
operator Container() const
{
return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
}
#elif !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
template< class Container
# if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
, class = typename boost::disable_if< is_initializer_list<Container> >::type
# endif
, class = typename Container::iterator
>
operator Container() const
{
return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
}
#else
template< class Container >
operator Container() const
{
return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
}
#endif
private:
void insert( T& r )
@ -578,9 +700,9 @@ namespace assign_detail
refs_[current_] = r;
++current_;
}
static_generic_list();
mutable assign_reference<internal_value_type> refs_[N];
int current_;
};
@ -590,26 +712,43 @@ namespace assign_detail
namespace assign
{
template< class T >
inline assign_detail::generic_list<T>
inline assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type>
list_of()
{
return assign_detail::generic_list<T>()( T() );
assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type> gl;
gl();
return gl;
}
#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
template< class T >
inline assign_detail::generic_list<T>
inline assign_detail::generic_list<T>
list_of( const T& t )
{
return assign_detail::generic_list<T>()( t );
}
#else
template< class T >
inline assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type>
list_of(T&& t)
{
assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type> gl;
gl(boost::forward<T>(t));
return gl;
}
#endif
template< int N, class T >
inline assign_detail::static_generic_list< BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>
ref_list_of( T& t )
{
return assign_detail::static_generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>( t );
}
template< int N, class T >
inline assign_detail::static_generic_list<const BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>
cref_list_of( const T& t )
@ -617,6 +756,8 @@ namespace assign
return assign_detail::static_generic_list<const BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>( t );
}
#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
#define BOOST_PP_LOCAL_MACRO(n) \
template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \
@ -626,7 +767,7 @@ namespace assign
return assign_detail::generic_list<T>()(u, BOOST_ASSIGN_PARAMS3(n)); \
} \
/**/
#include BOOST_PP_LOCAL_ITERATE()
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
@ -638,14 +779,34 @@ namespace assign
return assign_detail::generic_list< tuple<U, BOOST_ASSIGN_PARAMS4(n)> >()( tuple<U,BOOST_ASSIGN_PARAMS4(n)>( u, BOOST_ASSIGN_PARAMS3(n) )); \
} \
/**/
#include BOOST_PP_LOCAL_ITERATE()
#else
template< class T, class U, class... Us >
inline assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type>
list_of(U&& u, Us&&... us)
{
assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type> gl;
gl(boost::forward<U>(u), boost::forward<Us>(us)...);
return gl;
}
template< class U, class... Us >
inline assign_detail::generic_list< tuple<U, Us...> >
tuple_list_of(U u, Us... us)
{
assign_detail::generic_list< tuple<U, Us...> > gl;
gl(tuple<U, Us...>(u, us...));
return gl;
}
#endif
template< class Key, class T >
inline assign_detail::generic_list< std::pair
<
BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<Key>::type,
<
BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<Key>::type,
BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type
> >
map_list_of( const Key& k, const T& t )
@ -657,8 +818,8 @@ namespace assign
template< class F, class S >
inline assign_detail::generic_list< std::pair
<
BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<F>::type,
<
BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<F>::type,
BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<S>::type
> >
pair_list_of( const F& f, const S& s )
@ -671,6 +832,8 @@ namespace assign
} // namespace 'boost'
#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
#undef BOOST_ASSIGN_PARAMS1
#undef BOOST_ASSIGN_PARAMS2
#undef BOOST_ASSIGN_PARAMS3
@ -679,3 +842,6 @@ namespace assign
#undef BOOST_ASSIGN_MAX_PARAMETERS
#endif
#endif

View File

@ -18,12 +18,14 @@
#include <boost/assign/list_inserter.hpp>
#include <boost/config.hpp>
#include <boost/move/utility.hpp>
#include <deque>
namespace boost
{
namespace assign
{
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class V, class A, class V2 >
inline list_inserter< assign_detail::call_push_back< std::deque<V,A> >, V >
@ -31,7 +33,18 @@ namespace assign
{
return push_back( c )( v );
}
#else
template< class V, class A, class V2 >
inline list_inserter< assign_detail::call_push_back< std::deque<V, A> >, V >
operator+=(std::deque<V, A>& c, V2&& v)
{
return push_back(c)(boost::forward<V2>(v));
}
#endif
}
}

View File

@ -18,12 +18,14 @@
#include <boost/assign/list_inserter.hpp>
#include <boost/config.hpp>
#include <boost/move/utility.hpp>
#include <list>
namespace boost
{
namespace assign
{
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class V, class A, class V2 >
inline list_inserter< assign_detail::call_push_back< std::list<V,A> >, V >
@ -31,7 +33,18 @@ namespace assign
{
return push_back( c )( v );
}
#else
template< class V, class A, class V2 >
inline list_inserter< assign_detail::call_push_back< std::list<V, A> >, V >
operator+=(std::list<V, A>& c, V2&& v)
{
return push_back(c)(boost::forward<V2>(v));
}
#endif
}
}

View File

@ -18,12 +18,14 @@
#include <boost/assign/list_inserter.hpp>
#include <boost/config.hpp>
#include <boost/move/utility.hpp>
#include <queue>
namespace boost
{
namespace assign
{
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class V, class C, class V2 >
inline list_inserter< assign_detail::call_push< std::queue<V,C> >, V >
@ -39,6 +41,23 @@ namespace assign
return push( c )( v );
}
#else
template< class V, class C, class V2 >
inline list_inserter< assign_detail::call_push< std::queue<V, C> >, V >
operator+=(std::queue<V, C>& c, V2&& v)
{
return push(c)(boost::forward<V2>(v));
}
template< class V, class C, class V2 >
inline list_inserter< assign_detail::call_push< std::priority_queue<V, C> >, V >
operator+=(std::priority_queue<V, C>& c, V2&& v)
{
return push(c)(boost::forward<V2>(v));
}
#endif
}
}

View File

@ -18,12 +18,16 @@
#include <boost/assign/list_inserter.hpp>
#include <boost/config.hpp>
#include <boost/move/utility.hpp>
#include <set>
namespace boost
{
namespace assign
{
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class K, class C, class A, class K2 >
inline list_inserter< assign_detail::call_insert< std::set<K,C,A> >, K >
operator+=( std::set<K,C,A>& c, K2 k )
@ -37,7 +41,24 @@ namespace assign
{
return insert( c )( k );
}
#else
template< class K, class C, class A, class K2 >
inline list_inserter< assign_detail::call_insert< std::set<K, C, A> >, K >
operator+=(std::set<K, C, A>& c, K2&& k)
{
return insert(c)(boost::forward<K2>(k));
}
template< class K, class C, class A, class K2 >
inline list_inserter< assign_detail::call_insert< std::multiset<K, C, A> >, K >
operator+=(std::multiset<K, C, A>& c, K2&& k)
{
return insert(c)(boost::forward<K2>(k));
}
#endif
}
}

View File

@ -19,6 +19,7 @@
#endif
#include <boost/assign/list_inserter.hpp>
#include <boost/move/utility.hpp>
#ifdef BOOST_SLIST_HEADER
# include BOOST_SLIST_HEADER
#else
@ -29,14 +30,22 @@ namespace boost
{
namespace assign
{
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class V, class A, class V2 >
inline list_inserter< assign_detail::call_push_back< BOOST_STD_EXTENSION_NAMESPACE::slist<V,A> >, V >
operator+=( BOOST_STD_EXTENSION_NAMESPACE::slist<V,A>& c, V2 v )
{
return push_back( c )( v );
}
#else
template< class V, class A, class V2 >
inline list_inserter< assign_detail::call_push_back< BOOST_STD_EXTENSION_NAMESPACE::slist<V,A> >, V >
operator+=( BOOST_STD_EXTENSION_NAMESPACE::slist<V,A>& c, V2&& v )
{
return push_back( c )( boost::forward<V2>(v) );
}
#endif
}
}

View File

@ -17,12 +17,14 @@
#include <boost/assign/list_inserter.hpp>
#include <boost/config.hpp>
#include <boost/move/utility.hpp>
#include <stack>
namespace boost
{
namespace assign
{
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class V, class C, class V2 >
inline list_inserter< assign_detail::call_push< std::stack<V,C> >, V >
@ -30,7 +32,17 @@ namespace assign
{
return push( c )( v );
}
#else
template< class V, class C, class V2 >
inline list_inserter< assign_detail::call_push< std::stack<V, C> >, V >
operator+=(std::stack<V, C>& c, V2&& v)
{
return push(c)(boost::forward<V2>(v));
}
#endif
}
}

View File

@ -17,12 +17,14 @@
#include <boost/assign/list_inserter.hpp>
#include <boost/config.hpp>
#include <boost/move/utility.hpp>
#include <vector>
namespace boost
{
namespace assign
{
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template< class V, class A, class V2 >
inline list_inserter< assign_detail::call_push_back< std::vector<V,A> >, V >
@ -30,7 +32,17 @@ namespace assign
{
return push_back( c )( v );
}
#else
template< class V, class A, class V2 >
inline list_inserter< assign_detail::call_push_back< std::vector<V, A> >, V >
operator+=( std::vector<V, A>& c, V2&& v )
{
return push_back( c )( std::forward<V2>(v) );
}
#endif
}
}

View File

@ -21,6 +21,11 @@
#include <boost/atomic/atomic_flag.hpp>
#include <boost/atomic/detail/atomic_template.hpp>
#include <boost/atomic/detail/operations.hpp>
#include <boost/atomic/detail/extra_operations.hpp>
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
#include <boost/atomic/detail/fp_operations.hpp>
#include <boost/atomic/detail/extra_fp_operations.hpp>
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
@ -80,6 +85,12 @@ using atomics::atomic_uint_fast64_t;
using atomics::atomic_intmax_t;
using atomics::atomic_uintmax_t;
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
using atomics::atomic_float_t;
using atomics::atomic_double_t;
using atomics::atomic_long_double_t;
#endif
using atomics::atomic_size_t;
using atomics::atomic_ptrdiff_t;

View File

@ -17,9 +17,12 @@
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/platform.hpp>
#include <boost/atomic/detail/int_sizes.hpp>
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
#include <boost/atomic/detail/float_sizes.hpp>
#endif
#if !defined(BOOST_ATOMIC_EMULATED)
#include BOOST_ATOMIC_DETAIL_HEADER(boost/atomic/detail/caps_)
#include BOOST_ATOMIC_DETAIL_BACKEND_HEADER(boost/atomic/detail/caps_)
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
@ -150,6 +153,52 @@
#define BOOST_ATOMIC_FLAG_LOCK_FREE BOOST_ATOMIC_BOOL_LOCK_FREE
#endif
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
#if !defined(BOOST_ATOMIC_FLOAT_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT)
#if BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 2
#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 4
#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 8
#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 16
#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
#else
#define BOOST_ATOMIC_FLOAT_LOCK_FREE 0
#endif
#endif
#if !defined(BOOST_ATOMIC_DOUBLE_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE)
#if BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 2
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 4
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 8
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 16
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
#else
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE 0
#endif
#endif
#if !defined(BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE)
#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 2
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 4
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 8
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 16
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
#else
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE 0
#endif
#endif
#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
#ifndef BOOST_ATOMIC_THREAD_FENCE
#define BOOST_ATOMIC_THREAD_FENCE 0
#endif

View File

@ -0,0 +1,58 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/addressof.hpp
*
* This header defines \c addressof helper function. It is similar to \c boost::addressof but it is more
* lightweight and also contains a workaround for some compiler warnings.
*/
#ifndef BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
// Detection logic is based on boost/core/addressof.hpp
#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
#elif defined(BOOST_GCC) && BOOST_GCC >= 70000
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
#elif defined(__has_builtin)
#if __has_builtin(__builtin_addressof)
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
#endif
#endif
namespace boost {
namespace atomics {
namespace detail {
template< typename T >
BOOST_FORCEINLINE T* addressof(T& value) BOOST_NOEXCEPT
{
#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF)
return __builtin_addressof(value);
#else
// Note: The point of using a local struct as the intermediate type instead of char is to avoid gcc warnings
// if T is a const volatile char*:
// warning: casting 'const volatile char* const' to 'const volatile char&' does not dereference pointer
// The local struct makes sure T is not related to the cast target type.
struct opaque_type;
return reinterpret_cast< T* >(&const_cast< opaque_type& >(reinterpret_cast< const volatile opaque_type& >(value)));
#endif
}
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_

View File

@ -55,6 +55,7 @@ struct atomic_flag
BOOST_FORCEINLINE void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
BOOST_ASSERT(order != memory_order_consume);
BOOST_ASSERT(order != memory_order_acquire);
BOOST_ASSERT(order != memory_order_acq_rel);
operations::clear(m_storage.value, order);

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
*
* Copyright (c) 2009 Helge Bahmann
* Copyright (c) 2012 Tim Blechmann
* Copyright (c) 2013 - 2014 Andrey Semashev
* Copyright (c) 2013 - 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/bitwise_cast.hpp
@ -16,10 +16,11 @@
#ifndef BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
#include <cstddef>
#include <boost/atomic/detail/config.hpp>
#if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY)
#include <cstring>
#endif
#include <boost/atomic/detail/addressof.hpp>
#include <boost/atomic/detail/string_ops.hpp>
#include <boost/atomic/detail/type_traits/integral_constant.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
@ -29,21 +30,35 @@ namespace boost {
namespace atomics {
namespace detail {
template< std::size_t FromSize, typename To >
BOOST_FORCEINLINE void clear_padding(To& to, atomics::detail::true_type) BOOST_NOEXCEPT
{
BOOST_ATOMIC_DETAIL_MEMSET(reinterpret_cast< unsigned char* >(atomics::detail::addressof(to)) + FromSize, 0, sizeof(To) - FromSize);
}
template< std::size_t FromSize, typename To >
BOOST_FORCEINLINE void clear_padding(To&, atomics::detail::false_type) BOOST_NOEXCEPT
{
}
template< typename To, std::size_t FromSize, typename From >
BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT
{
To to;
BOOST_ATOMIC_DETAIL_MEMCPY
(
atomics::detail::addressof(to),
atomics::detail::addressof(from),
(FromSize < sizeof(To) ? FromSize : sizeof(To))
);
atomics::detail::clear_padding< FromSize >(to, atomics::detail::integral_constant< bool, FromSize < sizeof(To) >());
return to;
}
template< typename To, typename From >
BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT
{
struct
{
To to;
}
value = {};
BOOST_ATOMIC_DETAIL_MEMCPY
(
&reinterpret_cast< char& >(value.to),
&reinterpret_cast< const char& >(from),
(sizeof(From) < sizeof(To) ? sizeof(From) : sizeof(To))
);
return value.to;
return atomics::detail::bitwise_cast< To, sizeof(From) >(from);
}
} // namespace detail

View File

@ -0,0 +1,86 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/bitwise_fp_cast.hpp
*
* This header defines \c bitwise_fp_cast used to convert between storage and floating point value types
*/
#ifndef BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_
#include <cstddef>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/float_sizes.hpp>
#include <boost/atomic/detail/bitwise_cast.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
/*!
* \brief The type trait returns the size of the value of the specified floating point type
*
* This size may be less than <tt>sizeof(T)</tt> if the implementation uses padding bytes for a particular FP type. This is
* often the case with 80-bit extended double, which is stored in 12 or 16 bytes with padding filled with garbage.
*/
template< typename T >
struct value_sizeof
{
static BOOST_CONSTEXPR_OR_CONST std::size_t value = sizeof(T);
};
#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE)
template< >
struct value_sizeof< float >
{
static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE;
};
#endif
#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE)
template< >
struct value_sizeof< double >
{
static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE;
};
#endif
#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE)
template< >
struct value_sizeof< long double >
{
static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE;
};
#endif
template< typename T >
struct value_sizeof< const T > : value_sizeof< T > {};
template< typename T >
struct value_sizeof< volatile T > : value_sizeof< T > {};
template< typename T >
struct value_sizeof< const volatile T > : value_sizeof< T > {};
template< typename To, typename From >
BOOST_FORCEINLINE To bitwise_fp_cast(From const& from) BOOST_NOEXCEPT
{
return atomics::detail::bitwise_cast< To, atomics::detail::value_sizeof< From >::value >(from);
}
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_

View File

@ -19,29 +19,12 @@
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__))
// ARMv7 and later have dmb instruction
#define BOOST_ATOMIC_DETAIL_ARM_HAS_DMB 1
#endif
#if !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__))
// ARMv6k and ARMv7 have 8 and 16 ldrex/strex variants
#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB 1
#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH 1
#if !(((defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__)) && defined(__thumb__)) || defined(__ARM_ARCH_7M__))
// ARMv6k and ARMv7 except ARMv7-M have 64-bit ldrex/strex variants.
// Unfortunately, GCC (at least 4.7.3 on Ubuntu) does not allocate register pairs properly when targeting ARMv6k Thumb,
// which is required for ldrexd/strexd instructions, so we disable 64-bit support. When targeting ARMv6k ARM
// or ARMv7 (both ARM and Thumb 2) it works as expected.
#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD 1
#endif
#endif
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2

View File

@ -16,32 +16,31 @@
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/int_sizes.hpp>
#if defined(__i386__) || defined(__x86_64__)
#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
#elif defined(__arm__)
#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
#elif defined(__POWERPC__) || defined(__PPC__)
#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(__i386__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1
#endif
#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1
#endif
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT))
#define BOOST_ATOMIC_INT128_LOCK_FREE 2
#else
#define BOOST_ATOMIC_INT128_LOCK_FREE 0
#endif
#if __GCC_ATOMIC_LLONG_LOCK_FREE == 2
#if (__GCC_ATOMIC_LLONG_LOCK_FREE == 2) || (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) && BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8)
#define BOOST_ATOMIC_LLONG_LOCK_FREE 2
#else
#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
#endif
#if __GCC_ATOMIC_LONG_LOCK_FREE == 2
#if (__GCC_ATOMIC_LONG_LOCK_FREE == 2) || (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) && BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8)
#define BOOST_ATOMIC_LONG_LOCK_FREE 2
#else
#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE

View File

@ -17,6 +17,7 @@
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
@ -25,7 +26,7 @@
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#if defined(__powerpc64__) || defined(__PPC64__)
#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
#define BOOST_ATOMIC_INT64_LOCK_FREE 2
#endif
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2

View File

@ -17,19 +17,18 @@
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#if defined(__i386__) || defined(__x86_64__)
#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
#elif defined(__arm__)
#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
#elif defined(__POWERPC__) || defined(__PPC__)
#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(__i386__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1
#endif
#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\

View File

@ -17,47 +17,12 @@
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(__GNUC__)
#if defined(__i386__) &&\
(\
defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) ||\
defined(__i586__) || defined(__i686__) || defined(__pentium4__) || defined(__nocona__) || defined(__core2__) || defined(__corei7__) ||\
defined(__k6__) || defined(__athlon__) || defined(__k8__) || defined(__amdfam10__) || defined(__bdver1__) || defined(__bdver2__) || defined(__bdver3__) || defined(__btver1__) || defined(__btver2__)\
)
#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1
#endif
#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1
#endif
#if defined(__x86_64__) || defined(__SSE2__)
// Use mfence only if SSE2 is available
#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1
#endif
#else // defined(__GNUC__)
#if defined(__i386__) && !defined(BOOST_ATOMIC_NO_CMPXCHG8B)
#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1
#endif
#if defined(__x86_64__) && !defined(BOOST_ATOMIC_NO_CMPXCHG16B)
#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1
#endif
#if !defined(BOOST_ATOMIC_NO_MFENCE)
#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1
#endif
#endif // defined(__GNUC__)
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2

View File

@ -21,32 +21,8 @@
#pragma once
#endif
#if defined(__has_builtin)
#if __has_builtin(__builtin_memcpy)
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY
#endif
#if __has_builtin(__builtin_memcmp)
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP
#endif
#elif defined(BOOST_GCC)
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP
#endif
#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY)
#define BOOST_ATOMIC_DETAIL_MEMCPY __builtin_memcpy
#else
#define BOOST_ATOMIC_DETAIL_MEMCPY std::memcpy
#endif
#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP)
#define BOOST_ATOMIC_DETAIL_MEMCMP __builtin_memcmp
#else
#define BOOST_ATOMIC_DETAIL_MEMCMP std::memcmp
#endif
#if defined(__CUDACC__)
// nvcc does not support alternatives in asm statement constraints
// nvcc does not support alternatives ("q,m") in asm statement constraints
#define BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES
// nvcc does not support condition code register ("cc") clobber in asm statements
#define BOOST_ATOMIC_DETAIL_NO_ASM_CLOBBER_CC
@ -60,17 +36,115 @@
#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA
#endif
#if ((defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 403)) ||\
defined(__SUNPRO_CC)
// This macro indicates we're using older binutils that don't support implied zero displacements for memory opereands,
// making code like this invalid:
// movl 4+(%%edx), %%eax
#define BOOST_ATOMIC_DETAIL_NO_ASM_IMPLIED_ZERO_DISPLACEMENTS
#if (defined(__i386__) || defined(__x86_64__)) && (defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40500) || defined(__SUNPRO_CC))
// This macro indicates that the compiler does not support allocating eax:edx or rax:rdx register pairs ("A") in asm blocks
#define BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS
#endif
#if defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40500) || defined(__SUNPRO_CC)
// This macro indicates that the compiler does not support allocating rax:rdx register pairs ("A") in asm blocks
#define BOOST_ATOMIC_DETAIL_NO_ASM_RAX_RDX_PAIRS
#if defined(__i386__) && (defined(__PIC__) || defined(__PIE__)) && !(defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) >= 50100))
// This macro indicates that asm blocks should preserve ebx value unchanged. Some compilers are able to maintain ebx themselves
// around the asm blocks. For those compilers we don't need to save/restore ebx in asm blocks.
#define BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX
#endif
#if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
#if !(defined(BOOST_LIBSTDCXX11) && (BOOST_LIBSTDCXX_VERSION+0) >= 40700) /* libstdc++ from gcc >= 4.7 in C++11 mode */
// This macro indicates that there is not even a basic <type_traits> standard header that is sufficient for most Boost.Atomic needs.
#define BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS
#endif
#endif // defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
// Enable pointer/reference casts between storage and value when possible.
// Note: Despite that MSVC does not employ strict aliasing rules for optimizations
// and does not require an explicit markup for types that may alias, we still don't
// enable the optimization for this compiler because at least MSVC-8 and 9 are known
// to generate broken code sometimes when casts are used.
#define BOOST_ATOMIC_DETAIL_MAY_ALIAS BOOST_MAY_ALIAS
#if !defined(BOOST_NO_MAY_ALIAS)
#define BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS
#endif
#if defined(__GCC_ASM_FLAG_OUTPUTS__)
// The compiler supports output values in flag registers.
// See: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html, Section 6.44.3.
#define BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS
#endif
#if defined(__has_builtin)
#if __has_builtin(__builtin_constant_p)
#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
#endif
#elif defined(__GNUC__)
#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
#endif
#if !defined(BOOST_ATOMIC_DETAIL_IS_CONSTANT)
#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) false
#endif
#if (defined(__BYTE_ORDER__) && defined(__FLOAT_WORD_ORDER__) && (__BYTE_ORDER__+0) == (__FLOAT_WORD_ORDER__+0)) ||\
defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
// This macro indicates that integer and floating point endianness is the same
#define BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH
#endif
// Deprecated symbols markup
#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(_MSC_VER)
#if (_MSC_VER) >= 1400
#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __declspec(deprecated(msg))
#else
// MSVC 7.1 only supports the attribute without a message
#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __declspec(deprecated)
#endif
#endif
#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__has_extension)
#if __has_extension(attribute_deprecated_with_message)
#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated(msg)))
#endif
#endif
// gcc since 4.5 supports deprecated attribute with a message; older versions support the attribute without a message.
// Oracle Studio 12.4 supports deprecated attribute with a message; this is the first release that supports the attribute.
#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && (\
(defined(__GNUC__) && ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0)) >= 405) ||\
(defined(__SUNPRO_CC) && (__SUNPRO_CC + 0) >= 0x5130))
#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated(msg)))
#endif
#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && __cplusplus >= 201402
#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) [[deprecated(msg)]]
#endif
#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__GNUC__)
#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated))
#endif
#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__has_attribute)
#if __has_attribute(deprecated)
#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated))
#endif
#endif
#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED)
#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg)
#endif
// In Boost.Atomic 1.67 we changed (op)_and_test methods to return true when the result is non-zero. This would be more consistent
// with the other names used in Boost.Atomic and the C++ standard library. Since the methods were announced as experimental and
// the previous behavior was released only in Boost 1.66, it was decided to change the result without changing the method names.
// By defining BOOST_ATOMIC_HIGHLIGHT_OP_AND_TEST the user has a way to highlight all uses of the affected functions so
// that it is easier to find and update the affected code (which is typically adding or removing negation of the result). This
// highlighting functionality is a temporary measure to help users upgrade from Boost 1.66 to newer Boost versions. It will
// be removed eventually.
//
// More info at:
// https://github.com/boostorg/atomic/issues/11
// http://boost.2283326.n4.nabble.com/atomic-op-and-test-naming-tc4701445.html
#if defined(BOOST_ATOMIC_HIGHLIGHT_OP_AND_TEST)
#define BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST BOOST_ATOMIC_DETAIL_DEPRECATED("Boost.Atomic 1.67 has changed (op)_and_test result to the opposite. The functions now return true when the result is non-zero. Please, verify your use of the operation and undefine BOOST_ATOMIC_HIGHLIGHT_OP_AND_TEST.")
#else
#define BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST
#endif
#endif // BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_

View File

@ -0,0 +1,28 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_fp_operations.hpp
*
* This header defines extra floating point atomic operations, including the generic version.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_
#include <boost/atomic/detail/extra_fp_ops_generic.hpp>
#include <boost/atomic/detail/extra_fp_ops_emulated.hpp>
#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_GENERIC)
#include BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_HEADER(boost/atomic/detail/extra_fp_ops_)
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_

View File

@ -0,0 +1,35 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_fp_operations_fwd.hpp
*
* This header contains forward declaration of the \c extra_fp_operations template.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_
#include <cstddef>
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
template< typename Base, typename Value, std::size_t Size, bool = Base::is_always_lock_free >
struct extra_fp_operations;
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_

View File

@ -0,0 +1,107 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_fp_ops_emulated.hpp
*
* This header contains emulated (lock-based) implementation of the extra floating point atomic operations.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_
#include <cstddef>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/bitwise_fp_cast.hpp>
#include <boost/atomic/detail/extra_fp_operations_fwd.hpp>
#include <boost/atomic/detail/lockpool.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
//! Generic implementation of extra floating point operations
template< typename Base, typename Value, std::size_t Size >
struct emulated_extra_fp_operations :
public Base
{
typedef Base base_type;
typedef typename base_type::storage_type storage_type;
typedef Value value_type;
static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
value_type new_val = -old_val;
s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
return old_val;
}
static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
value_type new_val = -old_val;
s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
return new_val;
}
static BOOST_FORCEINLINE value_type add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
value_type new_val = old_val + v;
s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
return new_val;
}
static BOOST_FORCEINLINE value_type sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
value_type new_val = old_val - v;
s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
return new_val;
}
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
fetch_negate(storage, order);
}
static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_add(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_sub(storage, v, order);
}
};
template< typename Base, typename Value, std::size_t Size >
struct extra_fp_operations< Base, Value, Size, false > :
public emulated_extra_fp_operations< Base, Value, Size >
{
};
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_

View File

@ -0,0 +1,189 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_fp_ops_generic.hpp
*
* This header contains generic implementation of the extra floating point atomic operations.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_GENERIC_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_GENERIC_HPP_INCLUDED_
#include <cstddef>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/bitwise_fp_cast.hpp>
#include <boost/atomic/detail/storage_type.hpp>
#include <boost/atomic/detail/extra_fp_operations_fwd.hpp>
#include <boost/atomic/detail/type_traits/is_iec559.hpp>
#include <boost/atomic/detail/type_traits/is_integral.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 60000
#pragma GCC diagnostic push
// ignoring attributes on template argument X - this warning is because we need to pass storage_type as a template argument; no problem in this case
#pragma GCC diagnostic ignored "-Wignored-attributes"
#endif
namespace boost {
namespace atomics {
namespace detail {
//! Negate implementation
template<
typename Base,
typename Value,
std::size_t Size
#if defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH)
, bool = atomics::detail::is_iec559< Value >::value && atomics::detail::is_integral< typename Base::storage_type >::value
#endif
>
struct generic_extra_fp_negate :
public Base
{
typedef Base base_type;
typedef typename base_type::storage_type storage_type;
typedef Value value_type;
static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type old_storage, new_storage;
value_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_storage);
do
{
old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
new_val = -old_val;
new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
}
while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
return old_val;
}
static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type old_storage, new_storage;
value_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_storage);
do
{
old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
new_val = -old_val;
new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
}
while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
fetch_negate(storage, order);
}
};
#if defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH)
//! Negate implementation for IEEE 754 / IEC 559 floating point types. We leverage the fact that the sign bit is the most significant bit in the value.
template< typename Base, typename Value, std::size_t Size >
struct generic_extra_fp_negate< Base, Value, Size, true > :
public Base
{
typedef Base base_type;
typedef typename base_type::storage_type storage_type;
typedef Value value_type;
//! The mask with only one sign bit set to 1
static BOOST_CONSTEXPR_OR_CONST storage_type sign_mask = static_cast< storage_type >(1u) << (atomics::detail::value_sizeof< value_type >::value * 8u - 1u);
static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return atomics::detail::bitwise_fp_cast< value_type >(base_type::fetch_xor(storage, sign_mask, order));
}
static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return atomics::detail::bitwise_fp_cast< value_type >(base_type::bitwise_xor(storage, sign_mask, order));
}
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
base_type::opaque_xor(storage, sign_mask, order);
}
};
#endif // defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH)
//! Generic implementation of floating point operations
template< typename Base, typename Value, std::size_t Size >
struct generic_extra_fp_operations :
public generic_extra_fp_negate< Base, Value, Size >
{
typedef generic_extra_fp_negate< Base, Value, Size > base_type;
typedef typename base_type::storage_type storage_type;
typedef Value value_type;
static BOOST_FORCEINLINE value_type add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type old_storage, new_storage;
value_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_storage);
do
{
old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
new_val = old_val + v;
new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
}
while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE value_type sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type old_storage, new_storage;
value_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_storage);
do
{
old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
new_val = old_val - v;
new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
}
while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_add(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_sub(storage, v, order);
}
};
// Default extra_fp_operations template definition will be used unless specialized for a specific platform
template< typename Base, typename Value, std::size_t Size >
struct extra_fp_operations< Base, Value, Size, true > :
public generic_extra_fp_operations< Base, Value, Size >
{
};
} // namespace detail
} // namespace atomics
} // namespace boost
#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 60000
#pragma GCC diagnostic pop
#endif
#endif // BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_

View File

@ -0,0 +1,28 @@
/*
* 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)
*
* Copyright (c) 2017 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_operations.hpp
*
* This header defines extra atomic operations, including the generic version.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_
#include <boost/atomic/detail/extra_ops_generic.hpp>
#include <boost/atomic/detail/extra_ops_emulated.hpp>
#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_GENERIC)
#include BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_HEADER(boost/atomic/detail/extra_ops_)
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_

View File

@ -0,0 +1,35 @@
/*
* 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)
*
* Copyright (c) 2017 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_operations_fwd.hpp
*
* This header contains forward declaration of the \c extra_operations template.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_
#include <cstddef>
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
template< typename Base, std::size_t Size, bool Signed, bool = Base::is_always_lock_free >
struct extra_operations;
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_

View File

@ -0,0 +1,238 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_ops_emulated.hpp
*
* This header contains emulated (lock-based) implementation of the extra atomic operations.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
#include <cstddef>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/storage_type.hpp>
#include <boost/atomic/detail/extra_operations_fwd.hpp>
#include <boost/atomic/detail/lockpool.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
// unary minus operator applied to unsigned type, result still unsigned
#pragma warning(disable: 4146)
#endif
namespace boost {
namespace atomics {
namespace detail {
//! Generic implementation of extra operations
template< typename Base, std::size_t Size, bool Signed >
struct emulated_extra_operations :
public Base
{
typedef Base base_type;
typedef typename base_type::storage_type storage_type;
static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type old_val = s;
s = static_cast< storage_type >(-old_val);
return old_val;
}
static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type new_val = static_cast< storage_type >(-s);
s = new_val;
return new_val;
}
static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type new_val = s;
new_val += v;
s = new_val;
return new_val;
}
static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type new_val = s;
new_val -= v;
s = new_val;
return new_val;
}
static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type new_val = s;
new_val &= v;
s = new_val;
return new_val;
}
static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type new_val = s;
new_val |= v;
s = new_val;
return new_val;
}
static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type new_val = s;
new_val ^= v;
s = new_val;
return new_val;
}
static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type old_val = s;
s = static_cast< storage_type >(~old_val);
return old_val;
}
static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
{
storage_type& s = const_cast< storage_type& >(storage);
lockpool::scoped_lock lock(&storage);
storage_type new_val = static_cast< storage_type >(~s);
s = new_val;
return new_val;
}
static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
Base::fetch_add(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
Base::fetch_sub(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
fetch_negate(storage, order);
}
static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
Base::fetch_and(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
Base::fetch_or(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
Base::fetch_xor(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
fetch_complement(storage, order);
}
static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!add(storage, v, order);
}
static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!sub(storage, v, order);
}
static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!negate(storage, order);
}
static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_and(storage, v, order);
}
static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_or(storage, v, order);
}
static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_xor(storage, v, order);
}
static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_complement(storage, order);
}
static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
storage_type old_val = Base::fetch_or(storage, mask, order);
return !!(old_val & mask);
}
static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
storage_type old_val = Base::fetch_and(storage, ~mask, order);
return !!(old_val & mask);
}
static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
storage_type old_val = Base::fetch_xor(storage, mask, order);
return !!(old_val & mask);
}
};
template< typename Base, std::size_t Size, bool Signed >
struct extra_operations< Base, Size, Signed, false > :
public emulated_extra_operations< Base, Size, Signed >
{
};
} // namespace detail
} // namespace atomics
} // namespace boost
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,840 @@
/*
* 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)
*
* Copyright (c) 2017 - 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_ops_gcc_ppc.hpp
*
* This header contains implementation of the extra atomic operations for PowerPC.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
#include <cstddef>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/storage_type.hpp>
#include <boost/atomic/detail/extra_operations_fwd.hpp>
#include <boost/atomic/detail/extra_ops_generic.hpp>
#include <boost/atomic/detail/ops_gcc_ppc_common.hpp>
#include <boost/atomic/capabilities.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
template< typename Base >
struct gcc_ppc_extra_operations_common :
public Base
{
typedef Base base_type;
typedef typename base_type::storage_type storage_type;
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_negate(storage, order);
}
static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_complement(storage, order);
}
static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!base_type::negate(storage, order);
}
static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!base_type::add(storage, v, order);
}
static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!base_type::sub(storage, v, order);
}
static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!base_type::bitwise_and(storage, v, order);
}
static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!base_type::bitwise_or(storage, v, order);
}
static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!base_type::bitwise_xor(storage, v, order);
}
static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!base_type::bitwise_complement(storage, order);
}
};
template< typename Base, std::size_t Size, bool Signed >
struct gcc_ppc_extra_operations;
#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
template< typename Base, bool Signed >
struct gcc_ppc_extra_operations< Base, 1u, Signed > :
public generic_extra_operations< Base, 1u, Signed >
{
typedef generic_extra_operations< Base, 1u, Signed > base_type;
typedef typename base_type::storage_type storage_type;
static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"neg %1,%0\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return original;
}
static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"neg %1,%0\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"add %1,%0,%3\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"sub %1,%0,%3\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"and %1,%0,%3\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"or %1,%0,%3\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"xor %1,%0,%3\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"nor %1,%0,%0\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return original;
}
static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lbarx %0,%y2\n\t"
"nor %1,%0,%0\n\t"
"stbcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
};
template< typename Base, bool Signed >
struct extra_operations< Base, 1u, Signed, true > :
public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 1u, Signed > >
{
};
#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
template< typename Base, bool Signed >
struct gcc_ppc_extra_operations< Base, 2u, Signed > :
public generic_extra_operations< Base, 2u, Signed >
{
typedef generic_extra_operations< Base, 2u, Signed > base_type;
typedef typename base_type::storage_type storage_type;
static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"neg %1,%0\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return original;
}
static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"neg %1,%0\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"add %1,%0,%3\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"sub %1,%0,%3\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"and %1,%0,%3\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"or %1,%0,%3\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"xor %1,%0,%3\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"nor %1,%0,%0\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return original;
}
static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lharx %0,%y2\n\t"
"nor %1,%0,%0\n\t"
"sthcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
};
#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
template< typename Base, bool Signed >
struct gcc_ppc_extra_operations< Base, 4u, Signed > :
public generic_extra_operations< Base, 4u, Signed >
{
typedef generic_extra_operations< Base, 4u, Signed > base_type;
typedef typename base_type::storage_type storage_type;
static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"neg %1,%0\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return original;
}
static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"neg %1,%0\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"add %1,%0,%3\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"sub %1,%0,%3\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"and %1,%0,%3\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"or %1,%0,%3\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"xor %1,%0,%3\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"nor %1,%0,%0\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return original;
}
static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"lwarx %0,%y2\n\t"
"nor %1,%0,%0\n\t"
"stwcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
};
template< typename Base, bool Signed >
struct extra_operations< Base, 4u, Signed, true > :
public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 4u, Signed > >
{
};
#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
template< typename Base, bool Signed >
struct gcc_ppc_extra_operations< Base, 8u, Signed > :
public generic_extra_operations< Base, 8u, Signed >
{
typedef generic_extra_operations< Base, 8u, Signed > base_type;
typedef typename base_type::storage_type storage_type;
static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"neg %1,%0\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return original;
}
static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"neg %1,%0\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"add %1,%0,%3\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"sub %1,%0,%3\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"and %1,%0,%3\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"or %1,%0,%3\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type original, result;
gcc_ppc_operations_base::fence_before(order);
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"xor %1,%0,%3\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
: "b" (v)
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"nor %1,%0,%0\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return original;
}
static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
gcc_ppc_operations_base::fence_before(order);
storage_type original, result;
__asm__ __volatile__
(
"1:\n\t"
"ldarx %0,%y2\n\t"
"nor %1,%0,%0\n\t"
"stdcx. %1,%y2\n\t"
"bne- 1b\n\t"
: "=&b" (original), "=&b" (result), "+Z" (storage)
:
: BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
);
gcc_ppc_operations_base::fence_after(order);
return result;
}
};
template< typename Base, bool Signed >
struct extra_operations< Base, 8u, Signed, true > :
public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 8u, Signed > >
{
};
#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_PPC_INCLUDED_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,402 @@
/*
* 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)
*
* Copyright (c) 2015 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_ops_generic.hpp
*
* This header contains generic implementation of the extra atomic operations.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_
#include <cstddef>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/storage_type.hpp>
#include <boost/atomic/detail/integral_extend.hpp>
#include <boost/atomic/detail/extra_operations_fwd.hpp>
#include <boost/atomic/capabilities.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
// unary minus operator applied to unsigned type, result still unsigned
#pragma warning(disable: 4146)
#endif
namespace boost {
namespace atomics {
namespace detail {
//! Generic implementation of extra operations
template< typename Base, std::size_t Size, bool Signed, bool = Base::full_cas_based >
struct generic_extra_operations :
public Base
{
typedef Base base_type;
typedef typename base_type::storage_type storage_type;
typedef typename make_storage_type< Size >::type emulated_storage_type;
static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val;
atomics::detail::non_atomic_load(storage, old_val);
while (!base_type::compare_exchange_weak(storage, old_val, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)), order, memory_order_relaxed)) {}
return old_val;
}
static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_val);
do
{
new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val));
}
while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return base_type::fetch_add(storage, v, order) + v;
}
static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return base_type::fetch_sub(storage, v, order) - v;
}
static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return base_type::fetch_and(storage, v, order) & v;
}
static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return base_type::fetch_or(storage, v, order) | v;
}
static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return base_type::fetch_xor(storage, v, order) ^ v;
}
static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return base_type::fetch_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
}
static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u)));
return base_type::fetch_xor(storage, mask, order) ^ mask;
}
static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_add(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_sub(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
fetch_negate(storage, order);
}
static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_and(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_or(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_xor(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
fetch_complement(storage, order);
}
static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!static_cast< emulated_storage_type >(add(storage, v, order));
}
static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!static_cast< emulated_storage_type >(sub(storage, v, order));
}
static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!negate(storage, order);
}
static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_and(storage, v, order);
}
static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_or(storage, v, order);
}
static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_xor(storage, v, order);
}
static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!static_cast< emulated_storage_type >(bitwise_complement(storage, order));
}
static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
storage_type old_val = base_type::fetch_or(storage, mask, order);
return !!(old_val & mask);
}
static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
storage_type old_val = base_type::fetch_and(storage, ~mask, order);
return !!(old_val & mask);
}
static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
storage_type old_val = base_type::fetch_xor(storage, mask, order);
return !!(old_val & mask);
}
};
//! Specialization for cases when the platform only natively supports CAS
template< typename Base, std::size_t Size, bool Signed >
struct generic_extra_operations< Base, Size, Signed, true > :
public Base
{
typedef Base base_type;
typedef typename base_type::storage_type storage_type;
typedef typename make_storage_type< Size >::type emulated_storage_type;
static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val;
atomics::detail::non_atomic_load(storage, old_val);
while (!base_type::compare_exchange_weak(storage, old_val, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)), order, memory_order_relaxed)) {}
return old_val;
}
static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_val);
do
{
new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val));
}
while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_val);
do
{
new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val + v));
}
while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_val);
do
{
new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val - v));
}
while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_val);
do
{
new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val & v));
}
while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_val);
do
{
new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val | v));
}
while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
storage_type old_val, new_val;
atomics::detail::non_atomic_load(storage, old_val);
do
{
new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val ^ v));
}
while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
return new_val;
}
static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return base_type::fetch_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
}
static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return bitwise_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
}
static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_add(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_sub(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
fetch_negate(storage, order);
}
static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_and(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_or(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fetch_xor(storage, v, order);
}
static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
fetch_complement(storage, order);
}
static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!static_cast< emulated_storage_type >(add(storage, v, order));
}
static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!static_cast< emulated_storage_type >(sub(storage, v, order));
}
static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!negate(storage, order);
}
static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_and(storage, v, order);
}
static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_or(storage, v, order);
}
static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
return !!bitwise_xor(storage, v, order);
}
static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!static_cast< emulated_storage_type >(bitwise_complement(storage, order));
}
static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
storage_type old_val = base_type::fetch_or(storage, mask, order);
return !!(old_val & mask);
}
static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
storage_type old_val = base_type::fetch_and(storage, ~mask, order);
return !!(old_val & mask);
}
static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
storage_type old_val = base_type::fetch_xor(storage, mask, order);
return !!(old_val & mask);
}
};
// Default extra_operations template definition will be used unless specialized for a specific platform
template< typename Base, std::size_t Size, bool Signed >
struct extra_operations< Base, Size, Signed, true > :
public generic_extra_operations< Base, Size, Signed >
{
};
} // namespace detail
} // namespace atomics
} // namespace boost
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_

View File

@ -0,0 +1,106 @@
/*
* 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)
*
* Copyright (c) 2017 Andrey Semashev
*/
/*!
* \file atomic/detail/extra_ops_msvc_arm.hpp
*
* This header contains implementation of the extra atomic operations for ARM.
*/
#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_
#include <cstddef>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/interlocked.hpp>
#include <boost/atomic/detail/storage_type.hpp>
#include <boost/atomic/detail/extra_operations_fwd.hpp>
#include <boost/atomic/detail/extra_ops_generic.hpp>
#include <boost/atomic/capabilities.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
#if defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR)
template< typename Base, std::size_t Size, bool Signed >
struct extra_operations< Base, 4u, Signed, true > :
public generic_extra_operations< Base, 4u, Signed >
{
typedef generic_extra_operations< Base, 4u, Signed > base_type;
typedef typename base_type::storage_type storage_type;
static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
#if defined(BOOST_ATOMIC_INTERLOCKED_BTS_RELAXED) && defined(BOOST_ATOMIC_INTERLOCKED_BTS_ACQUIRE) && defined(BOOST_ATOMIC_INTERLOCKED_BTS_RELEASE)
bool result;
switch (order)
{
case memory_order_relaxed:
result = !!BOOST_ATOMIC_INTERLOCKED_BTS_RELAXED(&storage, bit_number);
break;
case memory_order_consume:
case memory_order_acquire:
result = !!BOOST_ATOMIC_INTERLOCKED_BTS_ACQUIRE(&storage, bit_number);
break;
case memory_order_release:
result = !!BOOST_ATOMIC_INTERLOCKED_BTS_RELEASE(&storage, bit_number);
break;
case memory_order_acq_rel:
case memory_order_seq_cst:
default:
result = !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
break;
}
return result;
#else
return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
#endif
}
static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
{
#if defined(BOOST_ATOMIC_INTERLOCKED_BTR_RELAXED) && defined(BOOST_ATOMIC_INTERLOCKED_BTR_ACQUIRE) && defined(BOOST_ATOMIC_INTERLOCKED_BTR_RELEASE)
bool result;
switch (order)
{
case memory_order_relaxed:
result = !!BOOST_ATOMIC_INTERLOCKED_BTR_RELAXED(&storage, bit_number);
break;
case memory_order_consume:
case memory_order_acquire:
result = !!BOOST_ATOMIC_INTERLOCKED_BTR_ACQUIRE(&storage, bit_number);
break;
case memory_order_release:
result = !!BOOST_ATOMIC_INTERLOCKED_BTR_RELEASE(&storage, bit_number);
break;
case memory_order_acq_rel:
case memory_order_seq_cst:
default:
result = !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
break;
}
return result;
#else
return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
#endif
}
};
#endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR)
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_

Some files were not shown because too many files have changed in this diff Show More