mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-05-28 04:12:32 -04:00
Bring boost::circular_buffer into thw wsjtx project
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@8412 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
f1aafe76c7
commit
8f0655b3f5
8
boost/INSTALL
Normal file
8
boost/INSTALL
Normal file
@ -0,0 +1,8 @@
|
||||
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
boost/Jamroot
Normal file
312
boost/Jamroot
Normal file
@ -0,0 +1,312 @@
|
||||
# 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) ;
|
23
boost/LICENSE_1_0.txt
Normal file
23
boost/LICENSE_1_0.txt
Normal file
@ -0,0 +1,23 @@
|
||||
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.
|
11
boost/README.txt
Normal file
11
boost/README.txt
Normal file
@ -0,0 +1,11 @@
|
||||
This boost tree is a cut down version of the 1.63.0 source tree built
|
||||
using the boost bcp utility, invoked thus:
|
||||
|
||||
cd <clean-boost-source-tree>
|
||||
<path-where-bcp-was-built>/bcp iterator range math numeric crc circular_buffer build bootstrap.bat bootstrap.sh boostcpp.jam boost-build.jam <this-directory>
|
||||
|
||||
Note that bcp is built from a separate boost source tree to avoid
|
||||
polluting the clean tree used to extract components from above.
|
||||
|
||||
Add other boost libraries as necessary. See the Subversion book for
|
||||
details on how to maintain 3rd-party vendor content used in a project.
|
17
boost/boost-build.jam
Normal file
17
boost/boost-build.jam
Normal file
@ -0,0 +1,17 @@
|
||||
# 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/boost.css
Normal file
66
boost/boost.css
Normal file
@ -0,0 +1,66 @@
|
||||
/*=============================================================================
|
||||
Copyright 2002 William E. Kempf
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompany-
|
||||
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
H1
|
||||
{
|
||||
FONT-SIZE: 200%;
|
||||
COLOR: #00008B;
|
||||
}
|
||||
H2
|
||||
{
|
||||
FONT-SIZE: 150%;
|
||||
}
|
||||
H3
|
||||
{
|
||||
FONT-SIZE: 125%;
|
||||
}
|
||||
H4
|
||||
{
|
||||
FONT-SIZE: 108%;
|
||||
}
|
||||
BODY
|
||||
{
|
||||
FONT-SIZE: 100%;
|
||||
BACKGROUND-COLOR: #ffffff;
|
||||
COLOR: #000000;
|
||||
}
|
||||
PRE
|
||||
{
|
||||
MARGIN-LEFT: 2em;
|
||||
FONT-FAMILY: Courier,
|
||||
monospace;
|
||||
}
|
||||
CODE
|
||||
{
|
||||
FONT-FAMILY: Courier,
|
||||
monospace;
|
||||
}
|
||||
CODE.as_pre
|
||||
{
|
||||
white-space: pre;
|
||||
}
|
||||
.index
|
||||
{
|
||||
TEXT-ALIGN: left;
|
||||
}
|
||||
.page-index
|
||||
{
|
||||
TEXT-ALIGN: left;
|
||||
}
|
||||
.definition
|
||||
{
|
||||
TEXT-ALIGN: left;
|
||||
}
|
||||
.footnote
|
||||
{
|
||||
FONT-SIZE: 66%;
|
||||
VERTICAL-ALIGN: super;
|
||||
TEXT-DECORATION: none;
|
||||
}
|
||||
.function-semantics
|
||||
{
|
||||
CLEAR: left;
|
||||
}
|
BIN
boost/boost.png
Normal file
BIN
boost/boost.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
62
boost/boost/circular_buffer.hpp
Normal file
62
boost/boost/circular_buffer.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Circular buffer library header file.
|
||||
|
||||
// Copyright (c) 2003-2008 Jan Gaspar
|
||||
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See www.boost.org/libs/circular_buffer for documentation.
|
||||
|
||||
#if !defined(BOOST_CIRCULAR_BUFFER_HPP)
|
||||
#define BOOST_CIRCULAR_BUFFER_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/circular_buffer_fwd.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
// BOOST_CB_ENABLE_DEBUG: Debug support control.
|
||||
#if !defined(BOOST_CB_ENABLE_DEBUG)
|
||||
#define BOOST_CB_ENABLE_DEBUG 0
|
||||
#endif
|
||||
|
||||
// BOOST_CB_ASSERT: Runtime assertion.
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
#include <boost/assert.hpp>
|
||||
#define BOOST_CB_ASSERT(Expr) BOOST_ASSERT(Expr)
|
||||
#else
|
||||
#define BOOST_CB_ASSERT(Expr) ((void)0)
|
||||
#endif
|
||||
|
||||
// BOOST_CB_IS_CONVERTIBLE: Check if Iterator::value_type is convertible to Type.
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) ((void)0)
|
||||
#else
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) \
|
||||
BOOST_STATIC_ASSERT((is_convertible<typename detail::iterator_traits<Iterator>::value_type, Type>::value))
|
||||
#endif
|
||||
|
||||
// BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS:
|
||||
// Check if the STL provides templated iterator constructors for its containers.
|
||||
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
|
||||
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_STATIC_ASSERT(false);
|
||||
#else
|
||||
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS ((void)0);
|
||||
#endif
|
||||
|
||||
#include <boost/circular_buffer/debug.hpp>
|
||||
#include <boost/circular_buffer/details.hpp>
|
||||
#include <boost/circular_buffer/base.hpp>
|
||||
#include <boost/circular_buffer/space_optimized.hpp>
|
||||
|
||||
#undef BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS
|
||||
#undef BOOST_CB_IS_CONVERTIBLE
|
||||
#undef BOOST_CB_ASSERT
|
||||
|
||||
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_HPP)
|
3123
boost/boost/circular_buffer/base.hpp
Normal file
3123
boost/boost/circular_buffer/base.hpp
Normal file
File diff suppressed because it is too large
Load Diff
248
boost/boost/circular_buffer/debug.hpp
Normal file
248
boost/boost/circular_buffer/debug.hpp
Normal file
@ -0,0 +1,248 @@
|
||||
// Debug support for the circular buffer library.
|
||||
|
||||
// Copyright (c) 2003-2008 Jan Gaspar
|
||||
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
|
||||
#define BOOST_CIRCULAR_BUFFER_DEBUG_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
#include <cstring>
|
||||
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std {
|
||||
using ::memset;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BOOST_CB_ENABLE_DEBUG
|
||||
namespace boost {
|
||||
|
||||
namespace cb_details {
|
||||
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
|
||||
// The value the uninitialized memory is filled with.
|
||||
const int UNINITIALIZED = 0xcc;
|
||||
|
||||
template <class T>
|
||||
inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT {
|
||||
std::memset(static_cast<void*>(data), UNINITIALIZED, size_in_bytes);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void do_fill_uninitialized_memory(T& /*data*/, std::size_t /*size_in_bytes*/) BOOST_NOEXCEPT {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
class debug_iterator_registry;
|
||||
|
||||
/*!
|
||||
\class debug_iterator_base
|
||||
\brief Registers/unregisters iterators into the registry of valid iterators.
|
||||
|
||||
This class is intended to be a base class of an iterator.
|
||||
*/
|
||||
class debug_iterator_base {
|
||||
|
||||
private:
|
||||
// Members
|
||||
|
||||
//! Iterator registry.
|
||||
mutable const debug_iterator_registry* m_registry;
|
||||
|
||||
//! Next iterator in the iterator chain.
|
||||
mutable const debug_iterator_base* m_next;
|
||||
|
||||
public:
|
||||
// Construction/destruction
|
||||
|
||||
//! Default constructor.
|
||||
debug_iterator_base();
|
||||
|
||||
//! Constructor taking the iterator registry as a parameter.
|
||||
debug_iterator_base(const debug_iterator_registry* registry);
|
||||
|
||||
//! Copy constructor.
|
||||
debug_iterator_base(const debug_iterator_base& rhs);
|
||||
|
||||
//! Destructor.
|
||||
~debug_iterator_base();
|
||||
|
||||
// Methods
|
||||
|
||||
//! Assign operator.
|
||||
debug_iterator_base& operator = (const debug_iterator_base& rhs);
|
||||
|
||||
//! Is the iterator valid?
|
||||
bool is_valid(const debug_iterator_registry* registry) const;
|
||||
|
||||
//! Invalidate the iterator.
|
||||
/*!
|
||||
\note The method is const in order to invalidate const iterators, too.
|
||||
*/
|
||||
void invalidate() const;
|
||||
|
||||
//! Return the next iterator in the iterator chain.
|
||||
const debug_iterator_base* next() const;
|
||||
|
||||
//! Set the next iterator in the iterator chain.
|
||||
/*!
|
||||
\note The method is const in order to set a next iterator to a const iterator, too.
|
||||
*/
|
||||
void set_next(const debug_iterator_base* it) const;
|
||||
|
||||
private:
|
||||
// Helpers
|
||||
|
||||
//! Register self as a valid iterator.
|
||||
void register_self();
|
||||
|
||||
//! Unregister self from valid iterators.
|
||||
void unregister_self();
|
||||
};
|
||||
|
||||
/*!
|
||||
\class debug_iterator_registry
|
||||
\brief Registry of valid iterators.
|
||||
|
||||
This class is intended to be a base class of a container.
|
||||
*/
|
||||
class debug_iterator_registry {
|
||||
|
||||
//! Pointer to the chain of valid iterators.
|
||||
mutable const debug_iterator_base* m_iterators;
|
||||
|
||||
public:
|
||||
// Methods
|
||||
|
||||
//! Default constructor.
|
||||
debug_iterator_registry() : m_iterators(0) {}
|
||||
|
||||
//! Register an iterator into the list of valid iterators.
|
||||
/*!
|
||||
\note The method is const in order to register iterators into const containers, too.
|
||||
*/
|
||||
void register_iterator(const debug_iterator_base* it) const {
|
||||
it->set_next(m_iterators);
|
||||
m_iterators = it;
|
||||
}
|
||||
|
||||
//! Unregister an iterator from the list of valid iterators.
|
||||
/*!
|
||||
\note The method is const in order to unregister iterators from const containers, too.
|
||||
*/
|
||||
void unregister_iterator(const debug_iterator_base* it) const {
|
||||
const debug_iterator_base* previous = 0;
|
||||
for (const debug_iterator_base* p = m_iterators; p != it; previous = p, p = p->next()) {}
|
||||
remove(it, previous);
|
||||
}
|
||||
|
||||
//! Invalidate every iterator pointing to the same element as the iterator passed as a parameter.
|
||||
template <class Iterator>
|
||||
void invalidate_iterators(const Iterator& it) {
|
||||
const debug_iterator_base* previous = 0;
|
||||
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) {
|
||||
if (((Iterator*)p)->m_it == it.m_it) {
|
||||
p->invalidate();
|
||||
remove(p, previous);
|
||||
continue;
|
||||
}
|
||||
previous = p;
|
||||
}
|
||||
}
|
||||
|
||||
//! Invalidate all iterators except an iterator poining to the same element as the iterator passed as a parameter.
|
||||
template <class Iterator>
|
||||
void invalidate_iterators_except(const Iterator& it) {
|
||||
const debug_iterator_base* previous = 0;
|
||||
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) {
|
||||
if (((Iterator*)p)->m_it != it.m_it) {
|
||||
p->invalidate();
|
||||
remove(p, previous);
|
||||
continue;
|
||||
}
|
||||
previous = p;
|
||||
}
|
||||
}
|
||||
|
||||
//! Invalidate all iterators.
|
||||
void invalidate_all_iterators() {
|
||||
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next())
|
||||
p->invalidate();
|
||||
m_iterators = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// Helpers
|
||||
|
||||
//! Remove the current iterator from the iterator chain.
|
||||
void remove(const debug_iterator_base* current,
|
||||
const debug_iterator_base* previous) const {
|
||||
if (previous == 0)
|
||||
m_iterators = m_iterators->next();
|
||||
else
|
||||
previous->set_next(current->next());
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation of the debug_iterator_base methods.
|
||||
|
||||
inline debug_iterator_base::debug_iterator_base() : m_registry(0), m_next(0) {}
|
||||
|
||||
inline debug_iterator_base::debug_iterator_base(const debug_iterator_registry* registry)
|
||||
: m_registry(registry), m_next(0) {
|
||||
register_self();
|
||||
}
|
||||
|
||||
inline debug_iterator_base::debug_iterator_base(const debug_iterator_base& rhs)
|
||||
: m_registry(rhs.m_registry), m_next(0) {
|
||||
register_self();
|
||||
}
|
||||
|
||||
inline debug_iterator_base::~debug_iterator_base() { unregister_self(); }
|
||||
|
||||
inline debug_iterator_base& debug_iterator_base::operator = (const debug_iterator_base& rhs) {
|
||||
if (m_registry == rhs.m_registry)
|
||||
return *this;
|
||||
unregister_self();
|
||||
m_registry = rhs.m_registry;
|
||||
register_self();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool debug_iterator_base::is_valid(const debug_iterator_registry* registry) const {
|
||||
return m_registry == registry;
|
||||
}
|
||||
|
||||
inline void debug_iterator_base::invalidate() const { m_registry = 0; }
|
||||
|
||||
inline const debug_iterator_base* debug_iterator_base::next() const { return m_next; }
|
||||
|
||||
inline void debug_iterator_base::set_next(const debug_iterator_base* it) const { m_next = it; }
|
||||
|
||||
inline void debug_iterator_base::register_self() {
|
||||
if (m_registry != 0)
|
||||
m_registry->register_iterator(this);
|
||||
}
|
||||
|
||||
inline void debug_iterator_base::unregister_self() {
|
||||
if (m_registry != 0)
|
||||
m_registry->unregister_iterator(this);
|
||||
}
|
||||
|
||||
#endif // #if BOOST_CB_ENABLE_DEBUG
|
||||
|
||||
} // namespace cb_details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
|
498
boost/boost/circular_buffer/details.hpp
Normal file
498
boost/boost/circular_buffer/details.hpp
Normal file
@ -0,0 +1,498 @@
|
||||
// Helper classes and functions for the circular buffer.
|
||||
|
||||
// Copyright (c) 2003-2008 Jan Gaspar
|
||||
// Copyright (c) 2014 Glen Fernandes // C++11 allocator model support.
|
||||
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
|
||||
#define BOOST_CIRCULAR_BUFFER_DETAILS_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <iterator>
|
||||
|
||||
// Silence MS /W4 warnings like C4913:
|
||||
// "user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used"
|
||||
// This might happen when previously including some boost headers that overload the coma operator.
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4913)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace cb_details {
|
||||
|
||||
template <class Traits> struct nonconst_traits;
|
||||
|
||||
template<class ForwardIterator, class Diff, class T, class Alloc>
|
||||
void uninitialized_fill_n_with_alloc(
|
||||
ForwardIterator first, Diff n, const T& item, Alloc& alloc);
|
||||
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
|
||||
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
|
||||
|
||||
/*!
|
||||
\struct const_traits
|
||||
\brief Defines the data types for a const iterator.
|
||||
*/
|
||||
template <class Traits>
|
||||
struct const_traits {
|
||||
// Basic types
|
||||
typedef typename Traits::value_type value_type;
|
||||
typedef typename Traits::const_pointer pointer;
|
||||
typedef typename Traits::const_reference reference;
|
||||
typedef typename Traits::size_type size_type;
|
||||
typedef typename Traits::difference_type difference_type;
|
||||
|
||||
// Non-const traits
|
||||
typedef nonconst_traits<Traits> nonconst_self;
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct nonconst_traits
|
||||
\brief Defines the data types for a non-const iterator.
|
||||
*/
|
||||
template <class Traits>
|
||||
struct nonconst_traits {
|
||||
// Basic types
|
||||
typedef typename Traits::value_type value_type;
|
||||
typedef typename Traits::pointer pointer;
|
||||
typedef typename Traits::reference reference;
|
||||
typedef typename Traits::size_type size_type;
|
||||
typedef typename Traits::difference_type difference_type;
|
||||
|
||||
// Non-const traits
|
||||
typedef nonconst_traits<Traits> nonconst_self;
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct iterator_wrapper
|
||||
\brief Helper iterator dereference wrapper.
|
||||
*/
|
||||
template <class Iterator>
|
||||
struct iterator_wrapper {
|
||||
mutable Iterator m_it;
|
||||
explicit iterator_wrapper(Iterator it) : m_it(it) {}
|
||||
Iterator operator () () const { return m_it++; }
|
||||
private:
|
||||
iterator_wrapper<Iterator>& operator = (const iterator_wrapper<Iterator>&); // do not generate
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct item_wrapper
|
||||
\brief Helper item dereference wrapper.
|
||||
*/
|
||||
template <class Pointer, class Value>
|
||||
struct item_wrapper {
|
||||
Value m_item;
|
||||
explicit item_wrapper(Value item) : m_item(item) {}
|
||||
Pointer operator () () const { return &m_item; }
|
||||
private:
|
||||
item_wrapper<Pointer, Value>& operator = (const item_wrapper<Pointer, Value>&); // do not generate
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct assign_n
|
||||
\brief Helper functor for assigning n items.
|
||||
*/
|
||||
template <class Value, class Alloc>
|
||||
struct assign_n {
|
||||
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
|
||||
size_type m_n;
|
||||
Value m_item;
|
||||
Alloc& m_alloc;
|
||||
assign_n(size_type n, Value item, Alloc& alloc) : m_n(n), m_item(item), m_alloc(alloc) {}
|
||||
template <class Pointer>
|
||||
void operator () (Pointer p) const {
|
||||
uninitialized_fill_n_with_alloc(p, m_n, m_item, m_alloc);
|
||||
}
|
||||
private:
|
||||
assign_n<Value, Alloc>& operator = (const assign_n<Value, Alloc>&); // do not generate
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct assign_range
|
||||
\brief Helper functor for assigning range of items.
|
||||
*/
|
||||
template <class Iterator, class Alloc>
|
||||
struct assign_range {
|
||||
Iterator m_first;
|
||||
Iterator m_last;
|
||||
Alloc& m_alloc;
|
||||
|
||||
assign_range(const Iterator& first, const Iterator& last, Alloc& alloc)
|
||||
: m_first(first), m_last(last), m_alloc(alloc) {}
|
||||
|
||||
template <class Pointer>
|
||||
void operator () (Pointer p) const {
|
||||
boost::cb_details::uninitialized_copy(m_first, m_last, p, m_alloc);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Iterator, class Alloc>
|
||||
inline assign_range<Iterator, Alloc> make_assign_range(const Iterator& first, const Iterator& last, Alloc& a) {
|
||||
return assign_range<Iterator, Alloc>(first, last, a);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class capacity_control
|
||||
\brief Capacity controller of the space optimized circular buffer.
|
||||
*/
|
||||
template <class Size>
|
||||
class capacity_control {
|
||||
|
||||
//! The capacity of the space-optimized circular buffer.
|
||||
Size m_capacity;
|
||||
|
||||
//! The lowest guaranteed or minimum capacity of the adapted space-optimized circular buffer.
|
||||
Size m_min_capacity;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor.
|
||||
capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0)
|
||||
: m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity)
|
||||
{ // Check for capacity lower than min_capacity.
|
||||
BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity);
|
||||
}
|
||||
|
||||
// Default copy constructor.
|
||||
|
||||
// Default assign operator.
|
||||
|
||||
//! Get the capacity of the space optimized circular buffer.
|
||||
Size capacity() const { return m_capacity; }
|
||||
|
||||
//! Get the minimal capacity of the space optimized circular buffer.
|
||||
Size min_capacity() const { return m_min_capacity; }
|
||||
|
||||
//! Size operator - returns the capacity of the space optimized circular buffer.
|
||||
operator Size() const { return m_capacity; }
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct iterator
|
||||
\brief Random access iterator for the circular buffer.
|
||||
\param Buff The type of the underlying circular buffer.
|
||||
\param Traits Basic iterator types.
|
||||
\note This iterator is not circular. It was designed
|
||||
for iterating from begin() to end() of the circular buffer.
|
||||
*/
|
||||
template <class Buff, class Traits>
|
||||
struct iterator :
|
||||
public std::iterator<
|
||||
std::random_access_iterator_tag,
|
||||
typename Traits::value_type,
|
||||
typename Traits::difference_type,
|
||||
typename Traits::pointer,
|
||||
typename Traits::reference>
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
, public debug_iterator_base
|
||||
#endif // #if BOOST_CB_ENABLE_DEBUG
|
||||
{
|
||||
// Helper types
|
||||
|
||||
//! Base iterator.
|
||||
typedef std::iterator<
|
||||
std::random_access_iterator_tag,
|
||||
typename Traits::value_type,
|
||||
typename Traits::difference_type,
|
||||
typename Traits::pointer,
|
||||
typename Traits::reference> base_iterator;
|
||||
|
||||
//! Non-const iterator.
|
||||
typedef iterator<Buff, typename Traits::nonconst_self> nonconst_self;
|
||||
|
||||
// Basic types
|
||||
|
||||
//! The type of the elements stored in the circular buffer.
|
||||
typedef typename base_iterator::value_type value_type;
|
||||
|
||||
//! Pointer to the element.
|
||||
typedef typename base_iterator::pointer pointer;
|
||||
|
||||
//! Reference to the element.
|
||||
typedef typename base_iterator::reference reference;
|
||||
|
||||
//! Size type.
|
||||
typedef typename Traits::size_type size_type;
|
||||
|
||||
//! Difference type.
|
||||
typedef typename base_iterator::difference_type difference_type;
|
||||
|
||||
// Member variables
|
||||
|
||||
//! The circular buffer where the iterator points to.
|
||||
const Buff* m_buff;
|
||||
|
||||
//! An internal iterator.
|
||||
pointer m_it;
|
||||
|
||||
// Construction & assignment
|
||||
|
||||
// Default copy constructor.
|
||||
|
||||
//! Default constructor.
|
||||
iterator() : m_buff(0), m_it(0) {}
|
||||
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
|
||||
//! Copy constructor (used for converting from a non-const to a const iterator).
|
||||
iterator(const nonconst_self& it) : debug_iterator_base(it), m_buff(it.m_buff), m_it(it.m_it) {}
|
||||
|
||||
//! Internal constructor.
|
||||
/*!
|
||||
\note This constructor is not intended to be used directly by the user.
|
||||
*/
|
||||
iterator(const Buff* cb, const pointer p) : debug_iterator_base(cb), m_buff(cb), m_it(p) {}
|
||||
|
||||
#else
|
||||
|
||||
iterator(const nonconst_self& it) : m_buff(it.m_buff), m_it(it.m_it) {}
|
||||
|
||||
iterator(const Buff* cb, const pointer p) : m_buff(cb), m_it(p) {}
|
||||
|
||||
#endif // #if BOOST_CB_ENABLE_DEBUG
|
||||
|
||||
//! Assign operator.
|
||||
iterator& operator = (const iterator& it) {
|
||||
if (this == &it)
|
||||
return *this;
|
||||
#if BOOST_CB_ENABLE_DEBUG
|
||||
debug_iterator_base::operator =(it);
|
||||
#endif // #if BOOST_CB_ENABLE_DEBUG
|
||||
m_buff = it.m_buff;
|
||||
m_it = it.m_it;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Random access iterator methods
|
||||
|
||||
//! Dereferencing operator.
|
||||
reference operator * () const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end()
|
||||
return *m_it;
|
||||
}
|
||||
|
||||
//! Dereferencing operator.
|
||||
pointer operator -> () const { return &(operator*()); }
|
||||
|
||||
//! Difference operator.
|
||||
template <class Traits0>
|
||||
difference_type operator - (const iterator<Buff, Traits0>& it) const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
return linearize_pointer(*this) - linearize_pointer(it);
|
||||
}
|
||||
|
||||
//! Increment operator (prefix).
|
||||
iterator& operator ++ () {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end()
|
||||
m_buff->increment(m_it);
|
||||
if (m_it == m_buff->m_last)
|
||||
m_it = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Increment operator (postfix).
|
||||
iterator operator ++ (int) {
|
||||
iterator<Buff, Traits> tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//! Decrement operator (prefix).
|
||||
iterator& operator -- () {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(m_it != m_buff->m_first); // check for iterator pointing to begin()
|
||||
if (m_it == 0)
|
||||
m_it = m_buff->m_last;
|
||||
m_buff->decrement(m_it);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Decrement operator (postfix).
|
||||
iterator operator -- (int) {
|
||||
iterator<Buff, Traits> tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//! Iterator addition.
|
||||
iterator& operator += (difference_type n) {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
if (n > 0) {
|
||||
BOOST_CB_ASSERT(m_buff->end() - *this >= n); // check for too large n
|
||||
m_it = m_buff->add(m_it, n);
|
||||
if (m_it == m_buff->m_last)
|
||||
m_it = 0;
|
||||
} else if (n < 0) {
|
||||
*this -= -n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Iterator addition.
|
||||
iterator operator + (difference_type n) const { return iterator<Buff, Traits>(*this) += n; }
|
||||
|
||||
//! Iterator subtraction.
|
||||
iterator& operator -= (difference_type n) {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
if (n > 0) {
|
||||
BOOST_CB_ASSERT(*this - m_buff->begin() >= n); // check for too large n
|
||||
m_it = m_buff->sub(m_it == 0 ? m_buff->m_last : m_it, n);
|
||||
} else if (n < 0) {
|
||||
*this += -n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Iterator subtraction.
|
||||
iterator operator - (difference_type n) const { return iterator<Buff, Traits>(*this) -= n; }
|
||||
|
||||
//! Element access operator.
|
||||
reference operator [] (difference_type n) const { return *(*this + n); }
|
||||
|
||||
// Equality & comparison
|
||||
|
||||
//! Equality.
|
||||
template <class Traits0>
|
||||
bool operator == (const iterator<Buff, Traits0>& it) const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
return m_it == it.m_it;
|
||||
}
|
||||
|
||||
//! Inequality.
|
||||
template <class Traits0>
|
||||
bool operator != (const iterator<Buff, Traits0>& it) const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
return m_it != it.m_it;
|
||||
}
|
||||
|
||||
//! Less.
|
||||
template <class Traits0>
|
||||
bool operator < (const iterator<Buff, Traits0>& it) const {
|
||||
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
|
||||
return linearize_pointer(*this) < linearize_pointer(it);
|
||||
}
|
||||
|
||||
//! Greater.
|
||||
template <class Traits0>
|
||||
bool operator > (const iterator<Buff, Traits0>& it) const { return it < *this; }
|
||||
|
||||
//! Less or equal.
|
||||
template <class Traits0>
|
||||
bool operator <= (const iterator<Buff, Traits0>& it) const { return !(it < *this); }
|
||||
|
||||
//! Greater or equal.
|
||||
template <class Traits0>
|
||||
bool operator >= (const iterator<Buff, Traits0>& it) const { return !(*this < it); }
|
||||
|
||||
// Helpers
|
||||
|
||||
//! Get a pointer which would point to the same element as the iterator in case the circular buffer is linearized.
|
||||
template <class Traits0>
|
||||
typename Traits0::pointer linearize_pointer(const iterator<Buff, Traits0>& it) const {
|
||||
return it.m_it == 0 ? m_buff->m_buff + m_buff->size() :
|
||||
(it.m_it < m_buff->m_first ? it.m_it + (m_buff->m_end - m_buff->m_first)
|
||||
: m_buff->m_buff + (it.m_it - m_buff->m_first));
|
||||
}
|
||||
};
|
||||
|
||||
//! Iterator addition.
|
||||
template <class Buff, class Traits>
|
||||
inline iterator<Buff, Traits>
|
||||
operator + (typename Traits::difference_type n, const iterator<Buff, Traits>& it) {
|
||||
return it + n;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest)
|
||||
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type.
|
||||
*/
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
|
||||
ForwardIterator next = dest;
|
||||
BOOST_TRY {
|
||||
for (; first != last; ++first, ++dest)
|
||||
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), *first);
|
||||
} BOOST_CATCH(...) {
|
||||
for (; next != dest; ++next)
|
||||
boost::container::allocator_traits<Alloc>::destroy(a, boost::addressof(*next));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return dest;
|
||||
}
|
||||
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
|
||||
true_type) {
|
||||
for (; first != last; ++first, ++dest)
|
||||
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), boost::move(*first));
|
||||
return dest;
|
||||
}
|
||||
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
|
||||
false_type) {
|
||||
return uninitialized_copy(first, last, dest, a);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest)
|
||||
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type and moves elements if they have noexcept move constructors.
|
||||
*/
|
||||
template<class InputIterator, class ForwardIterator, class Alloc>
|
||||
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
|
||||
typedef typename boost::is_nothrow_move_constructible<typename boost::container::allocator_traits<Alloc>::value_type>::type tag_t;
|
||||
return uninitialized_move_if_noexcept_impl(first, last, dest, a, tag_t());
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc)
|
||||
\brief Equivalent of <code>std::uninitialized_fill_n</code> with allocator.
|
||||
*/
|
||||
template<class ForwardIterator, class Diff, class T, class Alloc>
|
||||
inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) {
|
||||
ForwardIterator next = first;
|
||||
BOOST_TRY {
|
||||
for (; n > 0; ++first, --n)
|
||||
boost::container::allocator_traits<Alloc>::construct(alloc, boost::addressof(*first), item);
|
||||
} BOOST_CATCH(...) {
|
||||
for (; next != first; ++next)
|
||||
boost::container::allocator_traits<Alloc>::destroy(alloc, boost::addressof(*next));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
} // namespace cb_details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
|
1719
boost/boost/circular_buffer/space_optimized.hpp
Normal file
1719
boost/boost/circular_buffer/space_optimized.hpp
Normal file
File diff suppressed because it is too large
Load Diff
43
boost/boost/circular_buffer_fwd.hpp
Normal file
43
boost/boost/circular_buffer_fwd.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
// Forward declaration of the circular buffer and its adaptor.
|
||||
|
||||
// Copyright (c) 2003-2008 Jan Gaspar
|
||||
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See www.boost.org/libs/circular_buffer for documentation.
|
||||
|
||||
#if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP)
|
||||
#define BOOST_CIRCULAR_BUFFER_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if !defined(BOOST_NO_STD_ALLOCATOR)
|
||||
#include <memory>
|
||||
#else
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
#if !defined(BOOST_NO_STD_ALLOCATOR)
|
||||
#define BOOST_CB_DEFAULT_ALLOCATOR(T) std::allocator<T>
|
||||
#else
|
||||
#define BOOST_CB_DEFAULT_ALLOCATOR(T) BOOST_DEDUCED_TYPENAME std::vector<T>::allocator_type
|
||||
#endif
|
||||
|
||||
template <class T, class Alloc = BOOST_CB_DEFAULT_ALLOCATOR(T)>
|
||||
class circular_buffer;
|
||||
|
||||
template <class T, class Alloc = BOOST_CB_DEFAULT_ALLOCATOR(T)>
|
||||
class circular_buffer_space_optimized;
|
||||
|
||||
#undef BOOST_CB_DEFAULT_ALLOCATOR
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP)
|
36
boost/boost/detail/lightweight_main.hpp
Normal file
36
boost/boost/detail/lightweight_main.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
// boost/detail/lightweight_main.hpp -------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2010
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// //
|
||||
// exception reporting main() that calls cpp_main() //
|
||||
// //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
int cpp_main(int argc, char* argv[]);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
return cpp_main(argc, argv);
|
||||
}
|
||||
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::cout
|
||||
<< "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n"
|
||||
<< "\n****************************** std::exception *****************************\n"
|
||||
<< ex.what()
|
||||
<< "\n***************************************************************************\n"
|
||||
<< std::endl;
|
||||
}
|
||||
return 1;
|
||||
}
|
142
boost/boost/progress.hpp
Normal file
142
boost/boost/progress.hpp
Normal file
@ -0,0 +1,142 @@
|
||||
// boost progress.hpp header file ------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 1994-99. 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)
|
||||
|
||||
// See http://www.boost.org/libs/timer for documentation.
|
||||
|
||||
// Revision History
|
||||
// 1 Dec 01 Add leading progress display strings (suggested by Toon Knapen)
|
||||
// 20 May 01 Introduce several static_casts<> to eliminate warning messages
|
||||
// (Fixed by Beman, reported by Herve Bronnimann)
|
||||
// 12 Jan 01 Change to inline implementation to allow use without library
|
||||
// builds. See docs for more rationale. (Beman Dawes)
|
||||
// 22 Jul 99 Name changed to .hpp
|
||||
// 16 Jul 99 Second beta
|
||||
// 6 Jul 99 Initial boost version
|
||||
|
||||
#ifndef BOOST_PROGRESS_HPP
|
||||
#define BOOST_PROGRESS_HPP
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/cstdint.hpp> // for uintmax_t
|
||||
#include <iostream> // for ostream, cout, etc
|
||||
#include <string> // for string
|
||||
|
||||
namespace boost {
|
||||
|
||||
// progress_timer ----------------------------------------------------------//
|
||||
|
||||
// A progress_timer behaves like a timer except that the destructor displays
|
||||
// an elapsed time message at an appropriate place in an appropriate form.
|
||||
|
||||
class progress_timer : public timer, private noncopyable
|
||||
{
|
||||
|
||||
public:
|
||||
explicit progress_timer( std::ostream & os = std::cout )
|
||||
// os is hint; implementation may ignore, particularly in embedded systems
|
||||
: timer(), noncopyable(), m_os(os) {}
|
||||
~progress_timer()
|
||||
{
|
||||
// A) Throwing an exception from a destructor is a Bad Thing.
|
||||
// B) The progress_timer destructor does output which may throw.
|
||||
// C) A progress_timer is usually not critical to the application.
|
||||
// Therefore, wrap the I/O in a try block, catch and ignore all exceptions.
|
||||
try
|
||||
{
|
||||
// use istream instead of ios_base to workaround GNU problem (Greg Chicares)
|
||||
std::istream::fmtflags old_flags = m_os.setf( std::istream::fixed,
|
||||
std::istream::floatfield );
|
||||
std::streamsize old_prec = m_os.precision( 2 );
|
||||
m_os << elapsed() << " s\n" // "s" is System International d'Unites std
|
||||
<< std::endl;
|
||||
m_os.flags( old_flags );
|
||||
m_os.precision( old_prec );
|
||||
}
|
||||
|
||||
catch (...) {} // eat any exceptions
|
||||
} // ~progress_timer
|
||||
|
||||
private:
|
||||
std::ostream & m_os;
|
||||
};
|
||||
|
||||
|
||||
// progress_display --------------------------------------------------------//
|
||||
|
||||
// progress_display displays an appropriate indication of
|
||||
// progress at an appropriate place in an appropriate form.
|
||||
|
||||
// NOTE: (Jan 12, 2001) Tried to change unsigned long to boost::uintmax_t, but
|
||||
// found some compilers couldn't handle the required conversion to double.
|
||||
// Reverted to unsigned long until the compilers catch up.
|
||||
|
||||
class progress_display : private noncopyable
|
||||
{
|
||||
public:
|
||||
explicit progress_display( unsigned long expected_count_,
|
||||
std::ostream & os = std::cout,
|
||||
const std::string & s1 = "\n", //leading strings
|
||||
const std::string & s2 = "",
|
||||
const std::string & s3 = "" )
|
||||
// os is hint; implementation may ignore, particularly in embedded systems
|
||||
: noncopyable(), m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count_); }
|
||||
|
||||
void restart( unsigned long expected_count_ )
|
||||
// Effects: display appropriate scale
|
||||
// Postconditions: count()==0, expected_count()==expected_count_
|
||||
{
|
||||
_count = _next_tic_count = _tic = 0;
|
||||
_expected_count = expected_count_;
|
||||
|
||||
m_os << m_s1 << "0% 10 20 30 40 50 60 70 80 90 100%\n"
|
||||
<< m_s2 << "|----|----|----|----|----|----|----|----|----|----|"
|
||||
<< std::endl // endl implies flush, which ensures display
|
||||
<< m_s3;
|
||||
if ( !_expected_count ) _expected_count = 1; // prevent divide by zero
|
||||
} // restart
|
||||
|
||||
unsigned long operator+=( unsigned long increment )
|
||||
// Effects: Display appropriate progress tic if needed.
|
||||
// Postconditions: count()== original count() + increment
|
||||
// Returns: count().
|
||||
{
|
||||
if ( (_count += increment) >= _next_tic_count ) { display_tic(); }
|
||||
return _count;
|
||||
}
|
||||
|
||||
unsigned long operator++() { return operator+=( 1 ); }
|
||||
unsigned long count() const { return _count; }
|
||||
unsigned long expected_count() const { return _expected_count; }
|
||||
|
||||
private:
|
||||
std::ostream & m_os; // may not be present in all imps
|
||||
const std::string m_s1; // string is more general, safer than
|
||||
const std::string m_s2; // const char *, and efficiency or size are
|
||||
const std::string m_s3; // not issues
|
||||
|
||||
unsigned long _count, _expected_count, _next_tic_count;
|
||||
unsigned int _tic;
|
||||
void display_tic()
|
||||
{
|
||||
// use of floating point ensures that both large and small counts
|
||||
// work correctly. static_cast<>() is also used several places
|
||||
// to suppress spurious compiler warnings.
|
||||
unsigned int tics_needed = static_cast<unsigned int>((static_cast<double>(_count)
|
||||
/ static_cast<double>(_expected_count)) * 50.0);
|
||||
do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed );
|
||||
_next_tic_count =
|
||||
static_cast<unsigned long>((_tic/50.0) * static_cast<double>(_expected_count));
|
||||
if ( _count == _expected_count ) {
|
||||
if ( _tic < 51 ) m_os << '*';
|
||||
m_os << std::endl;
|
||||
}
|
||||
} // display_tic
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_PROGRESS_HPP
|
21
boost/boost/thread/condition.hpp
Normal file
21
boost/boost/thread/condition.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef BOOST_THREAD_CONDITION_HPP
|
||||
#define BOOST_THREAD_CONDITION_HPP
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_CONDITION
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
typedef condition_variable_any condition;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
155
boost/boost/thread/detail/thread_group.hpp
Normal file
155
boost/boost/thread/detail/thread_group.hpp
Normal file
@ -0,0 +1,155 @@
|
||||
#ifndef BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
|
||||
#define BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
|
||||
// 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)
|
||||
// (C) Copyright 2007-9 Anthony Williams
|
||||
|
||||
#include <list>
|
||||
#include <boost/thread/csbl/memory/unique_ptr.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/lock_guard.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4251)
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class thread_group
|
||||
{
|
||||
private:
|
||||
thread_group(thread_group const&);
|
||||
thread_group& operator=(thread_group const&);
|
||||
public:
|
||||
thread_group() {}
|
||||
~thread_group()
|
||||
{
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_this_thread_in()
|
||||
{
|
||||
thread::id id = this_thread::get_id();
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
if ((*it)->get_id() == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_thread_in(thread* thrd)
|
||||
{
|
||||
if(thrd)
|
||||
{
|
||||
thread::id id = thrd->get_id();
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
if ((*it)->get_id() == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
thread* create_thread(F threadfunc)
|
||||
{
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
boost::csbl::unique_ptr<thread> new_thread(new thread(threadfunc));
|
||||
threads.push_back(new_thread.get());
|
||||
return new_thread.release();
|
||||
}
|
||||
|
||||
void add_thread(thread* thrd)
|
||||
{
|
||||
if(thrd)
|
||||
{
|
||||
BOOST_THREAD_ASSERT_PRECONDITION( ! is_thread_in(thrd) ,
|
||||
thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying to add a duplicated thread")
|
||||
);
|
||||
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
threads.push_back(thrd);
|
||||
}
|
||||
}
|
||||
|
||||
void remove_thread(thread* thrd)
|
||||
{
|
||||
boost::lock_guard<shared_mutex> guard(m);
|
||||
std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
|
||||
if(it!=threads.end())
|
||||
{
|
||||
threads.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void join_all()
|
||||
{
|
||||
BOOST_THREAD_ASSERT_PRECONDITION( ! is_this_thread_in() ,
|
||||
thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying joining itself")
|
||||
);
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
if ((*it)->joinable())
|
||||
(*it)->join();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
void interrupt_all()
|
||||
{
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
|
||||
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
|
||||
it!=end;
|
||||
++it)
|
||||
{
|
||||
(*it)->interrupt();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
boost::shared_lock<shared_mutex> guard(m);
|
||||
return threads.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<thread*> threads;
|
||||
mutable shared_mutex m;
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
716
boost/boost/thread/pthread/shared_mutex.hpp
Normal file
716
boost/boost/thread/pthread/shared_mutex.hpp
Normal file
@ -0,0 +1,716 @@
|
||||
#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
|
||||
#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
|
||||
|
||||
// (C) Copyright 2006-8 Anthony Williams
|
||||
// (C) Copyright 2012 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
#include <boost/thread/detail/thread_interruption.hpp>
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/chrono/ceil.hpp>
|
||||
#endif
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class shared_mutex
|
||||
{
|
||||
private:
|
||||
class state_data
|
||||
{
|
||||
public:
|
||||
state_data () :
|
||||
shared_count(0),
|
||||
exclusive(false),
|
||||
upgrade(false),
|
||||
exclusive_waiting_blocked(false)
|
||||
{}
|
||||
|
||||
void assert_free() const
|
||||
{
|
||||
BOOST_ASSERT( ! exclusive );
|
||||
BOOST_ASSERT( ! upgrade );
|
||||
BOOST_ASSERT( shared_count==0 );
|
||||
}
|
||||
|
||||
void assert_locked() const
|
||||
{
|
||||
BOOST_ASSERT( exclusive );
|
||||
BOOST_ASSERT( shared_count==0 );
|
||||
BOOST_ASSERT( ! upgrade );
|
||||
}
|
||||
|
||||
void assert_lock_shared () const
|
||||
{
|
||||
BOOST_ASSERT( ! exclusive );
|
||||
BOOST_ASSERT( shared_count>0 );
|
||||
//BOOST_ASSERT( (! upgrade) || (shared_count>1));
|
||||
// if upgraded there are at least 2 threads sharing the mutex,
|
||||
// except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
|
||||
}
|
||||
|
||||
void assert_lock_upgraded () const
|
||||
{
|
||||
BOOST_ASSERT( ! exclusive );
|
||||
BOOST_ASSERT( upgrade );
|
||||
BOOST_ASSERT( shared_count>0 );
|
||||
}
|
||||
|
||||
void assert_lock_not_upgraded () const
|
||||
{
|
||||
BOOST_ASSERT( ! upgrade );
|
||||
}
|
||||
|
||||
bool can_lock () const
|
||||
{
|
||||
return ! (shared_count || exclusive);
|
||||
}
|
||||
|
||||
void exclusive_blocked (bool blocked)
|
||||
{
|
||||
exclusive_waiting_blocked = blocked;
|
||||
}
|
||||
|
||||
void lock ()
|
||||
{
|
||||
exclusive = true;
|
||||
}
|
||||
|
||||
void unlock ()
|
||||
{
|
||||
exclusive = false;
|
||||
exclusive_waiting_blocked = false;
|
||||
}
|
||||
|
||||
bool can_lock_shared () const
|
||||
{
|
||||
return ! (exclusive || exclusive_waiting_blocked);
|
||||
}
|
||||
|
||||
bool more_shared () const
|
||||
{
|
||||
return shared_count > 0 ;
|
||||
}
|
||||
unsigned get_shared_count () const
|
||||
{
|
||||
return shared_count ;
|
||||
}
|
||||
unsigned lock_shared ()
|
||||
{
|
||||
return ++shared_count;
|
||||
}
|
||||
|
||||
|
||||
void unlock_shared ()
|
||||
{
|
||||
--shared_count;
|
||||
}
|
||||
|
||||
bool unlock_shared_downgrades()
|
||||
{
|
||||
if (upgrade) {
|
||||
upgrade=false;
|
||||
exclusive=true;
|
||||
return true;
|
||||
} else {
|
||||
exclusive_waiting_blocked=false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void lock_upgrade ()
|
||||
{
|
||||
++shared_count;
|
||||
upgrade=true;
|
||||
}
|
||||
bool can_lock_upgrade () const
|
||||
{
|
||||
return ! (exclusive || exclusive_waiting_blocked || upgrade);
|
||||
}
|
||||
|
||||
void unlock_upgrade ()
|
||||
{
|
||||
upgrade=false;
|
||||
--shared_count;
|
||||
}
|
||||
|
||||
//private:
|
||||
unsigned shared_count;
|
||||
bool exclusive;
|
||||
bool upgrade;
|
||||
bool exclusive_waiting_blocked;
|
||||
};
|
||||
|
||||
|
||||
|
||||
state_data state;
|
||||
boost::mutex state_change;
|
||||
boost::condition_variable shared_cond;
|
||||
boost::condition_variable exclusive_cond;
|
||||
boost::condition_variable upgrade_cond;
|
||||
|
||||
void release_waiters()
|
||||
{
|
||||
exclusive_cond.notify_one();
|
||||
shared_cond.notify_all();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
BOOST_THREAD_NO_COPYABLE(shared_mutex)
|
||||
|
||||
shared_mutex()
|
||||
{
|
||||
}
|
||||
|
||||
~shared_mutex()
|
||||
{
|
||||
}
|
||||
|
||||
void lock_shared()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
while(!state.can_lock_shared())
|
||||
{
|
||||
shared_cond.wait(lk);
|
||||
}
|
||||
state.lock_shared();
|
||||
}
|
||||
|
||||
bool try_lock_shared()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
if(!state.can_lock_shared())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
state.lock_shared();
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock_shared(system_time const& timeout)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while(!state.can_lock_shared())
|
||||
{
|
||||
if(!shared_cond.timed_wait(lk,timeout))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.lock_shared();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock_shared(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock_shared(get_system_time()+relative_time);
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while(!state.can_lock_shared())
|
||||
//while(state.exclusive || state.exclusive_waiting_blocked)
|
||||
{
|
||||
if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.lock_shared();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
void unlock_shared()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
state.unlock_shared();
|
||||
if (! state.more_shared())
|
||||
{
|
||||
if (state.upgrade)
|
||||
{
|
||||
// As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()
|
||||
// avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
//lk.unlock();
|
||||
upgrade_cond.notify_one();
|
||||
}
|
||||
else
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
//lk.unlock();
|
||||
}
|
||||
release_waiters();
|
||||
}
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while (state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=true;
|
||||
exclusive_cond.wait(lk);
|
||||
}
|
||||
state.exclusive=true;
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock(system_time const& timeout)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=true;
|
||||
if(!exclusive_cond.timed_wait(lk,timeout))
|
||||
{
|
||||
if(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.exclusive=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock(get_system_time()+relative_time);
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
while(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=true;
|
||||
if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
|
||||
{
|
||||
if(state.shared_count || state.exclusive)
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.exclusive=true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
|
||||
if(state.shared_count || state.exclusive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.exclusive=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_locked();
|
||||
state.exclusive=false;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
state.assert_free();
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
void lock_upgrade()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
shared_cond.wait(lk);
|
||||
}
|
||||
state.lock_shared();
|
||||
state.upgrade=true;
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock_upgrade(system_time const& timeout)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
if(!shared_cond.timed_wait(lk,timeout))
|
||||
{
|
||||
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.lock_shared();
|
||||
state.upgrade=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock_upgrade(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock_upgrade(get_system_time()+relative_time);
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
|
||||
{
|
||||
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.lock_shared();
|
||||
state.upgrade=true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
bool try_lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.lock_shared();
|
||||
state.upgrade=true;
|
||||
state.assert_lock_upgraded();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_upgrade()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
//state.upgrade=false;
|
||||
state.unlock_upgrade();
|
||||
if(! state.more_shared() )
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
} else {
|
||||
shared_cond.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
// Upgrade <-> Exclusive
|
||||
void unlock_upgrade_and_lock()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_upgraded();
|
||||
state.unlock_shared();
|
||||
while (state.more_shared())
|
||||
{
|
||||
upgrade_cond.wait(lk);
|
||||
}
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
state.assert_locked();
|
||||
}
|
||||
|
||||
void unlock_and_lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_locked();
|
||||
state.exclusive=false;
|
||||
state.upgrade=true;
|
||||
state.lock_shared();
|
||||
state.exclusive_waiting_blocked=false;
|
||||
state.assert_lock_upgraded();
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
bool try_unlock_upgrade_and_lock()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_upgraded();
|
||||
if( !state.exclusive
|
||||
&& !state.exclusive_waiting_blocked
|
||||
&& state.upgrade
|
||||
&& state.shared_count==1)
|
||||
{
|
||||
state.shared_count=0;
|
||||
state.exclusive=true;
|
||||
state.upgrade=false;
|
||||
state.assert_locked();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_upgrade_and_lock_for(
|
||||
const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_upgrade_and_lock_until(
|
||||
chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_upgrade_and_lock_until(
|
||||
const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_upgraded();
|
||||
if (state.shared_count != 1)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
cv_status status = shared_cond.wait_until(lk,abs_time);
|
||||
if (state.shared_count == 1)
|
||||
break;
|
||||
if(status == cv_status::timeout)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
state.shared_count=0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Shared <-> Exclusive
|
||||
void unlock_and_lock_shared()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_locked();
|
||||
state.exclusive=false;
|
||||
state.lock_shared();
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
bool try_unlock_shared_and_lock()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
if( !state.exclusive
|
||||
&& !state.exclusive_waiting_blocked
|
||||
&& !state.upgrade
|
||||
&& state.shared_count==1)
|
||||
{
|
||||
state.shared_count=0;
|
||||
state.exclusive=true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_shared_and_lock_for(
|
||||
const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_shared_and_lock_until(
|
||||
chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_shared_and_lock_until(
|
||||
const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
if (state.shared_count != 1)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
cv_status status = shared_cond.wait_until(lk,abs_time);
|
||||
if (state.shared_count == 1)
|
||||
break;
|
||||
if(status == cv_status::timeout)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
state.shared_count=0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Shared <-> Upgrade
|
||||
void unlock_upgrade_and_lock_shared()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_upgraded();
|
||||
state.upgrade=false;
|
||||
state.exclusive_waiting_blocked=false;
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
bool try_unlock_shared_and_lock_upgrade()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
if( !state.exclusive
|
||||
&& !state.exclusive_waiting_blocked
|
||||
&& !state.upgrade
|
||||
)
|
||||
{
|
||||
state.upgrade=true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
try_unlock_shared_and_lock_upgrade_for(
|
||||
const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_unlock_shared_and_lock_upgrade_until(
|
||||
chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
try_unlock_shared_and_lock_upgrade_until(
|
||||
const chrono::time_point<Clock, Duration>& abs_time)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::this_thread::disable_interruption do_not_disturb;
|
||||
#endif
|
||||
boost::unique_lock<boost::mutex> lk(state_change);
|
||||
state.assert_lock_shared();
|
||||
if( state.exclusive
|
||||
|| state.exclusive_waiting_blocked
|
||||
|| state.upgrade
|
||||
)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
cv_status status = exclusive_cond.wait_until(lk,abs_time);
|
||||
if( ! state.exclusive
|
||||
&& ! state.exclusive_waiting_blocked
|
||||
&& ! state.upgrade
|
||||
)
|
||||
break;
|
||||
if(status == cv_status::timeout)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
state.upgrade=true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef shared_mutex upgrade_mutex;
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
50
boost/boost/thread/shared_mutex.hpp
Normal file
50
boost/boost/thread/shared_mutex.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef BOOST_THREAD_SHARED_MUTEX_HPP
|
||||
#define BOOST_THREAD_SHARED_MUTEX_HPP
|
||||
|
||||
// shared_mutex.hpp
|
||||
//
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#if defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
#if defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN)
|
||||
#include <boost/thread/pthread/shared_mutex.hpp>
|
||||
#else
|
||||
#include <boost/thread/win32/shared_mutex.hpp>
|
||||
#endif
|
||||
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
|
||||
//#include <boost/thread/v2/shared_mutex.hpp>
|
||||
#include <boost/thread/pthread/shared_mutex.hpp>
|
||||
#else
|
||||
#error "Boost threads unavailable on this platform"
|
||||
#endif
|
||||
|
||||
#include <boost/thread/lockable_traits.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
typedef shared_mutex shared_timed_mutex;
|
||||
namespace sync
|
||||
{
|
||||
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
|
||||
template<>
|
||||
struct is_basic_lockable<shared_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
template<>
|
||||
struct is_lockable<shared_mutex>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
16
boost/boost/thread/thread.hpp
Normal file
16
boost/boost/thread/thread.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef BOOST_THREAD_THREAD_HPP
|
||||
#define BOOST_THREAD_THREAD_HPP
|
||||
|
||||
// thread.hpp
|
||||
//
|
||||
// (C) Copyright 2007-8 Anthony Williams
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/thread/detail/thread_group.hpp>
|
||||
|
||||
|
||||
#endif
|
903
boost/boost/thread/win32/shared_mutex.hpp
Normal file
903
boost/boost/thread/win32/shared_mutex.hpp
Normal file
@ -0,0 +1,903 @@
|
||||
#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
|
||||
#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
|
||||
|
||||
// (C) Copyright 2006-8 Anthony Williams
|
||||
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/thread/win32/thread_primitives.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <limits.h>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/chrono/ceil.hpp>
|
||||
#endif
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class shared_mutex
|
||||
{
|
||||
private:
|
||||
struct state_data
|
||||
{
|
||||
unsigned shared_count:11,
|
||||
shared_waiting:11,
|
||||
exclusive:1,
|
||||
upgrade:1,
|
||||
exclusive_waiting:7,
|
||||
exclusive_waiting_blocked:1;
|
||||
|
||||
friend bool operator==(state_data const& lhs,state_data const& rhs)
|
||||
{
|
||||
return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
T interlocked_compare_exchange(T* target,T new_value,T comparand)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
|
||||
long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
|
||||
*reinterpret_cast<long*>(&new_value),
|
||||
*reinterpret_cast<long*>(&comparand));
|
||||
return *reinterpret_cast<T const*>(&res);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
unlock_sem = 0,
|
||||
exclusive_sem = 1
|
||||
};
|
||||
|
||||
state_data state;
|
||||
detail::win32::handle semaphores[2];
|
||||
detail::win32::handle upgrade_sem;
|
||||
|
||||
void release_waiters(state_data old_state)
|
||||
{
|
||||
if(old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
|
||||
}
|
||||
|
||||
if(old_state.shared_waiting || old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
|
||||
}
|
||||
}
|
||||
void release_shared_waiters(state_data old_state)
|
||||
{
|
||||
if(old_state.shared_waiting || old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
BOOST_THREAD_NO_COPYABLE(shared_mutex)
|
||||
shared_mutex()
|
||||
{
|
||||
semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
|
||||
semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
|
||||
if (!semaphores[exclusive_sem])
|
||||
{
|
||||
detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
|
||||
boost::throw_exception(thread_resource_error());
|
||||
}
|
||||
upgrade_sem=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
|
||||
if (!upgrade_sem)
|
||||
{
|
||||
detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
|
||||
detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX);
|
||||
boost::throw_exception(thread_resource_error());
|
||||
}
|
||||
state_data state_={0,0,0,0,0,0};
|
||||
state=state_;
|
||||
}
|
||||
|
||||
~shared_mutex()
|
||||
{
|
||||
detail::win32::CloseHandle(upgrade_sem);
|
||||
detail::win32::CloseHandle(semaphores[unlock_sem]);
|
||||
detail::win32::CloseHandle(semaphores[exclusive_sem]);
|
||||
}
|
||||
|
||||
bool try_lock_shared()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
|
||||
}
|
||||
|
||||
void lock_shared()
|
||||
{
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
|
||||
#else
|
||||
BOOST_VERIFY(try_lock_shared_until(chrono::steady_clock::now()));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock_shared(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock_shared(get_system_time()+relative_time);
|
||||
}
|
||||
bool timed_lock_shared(boost::system_time const& wait_until)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
++new_state.shared_waiting;
|
||||
if(!new_state.shared_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long const res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until), 0);
|
||||
if(res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
if(new_state.shared_waiting)
|
||||
{
|
||||
--new_state.shared_waiting;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(res==0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
system_clock::time_point s_now = system_clock::now();
|
||||
typename Clock::time_point c_now = Clock::now();
|
||||
return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now));
|
||||
}
|
||||
template <class Duration>
|
||||
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
|
||||
return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
|
||||
}
|
||||
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
++new_state.shared_waiting;
|
||||
if(!new_state.shared_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
chrono::system_clock::time_point n = chrono::system_clock::now();
|
||||
unsigned long res;
|
||||
if (tp>n) {
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
|
||||
res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],
|
||||
static_cast<unsigned long>(rel_time.count()), 0);
|
||||
} else {
|
||||
res=detail::win32::timeout;
|
||||
}
|
||||
if(res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
|
||||
{
|
||||
if(new_state.shared_waiting)
|
||||
{
|
||||
--new_state.shared_waiting;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(res==0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void unlock_shared()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
bool const last_reader=!--new_state.shared_count;
|
||||
|
||||
if(last_reader)
|
||||
{
|
||||
if(new_state.upgrade)
|
||||
{
|
||||
new_state.upgrade=false;
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
if(last_reader)
|
||||
{
|
||||
if(old_state.upgrade)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
|
||||
}
|
||||
else
|
||||
{
|
||||
release_waiters(old_state);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
|
||||
#else
|
||||
BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock(get_system_time()+relative_time);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock(boost::system_time const& wait_until)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
++new_state.exclusive_waiting;
|
||||
if(!new_state.exclusive_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
|
||||
new_state.exclusive_waiting_blocked=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!old_state.shared_count && !old_state.exclusive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#ifndef UNDER_CE
|
||||
const bool wait_all = true;
|
||||
#else
|
||||
const bool wait_all = false;
|
||||
#endif
|
||||
unsigned long const wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until), 0);
|
||||
if(wait_res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
bool must_notify = false;
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
if(!--new_state.exclusive_waiting)
|
||||
{
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
must_notify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if (must_notify)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
|
||||
}
|
||||
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
if(!old_state.shared_count && !old_state.exclusive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(wait_res<2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
return try_lock_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
system_clock::time_point s_now = system_clock::now();
|
||||
typename Clock::time_point c_now = Clock::now();
|
||||
return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
|
||||
}
|
||||
template <class Duration>
|
||||
bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
|
||||
return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
|
||||
}
|
||||
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
++new_state.exclusive_waiting;
|
||||
if(!new_state.exclusive_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
|
||||
new_state.exclusive_waiting_blocked=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!old_state.shared_count && !old_state.exclusive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#ifndef UNDER_CE
|
||||
const bool wait_all = true;
|
||||
#else
|
||||
const bool wait_all = false;
|
||||
#endif
|
||||
|
||||
chrono::system_clock::time_point n = chrono::system_clock::now();
|
||||
unsigned long wait_res;
|
||||
if (tp>n) {
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
|
||||
wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,
|
||||
static_cast<unsigned long>(rel_time.count()), 0);
|
||||
} else {
|
||||
wait_res=detail::win32::timeout;
|
||||
}
|
||||
if(wait_res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
bool must_notify = false;
|
||||
state_data new_state=old_state;
|
||||
if(new_state.shared_count || new_state.exclusive)
|
||||
{
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
if(!--new_state.exclusive_waiting)
|
||||
{
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
must_notify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if (must_notify)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
|
||||
}
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
if(!old_state.shared_count && !old_state.exclusive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(wait_res<2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void unlock()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.exclusive=false;
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
release_waiters(old_state);
|
||||
}
|
||||
|
||||
void lock_upgrade()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
|
||||
{
|
||||
++new_state.shared_waiting;
|
||||
if(!new_state.shared_waiting)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error());
|
||||
}
|
||||
new_state.upgrade=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
|
||||
if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],detail::win32::infinite, 0));
|
||||
}
|
||||
}
|
||||
|
||||
bool try_lock_upgrade()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
++new_state.shared_count;
|
||||
if(!new_state.shared_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_state.upgrade=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void unlock_upgrade()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.upgrade=false;
|
||||
bool const last_reader=!--new_state.shared_count;
|
||||
|
||||
new_state.shared_waiting=0;
|
||||
if(last_reader)
|
||||
{
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
if(last_reader)
|
||||
{
|
||||
release_waiters(old_state);
|
||||
}
|
||||
else {
|
||||
release_shared_waiters(old_state);
|
||||
}
|
||||
// #7720
|
||||
//else {
|
||||
// release_waiters(old_state);
|
||||
//}
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_upgrade_and_lock()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
bool const last_reader=!--new_state.shared_count;
|
||||
|
||||
if(last_reader)
|
||||
{
|
||||
new_state.upgrade=false;
|
||||
new_state.exclusive=true;
|
||||
}
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
if(!last_reader)
|
||||
{
|
||||
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(upgrade_sem,detail::win32::infinite, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_and_lock_upgrade()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.exclusive=false;
|
||||
new_state.upgrade=true;
|
||||
++new_state.shared_count;
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
release_waiters(old_state);
|
||||
}
|
||||
// bool try_unlock_upgrade_and_lock()
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//#ifdef BOOST_THREAD_USES_CHRONO
|
||||
// template <class Rep, class Period>
|
||||
// bool
|
||||
// try_unlock_upgrade_and_lock_for(
|
||||
// const chrono::duration<Rep, Period>& rel_time)
|
||||
// {
|
||||
// return try_unlock_upgrade_and_lock_until(
|
||||
// chrono::steady_clock::now() + rel_time);
|
||||
// }
|
||||
// template <class Clock, class Duration>
|
||||
// bool
|
||||
// try_unlock_upgrade_and_lock_until(
|
||||
// const chrono::time_point<Clock, Duration>& abs_time)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//#endif
|
||||
|
||||
void unlock_and_lock_shared()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.exclusive=false;
|
||||
++new_state.shared_count;
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
release_waiters(old_state);
|
||||
}
|
||||
void unlock_upgrade_and_lock_shared()
|
||||
{
|
||||
state_data old_state=state;
|
||||
for(;;)
|
||||
{
|
||||
state_data new_state=old_state;
|
||||
new_state.upgrade=false;
|
||||
if(new_state.exclusive_waiting)
|
||||
{
|
||||
--new_state.exclusive_waiting;
|
||||
new_state.exclusive_waiting_blocked=false;
|
||||
}
|
||||
new_state.shared_waiting=0;
|
||||
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if(current_state==old_state)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_state=current_state;
|
||||
}
|
||||
release_waiters(old_state);
|
||||
}
|
||||
|
||||
};
|
||||
typedef shared_mutex upgrade_mutex;
|
||||
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
173
boost/boost/tr1/detail/config.hpp
Normal file
173
boost/boost/tr1/detail/config.hpp
Normal file
@ -0,0 +1,173 @@
|
||||
// (C) Copyright John Maddock 2005-7.
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
|
||||
# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if (defined(__GNUC__) && !(defined(linux) || defined(__linux) || defined(__linux__))) \
|
||||
|| (!defined(__FreeBSD__) && defined(__GNUC__)) \
|
||||
|| (!defined(_AIX) && defined(__IBMCPP__) && (__IBMCPP__ >= 800))
|
||||
// Disable use of #include_next on Linux as typically we are installed in a
|
||||
// directory that is searched *after* the std lib include path.
|
||||
#if !defined(BOOST_HAS_INCLUDE_NEXT)
|
||||
# define BOOST_HAS_INCLUDE_NEXT
|
||||
#endif
|
||||
// Need to find out if we're using GLIBC:
|
||||
#ifdef BOOST_TR1_UTILITY_INCLUDED
|
||||
// Oops we're in a recursive include path!!
|
||||
// Need to include utility, or some std lib header,
|
||||
// but *not* via <utility> or <boost/config/no_tr1/utility.hpp>
|
||||
# ifndef BOOST_TR1_NO_RECURSION
|
||||
# define BOOST_TR1_NO_RECURSION
|
||||
# define BOOST_TR1_NO_CONFIG_RECURSION
|
||||
# endif
|
||||
# if defined(BOOST_HAS_INCLUDE_NEXT) && !defined(BOOST_TR1_DISABLE_INCLUDE_NEXT)
|
||||
# include_next <utility>
|
||||
# else
|
||||
# include BOOST_TR1_STD_HEADER(utility)
|
||||
# endif
|
||||
# ifdef BOOST_TR1_NO_CONFIG_RECURSION
|
||||
# undef BOOST_TR1_NO_CONFIG_RECURSION
|
||||
# undef BOOST_TR1_NO_RECURSION
|
||||
# endif
|
||||
#else
|
||||
#include <boost/config/no_tr1/utility.hpp>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__GLIBCXX__) && !defined(BOOST_TR1_PATH)
|
||||
# define BOOST_TR1_PATH(name) tr1/name
|
||||
#endif
|
||||
#if !defined(BOOST_TR1_PATH)
|
||||
# define BOOST_TR1_PATH(name) name
|
||||
#endif
|
||||
|
||||
#define BOOST_TR1_HEADER(name) <BOOST_TR1_PATH(name)>
|
||||
|
||||
// Can't use BOOST_WORKAROUND here, it leads to recursive includes:
|
||||
#if (defined(__BORLANDC__) && (__BORLANDC__ <= 0x600))
|
||||
# define BOOST_TR1_USE_OLD_TUPLE
|
||||
#endif
|
||||
|
||||
#ifdef __IBMCPP_TR1__
|
||||
// turn on support for everything:
|
||||
# define BOOST_HAS_TR1
|
||||
#endif
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
|
||||
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_TR1
|
||||
// turn on support for everything:
|
||||
# define BOOST_HAS_TR1_ARRAY
|
||||
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
|
||||
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
|
||||
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
|
||||
# define BOOST_HAS_TR1_RESULT_OF
|
||||
# define BOOST_HAS_TR1_MEM_FN
|
||||
# define BOOST_HAS_TR1_BIND
|
||||
# define BOOST_HAS_TR1_FUNCTION
|
||||
# define BOOST_HAS_TR1_HASH
|
||||
# define BOOST_HAS_TR1_SHARED_PTR
|
||||
# define BOOST_HAS_TR1_RANDOM
|
||||
# define BOOST_HAS_TR1_REGEX
|
||||
# define BOOST_HAS_TR1_TUPLE
|
||||
# define BOOST_HAS_TR1_TYPE_TRAITS
|
||||
# define BOOST_HAS_TR1_UTILITY
|
||||
# define BOOST_HAS_TR1_UNORDERED_MAP
|
||||
# define BOOST_HAS_TR1_UNORDERED_SET
|
||||
# define BOOST_HAS_TR1_CMATH
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__MWERKS__) && (__MWERKS__ >= 0x3205)
|
||||
//
|
||||
// Very preliminary MWCW support, may not be right:
|
||||
//
|
||||
# define BOOST_HAS_TR1_SHARED_PTR
|
||||
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
|
||||
# define BOOST_HAS_TR1_FUNCTION
|
||||
# define BOOST_HAS_TR1_TUPLE
|
||||
# define BOOST_HAS_TR1_RESULT_OF
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_GCC_TR1
|
||||
// turn on support for everything in gcc 4.0.x:
|
||||
# define BOOST_HAS_TR1_ARRAY
|
||||
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
|
||||
//# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
|
||||
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
|
||||
#endif
|
||||
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
|
||||
# define BOOST_HAS_TR1_RESULT_OF
|
||||
# define BOOST_HAS_TR1_MEM_FN
|
||||
# define BOOST_HAS_TR1_BIND
|
||||
# define BOOST_HAS_TR1_FUNCTION
|
||||
# define BOOST_HAS_TR1_HASH
|
||||
# define BOOST_HAS_TR1_SHARED_PTR
|
||||
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
|
||||
# define BOOST_HAS_TR1_RANDOM
|
||||
//# define BOOST_HAS_TR1_REGEX
|
||||
#ifdef _GLIBCXX_USE_C99_MATH_TR1
|
||||
# define BOOST_HAS_TR1_CMATH
|
||||
#endif
|
||||
#endif
|
||||
# define BOOST_HAS_TR1_TUPLE
|
||||
# define BOOST_HAS_TR1_TYPE_TRAITS
|
||||
# define BOOST_HAS_TR1_UTILITY
|
||||
# define BOOST_HAS_TR1_UNORDERED_MAP
|
||||
# define BOOST_HAS_TR1_UNORDERED_SET
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500) \
|
||||
&& defined(_MSC_FULL_VER) && \
|
||||
!defined(__SGI_STL_PORT) && \
|
||||
!defined(_STLPORT_VERSION) && \
|
||||
!defined(_RWSTD_VER_STR) && \
|
||||
!defined(_RWSTD_VER)
|
||||
//
|
||||
// MSVC-9.0 defines a not-quite TR1 conforming hash
|
||||
// function object in <functional>, so we must define
|
||||
// this here, in addition the feature pack for VC9
|
||||
// provides a more or less full TR1 implementation:
|
||||
//
|
||||
# if (defined(_HAS_TR1) && (_HAS_TR1 + 0)) || (_CPPLIB_VER >= 540)
|
||||
# define BOOST_HAS_TR1_ARRAY
|
||||
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
|
||||
# define BOOST_HAS_TR1_RESULT_OF
|
||||
# define BOOST_HAS_TR1_MEM_FN
|
||||
# define BOOST_HAS_TR1_BIND
|
||||
# define BOOST_HAS_TR1_FUNCTION
|
||||
# define BOOST_HAS_TR1_HASH
|
||||
# define BOOST_HAS_TR1_SHARED_PTR
|
||||
# define BOOST_HAS_TR1_RANDOM
|
||||
# define BOOST_HAS_TR1_REGEX
|
||||
# define BOOST_HAS_TR1_TUPLE
|
||||
# define BOOST_HAS_TR1_TYPE_TRAITS
|
||||
# define BOOST_HAS_TR1_UTILITY
|
||||
# define BOOST_HAS_TR1_UNORDERED_MAP
|
||||
# define BOOST_HAS_TR1_UNORDERED_SET
|
||||
# else
|
||||
# define BOOST_HAS_TR1_HASH
|
||||
# endif
|
||||
# if _MSC_VER >= 1600
|
||||
# define BOOST_HAS_CPP_0X
|
||||
# endif
|
||||
# if _MSC_VER >= 1700
|
||||
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
705
boost/boostcpp.jam
Normal file
705
boost/boostcpp.jam
Normal file
@ -0,0 +1,705 @@
|
||||
# Boost.Build support specific for the Boost C++ Libraries.
|
||||
# Copyright Vladimir Prus 2002-2010.
|
||||
# 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)
|
||||
|
||||
import "class" : new ;
|
||||
import common ;
|
||||
import configure ;
|
||||
import build-system ;
|
||||
import generate ;
|
||||
import modules ;
|
||||
import option ;
|
||||
import os ;
|
||||
import package ;
|
||||
import path ;
|
||||
import project ;
|
||||
import regex ;
|
||||
import set ;
|
||||
import targets ;
|
||||
import feature ;
|
||||
import property ;
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# 0. General setup. Parse options, check them.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
BOOST_ROOT = [ modules.binding $(__name__) ] ;
|
||||
BOOST_ROOT = $(BOOST_ROOT:D) ;
|
||||
|
||||
rule set-version ( version )
|
||||
{
|
||||
BOOST_VERSION = $(version) ;
|
||||
|
||||
local version-tag = [ MATCH ^([^.]+)[.]([^.]+)[.]([^.]+) : $(BOOST_VERSION)
|
||||
] ;
|
||||
if $(version-tag[3]) = 0
|
||||
{
|
||||
version-tag = $(version-tag[1-2]) ;
|
||||
}
|
||||
BOOST_VERSION_TAG = $(version-tag:J=_) ;
|
||||
}
|
||||
|
||||
# Option to choose how many variants to build. The default is "minimal".
|
||||
build-type = [ option.get build-type ] ;
|
||||
build-type ?= minimal ;
|
||||
if ! ( $(build-type) in complete minimal )
|
||||
{
|
||||
EXIT The value of the --build-type option should be either 'complete' or
|
||||
'minimal' ;
|
||||
}
|
||||
|
||||
# What kind of layout are we doing?
|
||||
layout = [ option.get layout : "" ] ;
|
||||
# On Windows, we used versioned layout by default in order to be compatible with
|
||||
# autolink. On other systems, we use system layout which is what every other
|
||||
# program uses. Note that the Windows check is static, and will not be affected
|
||||
# by specific build properties used.
|
||||
if ! $(layout)
|
||||
{
|
||||
if [ os.name ] = NT
|
||||
{
|
||||
layout = versioned ;
|
||||
}
|
||||
else
|
||||
{
|
||||
layout = system ;
|
||||
}
|
||||
}
|
||||
layout-$(layout) = true ;
|
||||
|
||||
if $(layout) = system && $(build-type) = complete
|
||||
{
|
||||
ECHO error: Cannot use --layout=system with --build-type complete. ;
|
||||
ECHO error: Please use either --layout=versioned or --layout=tagged ;
|
||||
ECHO error: if you wish to build multiple variants. ;
|
||||
if [ os.name ] != NT
|
||||
{
|
||||
ECHO error: Note that --layout=system is used by default on Unix
|
||||
starting with Boost 1.40. ;
|
||||
}
|
||||
EXIT ;
|
||||
}
|
||||
|
||||
# Possible stage only location.
|
||||
stage-locate = [ option.get stagedir ] ;
|
||||
stage-locate ?= stage ;
|
||||
BOOST_STAGE_LOCATE = $(stage-locate) ;
|
||||
|
||||
# Custom build ID.
|
||||
build-id = [ option.get buildid ] ;
|
||||
if $(build-id)
|
||||
{
|
||||
BUILD_ID = [ regex.replace $(build-id) "[*\\/:.\"\' ]" _ ] ;
|
||||
}
|
||||
|
||||
# Python build id (for Python libraries only).
|
||||
python-id = [ option.get "python-buildid" ] ;
|
||||
if $(python-id)
|
||||
{
|
||||
PYTHON_ID = [ regex.replace $(python-id) [*\\/:.\"\'] _ ] ;
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 1. 'tag' function adding decorations suitable to the properties if versioned
|
||||
# or tagged layout is requested. Called from Jamroot.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
rule tag ( name : type ? : property-set )
|
||||
{
|
||||
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
|
||||
{
|
||||
local result ;
|
||||
if $(layout) = versioned
|
||||
{
|
||||
result = [ common.format-name
|
||||
<base> <toolset> <threading> <runtime> -$(BOOST_VERSION_TAG)
|
||||
-$(BUILD_ID)
|
||||
: $(name) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
else if $(layout) = tagged
|
||||
{
|
||||
result = [ common.format-name
|
||||
<base> <threading> <runtime>
|
||||
-$(BUILD_ID)
|
||||
: $(name) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
else if $(layout) = system
|
||||
{
|
||||
result = [ common.format-name
|
||||
<base>
|
||||
-$(BUILD_ID)
|
||||
: $(name) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
EXIT error: invalid layout '$(layout:E=)' ;
|
||||
}
|
||||
|
||||
# Optionally add version suffix. On NT, library with version suffix will
|
||||
# not be recognized by linkers. On CYGWIN, we get strage duplicate
|
||||
# symbol errors when library is generated with version suffix. On OSX,
|
||||
# version suffix is not needed -- the linker expects the
|
||||
# libFoo.1.2.3.dylib format. AIX linkers do not accept version suffixes
|
||||
# either. Pgi compilers can not accept a library with version suffix.
|
||||
if $(type) = SHARED_LIB &&
|
||||
! [ $(property-set).get <target-os> ] in windows cygwin darwin aix &&
|
||||
! [ $(property-set).get <toolset> ] in pgi
|
||||
{
|
||||
result = $(result).$(BOOST_VERSION) ;
|
||||
}
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
}
|
||||
|
||||
# Specialized tag function to use for libraries linking to Python.
|
||||
# Appends value of --python-buildid if provided.
|
||||
rule python-tag ( name : type ? : property-set )
|
||||
{
|
||||
local result = $(name) ;
|
||||
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB && $(PYTHON_ID)
|
||||
{
|
||||
result = $(result)-$(PYTHON_ID) ;
|
||||
}
|
||||
|
||||
# forward to the boost tagging rule
|
||||
return [ tag $(result) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 2. Declare targets that build and install all libraries. Specifically:
|
||||
#
|
||||
# - 'stage-proper' that puts all libraries in stage/lib
|
||||
# - 'install-proper' that install libraries and headers to system location
|
||||
# - 'stage-unversioned' that creates links to libraries without boost version
|
||||
# in name
|
||||
# - 'install-unversioned' which creates unversioned linked to installed
|
||||
# libraries.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# Worker function suitable to the 'generate' metatarget. Creates a link to
|
||||
# 'source', striping any version number information from the name.
|
||||
rule make-unversioned-links ( project name ? : property-set : sources * )
|
||||
{
|
||||
local filter ;
|
||||
if [ modules.peek : NT ]
|
||||
{
|
||||
filter = (.*[.]lib) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
filter =
|
||||
(.*[.]so)[.0-9]*
|
||||
(.*[.]dylib)
|
||||
(.*[.]a) ;
|
||||
}
|
||||
|
||||
local result ;
|
||||
for local s in $(sources)
|
||||
{
|
||||
local m = [ MATCH ^(.*)-[0-9_]+$(filter)$ : [ $(s).name ] ] ;
|
||||
if $(m)
|
||||
{
|
||||
local ea = [ $(s).action ] ;
|
||||
local ep = [ $(ea).properties ] ;
|
||||
local a = [ new non-scanning-action $(s) : symlink.ln : $(ep) ] ;
|
||||
result += [ new file-target $(m:J=) exact : [ $(s).type ] :
|
||||
$(project) : $(a) ] ;
|
||||
}
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
rule filtered-target ( name : message + : sources + : requirements * )
|
||||
{
|
||||
message $(name)-message : warning: $(message) ;
|
||||
alias $(name) : $(sources) : $(requirements) ;
|
||||
alias $(name) : $(name)-message ;
|
||||
|
||||
local p = [ project.current ] ;
|
||||
$(p).mark-target-as-explicit $(name) ;
|
||||
$(p).mark-target-as-explicit $(name)-message ;
|
||||
}
|
||||
|
||||
rule declare_install_and_stage_proper_targets ( libraries * : headers * )
|
||||
{
|
||||
local p = [ project.current ] ;
|
||||
for local l in $(libraries)
|
||||
{
|
||||
if $(l) = locale
|
||||
{
|
||||
filtered-target $(l)-for-install :
|
||||
Skipping Boost.Locale library with threading=single. :
|
||||
libs/$(l)/build : <threading>multi ;
|
||||
}
|
||||
else if $(l) = wave
|
||||
{
|
||||
filtered-target $(l)-for-install :
|
||||
Skipping Boost.Wave library with threading=single. :
|
||||
libs/$(l)/build : <threading>multi ;
|
||||
}
|
||||
else if $(l) = thread
|
||||
{
|
||||
filtered-target $(l)-for-install :
|
||||
Skipping Boost.Thread library with threading=single. :
|
||||
libs/$(l)/build : <threading>multi ;
|
||||
}
|
||||
else
|
||||
{
|
||||
alias $(l)-for-install : libs/$(l)/build ;
|
||||
$(p).mark-target-as-explicit $(l)-for-install ;
|
||||
}
|
||||
}
|
||||
local library-targets = $(libraries)-for-install ;
|
||||
|
||||
install-requirements = <install-source-root>$(BOOST_ROOT)/boost ;
|
||||
|
||||
if $(layout-versioned)
|
||||
{
|
||||
install-requirements +=
|
||||
<install-header-subdir>boost-$(BOOST_VERSION_TAG)/boost ;
|
||||
}
|
||||
else
|
||||
{
|
||||
install-requirements += <install-header-subdir>boost ;
|
||||
}
|
||||
|
||||
if [ os.name ] = NT
|
||||
{
|
||||
install-requirements += <install-default-prefix>C:/Boost ;
|
||||
}
|
||||
else
|
||||
{
|
||||
install-requirements += <install-default-prefix>/usr/local ;
|
||||
}
|
||||
|
||||
p = [ project.current ] ;
|
||||
|
||||
# Complete install.
|
||||
package.install install-proper
|
||||
: $(install-requirements) <install-no-version-symlinks>on
|
||||
:
|
||||
: $(libraries)-for-install
|
||||
: $(headers)
|
||||
;
|
||||
$(p).mark-target-as-explicit install-proper ;
|
||||
|
||||
# Install just library.
|
||||
install stage-proper
|
||||
: $(libraries)-for-install
|
||||
: <location>$(stage-locate)/lib
|
||||
<install-dependencies>on <install-type>LIB
|
||||
<install-no-version-symlinks>on
|
||||
;
|
||||
$(p).mark-target-as-explicit stage-proper ;
|
||||
|
||||
# Commented out as it does not seem to work. Whoever wrote this originally,
|
||||
# left some typos in the code, but when that got corrected and the code got
|
||||
# enabled - it started reporting ambiguous/duplicate target Boost Build
|
||||
# errors. Anyone requiring unversioned staged libraries needs to correct
|
||||
# those errors before reenabling this code. For more detailed information
|
||||
# see the related Boost library development mailing list thread at
|
||||
# 'http://lists.boost.org/Archives/boost/2012/06/194312.php'.
|
||||
# (06.07.2012.) (Jurko)
|
||||
#~ if $(layout-versioned) && ( [ modules.peek : NT ] || [ modules.peek : UNIX ] )
|
||||
#~ {
|
||||
#~ generate stage-unversioned : stage-proper :
|
||||
#~ <generating-rule>@boostcpp.make-unversioned-links ;
|
||||
#~ $(p).mark-target-as-explicit stage-unversioned ;
|
||||
#~
|
||||
#~ generate install-unversioned : install-proper :
|
||||
#~ <generating-rule>@boostcpp.make-unversioned-links ;
|
||||
#~ $(p).mark-target-as-explicit install-unversioned ;
|
||||
#~ }
|
||||
#~ else
|
||||
{
|
||||
# Create do-nothing aliases.
|
||||
alias stage-unversioned ;
|
||||
$(p).mark-target-as-explicit stage-unversioned ;
|
||||
alias install-unversioned ;
|
||||
$(p).mark-target-as-explicit install-unversioned ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 3. Declare top-level targets 'stage' and 'install'. These examine the
|
||||
# --build-type option and, in case it is 'complete', build the 'install-proper'
|
||||
# and 'stage-proper' targets with a number of property sets.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
class top-level-target : alias-target-class
|
||||
{
|
||||
import modules ;
|
||||
|
||||
rule __init__ ( name : project : sources * : requirements *
|
||||
: default-build * : usage-requirements * )
|
||||
{
|
||||
alias-target-class.__init__ $(name) : $(project) : $(sources) :
|
||||
$(requirements) : $(default-build) : $(usage-requirements) ;
|
||||
|
||||
self.build-type = [ modules.peek boostcpp : build-type ] ;
|
||||
# On Linux, we build the release variant by default, since few users
|
||||
# will ever want to debug C++ Boost libraries, and there is no ABI
|
||||
# incompatibility between debug and release variants. We build shared
|
||||
# and static libraries since that is what most packages seem to provide
|
||||
# (.so in libfoo and .a in libfoo-dev).
|
||||
self.minimal-properties = [ property-set.create <variant>release
|
||||
<threading>multi <link>shared <link>static <runtime-link>shared ] ;
|
||||
# On Windows, new IDE projects use:
|
||||
#
|
||||
# runtime-link=dynamic, threading=multi, variant=(debug|release)
|
||||
#
|
||||
# and in addition, C++ Boost's autolink defaults to static linking.
|
||||
self.minimal-properties-win = [ property-set.create <variant>debug
|
||||
<variant>release <threading>multi <link>static <runtime-link>shared
|
||||
] ;
|
||||
|
||||
self.complete-properties = [ property-set.create
|
||||
<variant>debug <variant>release
|
||||
<threading>single <threading>multi
|
||||
<link>shared <link>static
|
||||
<runtime-link>shared <runtime-link>static ] ;
|
||||
}
|
||||
|
||||
rule generate ( property-set )
|
||||
{
|
||||
modules.poke : top-level-targets : [ modules.peek : top-level-targets ]
|
||||
$(self.name) ;
|
||||
if $(self.build-type) = minimal
|
||||
{
|
||||
local expanded ;
|
||||
|
||||
local os = [ $(property-set).get <target-os> ] ;
|
||||
# Because we completely override the parent's 'generate' we need to
|
||||
# check for default feature values ourselves.
|
||||
if ! $(os)
|
||||
{
|
||||
os = [ feature.defaults <target-os> ] ;
|
||||
os = $(os:G=) ;
|
||||
}
|
||||
|
||||
if $(os) = windows
|
||||
{
|
||||
expanded = [ targets.apply-default-build $(property-set)
|
||||
: $(self.minimal-properties-win) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
expanded = [ targets.apply-default-build $(property-set)
|
||||
: $(self.minimal-properties) ] ;
|
||||
}
|
||||
return [ build-multiple $(expanded) ] ;
|
||||
}
|
||||
else if $(self.build-type) = complete
|
||||
{
|
||||
local expanded = [ targets.apply-default-build $(property-set)
|
||||
: $(self.complete-properties) ] ;
|
||||
|
||||
# Filter inappopriate combinations.
|
||||
local filtered ;
|
||||
for local p in $(expanded)
|
||||
{
|
||||
# See comment in handle-static-runtime regarding this logic.
|
||||
if [ $(p).get <link> ] = shared
|
||||
&& [ $(p).get <runtime-link> ] = static
|
||||
&& [ $(p).get <toolset> ] != cw
|
||||
{
|
||||
# Skip this.
|
||||
}
|
||||
else
|
||||
{
|
||||
filtered += $(p) ;
|
||||
}
|
||||
}
|
||||
return [ build-multiple $(filtered) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
import errors ;
|
||||
errors.error "Unknown build type" ;
|
||||
}
|
||||
}
|
||||
|
||||
rule build-multiple ( property-sets * )
|
||||
{
|
||||
local usage-requirements = [ property-set.empty ] ;
|
||||
local result ;
|
||||
for local p in $(property-sets)
|
||||
{
|
||||
local r = [ alias-target-class.generate $(p) ] ;
|
||||
if $(r)
|
||||
{
|
||||
usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
|
||||
result += $(r[2-]) ;
|
||||
}
|
||||
}
|
||||
return $(usage-requirements) [ sequence.unique $(result) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
rule declare_top_level_targets ( libraries * : headers * )
|
||||
{
|
||||
declare_install_and_stage_proper_targets $(libraries) : $(headers) ;
|
||||
|
||||
targets.create-metatarget top-level-target : [ project.current ]
|
||||
: install
|
||||
: install-proper install-unversioned
|
||||
;
|
||||
targets.create-metatarget top-level-target : [ project.current ]
|
||||
: stage
|
||||
: stage-proper stage-unversioned
|
||||
;
|
||||
|
||||
p = [ project.current ] ;
|
||||
$(p).mark-target-as-explicit install stage ;
|
||||
|
||||
# This target is built by default, and will forward to 'stage' after
|
||||
# producing some explanations.
|
||||
targets.create-metatarget top-level-target : [ project.current ]
|
||||
: forward
|
||||
: explain stage
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
stage-abs = [ path.native [ path.root $(stage-locate)/lib [ path.pwd ] ] ] ;
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 4. Add hook to report configuration before the build, and confirmation with
|
||||
# setup instructions after the build.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
message explain : "\nBuilding the Boost C++ Libraries.\n\n" ;
|
||||
local p = [ project.current ] ;
|
||||
$(p).mark-target-as-explicit explain ;
|
||||
|
||||
rule pre-build ( )
|
||||
{
|
||||
local tl = [ modules.peek : top-level-targets ] ;
|
||||
if stage in $(tl) || install in $(tl)
|
||||
{
|
||||
# FIXME: Remove 'if' when Boost regression tests start using trunk bjam.
|
||||
if PAD in [ RULENAMES ]
|
||||
{
|
||||
configure.print-component-configuration ;
|
||||
}
|
||||
}
|
||||
}
|
||||
IMPORT $(__name__) : pre-build : : $(__name__).pre-build ;
|
||||
build-system.set-pre-build-hook $(__name__).pre-build ;
|
||||
|
||||
# FIXME: Revise stage_abs.
|
||||
rule post-build ( ok ? )
|
||||
{
|
||||
if forward in [ modules.peek : top-level-targets ]
|
||||
{
|
||||
if $(ok)
|
||||
{
|
||||
local include-path = [ path.native $(BOOST_ROOT) ] ;
|
||||
ECHO "
|
||||
|
||||
The Boost C++ Libraries were successfully built!
|
||||
|
||||
The following directory should be added to compiler include paths:
|
||||
|
||||
$(include-path)
|
||||
|
||||
The following directory should be added to linker library paths:
|
||||
|
||||
$(stage-abs)
|
||||
" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
IMPORT $(__name__) : post-build : : $(__name__).post-build ;
|
||||
build-system.set-post-build-hook $(__name__).post-build ;
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# 5. Top-level setup.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# Decides which libraries are to be installed by looking at --with-<library>
|
||||
# --without-<library> arguments. Returns the list of directories under "libs"
|
||||
# which must be built and installed.
|
||||
#
|
||||
rule libraries-to-install ( existing-libs * )
|
||||
{
|
||||
local argv = [ modules.peek : ARGV ] ;
|
||||
local with-parameter = [ MATCH ^--with-(.*) : $(argv) ] ;
|
||||
local without-parameter = [ MATCH ^--without-(.*) : $(argv) ] ;
|
||||
|
||||
if ! $(with-parameter) && ! $(without-parameter)
|
||||
{
|
||||
# Nothing is specified on command line. See if maybe project-config.jam
|
||||
# has some choices.
|
||||
local libs = [ modules.peek project-config : libraries ] ;
|
||||
with-parameter = [ MATCH ^--with-(.*) : $(libs) ] ;
|
||||
without-parameter = [ MATCH ^--without-(.*) : $(libs) ] ;
|
||||
}
|
||||
|
||||
# Do some checks.
|
||||
if $(with-parameter) && $(without-parameter)
|
||||
{
|
||||
EXIT error: both --with-<library> and --without-<library> specified ;
|
||||
}
|
||||
|
||||
local wrong = [ set.difference $(with-parameter) : $(existing-libs) ] ;
|
||||
if $(wrong)
|
||||
{
|
||||
EXIT error: wrong library name '$(wrong[1])' in the --with-<library>
|
||||
option. ;
|
||||
}
|
||||
local wrong = [ set.difference $(without-parameter) : $(existing-libs) ] ;
|
||||
if $(wrong)
|
||||
{
|
||||
EXIT error: wrong library name '$(wrong[1])' in the --without-<library>
|
||||
option. ;
|
||||
}
|
||||
|
||||
if $(with-parameter)
|
||||
{
|
||||
return [ set.intersection $(existing-libs) : $(with-parameter) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [ set.difference $(existing-libs) : $(without-parameter) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
rule declare-targets ( all-libraries * : headers * )
|
||||
{
|
||||
configure.register-components $(all-libraries) ;
|
||||
|
||||
# Select the libraries to install.
|
||||
libraries = [ libraries-to-install $(all-libraries) ] ;
|
||||
configure.components-building $(libraries) ;
|
||||
|
||||
if [ option.get "show-libraries" : : true ]
|
||||
{
|
||||
ECHO The following libraries require building: ;
|
||||
for local l in $(libraries)
|
||||
{
|
||||
ECHO " - $(l)" ;
|
||||
}
|
||||
EXIT ;
|
||||
}
|
||||
|
||||
declare_top_level_targets $(libraries) : $(headers) ;
|
||||
}
|
||||
|
||||
# Returns the properties identifying the toolset. We'll use them
|
||||
# below to configure checks. These are essentially same as in
|
||||
# configure.builds, except we don't use address-model and
|
||||
# architecture - as we're trying to detect them here.
|
||||
#
|
||||
rule toolset-properties ( properties * )
|
||||
{
|
||||
local toolset = [ property.select <toolset> : $(properties) ] ;
|
||||
local toolset-version-property = "<toolset-$(toolset:G=):version>" ;
|
||||
return [ property.select <target-os> <toolset> $(toolset-version-property) : $(properties) ] ;
|
||||
}
|
||||
|
||||
feature.feature deduced-address-model : 32 64 : propagated optional composite hidden ;
|
||||
feature.compose <deduced-address-model>32 : <address-model>32 ;
|
||||
feature.compose <deduced-address-model>64 : <address-model>64 ;
|
||||
|
||||
rule deduce-address-model ( properties * )
|
||||
{
|
||||
local result ;
|
||||
local filtered = [ toolset-properties $(properties) ] ;
|
||||
|
||||
if [ configure.builds /boost/architecture//32 : $(filtered) : 32-bit ]
|
||||
{
|
||||
result = 32 ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//64 : $(filtered) : 64-bit ]
|
||||
{
|
||||
result = 64 ;
|
||||
}
|
||||
|
||||
if $(result)
|
||||
{
|
||||
# Normally, returning composite feature here is equivalent to forcing
|
||||
# consituent properties as well. But we only want to indicate toolset
|
||||
# deduced default, so also pick whatever address-model is explicitly
|
||||
# specified, if any.
|
||||
result = <deduced-address-model>$(result) [ property.select <address-model> : $(properties) ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
rule address-model ( )
|
||||
{
|
||||
return <conditional>@boostcpp.deduce-address-model ;
|
||||
}
|
||||
|
||||
local deducable-architectures = arm mips1 power sparc x86 combined ;
|
||||
feature.feature deduced-architecture : $(deducable-architectures) : propagated optional composite hidden ;
|
||||
for a in $(deducable-architectures)
|
||||
{
|
||||
feature.compose <deduced-architecture>$(a) : <architecture>$(a) ;
|
||||
}
|
||||
|
||||
rule deduce-architecture ( properties * )
|
||||
{
|
||||
local result ;
|
||||
local filtered = [ toolset-properties $(properties) ] ;
|
||||
if [ configure.builds /boost/architecture//arm : $(filtered) : arm ]
|
||||
{
|
||||
result = arm ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//mips1 : $(filtered) : mips1 ]
|
||||
{
|
||||
result = mips1 ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//power : $(filtered) : power ]
|
||||
{
|
||||
result = power ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//sparc : $(filtered) : sparc ]
|
||||
{
|
||||
result = sparc ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//x86 : $(filtered) : x86 ]
|
||||
{
|
||||
result = x86 ;
|
||||
}
|
||||
else if [ configure.builds /boost/architecture//combined : $(filtered) : combined ]
|
||||
{
|
||||
result = combined ;
|
||||
}
|
||||
|
||||
if $(result)
|
||||
{
|
||||
# See comment in deduce-address-model.
|
||||
result = <deduced-architecture>$(result) [ property.select <architecture> : $(properties) ] ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
rule architecture ( )
|
||||
{
|
||||
return <conditional>@boostcpp.deduce-architecture ;
|
||||
}
|
81
boost/bootstrap.bat
Normal file
81
boost/bootstrap.bat
Normal file
@ -0,0 +1,81 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Copyright (C) 2009 Vladimir Prus
|
||||
REM
|
||||
REM Distributed under the Boost Software License, Version 1.0.
|
||||
REM (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
ECHO Building Boost.Build engine
|
||||
if exist ".\tools\build\src\engine\bin.ntx86\b2.exe" del tools\build\src\engine\bin.ntx86\b2.exe
|
||||
if exist ".\tools\build\src\engine\bin.ntx86\bjam.exe" del tools\build\src\engine\bin.ntx86\bjam.exe
|
||||
if exist ".\tools\build\src\engine\bin.ntx86_64\b2.exe" del tools\build\src\engine\bin.ntx86_64\b2.exe
|
||||
if exist ".\tools\build\src\engine\bin.ntx86_64\bjam.exe" del tools\build\src\engine\bin.ntx86_64\bjam.exe
|
||||
pushd tools\build\src\engine
|
||||
|
||||
call .\build.bat %* > ..\..\..\..\bootstrap.log
|
||||
@ECHO OFF
|
||||
|
||||
popd
|
||||
|
||||
if exist ".\tools\build\src\engine\bin.ntx86\bjam.exe" (
|
||||
copy .\tools\build\src\engine\bin.ntx86\b2.exe . > nul
|
||||
copy .\tools\build\src\engine\bin.ntx86\bjam.exe . > nul
|
||||
goto :bjam_built)
|
||||
|
||||
if exist ".\tools\build\src\engine\bin.ntx86_64\bjam.exe" (
|
||||
copy .\tools\build\src\engine\bin.ntx86_64\b2.exe . > nul
|
||||
copy .\tools\build\src\engine\bin.ntx86_64\bjam.exe . > nul
|
||||
goto :bjam_built)
|
||||
|
||||
goto :bjam_failure
|
||||
|
||||
:bjam_built
|
||||
|
||||
REM Ideally, we should obtain the toolset that build.bat has
|
||||
REM guessed. However, it uses setlocal at the start and does not
|
||||
REM export BOOST_JAM_TOOLSET, and I don't know how to do that
|
||||
REM properly. Default to msvc for now.
|
||||
set toolset=msvc
|
||||
|
||||
ECHO import option ; > project-config.jam
|
||||
ECHO. >> project-config.jam
|
||||
ECHO using %toolset% ; >> project-config.jam
|
||||
ECHO. >> project-config.jam
|
||||
ECHO option.set keep-going : false ; >> project-config.jam
|
||||
ECHO. >> project-config.jam
|
||||
|
||||
ECHO.
|
||||
ECHO Bootstrapping is done. To build, run:
|
||||
ECHO.
|
||||
ECHO .\b2
|
||||
ECHO.
|
||||
ECHO To adjust configuration, edit 'project-config.jam'.
|
||||
ECHO Further information:
|
||||
ECHO.
|
||||
ECHO - Command line help:
|
||||
ECHO .\b2 --help
|
||||
ECHO.
|
||||
ECHO - Getting started guide:
|
||||
ECHO http://boost.org/more/getting_started/windows.html
|
||||
ECHO.
|
||||
ECHO - Boost.Build documentation:
|
||||
ECHO http://www.boost.org/build/doc/html/index.html
|
||||
|
||||
goto :end
|
||||
|
||||
:bjam_failure
|
||||
|
||||
ECHO.
|
||||
ECHO Failed to build Boost.Build engine.
|
||||
ECHO Please consult bootstrap.log for further diagnostics.
|
||||
ECHO.
|
||||
ECHO You can try to obtain a prebuilt binary from
|
||||
ECHO.
|
||||
ECHO http://sf.net/project/showfiles.php?group_id=7586^&package_id=72941
|
||||
ECHO.
|
||||
ECHO Also, you can file an issue at http://svn.boost.org
|
||||
ECHO Please attach bootstrap.log in that case.
|
||||
|
||||
goto :end
|
||||
|
||||
:end
|
409
boost/bootstrap.sh
Normal file
409
boost/bootstrap.sh
Normal file
@ -0,0 +1,409 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2005, 2006 Douglas Gregor.
|
||||
# Copyright (C) 2006 The Trustees of Indiana University
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# boostinspect:notab - Tabs are required for the Makefile.
|
||||
|
||||
BJAM=""
|
||||
TOOLSET=""
|
||||
BJAM_CONFIG=""
|
||||
BUILD=""
|
||||
PREFIX=/usr/local
|
||||
EPREFIX=
|
||||
LIBDIR=
|
||||
INCLUDEDIR=
|
||||
LIBS=""
|
||||
PYTHON=python
|
||||
PYTHON_VERSION=
|
||||
PYTHON_ROOT=
|
||||
ICU_ROOT=
|
||||
|
||||
# Handle case where builtin shell version of echo command doesn't
|
||||
# support -n. Use the installed echo executable if there is one
|
||||
# rather than builtin version to ensure -n is supported.
|
||||
ECHO=`which echo`
|
||||
if test "x$ECHO" = x; then
|
||||
ECHO=echo
|
||||
fi
|
||||
|
||||
# Internal flags
|
||||
flag_no_python=
|
||||
flag_icu=
|
||||
flag_show_libraries=
|
||||
|
||||
for option
|
||||
do
|
||||
case $option in
|
||||
|
||||
-help | --help | -h)
|
||||
want_help=yes ;;
|
||||
|
||||
-prefix=* | --prefix=*)
|
||||
PREFIX=`expr "x$option" : "x-*prefix=\(.*\)"`
|
||||
;;
|
||||
|
||||
-exec-prefix=* | --exec-prefix=*)
|
||||
EPREFIX=`expr "x$option" : "x-*exec-prefix=\(.*\)"`
|
||||
;;
|
||||
|
||||
-libdir=* | --libdir=*)
|
||||
LIBDIR=`expr "x$option" : "x-*libdir=\(.*\)"`
|
||||
;;
|
||||
|
||||
-includedir=* | --includedir=*)
|
||||
INCLUDEDIR=`expr "x$option" : "x-*includedir=\(.*\)"`
|
||||
;;
|
||||
|
||||
-show-libraries | --show-libraries )
|
||||
flag_show_libraries=yes
|
||||
;;
|
||||
|
||||
-with-bjam=* | --with-bjam=* )
|
||||
BJAM=`expr "x$option" : "x-*with-bjam=\(.*\)"`
|
||||
;;
|
||||
|
||||
-with-icu | --with-icu )
|
||||
flag_icu=yes
|
||||
;;
|
||||
|
||||
-with-icu=* | --with-icu=* )
|
||||
flag_icu=yes
|
||||
ICU_ROOT=`expr "x$option" : "x-*with-icu=\(.*\)"`
|
||||
;;
|
||||
|
||||
-without-icu | --without-icu )
|
||||
flag_icu=no
|
||||
;;
|
||||
|
||||
-with-libraries=* | --with-libraries=* )
|
||||
library_list=`expr "x$option" : "x-*with-libraries=\(.*\)"`
|
||||
if test "$library_list" != "all"; then
|
||||
old_IFS=$IFS
|
||||
IFS=,
|
||||
for library in $library_list
|
||||
do
|
||||
LIBS="$LIBS --with-$library"
|
||||
|
||||
if test $library = python; then
|
||||
requested_python=yes
|
||||
fi
|
||||
done
|
||||
IFS=$old_IFS
|
||||
|
||||
if test "x$requested_python" != xyes; then
|
||||
flag_no_python=yes
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
-without-libraries=* | --without-libraries=* )
|
||||
library_list=`expr "x$option" : "x-*without-libraries=\(.*\)"`
|
||||
old_IFS=$IFS
|
||||
IFS=,
|
||||
for library in $library_list
|
||||
do
|
||||
LIBS="$LIBS --without-$library"
|
||||
|
||||
if test $library = python; then
|
||||
flag_no_python=yes
|
||||
fi
|
||||
done
|
||||
IFS=$old_IFS
|
||||
;;
|
||||
|
||||
-with-python=* | --with-python=* )
|
||||
PYTHON=`expr "x$option" : "x-*with-python=\(.*\)"`
|
||||
;;
|
||||
|
||||
-with-python-root=* | --with-python-root=* )
|
||||
PYTHON_ROOT=`expr "x$option" : "x-*with-python-root=\(.*\)"`
|
||||
;;
|
||||
|
||||
-with-python-version=* | --with-python-version=* )
|
||||
PYTHON_VERSION=`expr "x$option" : "x-*with-python-version=\(.*\)"`
|
||||
;;
|
||||
|
||||
-with-toolset=* | --with-toolset=* )
|
||||
TOOLSET=`expr "x$option" : "x-*with-toolset=\(.*\)"`
|
||||
;;
|
||||
|
||||
-*)
|
||||
{ echo "error: unrecognized option: $option
|
||||
Try \`$0 --help' for more information." >&2
|
||||
{ (exit 1); exit 1; }; }
|
||||
;;
|
||||
|
||||
esac
|
||||
done
|
||||
|
||||
if test "x$want_help" = xyes; then
|
||||
cat <<EOF
|
||||
\`./bootstrap.sh' prepares Boost for building on a few kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]...
|
||||
|
||||
Defaults for the options are specified in brackets.
|
||||
|
||||
Configuration:
|
||||
-h, --help display this help and exit
|
||||
--with-bjam=BJAM use existing Boost.Jam executable (bjam)
|
||||
[automatically built]
|
||||
--with-toolset=TOOLSET use specific Boost.Build toolset
|
||||
[automatically detected]
|
||||
--show-libraries show the set of libraries that require build
|
||||
and installation steps (i.e., those libraries
|
||||
that can be used with --with-libraries or
|
||||
--without-libraries), then exit
|
||||
--with-libraries=list build only a particular set of libraries,
|
||||
describing using either a comma-separated list of
|
||||
library names or "all"
|
||||
[all]
|
||||
--without-libraries=list build all libraries except the ones listed []
|
||||
--with-icu enable Unicode/ICU support in Regex
|
||||
[automatically detected]
|
||||
--without-icu disable Unicode/ICU support in Regex
|
||||
--with-icu=DIR specify the root of the ICU library installation
|
||||
and enable Unicode/ICU support in Regex
|
||||
[automatically detected]
|
||||
--with-python=PYTHON specify the Python executable [python]
|
||||
--with-python-root=DIR specify the root of the Python installation
|
||||
[automatically detected]
|
||||
--with-python-version=X.Y specify the Python version as X.Y
|
||||
[automatically detected]
|
||||
|
||||
Installation directories:
|
||||
--prefix=PREFIX install Boost into the given PREFIX
|
||||
[/usr/local]
|
||||
--exec-prefix=EPREFIX install Boost binaries into the given EPREFIX
|
||||
[PREFIX]
|
||||
|
||||
More precise control over installation directories:
|
||||
--libdir=DIR install libraries here [EPREFIX/lib]
|
||||
--includedir=DIR install headers here [PREFIX/include]
|
||||
|
||||
EOF
|
||||
fi
|
||||
test -n "$want_help" && exit 0
|
||||
|
||||
# TBD: Determine where the script is located
|
||||
my_dir="."
|
||||
|
||||
# Determine the toolset, if not already decided
|
||||
if test "x$TOOLSET" = x; then
|
||||
guessed_toolset=`$my_dir/tools/build/src/engine/build.sh --guess-toolset`
|
||||
case $guessed_toolset in
|
||||
acc | darwin | gcc | como | mipspro | pathscale | pgi | qcc | vacpp )
|
||||
TOOLSET=$guessed_toolset
|
||||
;;
|
||||
|
||||
intel-* )
|
||||
TOOLSET=intel
|
||||
;;
|
||||
|
||||
mingw )
|
||||
TOOLSET=gcc
|
||||
;;
|
||||
|
||||
sun* )
|
||||
TOOLSET=sun
|
||||
;;
|
||||
|
||||
* )
|
||||
# Not supported by Boost.Build
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
rm -f config.log
|
||||
|
||||
# Build bjam
|
||||
if test "x$BJAM" = x; then
|
||||
$ECHO -n "Building Boost.Build engine with toolset $TOOLSET... "
|
||||
pwd=`pwd`
|
||||
(cd "$my_dir/tools/build/src/engine" && ./build.sh "$TOOLSET") > bootstrap.log 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo
|
||||
echo "Failed to build Boost.Build build engine"
|
||||
echo "Consult 'bootstrap.log' for more details"
|
||||
exit 1
|
||||
fi
|
||||
cd "$pwd"
|
||||
arch=`cd $my_dir/tools/build/src/engine && ./bootstrap/jam0 -d0 -f build.jam --toolset=$TOOLSET --toolset-root= --show-locate-target && cd ..`
|
||||
BJAM="$my_dir/tools/build/src/engine/$arch/b2"
|
||||
echo "tools/build/src/engine/$arch/b2"
|
||||
cp "$BJAM" .
|
||||
cp "$my_dir/tools/build/src/engine/$arch/bjam" .
|
||||
|
||||
fi
|
||||
|
||||
# TBD: Turn BJAM into an absolute path
|
||||
|
||||
# If there is a list of libraries
|
||||
if test "x$flag_show_libraries" = xyes; then
|
||||
cat <<EOF
|
||||
|
||||
The following Boost libraries have portions that require a separate build
|
||||
and installation step. Any library not listed here can be used by including
|
||||
the headers only.
|
||||
|
||||
The Boost libraries requiring separate building and installation are:
|
||||
EOF
|
||||
$BJAM -d0 --show-libraries | grep '^[[:space:]]*-'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Setup paths
|
||||
if test "x$EPREFIX" = x; then
|
||||
EPREFIX="$PREFIX"
|
||||
fi
|
||||
|
||||
if test "x$LIBDIR" = x; then
|
||||
LIBDIR="$EPREFIX/lib"
|
||||
fi
|
||||
|
||||
if test "x$INCLUDEDIR" = x; then
|
||||
INCLUDEDIR="$PREFIX/include"
|
||||
fi
|
||||
|
||||
# Find Python
|
||||
if test "x$flag_no_python" = x; then
|
||||
result=`$PYTHON -c "exit" > /dev/null 2>&1`
|
||||
if [ "$?" -ne "0" ]; then
|
||||
flag_no_python=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$flag_no_python" = x; then
|
||||
if test "x$PYTHON_VERSION" = x; then
|
||||
$ECHO -n "Detecting Python version... "
|
||||
PYTHON_VERSION=`$PYTHON -c "import sys; print (\"%d.%d\" % (sys.version_info[0], sys.version_info[1]))"`
|
||||
echo $PYTHON_VERSION
|
||||
fi
|
||||
|
||||
if test "x$PYTHON_ROOT" = x; then
|
||||
$ECHO -n "Detecting Python root... "
|
||||
PYTHON_ROOT=`$PYTHON -c "import sys; print(sys.prefix)"`
|
||||
echo $PYTHON_ROOT
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure ICU
|
||||
$ECHO -n "Unicode/ICU support for Boost.Regex?... "
|
||||
if test "x$flag_icu" != xno; then
|
||||
if test "x$ICU_ROOT" = x; then
|
||||
COMMON_ICU_PATHS="/usr /usr/local /sw"
|
||||
for p in $COMMON_ICU_PATHS; do
|
||||
if test -r $p/include/unicode/utypes.h; then
|
||||
ICU_ROOT=$p
|
||||
fi
|
||||
done
|
||||
|
||||
if test "x$ICU_ROOT" = x; then
|
||||
echo "not found."
|
||||
else
|
||||
BJAM_CONFIG="$BJAM_CONFIG -sICU_PATH=$ICU_ROOT"
|
||||
echo "$ICU_ROOT"
|
||||
fi
|
||||
else
|
||||
BJAM_CONFIG="$BJAM_CONFIG -sICU_PATH=$ICU_ROOT"
|
||||
echo "$ICU_ROOT"
|
||||
fi
|
||||
else
|
||||
echo "disabled."
|
||||
fi
|
||||
|
||||
# Backup the user's existing project-config.jam
|
||||
JAM_CONFIG_OUT="project-config.jam"
|
||||
if test -r "project-config.jam"; then
|
||||
counter=1
|
||||
|
||||
while test -r "project-config.jam.$counter"; do
|
||||
counter=`expr $counter + 1`
|
||||
done
|
||||
|
||||
echo "Backing up existing Boost.Build configuration in project-config.jam.$counter"
|
||||
mv "project-config.jam" "project-config.jam.$counter"
|
||||
fi
|
||||
|
||||
# Generate user-config.jam
|
||||
echo "Generating Boost.Build configuration in project-config.jam..."
|
||||
cat > project-config.jam <<EOF
|
||||
# Boost.Build Configuration
|
||||
# Automatically generated by bootstrap.sh
|
||||
|
||||
import option ;
|
||||
import feature ;
|
||||
|
||||
# Compiler configuration. This definition will be used unless
|
||||
# you already have defined some toolsets in your user-config.jam
|
||||
# file.
|
||||
if ! $TOOLSET in [ feature.values <toolset> ]
|
||||
{
|
||||
using $TOOLSET ;
|
||||
}
|
||||
|
||||
project : default-build <toolset>$TOOLSET ;
|
||||
EOF
|
||||
|
||||
# - Python configuration
|
||||
if test "x$flag_no_python" = x; then
|
||||
cat >> project-config.jam <<EOF
|
||||
|
||||
# Python configuration
|
||||
import python ;
|
||||
if ! [ python.configured ]
|
||||
{
|
||||
using python : $PYTHON_VERSION : $PYTHON_ROOT ;
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
if test "x$ICU_ROOT" != x; then
|
||||
cat >> project-config.jam << EOF
|
||||
|
||||
path-constant ICU_PATH : $ICU_ROOT ;
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >> project-config.jam << EOF
|
||||
|
||||
# List of --with-<library> and --without-<library>
|
||||
# options. If left empty, all libraries will be built.
|
||||
# Options specified on the command line completely
|
||||
# override this variable.
|
||||
libraries = $LIBS ;
|
||||
|
||||
# These settings are equivivalent to corresponding command-line
|
||||
# options.
|
||||
option.set prefix : $PREFIX ;
|
||||
option.set exec-prefix : $EPREFIX ;
|
||||
option.set libdir : $LIBDIR ;
|
||||
option.set includedir : $INCLUDEDIR ;
|
||||
|
||||
# Stop on first error
|
||||
option.set keep-going : false ;
|
||||
EOF
|
||||
|
||||
cat << EOF
|
||||
|
||||
Bootstrapping is done. To build, run:
|
||||
|
||||
./b2
|
||||
|
||||
To adjust configuration, edit 'project-config.jam'.
|
||||
Further information:
|
||||
|
||||
- Command line help:
|
||||
./b2 --help
|
||||
|
||||
- Getting started guide:
|
||||
http://www.boost.org/more/getting_started/unix-variants.html
|
||||
|
||||
- Boost.Build documentation:
|
||||
http://www.boost.org/build/doc/html/index.html
|
||||
|
||||
EOF
|
149
boost/rst.css
Normal file
149
boost/rst.css
Normal file
@ -0,0 +1,149 @@
|
||||
@import url("doc/src/boostbook.css");
|
||||
@import url("doc/src/docutils.css");
|
||||
/* Copyright David Abrahams 2006. 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)
|
||||
*/
|
||||
|
||||
dl.docutils dt {
|
||||
font-weight: bold }
|
||||
|
||||
img.boost-logo {
|
||||
border: none;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
pre.literal-block span.concept {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.prevpage {
|
||||
padding-top: -5px;
|
||||
text-align: left;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.nextpage {
|
||||
padding-top: -20px;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.small {
|
||||
font-size: smaller }
|
||||
|
||||
h2 a {
|
||||
font-size: 90%;
|
||||
}
|
||||
h3 a {
|
||||
font-size: 80%;
|
||||
}
|
||||
h4 a {
|
||||
font-size: 70%;
|
||||
}
|
||||
h5 a {
|
||||
font-size: 60%;
|
||||
}
|
||||
|
||||
dl,table
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
Tables
|
||||
=============================================================================*/
|
||||
|
||||
/* The only clue docutils gives us that tables are logically tables,
|
||||
and not, e.g., footnotes, is that they have border="1". Therefore
|
||||
we're keying off of that. We used to manually patch docutils to
|
||||
add a "table" class to all logical tables, but that proved much too
|
||||
fragile.
|
||||
*/
|
||||
|
||||
table[border="1"]
|
||||
{
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
}
|
||||
|
||||
table[border="1"]
|
||||
{
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* Table Cells */
|
||||
table[border="1"] tr td
|
||||
{
|
||||
padding: 0.5em;
|
||||
text-align: left;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
table[border="1"] tr th
|
||||
{
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
border: 1pt solid white;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
@media screen
|
||||
{
|
||||
|
||||
/* Tables */
|
||||
table[border="1"] tr td
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
table[border="1"] tr th
|
||||
{
|
||||
background-color: #F0F0F0;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
pre,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
td pre
|
||||
td .screen
|
||||
{
|
||||
border: 0px
|
||||
}
|
||||
|
||||
.sidebar pre
|
||||
{
|
||||
border: 0px
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pre,
|
||||
.screen
|
||||
{
|
||||
font-size: 9pt;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
/* Program listings in tables don't get borders */
|
||||
td pre,
|
||||
td .screen
|
||||
{
|
||||
margin: 0pc 0pc 0pc 0pc;
|
||||
padding: 0pc 0pc 0pc 0pc;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user