mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-21 19:55:20 -05:00
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:
parent
edd0930758
commit
d361e123c6
8
INSTALL
8
INSTALL
@ -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
312
Jamroot
@ -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) ;
|
@ -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.
|
15
README.md
15
README.md
@ -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
|
||||
|
@ -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) ;
|
66
boost.css
66
boost.css
@ -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;
|
||||
}
|
@ -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 );
|
||||
}
|
||||
|
553
boost/algorithm/minmax_element.hpp
Normal file
553
boost/algorithm/minmax_element.hpp
Normal 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
|
@ -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 ) {}
|
||||
|
||||
|
@ -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) {}
|
||||
|
@ -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);
|
||||
|
@ -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 >
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -40,6 +40,7 @@ class BOOST_SYMBOL_VISIBLE common_iarchive :
|
||||
public interface_iarchive<Archive>
|
||||
{
|
||||
friend class interface_iarchive<Archive>;
|
||||
friend class basic_iarchive;
|
||||
private:
|
||||
virtual void vload(version_type & t){
|
||||
* this->This() >> t;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
218
boost/archive/detail/polymorphic_iarchive_route.hpp
Normal file
218
boost/archive/detail/polymorphic_iarchive_route.hpp
Normal 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
|
209
boost/archive/detail/polymorphic_oarchive_route.hpp
Normal file
209
boost/archive/detail/polymorphic_oarchive_route.hpp
Normal 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
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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>";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -102,7 +102,8 @@ public:
|
||||
super_t(base),
|
||||
m_bnext(NULL),
|
||||
m_bend(NULL),
|
||||
m_full(false)
|
||||
m_full(false),
|
||||
m_current_value(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
54
boost/archive/polymorphic_binary_iarchive.hpp
Normal file
54
boost/archive/polymorphic_binary_iarchive.hpp
Normal 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
|
||||
|
45
boost/archive/polymorphic_binary_oarchive.hpp
Normal file
45
boost/archive/polymorphic_binary_oarchive.hpp
Normal 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
|
||||
|
54
boost/archive/polymorphic_text_iarchive.hpp
Normal file
54
boost/archive/polymorphic_text_iarchive.hpp
Normal 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
|
||||
|
45
boost/archive/polymorphic_text_oarchive.hpp
Normal file
45
boost/archive/polymorphic_text_oarchive.hpp
Normal 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
|
||||
|
59
boost/archive/polymorphic_text_wiarchive.hpp
Normal file
59
boost/archive/polymorphic_text_wiarchive.hpp
Normal 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
|
||||
|
50
boost/archive/polymorphic_text_woarchive.hpp
Normal file
50
boost/archive/polymorphic_text_woarchive.hpp
Normal 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
|
||||
|
54
boost/archive/polymorphic_xml_iarchive.hpp
Normal file
54
boost/archive/polymorphic_xml_iarchive.hpp
Normal 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
|
||||
|
44
boost/archive/polymorphic_xml_oarchive.hpp
Normal file
44
boost/archive/polymorphic_xml_oarchive.hpp
Normal 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
|
||||
|
50
boost/archive/polymorphic_xml_wiarchive.hpp
Normal file
50
boost/archive/polymorphic_xml_wiarchive.hpp
Normal 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
|
||||
|
50
boost/archive/polymorphic_xml_woarchive.hpp
Normal file
50
boost/archive/polymorphic_xml_woarchive.hpp
Normal 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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
@ -29,7 +30,7 @@ namespace boost
|
||||
: what_( _what )
|
||||
{ }
|
||||
|
||||
virtual const char* what() const throw()
|
||||
virtual const char* what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return what_;
|
||||
}
|
||||
|
@ -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
|
||||
@ -54,6 +59,17 @@ namespace assign_detail
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
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 >
|
||||
@ -77,11 +101,19 @@ namespace assign_detail
|
||||
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 >
|
||||
@ -107,11 +147,19 @@ namespace assign_detail
|
||||
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,
|
||||
@ -187,6 +236,7 @@ namespace assign
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< class T >
|
||||
list_inserter& operator=( const 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,6 +399,71 @@ 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
|
||||
{
|
||||
@ -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
|
||||
|
@ -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>
|
||||
@ -71,6 +91,10 @@ namespace assign_detail
|
||||
|
||||
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>* );
|
||||
@ -107,7 +131,13 @@ 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
|
||||
@ -169,14 +199,14 @@ 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
|
||||
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" );
|
||||
BOOST_THROW_EXCEPTION( assign::assignment_exception( "array initialized with too many elements" ) );
|
||||
std::size_t n = 0;
|
||||
iterator i = begin(),
|
||||
e = end();
|
||||
@ -352,8 +382,12 @@ namespace assign_detail
|
||||
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 )
|
||||
{
|
||||
@ -361,18 +395,36 @@ namespace assign_detail
|
||||
return *this;
|
||||
}
|
||||
|
||||
generic_list& operator()()
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
generic_list& operator,( Ty&& u )
|
||||
{
|
||||
this->push_back( Ty() );
|
||||
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;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
|
||||
|
||||
#ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
|
||||
#define BOOST_ASSIGN_MAX_PARAMS 5
|
||||
@ -396,6 +448,14 @@ namespace assign_detail
|
||||
|
||||
#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 )
|
||||
@ -429,12 +489,44 @@ 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<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
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
@ -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)
|
||||
@ -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 )
|
||||
@ -590,12 +712,16 @@ 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>
|
||||
list_of( const T& t )
|
||||
@ -603,6 +729,19 @@ namespace assign
|
||||
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 )
|
||||
@ -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) > \
|
||||
@ -641,6 +782,26 @@ namespace assign
|
||||
|
||||
#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
|
||||
@ -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
|
||||
|
@ -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 >
|
||||
@ -32,6 +34,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::deque<V, A> >, V >
|
||||
operator+=(std::deque<V, A>& c, V2&& v)
|
||||
{
|
||||
return push_back(c)(boost::forward<V2>(v));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 >
|
||||
@ -32,6 +34,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::list<V, A> >, V >
|
||||
operator+=(std::list<V, A>& c, V2&& v)
|
||||
{
|
||||
return push_back(c)(boost::forward<V2>(v));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 )
|
||||
@ -38,6 +42,23 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 >
|
||||
@ -31,6 +33,16 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 >
|
||||
@ -31,6 +33,16 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
58
boost/atomic/detail/addressof.hpp
Normal file
58
boost/atomic/detail/addressof.hpp
Normal 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_
|
@ -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
@ -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
|
||||
|
86
boost/atomic/detail/bitwise_fp_cast.hpp
Normal file
86
boost/atomic/detail/bitwise_fp_cast.hpp
Normal 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_
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)\
|
||||
|
@ -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
|
||||
|
@ -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_
|
||||
|
28
boost/atomic/detail/extra_fp_operations.hpp
Normal file
28
boost/atomic/detail/extra_fp_operations.hpp
Normal 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_
|
35
boost/atomic/detail/extra_fp_operations_fwd.hpp
Normal file
35
boost/atomic/detail/extra_fp_operations_fwd.hpp
Normal 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_
|
107
boost/atomic/detail/extra_fp_ops_emulated.hpp
Normal file
107
boost/atomic/detail/extra_fp_ops_emulated.hpp
Normal 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_
|
189
boost/atomic/detail/extra_fp_ops_generic.hpp
Normal file
189
boost/atomic/detail/extra_fp_ops_generic.hpp
Normal 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_
|
28
boost/atomic/detail/extra_operations.hpp
Normal file
28
boost/atomic/detail/extra_operations.hpp
Normal 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_
|
35
boost/atomic/detail/extra_operations_fwd.hpp
Normal file
35
boost/atomic/detail/extra_operations_fwd.hpp
Normal 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_
|
238
boost/atomic/detail/extra_ops_emulated.hpp
Normal file
238
boost/atomic/detail/extra_ops_emulated.hpp
Normal 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_
|
1111
boost/atomic/detail/extra_ops_gcc_arm.hpp
Normal file
1111
boost/atomic/detail/extra_ops_gcc_arm.hpp
Normal file
File diff suppressed because it is too large
Load Diff
840
boost/atomic/detail/extra_ops_gcc_ppc.hpp
Normal file
840
boost/atomic/detail/extra_ops_gcc_ppc.hpp
Normal 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_
|
1656
boost/atomic/detail/extra_ops_gcc_x86.hpp
Normal file
1656
boost/atomic/detail/extra_ops_gcc_x86.hpp
Normal file
File diff suppressed because it is too large
Load Diff
402
boost/atomic/detail/extra_ops_generic.hpp
Normal file
402
boost/atomic/detail/extra_ops_generic.hpp
Normal 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_
|
106
boost/atomic/detail/extra_ops_msvc_arm.hpp
Normal file
106
boost/atomic/detail/extra_ops_msvc_arm.hpp
Normal 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
Loading…
Reference in New Issue
Block a user