diff options
author | Remko Tronçon <git@el-tramo.be> | 2011-03-11 20:22:35 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-03-11 22:22:04 (GMT) |
commit | 59aa5d7e29ca142ae324ad97e6a5f0353d1a6b89 (patch) | |
tree | e450b95ff4c0ba7f770723402a2634773f1a0451 | |
parent | 3ff52013d810f94b6095e93f550f58133e2df239 (diff) | |
download | swift-59aa5d7e29ca142ae324ad97e6a5f0353d1a6b89.zip swift-59aa5d7e29ca142ae324ad97e6a5f0353d1a6b89.tar.bz2 |
Store JID->Avatar mappings.
Resolves: #653
143 files changed, 19117 insertions, 28 deletions
diff --git a/3rdParty/Boost/src/boost/archive/archive_exception.hpp b/3rdParty/Boost/src/boost/archive/archive_exception.hpp new file mode 100644 index 0000000..242f752 --- /dev/null +++ b/3rdParty/Boost/src/boost/archive/archive_exception.hpp @@ -0,0 +1,97 @@ +#ifndef BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP +#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive/archive_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <exception> +#include <cassert> +#include <string> + +#include <boost/config.hpp> +#include <boost/preprocessor/empty.hpp> +#include <boost/archive/detail/decl.hpp> + +// note: the only reason this is in here is that windows header +// includes #define exception_code _exception_code (arrrgghhhh!). +// the most expedient way to address this is be sure that this +// header is always included whenever this header file is included. +#if defined(BOOST_WINDOWS) +#include <excpt.h> +#endif + +#include <boost/archive/detail/abi_prefix.hpp> // must be the last header + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by archives +// +class BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) archive_exception : + public virtual std::exception +{ +public: + typedef enum { + no_exception, // initialized without code + other_exception, // any excepton not listed below + unregistered_class, // attempt to serialize a pointer of an + // an unregistered class + invalid_signature, // first line of archive does not contain + // expected string + unsupported_version,// archive created with library version + // subsequent to this one + pointer_conflict, // an attempt has been made to directly + // serialize an object which has + // already been serialzed through a pointer. + // Were this permited, the archive load would result + // in the creation of an extra copy of the obect. + incompatible_native_format, // attempt to read native binary format + // on incompatible platform + array_size_too_short,// array being loaded doesn't fit in array allocated + input_stream_error, // error on input stream + invalid_class_name, // class name greater than the maximum permitted. + // most likely a corrupted archive or an attempt + // to insert virus via buffer overrun method. + unregistered_cast, // base - derived relationship not registered with + // void_cast_register + unsupported_class_version, // type saved with a version # greater than the + // one used by the program. This indicates that the proggram + // needs to be rebuilt. + multiple_code_instantiation, // code for implementing serialization for some + // type has been instantiated in more than one module. + output_stream_error // error on input stream + } exception_code; +protected: + std::string m_msg; +public: + exception_code code; + archive_exception( + exception_code c, + const char * e1 = NULL, + const char * e2 = NULL + ); + ~archive_exception() throw (); + virtual const char *what( ) const throw(); +protected: + archive_exception(); +}; + +}// namespace archive +}// namespace boost + +#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP diff --git a/3rdParty/Boost/src/boost/archive/detail/abi_prefix.hpp b/3rdParty/Boost/src/boost/archive/detail/abi_prefix.hpp new file mode 100644 index 0000000..e39ef11 --- /dev/null +++ b/3rdParty/Boost/src/boost/archive/detail/abi_prefix.hpp @@ -0,0 +1,20 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// abi_prefix.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config/abi_prefix.hpp> // must be the last header +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/3rdParty/Boost/src/boost/archive/detail/abi_suffix.hpp b/3rdParty/Boost/src/boost/archive/detail/abi_suffix.hpp new file mode 100644 index 0000000..a283b36 --- /dev/null +++ b/3rdParty/Boost/src/boost/archive/detail/abi_suffix.hpp @@ -0,0 +1,19 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// abi_suffix.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +#include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/3rdParty/Boost/src/boost/archive/detail/decl.hpp b/3rdParty/Boost/src/boost/archive/detail/decl.hpp new file mode 100644 index 0000000..9695001 --- /dev/null +++ b/3rdParty/Boost/src/boost/archive/detail/decl.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_ARCHIVE_DETAIL_DECL_HPP +#define BOOST_ARCHIVE_DETAIL_DECL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 +// decl.hpp +// +// (c) Copyright Robert Ramey 2004 +// 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 library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include <boost/config.hpp> +#include <boost/preprocessor/facilities/empty.hpp> + +#if defined(BOOST_HAS_DECLSPEC) + #if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)) + #if defined(BOOST_ARCHIVE_SOURCE) + #if defined(__BORLANDC__) + #define BOOST_ARCHIVE_DECL(T) T __export + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __export + #else + #define BOOST_ARCHIVE_DECL(T) __declspec(dllexport) T + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllexport) T + #endif + #else + #if defined(__BORLANDC__) + #define BOOST_ARCHIVE_DECL(T) T __import + #else + #define BOOST_ARCHIVE_DECL(T) __declspec(dllimport) T + #endif + #endif + #if defined(BOOST_WARCHIVE_SOURCE) + #if defined(__BORLANDC__) + #define BOOST_WARCHIVE_DECL(T) T __export + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __export + #else + #define BOOST_WARCHIVE_DECL(T) __declspec(dllexport) T + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllexport) T + #endif + #else + #if defined(__BORLANDC__) + #define BOOST_WARCHIVE_DECL(T) T __import + #else + #define BOOST_WARCHIVE_DECL(T) __declspec(dllimport) T + #endif + #endif + #if !defined(BOOST_WARCHIVE_SOURCE) && !defined(BOOST_ARCHIVE_SOURCE) + #if defined(__BORLANDC__) + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T __import + #else + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) __declspec(dllimport) T + #endif + #endif + #endif +#endif // BOOST_HAS_DECLSPEC + +#if ! defined(BOOST_ARCHIVE_DECL) + #define BOOST_ARCHIVE_DECL(T) T +#endif +#if ! defined(BOOST_WARCHIVE_DECL) + #define BOOST_WARCHIVE_DECL(T) T +#endif +#if ! defined(BOOST_ARCHIVE_OR_WARCHIVE_DECL) + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL(T) T +#endif + +#endif // BOOST_ARCHIVE_DETAIL_DECL_HPP diff --git a/3rdParty/Boost/src/boost/mpl/aux_/config/operators.hpp b/3rdParty/Boost/src/boost/mpl/aux_/config/operators.hpp new file mode 100644 index 0000000..2a38a3d --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/aux_/config/operators.hpp @@ -0,0 +1,33 @@ + +#ifndef BOOST_MPL_AUX_CONFIG_OPERATORS_HPP_INCLUDED +#define BOOST_MPL_AUX_CONFIG_OPERATORS_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: operators.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/aux_/config/gcc.hpp> +#include <boost/mpl/aux_/config/msvc.hpp> +#include <boost/mpl/aux_/config/workaround.hpp> + +#if !defined(BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING) \ + && ( BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ + || BOOST_WORKAROUND(__EDG_VERSION__, <= 245) \ + || BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0295) \ + || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ + ) + +# define BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING + +#endif + +#endif // BOOST_MPL_AUX_CONFIG_OPERATORS_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/aux_/has_key_impl.hpp b/3rdParty/Boost/src/boost/mpl/aux_/has_key_impl.hpp new file mode 100644 index 0000000..3a12a22 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/aux_/has_key_impl.hpp @@ -0,0 +1,34 @@ + +#ifndef BOOST_MPL_AUX_HAS_KEY_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_HAS_KEY_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2002-2004 +// Copyright David Abrahams 2003 +// +// 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/mpl for documentation. + +// $Id: has_key_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/has_key_fwd.hpp> +#include <boost/mpl/aux_/traits_lambda_spec.hpp> + +namespace boost { namespace mpl { + +// no default implementation; the definition is needed to make MSVC happy + +template< typename Tag > struct has_key_impl +{ + template< typename AssociativeSequence, typename Key > struct apply; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2,has_key_impl) + +}} + +#endif // BOOST_MPL_AUX_HAS_KEY_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/aux_/overload_names.hpp b/3rdParty/Boost/src/boost/mpl/aux_/overload_names.hpp new file mode 100644 index 0000000..0fa4a98 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/aux_/overload_names.hpp @@ -0,0 +1,48 @@ + +#ifndef BOOST_MPL_AUX_OVERLOAD_NAMES_HPP_INCLUDED +#define BOOST_MPL_AUX_OVERLOAD_NAMES_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: overload_names.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/aux_/ptr_to_ref.hpp> +#include <boost/mpl/aux_/config/operators.hpp> + +#if defined(BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING) + +# include <boost/mpl/aux_/static_cast.hpp> + +# define BOOST_MPL_AUX_OVERLOAD_VALUE_BY_KEY operator/ +# define BOOST_MPL_AUX_OVERLOAD_ITEM_BY_ORDER operator| +# define BOOST_MPL_AUX_OVERLOAD_ORDER_BY_KEY operator|| +# define BOOST_MPL_AUX_OVERLOAD_IS_MASKED operator% + +# define BOOST_MPL_AUX_OVERLOAD_CALL_VALUE_BY_KEY(T, x) BOOST_MPL_AUX_PTR_TO_REF(T) / x +# define BOOST_MPL_AUX_OVERLOAD_CALL_ITEM_BY_ORDER(T, x) BOOST_MPL_AUX_PTR_TO_REF(T) | x +# define BOOST_MPL_AUX_OVERLOAD_CALL_ORDER_BY_KEY(T, x) BOOST_MPL_AUX_PTR_TO_REF(T) || x +# define BOOST_MPL_AUX_OVERLOAD_CALL_IS_MASKED(T, x) BOOST_MPL_AUX_PTR_TO_REF(T) % x + +#else + +# define BOOST_MPL_AUX_OVERLOAD_VALUE_BY_KEY value_by_key_ +# define BOOST_MPL_AUX_OVERLOAD_ITEM_BY_ORDER item_by_order_ +# define BOOST_MPL_AUX_OVERLOAD_ORDER_BY_KEY order_by_key_ +# define BOOST_MPL_AUX_OVERLOAD_IS_MASKED is_masked_ + +# define BOOST_MPL_AUX_OVERLOAD_CALL_VALUE_BY_KEY(T, x) T::BOOST_MPL_AUX_OVERLOAD_VALUE_BY_KEY( BOOST_MPL_AUX_PTR_TO_REF(T), x ) +# define BOOST_MPL_AUX_OVERLOAD_CALL_ITEM_BY_ORDER(T, x) T::BOOST_MPL_AUX_OVERLOAD_ITEM_BY_ORDER( BOOST_MPL_AUX_PTR_TO_REF(T), x ) +# define BOOST_MPL_AUX_OVERLOAD_CALL_ORDER_BY_KEY(T, x) T::BOOST_MPL_AUX_OVERLOAD_ORDER_BY_KEY( BOOST_MPL_AUX_PTR_TO_REF(T), x ) +# define BOOST_MPL_AUX_OVERLOAD_CALL_IS_MASKED(T, x) T::BOOST_MPL_AUX_OVERLOAD_IS_MASKED( BOOST_MPL_AUX_PTR_TO_REF(T), x ) + +#endif + +#endif // BOOST_MPL_AUX_OVERLOAD_NAMES_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/aux_/ptr_to_ref.hpp b/3rdParty/Boost/src/boost/mpl/aux_/ptr_to_ref.hpp new file mode 100644 index 0000000..3b5415c --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/aux_/ptr_to_ref.hpp @@ -0,0 +1,46 @@ + +#ifndef BOOST_MPL_AUX_PTR_TO_REF_HPP_INCLUDED +#define BOOST_MPL_AUX_PTR_TO_REF_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: ptr_to_ref.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/aux_/static_cast.hpp> +#include <boost/mpl/aux_/config/msvc.hpp> +#include <boost/mpl/aux_/config/workaround.hpp> + + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ + || ( BOOST_WORKAROUND(__EDG_VERSION__, <= 245) \ + && !(defined(__STD_STRICT_ANSI) \ + || defined(__STD_STRICT_ANSI_ERRORS)) ) + +# define BOOST_MPL_AUX_PTR_TO_REF(X) \ + *BOOST_MPL_AUX_STATIC_CAST(X*, 0) \ +/**/ + +#else + +# define BOOST_MPL_AUX_PTR_TO_REF(X) \ + aux::ptr_to_ref(BOOST_MPL_AUX_STATIC_CAST(X*, 0)) \ +/**/ + +#endif + + +namespace boost { namespace mpl { namespace aux { + +template< typename T > static T const& ptr_to_ref(T*); + +}}} + +#endif // BOOST_MPL_AUX_PTR_TO_REF_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/aux_/reverse_iter_fold_impl.hpp b/3rdParty/Boost/src/boost/mpl/aux_/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..ce9257f --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/aux_/reverse_iter_fold_impl.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_AUX_ITER_FOLD_BACKWARD_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_ITER_FOLD_BACKWARD_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: reverse_iter_fold_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#if !defined(BOOST_MPL_PREPROCESSING_MODE) +# include <boost/mpl/next_prior.hpp> +# include <boost/mpl/apply.hpp> +# include <boost/mpl/aux_/config/ctps.hpp> +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + || defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) +# include <boost/mpl/if.hpp> +# include <boost/type_traits/is_same.hpp> +# endif +#endif + +#include <boost/mpl/aux_/config/use_preprocessed.hpp> + +#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ + && !defined(BOOST_MPL_PREPROCESSING_MODE) + +# define BOOST_MPL_PREPROCESSED_HEADER reverse_iter_fold_impl.hpp +# include <boost/mpl/aux_/include_preprocessed.hpp> + +#else + +# define AUX778076_FOLD_IMPL_OP(iter) iter +# define AUX778076_FOLD_IMPL_NAME_PREFIX reverse_iter_fold +# include <boost/mpl/aux_/reverse_fold_impl_body.hpp> + +#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif // BOOST_MPL_AUX_ITER_FOLD_BACKWARD_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/base.hpp b/3rdParty/Boost/src/boost/mpl/base.hpp new file mode 100644 index 0000000..3f7e8a4 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/base.hpp @@ -0,0 +1,35 @@ + +#ifndef BOOST_MPL_BASE_HPP_INCLUDED +#define BOOST_MPL_BASE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: base.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/aux_/na_spec.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct base +{ + typedef typename T::base type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,base,(T)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, base) + +}} + +#endif // BOOST_MPL_BASE_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/comparison.hpp b/3rdParty/Boost/src/boost/mpl/comparison.hpp new file mode 100644 index 0000000..005d280 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/comparison.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_COMPARISON_HPP_INCLUDED +#define BOOST_MPL_COMPARISON_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: comparison.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/not_equal_to.hpp> +#include <boost/mpl/less.hpp> +#include <boost/mpl/greater.hpp> +#include <boost/mpl/less_equal.hpp> +#include <boost/mpl/greater_equal.hpp> + +#endif // BOOST_MPL_COMPARISON_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/erase_fwd.hpp b/3rdParty/Boost/src/boost/mpl/erase_fwd.hpp new file mode 100644 index 0000000..0626ecb --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/erase_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_ERASE_FWD_HPP_INCLUDED +#define BOOST_MPL_ERASE_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: erase_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +namespace boost { namespace mpl { + +template< typename Tag > struct erase_impl; +template< typename Sequence, typename First, typename Last > struct erase; + +}} + +#endif // BOOST_MPL_ERASE_FWD_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/erase_key_fwd.hpp b/3rdParty/Boost/src/boost/mpl/erase_key_fwd.hpp new file mode 100644 index 0000000..4844893 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/erase_key_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_ERASE_KEY_FWD_HPP_INCLUDED +#define BOOST_MPL_ERASE_KEY_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: erase_key_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +namespace boost { namespace mpl { + +template< typename Tag > struct erase_key_impl; +template< typename Sequence, typename Key > struct erase_key; + +}} + +#endif // BOOST_MPL_ERASE_KEY_FWD_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/greater.hpp b/3rdParty/Boost/src/boost/mpl/greater.hpp new file mode 100644 index 0000000..e33ae48 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/greater.hpp @@ -0,0 +1,21 @@ + +#ifndef BOOST_MPL_GREATER_HPP_INCLUDED +#define BOOST_MPL_GREATER_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: greater.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#define AUX778076_OP_NAME greater +#define AUX778076_OP_TOKEN > +#include <boost/mpl/aux_/comparison_op.hpp> + +#endif // BOOST_MPL_GREATER_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/greater_equal.hpp b/3rdParty/Boost/src/boost/mpl/greater_equal.hpp new file mode 100644 index 0000000..91ccf83 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/greater_equal.hpp @@ -0,0 +1,21 @@ + +#ifndef BOOST_MPL_GREATER_EQUAL_HPP_INCLUDED +#define BOOST_MPL_GREATER_EQUAL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: greater_equal.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#define AUX778076_OP_NAME greater_equal +#define AUX778076_OP_TOKEN >= +#include <boost/mpl/aux_/comparison_op.hpp> + +#endif // BOOST_MPL_GREATER_EQUAL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/has_key.hpp b/3rdParty/Boost/src/boost/mpl/has_key.hpp new file mode 100644 index 0000000..85102ed --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/has_key.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_HAS_KEY_HPP_INCLUDED +#define BOOST_MPL_HAS_KEY_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: has_key.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/has_key_fwd.hpp> +#include <boost/mpl/sequence_tag.hpp> +#include <boost/mpl/aux_/has_key_impl.hpp> +#include <boost/mpl/aux_/na_spec.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(AssociativeSequence) + , typename BOOST_MPL_AUX_NA_PARAM(Key) + > +struct has_key + : has_key_impl< typename sequence_tag<AssociativeSequence>::type > + ::template apply<AssociativeSequence,Key> +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,has_key,(AssociativeSequence,Key)) +}; + +BOOST_MPL_AUX_NA_SPEC(2, has_key) + +}} + +#endif // BOOST_MPL_HAS_KEY_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/has_key_fwd.hpp b/3rdParty/Boost/src/boost/mpl/has_key_fwd.hpp new file mode 100644 index 0000000..49b0fb5 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/has_key_fwd.hpp @@ -0,0 +1,25 @@ + +#ifndef BOOST_MPL_HAS_KEY_FWD_HPP_INCLUDED +#define BOOST_MPL_HAS_KEY_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: has_key_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +namespace boost { namespace mpl { + +template< typename Tag > struct has_key_impl; +template< typename AssociativeSequence, typename Key > struct has_key; + +}} + +#endif // BOOST_MPL_HAS_KEY_FWD_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/insert_fwd.hpp b/3rdParty/Boost/src/boost/mpl/insert_fwd.hpp new file mode 100644 index 0000000..9c6ff64 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/insert_fwd.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_INSERT_FWD_HPP_INCLUDED +#define BOOST_MPL_INSERT_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: insert_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +namespace boost { namespace mpl { + +template< typename Tag > struct insert_impl; +template< typename Sequence, typename Pos_or_T, typename T > struct insert; + +}} + +#endif // BOOST_MPL_INSERT_FWD_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/key_type_fwd.hpp b/3rdParty/Boost/src/boost/mpl/key_type_fwd.hpp new file mode 100644 index 0000000..95f8445 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/key_type_fwd.hpp @@ -0,0 +1,25 @@ + +#ifndef BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED +#define BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: key_type_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +namespace boost { namespace mpl { + +template< typename Tag > struct key_type_impl; +template< typename AssociativeSequence, typename T > struct key_type; + +}} + +#endif // BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/less_equal.hpp b/3rdParty/Boost/src/boost/mpl/less_equal.hpp new file mode 100644 index 0000000..2284d1d --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/less_equal.hpp @@ -0,0 +1,21 @@ + +#ifndef BOOST_MPL_LESS_EQUAL_HPP_INCLUDED +#define BOOST_MPL_LESS_EQUAL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: less_equal.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#define AUX778076_OP_NAME less_equal +#define AUX778076_OP_TOKEN <= +#include <boost/mpl/aux_/comparison_op.hpp> + +#endif // BOOST_MPL_LESS_EQUAL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/not_equal_to.hpp b/3rdParty/Boost/src/boost/mpl/not_equal_to.hpp new file mode 100644 index 0000000..00132b1 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/not_equal_to.hpp @@ -0,0 +1,21 @@ + +#ifndef BOOST_MPL_NOT_EQUAL_TO_HPP_INCLUDED +#define BOOST_MPL_NOT_EQUAL_TO_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: not_equal_to.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#define AUX778076_OP_NAME not_equal_to +#define AUX778076_OP_TOKEN != +#include <boost/mpl/aux_/comparison_op.hpp> + +#endif // BOOST_MPL_NOT_EQUAL_TO_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/reverse_iter_fold.hpp b/3rdParty/Boost/src/boost/mpl/reverse_iter_fold.hpp new file mode 100644 index 0000000..e6b3ed3 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/reverse_iter_fold.hpp @@ -0,0 +1,56 @@ + +#ifndef BOOST_MPL_ITER_FOLD_BACKWARD_HPP_INCLUDED +#define BOOST_MPL_ITER_FOLD_BACKWARD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2001-2004 +// Copyright Dave Abrahams 2001-2002 +// +// 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/mpl for documentation. + +// $Id: reverse_iter_fold.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/O1_size.hpp> +#include <boost/mpl/arg.hpp> +#include <boost/mpl/lambda.hpp> +#include <boost/mpl/aux_/reverse_iter_fold_impl.hpp> +#include <boost/mpl/aux_/na_spec.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(State) + , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp) + , typename ForwardOp = arg<1> + > +struct reverse_iter_fold +{ + typedef typename aux::reverse_iter_fold_impl< + ::boost::mpl::O1_size<Sequence>::value + , typename begin<Sequence>::type + , typename end<Sequence>::type + , State + , typename lambda<BackwardOp>::type + , typename lambda<ForwardOp>::type + >::state type; + + BOOST_MPL_AUX_LAMBDA_SUPPORT( + 4 + , reverse_iter_fold + , (Sequence,State,BackwardOp,ForwardOp) + ) +}; + +BOOST_MPL_AUX_NA_SPEC(3, reverse_iter_fold) + +}} + +#endif // BOOST_MPL_ITER_FOLD_BACKWARD_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/at_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/at_impl.hpp new file mode 100644 index 0000000..ad74477 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/at_impl.hpp @@ -0,0 +1,40 @@ + +#ifndef BOOST_MPL_SET_AUX_AT_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_AT_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: at_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/at_fwd.hpp> +#include <boost/mpl/set/aux_/has_key_impl.hpp> +#include <boost/mpl/set/aux_/tag.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/void.hpp> + +namespace boost { namespace mpl { + +template<> +struct at_impl< aux::set_tag > +{ + template< typename Set, typename T > struct apply + { + typedef typename if_< + has_key_impl<aux::set_tag>::apply<Set,T> + , T + , void_ + >::type type; + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_AT_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/begin_end_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/begin_end_impl.hpp new file mode 100644 index 0000000..f012c2a --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/begin_end_impl.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_MPL_SET_AUX_BEGIN_END_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_BEGIN_END_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2007 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: begin_end_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/begin_end_fwd.hpp> +#include <boost/mpl/set/aux_/iterator.hpp> + +namespace boost { namespace mpl { + +template<> +struct begin_impl< aux::set_tag > +{ + template< typename Set > struct apply + : s_iter_get<Set,typename Set::item_> + { + }; +}; + +template<> +struct end_impl< aux::set_tag > +{ + template< typename Set > struct apply + { + typedef s_iter< Set,set0<> > type; + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_BEGIN_END_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/clear_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/clear_impl.hpp new file mode 100644 index 0000000..4c965f6 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/clear_impl.hpp @@ -0,0 +1,35 @@ + +#ifndef BOOST_MPL_SET_AUX_CLEAR_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_CLEAR_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: clear_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/clear_fwd.hpp> +#include <boost/mpl/set/aux_/set0.hpp> +#include <boost/mpl/set/aux_/tag.hpp> + +namespace boost { namespace mpl { + +template<> +struct clear_impl< aux::set_tag > +{ + template< typename Set > struct apply + { + typedef set0<> type; + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_CLEAR_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/empty_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/empty_impl.hpp new file mode 100644 index 0000000..d40a9c4 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/empty_impl.hpp @@ -0,0 +1,34 @@ + +#ifndef BOOST_MPL_SET_AUX_EMPTY_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_EMPTY_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: empty_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/empty_fwd.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/set/aux_/tag.hpp> + +namespace boost { namespace mpl { + +template<> +struct empty_impl< aux::set_tag > +{ + template< typename Set > struct apply + : not_< typename Set::size > + { + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_EMPTY_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/erase_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/erase_impl.hpp new file mode 100644 index 0000000..954a70c --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/erase_impl.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_SET_AUX_ERASE_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_ERASE_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: erase_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/erase_fwd.hpp> +#include <boost/mpl/set/aux_/erase_key_impl.hpp> +#include <boost/mpl/set/aux_/tag.hpp> + +namespace boost { namespace mpl { + +template<> +struct erase_impl< aux::set_tag > +{ + template< + typename Set + , typename Pos + , typename unused_ + > + struct apply + : erase_key_impl<aux::set_tag> + ::apply<Set,typename Pos::type> + { + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_ERASE_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/erase_key_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/erase_key_impl.hpp new file mode 100644 index 0000000..9885196 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/erase_key_impl.hpp @@ -0,0 +1,53 @@ + +#ifndef BOOST_MPL_SET_AUX_ERASE_KEY_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_ERASE_KEY_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2007 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: erase_key_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/erase_key_fwd.hpp> +#include <boost/mpl/set/aux_/has_key_impl.hpp> +#include <boost/mpl/set/aux_/item.hpp> +#include <boost/mpl/set/aux_/tag.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/base.hpp> +#include <boost/mpl/eval_if.hpp> + +#include <boost/type_traits/is_same.hpp> + +namespace boost { namespace mpl { + +template<> +struct erase_key_impl< aux::set_tag > +{ + template< + typename Set + , typename T + > + struct apply + : eval_if< + has_key_impl<aux::set_tag>::apply<Set,T> + , eval_if< + is_same< T,typename Set::item_type_ > + , base<Set> + , identity< s_mask<T,typename Set::item_> > + > + , identity<Set> + > + { + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_ERASE_KEY_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/has_key_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/has_key_impl.hpp new file mode 100644 index 0000000..d3cae50 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/has_key_impl.hpp @@ -0,0 +1,60 @@ + +#ifndef BOOST_MPL_SET_AUX_HAS_KEY_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_HAS_KEY_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: has_key_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/set/aux_/tag.hpp> +#include <boost/mpl/has_key_fwd.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/aux_/overload_names.hpp> +#include <boost/mpl/aux_/static_cast.hpp> +#include <boost/mpl/aux_/yes_no.hpp> +#include <boost/mpl/aux_/type_wrapper.hpp> +#include <boost/mpl/aux_/config/workaround.hpp> +#include <boost/mpl/aux_/config/static_constant.hpp> + +namespace boost { namespace mpl { + +template<> +struct has_key_impl< aux::set_tag > +{ + template< typename Set, typename T > struct apply +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ + || BOOST_WORKAROUND(__EDG_VERSION__, <= 245) + { + BOOST_STATIC_CONSTANT(bool, value = + ( sizeof( BOOST_MPL_AUX_OVERLOAD_CALL_IS_MASKED( + Set + , BOOST_MPL_AUX_STATIC_CAST(aux::type_wrapper<T>*, 0) + ) ) == sizeof(aux::no_tag) ) + ); + + typedef bool_<value> type; + +#else // ISO98 C++ + : bool_< + ( sizeof( BOOST_MPL_AUX_OVERLOAD_CALL_IS_MASKED( + Set + , BOOST_MPL_AUX_STATIC_CAST(aux::type_wrapper<T>*, 0) + ) ) == sizeof(aux::no_tag) ) + > + { +#endif + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_HAS_KEY_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/insert_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/insert_impl.hpp new file mode 100644 index 0000000..f1d72ec --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/insert_impl.hpp @@ -0,0 +1,65 @@ + +#ifndef BOOST_MPL_SET_AUX_INSERT_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_INSERT_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2007 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: insert_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/insert_fwd.hpp> +#include <boost/mpl/set/aux_/has_key_impl.hpp> +#include <boost/mpl/set/aux_/item.hpp> +#include <boost/mpl/set/aux_/tag.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/base.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/aux_/na.hpp> + +#include <boost/type_traits/is_same.hpp> + +namespace boost { namespace mpl { + +namespace aux { +template< typename Set, typename T > struct set_insert_impl + : eval_if< + has_key_impl<aux::set_tag>::apply<Set,T> + , identity<Set> + , eval_if< + is_same< T,typename Set::last_masked_ > + , base<Set> + , identity< s_item<T,typename Set::item_> > + > + > +{ +}; +} + +template<> +struct insert_impl< aux::set_tag > +{ + template< + typename Set + , typename PosOrKey + , typename KeyOrNA + > + struct apply + : aux::set_insert_impl< + Set + , typename if_na<KeyOrNA,PosOrKey>::type + > + { + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_INSERT_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/item.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/item.hpp new file mode 100644 index 0000000..b9ca19e --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/item.hpp @@ -0,0 +1,80 @@ + +#ifndef BOOST_MPL_SET_AUX_ITEM_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_ITEM_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2007 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: item.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/long.hpp> +#include <boost/mpl/void.hpp> +#include <boost/mpl/next.hpp> +#include <boost/mpl/prior.hpp> +#include <boost/mpl/set/aux_/set0.hpp> +#include <boost/mpl/aux_/type_wrapper.hpp> +#include <boost/mpl/aux_/config/arrays.hpp> + +namespace boost { namespace mpl { + +template< typename T, typename Base > +struct s_item + : Base +{ + typedef s_item<T,Base> item_; + typedef void_ last_masked_; + typedef T item_type_; + typedef Base base; + + typedef typename next< typename Base::size >::type size; + typedef typename next< typename Base::order >::type order; + +#if defined(BOOST_MPL_CFG_NO_DEPENDENT_ARRAY_TYPES) + typedef typename aux::weighted_tag<BOOST_MPL_AUX_MSVC_VALUE_WKND(order)::value>::type order_tag_; +#else + typedef char (&order_tag_)[BOOST_MPL_AUX_MSVC_VALUE_WKND(order)::value]; +#endif + + BOOST_MPL_AUX_SET_OVERLOAD( order_tag_, ORDER_BY_KEY, s_item, aux::type_wrapper<T>* ); + BOOST_MPL_AUX_SET_OVERLOAD( aux::no_tag, IS_MASKED, s_item, aux::type_wrapper<T>* ); +}; + + +template< typename T, typename Base > +struct s_mask + : Base +{ + typedef s_mask<T,Base> item_; + typedef T last_masked_; + typedef void_ item_type_; + typedef Base base; + typedef typename prior< typename Base::size >::type size; + + BOOST_MPL_AUX_SET_OVERLOAD( aux::yes_tag, IS_MASKED, s_mask, aux::type_wrapper<T>* ); +}; + + +template< typename T, typename Base > +struct s_unmask + : Base +{ + typedef s_unmask<T,Base> item_; + typedef void_ last_masked_; + typedef T item_type_; + typedef Base base; + typedef typename next< typename Base::size >::type size; + + BOOST_MPL_AUX_SET_OVERLOAD( aux::no_tag, IS_MASKED, s_unmask, aux::type_wrapper<T>* ); +}; + +}} + +#endif // BOOST_MPL_SET_AUX_ITEM_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/iterator.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/iterator.hpp new file mode 100644 index 0000000..90666a6 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/iterator.hpp @@ -0,0 +1,98 @@ + +#ifndef BOOST_MPL_SET_AUX_ITERATOR_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_ITERATOR_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2007 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: iterator.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/set/aux_/set0.hpp> +#include <boost/mpl/has_key.hpp> +#include <boost/mpl/iterator_tags.hpp> +#include <boost/mpl/next.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/aux_/config/ctps.hpp> + +namespace boost { namespace mpl { + +// used by 's_iter_get' +template< typename Set, typename Tail > struct s_iter; + +template< typename Set, typename Tail > struct s_iter_get + : eval_if< + has_key< Set,typename Tail::item_type_ > + , identity< s_iter<Set,Tail> > + , next< s_iter<Set,Tail> > + > +{ +}; + +template< typename Set, typename Tail > struct s_iter_impl +{ + typedef Tail tail_; + typedef forward_iterator_tag category; + typedef typename Tail::item_type_ type; + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + typedef typename s_iter_get< Set,typename Tail::base >::type next; +#endif +}; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template< typename Set, typename Tail > +struct next< s_iter<Set,Tail> > + : s_iter_get< Set,typename Tail::base > +{ +}; + +template< typename Set > +struct next< s_iter<Set,set0<> > > +{ + typedef s_iter<Set,set0<> > type; +}; + +template< typename Set, typename Tail > struct s_iter + : s_iter_impl<Set,Tail> +{ +}; + +template< typename Set > struct s_iter<Set, set0<> > +{ + typedef forward_iterator_tag category; +}; + +#else + +template< typename Set > +struct s_end_iter +{ + typedef forward_iterator_tag category; + typedef s_iter<Set,set0<> > next; +}; + +template< typename Set, typename Tail > struct s_iter + : if_< + is_same< Tail,set0<> > + , s_end_iter<Set> + , s_iter_impl<Set,Tail> + >::type +{ +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +}} + +#endif // BOOST_MPL_SET_AUX_ITERATOR_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/key_type_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/key_type_impl.hpp new file mode 100644 index 0000000..23b1a18 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/key_type_impl.hpp @@ -0,0 +1,34 @@ + +#ifndef BOOST_MPL_SET_AUX_KEY_TYPE_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_KEY_TYPE_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: key_type_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/key_type_fwd.hpp> +#include <boost/mpl/set/aux_/tag.hpp> + +namespace boost { namespace mpl { + +template<> +struct key_type_impl< aux::set_tag > +{ + template< typename Set, typename T > struct apply + { + typedef T type; + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_KEY_TYPE_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/set0.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/set0.hpp new file mode 100644 index 0000000..58f1d7d --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/set0.hpp @@ -0,0 +1,69 @@ + +#ifndef BOOST_MPL_SET_AUX_SET0_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_SET0_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: set0.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/long.hpp> +#include <boost/mpl/void.hpp> +#include <boost/mpl/aux_/na.hpp> +#include <boost/mpl/set/aux_/tag.hpp> +#include <boost/mpl/aux_/yes_no.hpp> +#include <boost/mpl/aux_/overload_names.hpp> +#include <boost/mpl/aux_/config/operators.hpp> + +#include <boost/preprocessor/cat.hpp> + +namespace boost { namespace mpl { + +#if defined(BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING) + +# define BOOST_MPL_AUX_SET0_OVERLOAD(R, f, X, T) \ + friend R BOOST_PP_CAT(BOOST_MPL_AUX_OVERLOAD_,f)(X const&, T) \ +/**/ + +# define BOOST_MPL_AUX_SET_OVERLOAD(R, f, X, T) \ + BOOST_MPL_AUX_SET0_OVERLOAD(R, f, X, T) \ +/**/ + +#else + +# define BOOST_MPL_AUX_SET0_OVERLOAD(R, f, X, T) \ + static R BOOST_PP_CAT(BOOST_MPL_AUX_OVERLOAD_,f)(X const&, T) \ +/**/ + +# define BOOST_MPL_AUX_SET_OVERLOAD(R, f, X, T) \ + BOOST_MPL_AUX_SET0_OVERLOAD(R, f, X, T); \ + using Base::BOOST_PP_CAT(BOOST_MPL_AUX_OVERLOAD_,f) \ +/**/ + +#endif + +template< typename Dummy = na > struct set0 +{ + typedef set0<> item_; + typedef item_ type; + typedef aux::set_tag tag; + typedef void_ last_masked_; + typedef void_ item_type_; + typedef long_<0> size; + typedef long_<1> order; + + BOOST_MPL_AUX_SET0_OVERLOAD( aux::no_tag, ORDER_BY_KEY, set0<>, void const volatile* ); + BOOST_MPL_AUX_SET0_OVERLOAD( aux::yes_tag, IS_MASKED, set0<>, void const volatile* ); +}; + +}} + +#endif // BOOST_MPL_SET_AUX_SET0_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/size_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/size_impl.hpp new file mode 100644 index 0000000..0443776 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/size_impl.hpp @@ -0,0 +1,33 @@ + +#ifndef BOOST_MPL_SET_AUX_SIZE_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_SIZE_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: size_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/size_fwd.hpp> +#include <boost/mpl/set/aux_/tag.hpp> + +namespace boost { namespace mpl { + +template<> +struct size_impl< aux::set_tag > +{ + template< typename Set > struct apply + : Set::size + { + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_SIZE_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/tag.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/tag.hpp new file mode 100644 index 0000000..651ed44 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/tag.hpp @@ -0,0 +1,24 @@ + +#ifndef BOOST_MPL_SET_AUX_TAG_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_TAG_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: tag.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +namespace boost { namespace mpl { namespace aux { + +struct set_tag; + +}}} + +#endif // BOOST_MPL_SET_AUX_TAG_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/aux_/value_type_impl.hpp b/3rdParty/Boost/src/boost/mpl/set/aux_/value_type_impl.hpp new file mode 100644 index 0000000..7166dae --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/aux_/value_type_impl.hpp @@ -0,0 +1,34 @@ + +#ifndef BOOST_MPL_SET_AUX_VALUE_TYPE_IMPL_HPP_INCLUDED +#define BOOST_MPL_SET_AUX_VALUE_TYPE_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: value_type_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/value_type_fwd.hpp> +#include <boost/mpl/set/aux_/tag.hpp> + +namespace boost { namespace mpl { + +template<> +struct value_type_impl< aux::set_tag > +{ + template< typename Set, typename T > struct apply + { + typedef T type; + }; +}; + +}} + +#endif // BOOST_MPL_SET_AUX_VALUE_TYPE_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/set/set0.hpp b/3rdParty/Boost/src/boost/mpl/set/set0.hpp new file mode 100644 index 0000000..f6e5b60 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/set/set0.hpp @@ -0,0 +1,35 @@ + +#ifndef BOOST_MPL_SET_SET0_HPP_INCLUDED +#define BOOST_MPL_SET_SET0_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: set0.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/set/aux_/at_impl.hpp> +#include <boost/mpl/set/aux_/clear_impl.hpp> +//#include <boost/mpl/set/aux_/O1_size.hpp> +#include <boost/mpl/set/aux_/size_impl.hpp> +#include <boost/mpl/set/aux_/empty_impl.hpp> +#include <boost/mpl/set/aux_/insert_impl.hpp> +#include <boost/mpl/set/aux_/erase_impl.hpp> +#include <boost/mpl/set/aux_/erase_key_impl.hpp> +#include <boost/mpl/set/aux_/has_key_impl.hpp> +#include <boost/mpl/set/aux_/key_type_impl.hpp> +#include <boost/mpl/set/aux_/value_type_impl.hpp> +#include <boost/mpl/set/aux_/begin_end_impl.hpp> +#include <boost/mpl/set/aux_/iterator.hpp> +#include <boost/mpl/set/aux_/item.hpp> +#include <boost/mpl/set/aux_/set0.hpp> +#include <boost/mpl/set/aux_/tag.hpp> + +#endif // BOOST_MPL_SET_SET0_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/value_type_fwd.hpp b/3rdParty/Boost/src/boost/mpl/value_type_fwd.hpp new file mode 100644 index 0000000..96de3ad --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/value_type_fwd.hpp @@ -0,0 +1,25 @@ + +#ifndef BOOST_MPL_VALUE_TYPE_FWD_HPP_INCLUDED +#define BOOST_MPL_VALUE_TYPE_FWD_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2003-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: value_type_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +namespace boost { namespace mpl { + +template< typename Tag > struct value_type_impl; +template< typename AssociativeSequence, typename T > struct value_type; + +}} + +#endif // BOOST_MPL_VALUE_TYPE_FWD_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/multi_index/detail/access_specifier.hpp b/3rdParty/Boost/src/boost/multi_index/detail/access_specifier.hpp new file mode 100644 index 0000000..84c2f7d --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/access_specifier.hpp @@ -0,0 +1,55 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP +#define BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +/* In those compilers that do not accept the member template friend syntax, + * some protected and private sections might need to be specified as + * public. + */ + +#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) +#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS public +#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS public +#else +#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS protected +#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS private +#endif + +/* GCC does not correctly support in-class using declarations for template + * functions. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9810 + * MSVC 7.1/8.0 seem to have a similar problem, though the conditions in + * which the error happens are not that simple. I have yet to isolate this + * into a snippet suitable for bug reporting. + * Sun Studio also has this problem, which might be related, from the + * information gathered at Sun forums, with a known issue notified at the + * internal bug report 6421933. The bug is present up to Studio Express 2, + * the latest preview version of the future Sun Studio 12. As of this writing + * (October 2006) it is not known whether a fix will finally make it into the + * official Sun Studio 12. + */ + +#if BOOST_WORKAROUND(__GNUC__, <3)||\ + BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\ + BOOST_WORKAROUND(BOOST_MSVC,==1310)||\ + BOOST_WORKAROUND(BOOST_MSVC,==1400)||\ + BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590)) +#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS public +#else +#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS private +#endif + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/adl_swap.hpp b/3rdParty/Boost/src/boost/multi_index/detail/adl_swap.hpp new file mode 100644 index 0000000..e78235d --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/adl_swap.hpp @@ -0,0 +1,44 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP +#define BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template<typename T> +void adl_swap(T& x,T& y) +{ + +#if !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) + using std::swap; + swap(x,y); +#else + std::swap(x,y); +#endif + +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/archive_constructed.hpp b/3rdParty/Boost/src/boost/multi_index/detail/archive_constructed.hpp new file mode 100644 index 0000000..ee00dfa --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/archive_constructed.hpp @@ -0,0 +1,79 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP +#define BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/noncopyable.hpp> +#include <boost/serialization/serialization.hpp> +#include <boost/type_traits/aligned_storage.hpp> +#include <boost/type_traits/alignment_of.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* constructs a stack-based object from a serialization archive */ + +template<typename T> +struct archive_constructed:private noncopyable +{ + template<class Archive> + archive_constructed(Archive& ar,const unsigned int version) + { + serialization::load_construct_data_adl(ar,&get(),version); + BOOST_TRY{ + ar>>get(); + } + BOOST_CATCH(...){ + (&get())->~T(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + template<class Archive> + archive_constructed(const char* name,Archive& ar,const unsigned int version) + { + serialization::load_construct_data_adl(ar,&get(),version); + BOOST_TRY{ + ar>>serialization::make_nvp(name,get()); + } + BOOST_CATCH(...){ + (&get())->~T(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + ~archive_constructed() + { + (&get())->~T(); + } + + T& get(){return *static_cast<T*>(static_cast<void*>(&space));} + +private: + typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/auto_space.hpp b/3rdParty/Boost/src/boost/multi_index/detail/auto_space.hpp new file mode 100644 index 0000000..9b0a0dc --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/auto_space.hpp @@ -0,0 +1,95 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP +#define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> +#include <boost/detail/allocator_utilities.hpp> +#include <boost/multi_index/detail/adl_swap.hpp> +#include <boost/multi_index/detail/prevent_eti.hpp> +#include <boost/noncopyable.hpp> +#include <memory> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* auto_space provides uninitialized space suitably to store + * a given number of elements of a given type. + */ + +/* NB: it is not clear whether using an allocator to handle + * zero-sized arrays of elements is conformant or not. GCC 3.3.1 + * and prior fail here, other stdlibs handle the issue gracefully. + * To be on the safe side, the case n==0 is given special treatment. + * References: + * GCC Bugzilla, "standard allocator crashes when deallocating segment + * "of zero length", http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14176 + * C++ Standard Library Defect Report List (Revision 28), issue 199 + * "What does allocate(0) return?", + * http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#199 + */ + +template<typename T,typename Allocator=std::allocator<T> > +struct auto_space:private noncopyable +{ + typedef typename prevent_eti< + Allocator, + typename boost::detail::allocator::rebind_to< + Allocator,T + >::type + >::type::pointer pointer; + + explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1): + al_(al),n_(n),data_(n_?al_.allocate(n_):pointer(0)) + {} + + ~auto_space() + { + if(n_)al_.deallocate(data_,n_); + } + + Allocator get_allocator()const{return al_;} + + pointer data()const{return data_;} + + void swap(auto_space& x) + { + if(al_!=x.al_)adl_swap(al_,x.al_); + std::swap(n_,x.n_); + std::swap(data_,x.data_); + } + +private: + typename boost::detail::allocator::rebind_to< + Allocator,T>::type al_; + std::size_t n_; + pointer data_; +}; + +template<typename T,typename Allocator> +void swap(auto_space<T,Allocator>& x,auto_space<T,Allocator>& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/base_type.hpp b/3rdParty/Boost/src/boost/multi_index/detail/base_type.hpp new file mode 100644 index 0000000..d25332e --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/base_type.hpp @@ -0,0 +1,87 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP +#define BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/detail/workaround.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/apply.hpp> +#include <boost/mpl/size.hpp> +#include <boost/multi_index/detail/index_base.hpp> +#include <boost/multi_index/detail/is_index_list.hpp> +#include <boost/multi_index/detail/msvc_index_specifier.hpp> +#include <boost/static_assert.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* MPL machinery to construct a linear hierarchy of indices out of + * a index list. + */ + +#if BOOST_WORKAROUND(BOOST_MSVC,<1310) +struct index_applier +{ + template<typename IndexSpecifierMeta,typename SuperMeta> + struct apply: + msvc_index_specifier<IndexSpecifierMeta::type>:: + template result_index_class<SuperMeta> + { + }; +}; +#else +struct index_applier +{ + template<typename IndexSpecifierMeta,typename SuperMeta> + struct apply + { + typedef typename IndexSpecifierMeta::type index_specifier; + typedef typename index_specifier:: + BOOST_NESTED_TEMPLATE index_class<SuperMeta>::type type; + }; +}; +#endif + +template<int N,typename Value,typename IndexSpecifierList,typename Allocator> +struct nth_layer +{ + BOOST_STATIC_CONSTANT(int,length=mpl::size<IndexSpecifierList>::value); + + typedef typename mpl::eval_if_c< + N==length, + mpl::identity<index_base<Value,IndexSpecifierList,Allocator> >, + mpl::apply2< + index_applier, + mpl::at_c<IndexSpecifierList,N>, + nth_layer<N+1,Value,IndexSpecifierList,Allocator> + > + >::type type; +}; + +template<typename Value,typename IndexSpecifierList,typename Allocator> +struct multi_index_base_type:nth_layer<0,Value,IndexSpecifierList,Allocator> +{ + BOOST_STATIC_ASSERT(detail::is_index_list<IndexSpecifierList>::value); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/bidir_node_iterator.hpp b/3rdParty/Boost/src/boost/multi_index/detail/bidir_node_iterator.hpp new file mode 100644 index 0000000..2155255 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/bidir_node_iterator.hpp @@ -0,0 +1,113 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/operators.hpp> + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include <boost/serialization/nvp.hpp> +#include <boost/serialization/split_member.hpp> +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Iterator class for node-based indices with bidirectional + * iterators (ordered and sequenced indices.) + */ + +template<typename Node> +class bidir_node_iterator: + public bidirectional_iterator_helper< + bidir_node_iterator<Node>, + typename Node::value_type, + std::ptrdiff_t, + const typename Node::value_type*, + const typename Node::value_type&> +{ +public: + bidir_node_iterator(){} + explicit bidir_node_iterator(Node* node_):node(node_){} + + const typename Node::value_type& operator*()const + { + return node->value(); + } + + bidir_node_iterator& operator++() + { + Node::increment(node); + return *this; + } + + bidir_node_iterator& operator--() + { + Node::decrement(node); + return *this; + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* Serialization. As for why the following is public, + * see explanation in safe_mode_iterator notes in safe_mode.hpp. + */ + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + typedef typename Node::base_type node_base_type; + + template<class Archive> + void save(Archive& ar,const unsigned int)const + { + node_base_type* bnode=node; + ar<<serialization::make_nvp("pointer",bnode); + } + + template<class Archive> + void load(Archive& ar,const unsigned int) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast<Node*>(bnode); + } +#endif + + /* get_node is not to be used by the user */ + + typedef Node node_type; + + Node* get_node()const{return node;} + +private: + Node* node; +}; + +template<typename Node> +bool operator==( + const bidir_node_iterator<Node>& x, + const bidir_node_iterator<Node>& y) +{ + return x.get_node()==y.get_node(); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/converter.hpp b/3rdParty/Boost/src/boost/multi_index/detail/converter.hpp new file mode 100644 index 0000000..a46cff6 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/converter.hpp @@ -0,0 +1,52 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP +#define BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* converter offers means to access indices of a given multi_index_container + * and for convertibilty between index iterators, so providing a + * localized access point for get() and project() functions. + */ + +template<typename MultiIndexContainer,typename Index> +struct converter +{ + static const Index& index(const MultiIndexContainer& x){return x;} + static Index& index(MultiIndexContainer& x){return x;} + + static typename Index::const_iterator const_iterator( + const MultiIndexContainer& x,typename MultiIndexContainer::node_type* node) + { + return x.Index::make_iterator(node); + } + + static typename Index::iterator iterator( + MultiIndexContainer& x,typename MultiIndexContainer::node_type* node) + { + return x.Index::make_iterator(node); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/copy_map.hpp b/3rdParty/Boost/src/boost/multi_index/detail/copy_map.hpp new file mode 100644 index 0000000..4279a8d --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/copy_map.hpp @@ -0,0 +1,140 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP +#define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/multi_index/detail/auto_space.hpp> +#include <boost/multi_index/detail/prevent_eti.hpp> +#include <boost/noncopyable.hpp> +#include <cstddef> +#include <functional> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* copy_map is used as an auxiliary structure during copy_() operations. + * When a container with n nodes is replicated, node_map holds the pairings + * between original and copied nodes, and provides a fast way to find a + * copied node from an original one. + * The semantics of the class are not simple, and no attempt has been made + * to enforce it: multi_index_container handles it right. On the other hand, + * the const interface, which is the one provided to index implementations, + * only allows for: + * - Enumeration of pairs of (original,copied) nodes (excluding the headers), + * - fast retrieval of copied nodes (including the headers.) + */ + +template <typename Node> +struct copy_map_entry +{ + copy_map_entry(Node* f,Node* s):first(f),second(s){} + + Node* first; + Node* second; + + bool operator<(const copy_map_entry<Node>& x)const + { + return std::less<Node*>()(first,x.first); + } +}; + +template <typename Node,typename Allocator> +class copy_map:private noncopyable +{ +public: + typedef const copy_map_entry<Node>* const_iterator; + + copy_map( + const Allocator& al,std::size_t size,Node* header_org,Node* header_cpy): + al_(al),size_(size),spc(al_,size_),n(0), + header_org_(header_org),header_cpy_(header_cpy),released(false) + {} + + ~copy_map() + { + if(!released){ + for(std::size_t i=0;i<n;++i){ + boost::detail::allocator::destroy(&(spc.data()+i)->second->value()); + deallocate((spc.data()+i)->second); + } + } + } + + const_iterator begin()const{return &*spc.data();} + const_iterator end()const{return &*(spc.data()+n);} + + void clone(Node* node) + { + (spc.data()+n)->first=node; + (spc.data()+n)->second=&*al_.allocate(1); + BOOST_TRY{ + boost::detail::allocator::construct( + &(spc.data()+n)->second->value(),node->value()); + } + BOOST_CATCH(...){ + deallocate((spc.data()+n)->second); + BOOST_RETHROW; + } + BOOST_CATCH_END + ++n; + + if(n==size_)std::sort(&*spc.data(),&*spc.data()+size_); + } + + Node* find(Node* node)const + { + if(node==header_org_)return header_cpy_; + return std::lower_bound( + begin(),end(),copy_map_entry<Node>(node,0))->second; + } + + void release() + { + released=true; + } + +private: + typedef typename prevent_eti< + Allocator, + typename boost::detail::allocator::rebind_to< + Allocator,Node>::type + >::type allocator_type; + typedef typename allocator_type::pointer allocator_pointer; + + allocator_type al_; + std::size_t size_; + auto_space<copy_map_entry<Node>,Allocator> spc; + std::size_t n; + Node* header_org_; + Node* header_cpy_; + bool released; + + void deallocate(Node* node) + { + al_.deallocate(static_cast<allocator_pointer>(node),1); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/duplicates_iterator.hpp b/3rdParty/Boost/src/boost/multi_index/detail/duplicates_iterator.hpp new file mode 100644 index 0000000..027dabd --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/duplicates_iterator.hpp @@ -0,0 +1,120 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <cstddef> +#include <iterator> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* duplicates_operator is given a range of ordered elements and + * passes only over those which are duplicated. + */ + +template<typename Node,typename Predicate> +class duplicates_iterator +{ +public: + typedef typename Node::value_type value_type; + typedef std::ptrdiff_t difference_type; + typedef const typename Node::value_type* pointer; + typedef const typename Node::value_type& reference; + typedef std::forward_iterator_tag iterator_category; + + duplicates_iterator(Node* node_,Node* end_,Predicate pred_): + node(node_),begin_chunk(0),end(end_),pred(pred_) + { + advance(); + } + + duplicates_iterator(Node* end_,Predicate pred_): + node(end_),begin_chunk(end_),end(end_),pred(pred_) + { + } + + reference operator*()const + { + return node->value(); + } + + pointer operator->()const + { + return &node->value(); + } + + duplicates_iterator& operator++() + { + Node::increment(node); + sync(); + return *this; + } + + duplicates_iterator operator++(int) + { + duplicates_iterator tmp(*this); + ++(*this); + return tmp; + } + + Node* get_node()const{return node;} + +private: + void sync() + { + if(node!=end&&pred(begin_chunk->value(),node->value()))advance(); + } + + void advance() + { + for(Node* node2=node;node!=end;node=node2){ + Node::increment(node2); + if(node2!=end&&!pred(node->value(),node2->value()))break; + } + begin_chunk=node; + } + + Node* node; + Node* begin_chunk; + Node* end; + Predicate pred; +}; + +template<typename Node,typename Predicate> +bool operator==( + const duplicates_iterator<Node,Predicate>& x, + const duplicates_iterator<Node,Predicate>& y) +{ + return x.get_node()==y.get_node(); +} + +template<typename Node,typename Predicate> +bool operator!=( + const duplicates_iterator<Node,Predicate>& x, + const duplicates_iterator<Node,Predicate>& y) +{ + return !(x==y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/has_tag.hpp b/3rdParty/Boost/src/boost/multi_index/detail/has_tag.hpp new file mode 100644 index 0000000..83b28cc --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/has_tag.hpp @@ -0,0 +1,42 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP +#define BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/mpl/contains.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* determines whether an index type has a given tag in its tag list */ + +template<typename Tag> +struct has_tag +{ + template<typename Index> + struct apply:mpl::contains<BOOST_DEDUCED_TYPENAME Index::tag_list,Tag> + { + }; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/header_holder.hpp b/3rdParty/Boost/src/boost/multi_index/detail/header_holder.hpp new file mode 100644 index 0000000..8716e83 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/header_holder.hpp @@ -0,0 +1,50 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP +#define BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/noncopyable.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* A utility class used to hold a pointer to the header node. + * The base from member idiom is used because index classes, which are + * superclasses of multi_index_container, need this header in construction + * time. The allocation is made by the allocator of the multi_index_container + * class --hence, this allocator needs also be stored resorting + * to the base from member trick. + */ + +template<typename NodeTypePtr,typename Final> +struct header_holder:private noncopyable +{ + header_holder():member(final().allocate_node()){} + ~header_holder(){final().deallocate_node(&*member);} + + NodeTypePtr member; + +private: + Final& final(){return *static_cast<Final*>(this);} +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/index_base.hpp b/3rdParty/Boost/src/boost/multi_index/detail/index_base.hpp new file mode 100644 index 0000000..9b73a4b --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/index_base.hpp @@ -0,0 +1,185 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/call_traits.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/multi_index/detail/copy_map.hpp> +#include <boost/multi_index/detail/node_type.hpp> +#include <boost/multi_index_container_fwd.hpp> +#include <boost/tuple/tuple.hpp> +#include <utility> + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include <boost/multi_index/detail/index_loader.hpp> +#include <boost/multi_index/detail/index_saver.hpp> +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* The role of this class is threefold: + * - tops the linear hierarchy of indices. + * - terminates some cascading backbone function calls (insert_, etc.), + * - grants access to the backbone functions of the final + * multi_index_container class (for access restriction reasons, these + * cannot be called directly from the index classes.) + */ + +template<typename Value,typename IndexSpecifierList,typename Allocator> +class index_base +{ +protected: + typedef index_node_base<Value,Allocator> node_type; + typedef typename multi_index_node_type< + Value,IndexSpecifierList,Allocator>::type final_node_type; + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> final_type; + typedef tuples::null_type ctor_args_list; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + typename Allocator::value_type>::type final_allocator_type; + typedef mpl::vector0<> index_type_list; + typedef mpl::vector0<> iterator_type_list; + typedef mpl::vector0<> const_iterator_type_list; + typedef copy_map< + final_node_type, + final_allocator_type> copy_map_type; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + typedef index_saver< + node_type, + final_allocator_type> index_saver_type; + typedef index_loader< + node_type, + final_node_type, + final_allocator_type> index_loader_type; +#endif + +private: + typedef typename call_traits<Value>::param_type value_param_type; + +protected: + explicit index_base(const ctor_args_list&,const Allocator&){} + + void copy_( + const index_base<Value,IndexSpecifierList,Allocator>&,const copy_map_type&) + {} + + node_type* insert_(value_param_type v,node_type* x) + { + boost::detail::allocator::construct(&x->value(),v); + return x; + } + + node_type* insert_(value_param_type v,node_type*,node_type* x) + { + boost::detail::allocator::construct(&x->value(),v); + return x; + } + + void erase_(node_type* x) + { + boost::detail::allocator::destroy(&x->value()); + } + + void delete_node_(node_type* x) + { + boost::detail::allocator::destroy(&x->value()); + } + + void clear_(){} + + void swap_(index_base<Value,IndexSpecifierList,Allocator>&){} + + bool replace_(value_param_type v,node_type* x) + { + x->value()=v; + return true; + } + + bool modify_(node_type*){return true;} + + bool modify_rollback_(node_type*){return true;} + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template<typename Archive> + void save_(Archive&,const unsigned int,const index_saver_type&)const{} + + template<typename Archive> + void load_(Archive&,const unsigned int,const index_loader_type&){} +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const{return true;} +#endif + + /* access to backbone memfuns of Final class */ + + final_type& final(){return *static_cast<final_type*>(this);} + const final_type& final()const{return *static_cast<const final_type*>(this);} + + final_node_type* final_header()const{return final().header();} + + bool final_empty_()const{return final().empty_();} + std::size_t final_size_()const{return final().size_();} + std::size_t final_max_size_()const{return final().max_size_();} + + std::pair<final_node_type*,bool> final_insert_(value_param_type x) + {return final().insert_(x);} + std::pair<final_node_type*,bool> final_insert_( + value_param_type x,final_node_type* position) + {return final().insert_(x,position);} + + void final_erase_(final_node_type* x){final().erase_(x);} + + void final_delete_node_(final_node_type* x){final().delete_node_(x);} + void final_delete_all_nodes_(){final().delete_all_nodes_();} + void final_clear_(){final().clear_();} + + void final_swap_(final_type& x){final().swap_(x);} + bool final_replace_( + value_param_type k,final_node_type* x) + {return final().replace_(k,x);} + + template<typename Modifier> + bool final_modify_(Modifier& mod,final_node_type* x) + {return final().modify_(mod,x);} + + template<typename Modifier,typename Rollback> + bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x) + {return final().modify_(mod,back,x);} + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + void final_check_invariant_()const{final().check_invariant_();} +#endif +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/index_loader.hpp b/3rdParty/Boost/src/boost/multi_index/detail/index_loader.hpp new file mode 100644 index 0000000..001c01b --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/index_loader.hpp @@ -0,0 +1,138 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> +#include <boost/archive/archive_exception.hpp> +#include <boost/noncopyable.hpp> +#include <boost/multi_index/detail/auto_space.hpp> +#include <boost/serialization/nvp.hpp> +#include <boost/throw_exception.hpp> +#include <cstddef> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Counterpart of index_saver (check index_saver.hpp for serialization + * details.)* multi_index_container is in charge of supplying the info about + * the base sequence, and each index can subsequently load itself using the + * const interface of index_loader. + */ + +template<typename Node,typename FinalNode,typename Allocator> +class index_loader:private noncopyable +{ +public: + index_loader(const Allocator& al,std::size_t size): + spc(al,size),size_(size),n(0),sorted(false) + { + } + + template<class Archive> + void add(Node* node,Archive& ar,const unsigned int) + { + ar>>serialization::make_nvp("position",*node); + entries()[n++]=node; + } + + template<class Archive> + void add_track(Node* node,Archive& ar,const unsigned int) + { + ar>>serialization::make_nvp("position",*node); + } + + /* A rearranger is passed two nodes, and is expected to + * reposition the second after the first. + * If the first node is 0, then the second should be moved + * to the beginning of the sequence. + */ + + template<typename Rearranger,class Archive> + void load(Rearranger r,Archive& ar,const unsigned int)const + { + FinalNode* prev=unchecked_load_node(ar); + if(!prev)return; + + if(!sorted){ + std::sort(entries(),entries()+size_); + sorted=true; + } + + check_node(prev); + + for(;;){ + for(;;){ + FinalNode* node=load_node(ar); + if(!node)break; + + if(node==prev)prev=0; + r(prev,node); + + prev=node; + } + prev=load_node(ar); + if(!prev)break; + } + } + +private: + Node** entries()const{return &*spc.data();} + + /* We try to delay sorting as much as possible just in case it + * is not necessary, hence this version of load_node. + */ + + template<class Archive> + FinalNode* unchecked_load_node(Archive& ar)const + { + Node* node=0; + ar>>serialization::make_nvp("pointer",node); + return static_cast<FinalNode*>(node); + } + + template<class Archive> + FinalNode* load_node(Archive& ar)const + { + Node* node=0; + ar>>serialization::make_nvp("pointer",node); + check_node(node); + return static_cast<FinalNode*>(node); + } + + void check_node(Node* node)const + { + if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){ + throw_exception( + archive::archive_exception( + archive::archive_exception::other_exception)); + } + } + + auto_space<Node*,Allocator> spc; + std::size_t size_; + std::size_t n; + mutable bool sorted; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/index_matcher.hpp b/3rdParty/Boost/src/boost/multi_index/detail/index_matcher.hpp new file mode 100644 index 0000000..5828137 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/index_matcher.hpp @@ -0,0 +1,248 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> +#include <boost/noncopyable.hpp> +#include <boost/multi_index/detail/auto_space.hpp> +#include <cstddef> +#include <functional> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* index_matcher compares a sequence of elements against a + * base sequence, identifying those elements that belong to the + * longest subsequence which is ordered with respect to the base. + * For instance, if the base sequence is: + * + * 0 1 2 3 4 5 6 7 8 9 + * + * and the compared sequence (not necesarilly the same length): + * + * 1 4 2 3 0 7 8 9 + * + * the elements of the longest ordered subsequence are: + * + * 1 2 3 7 8 9 + * + * The algorithm for obtaining such a subsequence is called + * Patience Sorting, described in ch. 1 of: + * Aldous, D., Diaconis, P.: "Longest increasing subsequences: from + * patience sorting to the Baik-Deift-Johansson Theorem", Bulletin + * of the American Mathematical Society, vol. 36, no 4, pp. 413-432, + * July 1999. + * http://www.ams.org/bull/1999-36-04/S0273-0979-99-00796-X/ + * S0273-0979-99-00796-X.pdf + * + * This implementation is not fully generic since it assumes that + * the sequences given are pointed to by index iterators (having a + * get_node() memfun.) + */ + +namespace index_matcher{ + +/* The algorithm stores the nodes of the base sequence and a number + * of "piles" that are dynamically updated during the calculation + * stage. From a logical point of view, nodes form an independent + * sequence from piles. They are stored together so as to minimize + * allocated memory. + */ + +struct entry +{ + entry(void* node_,std::size_t pos_=0):node(node_),pos(pos_){} + + /* node stuff */ + + void* node; + std::size_t pos; + entry* previous; + bool ordered; + + struct less_by_node + { + bool operator()( + const entry& x,const entry& y)const + { + return std::less<void*>()(x.node,y.node); + } + }; + + /* pile stuff */ + + std::size_t pile_top; + entry* pile_top_entry; + + struct less_by_pile_top + { + bool operator()( + const entry& x,const entry& y)const + { + return x.pile_top<y.pile_top; + } + }; +}; + +/* common code operating on void *'s */ + +template<typename Allocator> +class algorithm_base:private noncopyable +{ +protected: + algorithm_base(const Allocator& al,std::size_t size): + spc(al,size),size_(size),n(0),sorted(false) + { + } + + void add(void* node) + { + entries()[n]=entry(node,n); + ++n; + } + + void begin_algorithm()const + { + if(!sorted){ + std::sort(entries(),entries()+size_,entry::less_by_node()); + sorted=true; + } + num_piles=0; + } + + void add_node_to_algorithm(void* node)const + { + entry* ent= + std::lower_bound( + entries(),entries()+size_, + entry(node),entry::less_by_node()); /* localize entry */ + ent->ordered=false; + std::size_t n=ent->pos; /* get its position */ + + entry dummy(0); + dummy.pile_top=n; + + entry* pile_ent= /* find the first available pile */ + std::lower_bound( /* to stack the entry */ + entries(),entries()+num_piles, + dummy,entry::less_by_pile_top()); + + pile_ent->pile_top=n; /* stack the entry */ + pile_ent->pile_top_entry=ent; + + /* if not the first pile, link entry to top of the preceding pile */ + if(pile_ent>&entries()[0]){ + ent->previous=(pile_ent-1)->pile_top_entry; + } + + if(pile_ent==&entries()[num_piles]){ /* new pile? */ + ++num_piles; + } + } + + void finish_algorithm()const + { + if(num_piles>0){ + /* Mark those elements which are in their correct position, i.e. those + * belonging to the longest increasing subsequence. These are those + * elements linked from the top of the last pile. + */ + + entry* ent=entries()[num_piles-1].pile_top_entry; + for(std::size_t n=num_piles;n--;){ + ent->ordered=true; + ent=ent->previous; + } + } + } + + bool is_ordered(void * node)const + { + return std::lower_bound( + entries(),entries()+size_, + entry(node),entry::less_by_node())->ordered; + } + +private: + entry* entries()const{return &*spc.data();} + + auto_space<entry,Allocator> spc; + std::size_t size_; + std::size_t n; + mutable bool sorted; + mutable std::size_t num_piles; +}; + +/* The algorithm has three phases: + * - Initialization, during which the nodes of the base sequence are added. + * - Execution. + * - Results querying, through the is_ordered memfun. + */ + +template<typename Node,typename Allocator> +class algorithm:private algorithm_base<Allocator> +{ + typedef algorithm_base<Allocator> super; + +public: + algorithm(const Allocator& al,std::size_t size):super(al,size){} + + void add(Node* node) + { + super::add(node); + } + + template<typename IndexIterator> + void execute(IndexIterator first,IndexIterator last)const + { + super::begin_algorithm(); + + for(IndexIterator it=first;it!=last;++it){ + add_node_to_algorithm(get_node(it)); + } + + super::finish_algorithm(); + } + + bool is_ordered(Node* node)const + { + return super::is_ordered(node); + } + +private: + void add_node_to_algorithm(Node* node)const + { + super::add_node_to_algorithm(node); + } + + template<typename IndexIterator> + static Node* get_node(IndexIterator it) + { + return static_cast<Node*>(it.get_node()); + } +}; + +} /* namespace multi_index::detail::index_matcher */ + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/index_node_base.hpp b/3rdParty/Boost/src/boost/multi_index/detail/index_node_base.hpp new file mode 100644 index 0000000..ee9f1c6 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/index_node_base.hpp @@ -0,0 +1,135 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/type_traits/aligned_storage.hpp> +#include <boost/type_traits/alignment_of.hpp> + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include <boost/archive/archive_exception.hpp> +#include <boost/serialization/access.hpp> +#include <boost/throw_exception.hpp> +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* index_node_base tops the node hierarchy of multi_index_container. It holds + * the value of the element contained. + */ + +template<typename Value> +struct pod_value_holder +{ + typename aligned_storage< + sizeof(Value), + alignment_of<Value>::value + >::type space; +}; + +template<typename Value,typename Allocator> +struct index_node_base:private pod_value_holder<Value> +{ + typedef index_node_base base_type; /* used for serialization purposes */ + typedef Value value_type; + typedef Allocator allocator_type; + + value_type& value() + { + return *static_cast<value_type*>( + static_cast<void*>(&this->space)); + } + + const value_type& value()const + { + return *static_cast<const value_type*>( + static_cast<const void*>(&this->space)); + } + + static index_node_base* from_value(const value_type* p) + { + return static_cast<index_node_base *>( + reinterpret_cast<pod_value_holder<Value>*>( /* std 9.2.17 */ + const_cast<value_type*>(p))); + } + +private: +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + friend class boost::serialization::access; + + /* nodes do not emit any kind of serialization info. They are + * fed to Boost.Serialization so that pointers to nodes are + * tracked correctly. + */ + + template<class Archive> + void serialize(Archive&,const unsigned int) + { + } +#endif +}; + +template<typename Node,typename Value> +Node* node_from_value( + const Value* p + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node)) +{ + typedef typename Node::allocator_type allocator_type; + return static_cast<Node*>( + index_node_base<Value,allocator_type>::from_value(p)); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +/* Index nodes never get constructed directly by Boost.Serialization, + * as archives are always fed pointers to previously existent + * nodes. So, if this is called it means we are dealing with a + * somehow invalid archive. + */ + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace serialization{ +#else +namespace multi_index{ +namespace detail{ +#endif + +template<class Archive,typename Value,typename Allocator> +inline void load_construct_data( + Archive&,boost::multi_index::detail::index_node_base<Value,Allocator>*, + const unsigned int) +{ + throw_exception( + archive::archive_exception(archive::archive_exception::other_exception)); +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} /* namespace serialization */ +#else +} /* namespace multi_index::detail */ +} /* namespace multi_index */ +#endif + +#endif + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/index_saver.hpp b/3rdParty/Boost/src/boost/multi_index/detail/index_saver.hpp new file mode 100644 index 0000000..d9e6bc7 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/index_saver.hpp @@ -0,0 +1,135 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/multi_index/detail/index_matcher.hpp> +#include <boost/noncopyable.hpp> +#include <boost/serialization/nvp.hpp> +#include <cstddef> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* index_saver accepts a base sequence of previously saved elements + * and saves a possibly reordered subsequence in an efficient manner, + * serializing only the information needed to rearrange the subsequence + * based on the original order of the base. + * multi_index_container is in charge of supplying the info about the + * base sequence, and each index can subsequently save itself using the + * const interface of index_saver. + */ + +template<typename Node,typename Allocator> +class index_saver:private noncopyable +{ +public: + index_saver(const Allocator& al,std::size_t size):alg(al,size){} + + template<class Archive> + void add(Node* node,Archive& ar,const unsigned int) + { + ar<<serialization::make_nvp("position",*node); + alg.add(node); + } + + template<class Archive> + void add_track(Node* node,Archive& ar,const unsigned int) + { + ar<<serialization::make_nvp("position",*node); + } + + template<typename IndexIterator,class Archive> + void save( + IndexIterator first,IndexIterator last,Archive& ar, + const unsigned int)const + { + /* calculate ordered positions */ + + alg.execute(first,last); + + /* Given a consecutive subsequence of displaced elements + * x1,...,xn, the following information is serialized: + * + * p0,p1,...,pn,0 + * + * where pi is a pointer to xi and p0 is a pointer to the element + * preceding x1. Crealy, from this information is possible to + * restore the original order on loading time. If x1 is the first + * element in the sequence, the following is serialized instead: + * + * p1,p1,...,pn,0 + * + * For each subsequence of n elements, n+2 pointers are serialized. + * An optimization policy is applied: consider for instance the + * sequence + * + * a,B,c,D + * + * where B and D are displaced, but c is in its correct position. + * Applying the schema described above we would serialize 6 pointers: + * + * p(a),p(B),0 + * p(c),p(D),0 + * + * but this can be reduced to 5 pointers by treating c as a displaced + * element: + * + * p(a),p(B),p(c),p(D),0 + */ + + std::size_t last_saved=3; /* distance to last pointer saved */ + for(IndexIterator it=first,prev=first;it!=last;prev=it++,++last_saved){ + if(!alg.is_ordered(get_node(it))){ + if(last_saved>1)save_node(get_node(prev),ar); + save_node(get_node(it),ar); + last_saved=0; + } + else if(last_saved==2)save_node(null_node(),ar); + } + if(last_saved<=2)save_node(null_node(),ar); + + /* marks the end of the serialization info for [first,last) */ + + save_node(null_node(),ar); + } + +private: + template<typename IndexIterator> + static Node* get_node(IndexIterator it) + { + return it.get_node(); + } + + static Node* null_node(){return 0;} + + template<typename Archive> + static void save_node(Node* node,Archive& ar) + { + ar<<serialization::make_nvp("pointer",node); + } + + index_matcher::algorithm<Node,Allocator> alg; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/invariant_assert.hpp b/3rdParty/Boost/src/boost/multi_index/detail/invariant_assert.hpp new file mode 100644 index 0000000..d5fc256 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/invariant_assert.hpp @@ -0,0 +1,21 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP +#define BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#if !defined(BOOST_MULTI_INDEX_INVARIANT_ASSERT) +#include <boost/assert.hpp> +#define BOOST_MULTI_INDEX_INVARIANT_ASSERT BOOST_ASSERT +#endif + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/is_index_list.hpp b/3rdParty/Boost/src/boost/multi_index/detail/is_index_list.hpp new file mode 100644 index 0000000..9ee30ba --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/is_index_list.hpp @@ -0,0 +1,40 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP +#define BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/mpl/empty.hpp> +#include <boost/mpl/is_sequence.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template<typename T> +struct is_index_list +{ + BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence<T>::value); + BOOST_STATIC_CONSTANT(bool,non_empty=!mpl::empty<T>::value); + BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/iter_adaptor.hpp b/3rdParty/Boost/src/boost/multi_index/detail/iter_adaptor.hpp new file mode 100644 index 0000000..0346184 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/iter_adaptor.hpp @@ -0,0 +1,325 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/mpl/apply.hpp> +#include <boost/multi_index/detail/prevent_eti.hpp> +#include <boost/operators.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Poor man's version of boost::iterator_adaptor. Used instead of the + * original as compile times for the latter are significantly higher. + * The interface is not replicated exactly, only to the extent necessary + * for internal consumption. + */ + +/* NB. The purpose of the (non-inclass) global operators ==, < and - defined + * above is to partially alleviate a problem of MSVC++ 6.0 by * which + * friend-injected operators on T are not visible if T is instantiated only + * in template code where T is a dependent type. + */ + +class iter_adaptor_access +{ +public: + template<class Class> + static typename Class::reference dereference(const Class& x) + { + return x.dereference(); + } + + template<class Class> + static bool equal(const Class& x,const Class& y) + { + return x.equal(y); + } + + template<class Class> + static void increment(Class& x) + { + x.increment(); + } + + template<class Class> + static void decrement(Class& x) + { + x.decrement(); + } + + template<class Class> + static void advance(Class& x,typename Class::difference_type n) + { + x.advance(n); + } + + template<class Class> + static typename Class::difference_type distance_to( + const Class& x,const Class& y) + { + return x.distance_to(y); + } +}; + +template<typename Category> +struct iter_adaptor_selector; + +template<class Derived,class Base> +class forward_iter_adaptor_base: + public forward_iterator_helper< + Derived, + typename Base::value_type, + typename Base::difference_type, + typename Base::pointer, + typename Base::reference> +{ +public: + typedef typename Base::reference reference; + + reference operator*()const + { + return iter_adaptor_access::dereference(final()); + } + + friend bool operator==(const Derived& x,const Derived& y) + { + return iter_adaptor_access::equal(x,y); + } + + Derived& operator++() + { + iter_adaptor_access::increment(final()); + return final(); + } + +private: + Derived& final(){return *static_cast<Derived*>(this);} + const Derived& final()const{return *static_cast<const Derived*>(this);} +}; + +template<class Derived,class Base> +bool operator==( + const forward_iter_adaptor_base<Derived,Base>& x, + const forward_iter_adaptor_base<Derived,Base>& y) +{ + return iter_adaptor_access::equal( + static_cast<const Derived&>(x),static_cast<const Derived&>(y)); +} + +template<> +struct iter_adaptor_selector<std::forward_iterator_tag> +{ + template<class Derived,class Base> + struct apply + { + typedef forward_iter_adaptor_base<Derived,Base> type; + }; +}; + +template<class Derived,class Base> +class bidirectional_iter_adaptor_base: + public bidirectional_iterator_helper< + Derived, + typename Base::value_type, + typename Base::difference_type, + typename Base::pointer, + typename Base::reference> +{ +public: + typedef typename Base::reference reference; + + reference operator*()const + { + return iter_adaptor_access::dereference(final()); + } + + friend bool operator==(const Derived& x,const Derived& y) + { + return iter_adaptor_access::equal(x,y); + } + + Derived& operator++() + { + iter_adaptor_access::increment(final()); + return final(); + } + + Derived& operator--() + { + iter_adaptor_access::decrement(final()); + return final(); + } + +private: + Derived& final(){return *static_cast<Derived*>(this);} + const Derived& final()const{return *static_cast<const Derived*>(this);} +}; + +template<class Derived,class Base> +bool operator==( + const bidirectional_iter_adaptor_base<Derived,Base>& x, + const bidirectional_iter_adaptor_base<Derived,Base>& y) +{ + return iter_adaptor_access::equal( + static_cast<const Derived&>(x),static_cast<const Derived&>(y)); +} + +template<> +struct iter_adaptor_selector<std::bidirectional_iterator_tag> +{ + template<class Derived,class Base> + struct apply + { + typedef bidirectional_iter_adaptor_base<Derived,Base> type; + }; +}; + +template<class Derived,class Base> +class random_access_iter_adaptor_base: + public random_access_iterator_helper< + Derived, + typename Base::value_type, + typename Base::difference_type, + typename Base::pointer, + typename Base::reference> +{ +public: + typedef typename Base::reference reference; + typedef typename Base::difference_type difference_type; + + reference operator*()const + { + return iter_adaptor_access::dereference(final()); + } + + friend bool operator==(const Derived& x,const Derived& y) + { + return iter_adaptor_access::equal(x,y); + } + + friend bool operator<(const Derived& x,const Derived& y) + { + return iter_adaptor_access::distance_to(x,y)>0; + } + + Derived& operator++() + { + iter_adaptor_access::increment(final()); + return final(); + } + + Derived& operator--() + { + iter_adaptor_access::decrement(final()); + return final(); + } + + Derived& operator+=(difference_type n) + { + iter_adaptor_access::advance(final(),n); + return final(); + } + + Derived& operator-=(difference_type n) + { + iter_adaptor_access::advance(final(),-n); + return final(); + } + + friend difference_type operator-(const Derived& x,const Derived& y) + { + return iter_adaptor_access::distance_to(y,x); + } + +private: + Derived& final(){return *static_cast<Derived*>(this);} + const Derived& final()const{return *static_cast<const Derived*>(this);} +}; + +template<class Derived,class Base> +bool operator==( + const random_access_iter_adaptor_base<Derived,Base>& x, + const random_access_iter_adaptor_base<Derived,Base>& y) +{ + return iter_adaptor_access::equal( + static_cast<const Derived&>(x),static_cast<const Derived&>(y)); +} + +template<class Derived,class Base> +bool operator<( + const random_access_iter_adaptor_base<Derived,Base>& x, + const random_access_iter_adaptor_base<Derived,Base>& y) +{ + return iter_adaptor_access::distance_to( + static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0; +} + +template<class Derived,class Base> +typename random_access_iter_adaptor_base<Derived,Base>::difference_type +operator-( + const random_access_iter_adaptor_base<Derived,Base>& x, + const random_access_iter_adaptor_base<Derived,Base>& y) +{ + return iter_adaptor_access::distance_to( + static_cast<const Derived&>(y),static_cast<const Derived&>(x)); +} + +template<> +struct iter_adaptor_selector<std::random_access_iterator_tag> +{ + template<class Derived,class Base> + struct apply + { + typedef random_access_iter_adaptor_base<Derived,Base> type; + }; +}; + +template<class Derived,class Base> +struct iter_adaptor_base +{ + typedef iter_adaptor_selector< + typename Base::iterator_category> selector; + typedef typename prevent_eti< + selector, + typename mpl::apply2< + selector,Derived,Base>::type + >::type type; +}; + +template<class Derived,class Base> +class iter_adaptor:public iter_adaptor_base<Derived,Base>::type +{ +protected: + iter_adaptor(){} + explicit iter_adaptor(const Base& b_):b(b_){} + + const Base& base_reference()const{return b;} + Base& base_reference(){return b;} + +private: + Base b; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/modify_key_adaptor.hpp b/3rdParty/Boost/src/boost/multi_index/detail/modify_key_adaptor.hpp new file mode 100644 index 0000000..8a93b96 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/modify_key_adaptor.hpp @@ -0,0 +1,49 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Functional adaptor to resolve modify_key as a call to modify. + * Preferred over compose_f_gx and stuff cause it eliminates problems + * with references to references, dealing with function pointers, etc. + */ + +template<typename Fun,typename Value,typename KeyFromValue> +struct modify_key_adaptor +{ + + modify_key_adaptor(Fun f_,KeyFromValue kfv_):f(f_),kfv(kfv_){} + + void operator()(Value& x) + { + f(kfv(x)); + } + +private: + Fun f; + KeyFromValue kfv; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/msvc_index_specifier.hpp b/3rdParty/Boost/src/boost/multi_index/detail/msvc_index_specifier.hpp new file mode 100644 index 0000000..4766e53 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/msvc_index_specifier.hpp @@ -0,0 +1,69 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_MSVC_INDEX_SPECIFIER_HPP +#define BOOST_MULTI_INDEX_DETAIL_MSVC_INDEX_SPECIFIER_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(BOOST_MSVC,<1310) +/* Workaround for a problem in MSVC with dependent template typedefs + * when accesing index specifiers. + * Modeled after <boost/mpl/aux_/msvc_dtw.hpp> (thanks, Aleksey!) + */ + +#include <boost/mpl/aux_/msvc_never_true.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template<typename IndexSpecifier> +struct msvc_index_specifier +{ + template<bool> struct fake_index_type:IndexSpecifier{}; + template<> struct fake_index_type<true> + { + template<typename Super> + struct node_class{}; + + template<typename Super> + struct index_class{}; + }; + + template<typename Super> + struct result_node_class: + fake_index_type<mpl::aux::msvc_never_true<IndexSpecifier>::value>:: + template node_class<Super> + { + }; + + template<typename Super> + struct result_index_class: + fake_index_type<mpl::aux::msvc_never_true<IndexSpecifier>::value>:: + template index_class<Super> + { + }; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif /* workaround */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/no_duplicate_tags.hpp b/3rdParty/Boost/src/boost/multi_index/detail/no_duplicate_tags.hpp new file mode 100644 index 0000000..9b56e83 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/no_duplicate_tags.hpp @@ -0,0 +1,97 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP +#define BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/mpl/fold.hpp> +#include <boost/mpl/set/set0.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* no_duplicate_tags check at compile-time that a tag list + * has no duplicate tags. + * The algorithm deserves some explanation: tags + * are sequentially inserted into a mpl::set if they were + * not already present. Due to the magic of mpl::set + * (mpl::has_key is contant time), this operation takes linear + * time, and even MSVC++ 6.5 handles it gracefully (other obvious + * solutions are quadratic.) + */ + +struct duplicate_tag_mark{}; + +struct duplicate_tag_marker +{ + template <typename MplSet,typename Tag> + struct apply + { + typedef mpl::s_item< + typename mpl::if_<mpl::has_key<MplSet,Tag>,duplicate_tag_mark,Tag>::type, + MplSet + > type; + }; +}; + +template<typename TagList> +struct no_duplicate_tags +{ + typedef typename mpl::fold< + TagList, + mpl::set0<>, + duplicate_tag_marker + >::type aux; + + BOOST_STATIC_CONSTANT( + bool,value=!(mpl::has_key<aux,duplicate_tag_mark>::value)); +}; + +/* Variant for an index list: duplication is checked + * across all the indices. + */ + +struct duplicate_tag_list_marker +{ + template <typename MplSet,typename Index> + struct apply:mpl::fold< + BOOST_DEDUCED_TYPENAME Index::tag_list, + MplSet, + duplicate_tag_marker> + { + }; +}; + +template<typename IndexList> +struct no_duplicate_tags_in_index_list +{ + typedef typename mpl::fold< + IndexList, + mpl::set0<>, + duplicate_tag_list_marker + >::type aux; + + BOOST_STATIC_CONSTANT( + bool,value=!(mpl::has_key<aux,duplicate_tag_mark>::value)); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/node_type.hpp b/3rdParty/Boost/src/boost/multi_index/detail/node_type.hpp new file mode 100644 index 0000000..0e87261 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/node_type.hpp @@ -0,0 +1,79 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP +#define BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/detail/workaround.hpp> +#include <boost/mpl/bind.hpp> +#include <boost/mpl/reverse_iter_fold.hpp> +#include <boost/mpl/deref.hpp> +#include <boost/multi_index_container_fwd.hpp> +#include <boost/multi_index/detail/header_holder.hpp> +#include <boost/multi_index/detail/index_node_base.hpp> +#include <boost/multi_index/detail/is_index_list.hpp> +#include <boost/multi_index/detail/msvc_index_specifier.hpp> +#include <boost/static_assert.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* MPL machinery to construct the internal node type associated to an + * index list. + */ + +#if BOOST_WORKAROUND(BOOST_MSVC,<1310) +struct index_node_applier +{ + template<typename IndexSpecifierIterator,typename Super> + struct apply: + msvc_index_specifier< mpl::deref<IndexSpecifierIterator>::type >:: + template result_node_class<Super> + { + }; +}; +#else +struct index_node_applier +{ + template<typename IndexSpecifierIterator,typename Super> + struct apply + { + typedef typename mpl::deref<IndexSpecifierIterator>::type index_specifier; + typedef typename index_specifier:: + BOOST_NESTED_TEMPLATE node_class<Super>::type type; + }; +}; +#endif + +template<typename Value,typename IndexSpecifierList,typename Allocator> +struct multi_index_node_type +{ + BOOST_STATIC_ASSERT(detail::is_index_list<IndexSpecifierList>::value); + + typedef typename mpl::reverse_iter_fold< + IndexSpecifierList, + index_node_base<Value,Allocator>, + mpl::bind2<index_node_applier,mpl::_2,mpl::_1> + >::type type; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/ord_index_args.hpp b/3rdParty/Boost/src/boost/multi_index/detail/ord_index_args.hpp new file mode 100644 index 0000000..bb8eb41 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/ord_index_args.hpp @@ -0,0 +1,83 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/mpl/aux_/na.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/if.hpp> +#include <boost/multi_index/tag.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <functional> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Oredered index specifiers can be instantiated in two forms: + * + * (ordered_unique|ordered_non_unique)< + * KeyFromValue,Compare=std::less<KeyFromValue::result_type> > + * (ordered_unique|ordered_non_unique)< + * TagList,KeyFromValue,Compare=std::less<KeyFromValue::result_type> > + * + * index_args implements the machinery to accept this argument-dependent + * polymorphism. + */ + +template<typename KeyFromValue> +struct index_args_default_compare +{ + typedef std::less<typename KeyFromValue::result_type> type; +}; + +template<typename Arg1,typename Arg2,typename Arg3> +struct ordered_index_args +{ + typedef is_tag<Arg1> full_form; + + typedef typename mpl::if_< + full_form, + Arg1, + tag< > >::type tag_list_type; + typedef typename mpl::if_< + full_form, + Arg2, + Arg1>::type key_from_value_type; + typedef typename mpl::if_< + full_form, + Arg3, + Arg2>::type supplied_compare_type; + typedef typename mpl::eval_if< + mpl::is_na<supplied_compare_type>, + index_args_default_compare<key_from_value_type>, + mpl::identity<supplied_compare_type> + >::type compare_type; + + BOOST_STATIC_ASSERT(is_tag<tag_list_type>::value); + BOOST_STATIC_ASSERT(!mpl::is_na<key_from_value_type>::value); + BOOST_STATIC_ASSERT(!mpl::is_na<compare_type>::value); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/ord_index_node.hpp b/3rdParty/Boost/src/boost/multi_index/detail/ord_index_node.hpp new file mode 100644 index 0000000..edc4329 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/ord_index_node.hpp @@ -0,0 +1,650 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + * + * The internal implementation of red-black trees is based on that of SGI STL + * stl_tree.h file: + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <cstddef> +#include <boost/detail/allocator_utilities.hpp> +#include <boost/multi_index/detail/prevent_eti.hpp> + +#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) +#include <boost/mpl/and.hpp> +#include <boost/mpl/if.hpp> +#include <boost/multi_index/detail/uintptr_type.hpp> +#include <boost/type_traits/alignment_of.hpp> +#include <boost/type_traits/is_same.hpp> +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* definition of red-black nodes for ordered_index */ + +enum ordered_index_color{red=false,black=true}; +enum ordered_index_side{to_left=false,to_right=true}; + +template<typename Allocator> +struct ordered_index_node_impl; /* fwd decl. */ + +template<typename Allocator> +struct ordered_index_node_std_base +{ + typedef typename prevent_eti< + Allocator, + typename boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl<Allocator> + >::type + >::type::pointer pointer; + typedef typename prevent_eti< + Allocator, + typename boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl<Allocator> + >::type + >::type::const_pointer const_pointer; + typedef ordered_index_color& color_ref; + typedef pointer& parent_ref; + + ordered_index_color& color(){return color_;} + ordered_index_color color()const{return color_;} + pointer& parent(){return parent_;} + pointer parent()const{return parent_;} + pointer& left(){return left_;} + pointer left()const{return left_;} + pointer& right(){return right_;} + pointer right()const{return right_;} + +private: + ordered_index_color color_; + pointer parent_; + pointer left_; + pointer right_; +}; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) +/* If ordered_index_node_impl has even alignment, we can use the least + * significant bit of one of the ordered_index_node_impl pointers to + * store color information. This typically reduces the size of + * ordered_index_node_impl by 25%. + */ + +#if defined(BOOST_MSVC) +/* This code casts pointers to an integer type that has been computed + * to be large enough to hold the pointer, however the metaprogramming + * logic is not always spotted by the VC++ code analyser that issues a + * long list of warnings. + */ + +#pragma warning(push) +#pragma warning(disable:4312 4311) +#endif + +template<typename Allocator> +struct ordered_index_node_compressed_base +{ + typedef ordered_index_node_impl<Allocator>* pointer; + typedef const ordered_index_node_impl<Allocator>* const_pointer; + + struct color_ref + { + color_ref(uintptr_type* r_):r(r_){} + + operator ordered_index_color()const + { + return ordered_index_color(*r&uintptr_type(1)); + } + + color_ref& operator=(ordered_index_color c) + { + *r&=~uintptr_type(1); + *r|=uintptr_type(c); + return *this; + } + + color_ref& operator=(const color_ref& x) + { + return operator=(x.operator ordered_index_color()); + } + + private: + uintptr_type* r; + }; + + struct parent_ref + { + parent_ref(uintptr_type* r_):r(r_){} + + operator pointer()const + { + return (pointer)(void*)(*r&~uintptr_type(1)); + } + + parent_ref& operator=(pointer p) + { + *r=((uintptr_type)(void*)p)|(*r&uintptr_type(1)); + return *this; + } + + parent_ref& operator=(const parent_ref& x) + { + return operator=(x.operator pointer()); + } + + pointer operator->()const + { + return operator pointer(); + } + + private: + uintptr_type* r; + }; + + color_ref color(){return color_ref(&parentcolor_);} + ordered_index_color color()const + { + return ordered_index_color(parentcolor_&std::size_t(1ul)); + } + + parent_ref parent(){return parent_ref(&parentcolor_);} + pointer parent()const + { + return (pointer)(void*)(parentcolor_&~uintptr_type(1)); + } + + pointer& left(){return left_;} + pointer left()const{return left_;} + pointer& right(){return right_;} + pointer right()const{return right_;} + +private: + uintptr_type parentcolor_; + pointer left_; + pointer right_; +}; +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif +#endif + +template<typename Allocator> +struct ordered_index_node_impl_base: + +#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) + mpl::if_c< + !(has_uintptr_type::value)|| + (alignment_of<ordered_index_node_compressed_base<Allocator> >::value%2)|| + !(is_same< + typename prevent_eti< + Allocator, + typename boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl<Allocator> + >::type + >::type::pointer, + ordered_index_node_impl<Allocator>*>::value), + ordered_index_node_std_base<Allocator>, + ordered_index_node_compressed_base<Allocator> + >::type +#else + ordered_index_node_std_base<Allocator> +#endif + +{}; + +template<typename Allocator> +struct ordered_index_node_impl:ordered_index_node_impl_base<Allocator> +{ +private: + typedef ordered_index_node_impl_base<Allocator> super; + +public: + typedef typename super::color_ref color_ref; + typedef typename super::parent_ref parent_ref; + typedef typename super::pointer pointer; + typedef typename super::const_pointer const_pointer; + + /* interoperability with bidir_node_iterator */ + + static void increment(pointer& x) + { + if(x->right()!=pointer(0)){ + x=x->right(); + while(x->left()!=pointer(0))x=x->left(); + } + else{ + pointer y=x->parent(); + while(x==y->right()){ + x=y; + y=y->parent(); + } + if(x->right()!=y)x=y; + } + } + + static void decrement(pointer& x) + { + if(x->color()==red&&x->parent()->parent()==x){ + x=x->right(); + } + else if(x->left()!=pointer(0)){ + pointer y=x->left(); + while(y->right()!=pointer(0))y=y->right(); + x=y; + }else{ + pointer y=x->parent(); + while(x==y->left()){ + x=y; + y=y->parent(); + } + x=y; + } + } + + /* algorithmic stuff */ + + static void rotate_left(pointer x,parent_ref root) + { + pointer y=x->right(); + x->right()=y->left(); + if(y->left()!=pointer(0))y->left()->parent()=x; + y->parent()=x->parent(); + + if(x==root) root=y; + else if(x==x->parent()->left())x->parent()->left()=y; + else x->parent()->right()=y; + y->left()=x; + x->parent()=y; + } + + static pointer minimum(pointer x) + { + while(x->left()!=pointer(0))x=x->left(); + return x; + } + + static pointer maximum(pointer x) + { + while(x->right()!=pointer(0))x=x->right(); + return x; + } + + static void rotate_right(pointer x,parent_ref root) + { + pointer y=x->left(); + x->left()=y->right(); + if(y->right()!=pointer(0))y->right()->parent()=x; + y->parent()=x->parent(); + + if(x==root) root=y; + else if(x==x->parent()->right())x->parent()->right()=y; + else x->parent()->left()=y; + y->right()=x; + x->parent()=y; + } + + static void rebalance(pointer x,parent_ref root) + { + x->color()=red; + while(x!=root&&x->parent()->color()==red){ + if(x->parent()==x->parent()->parent()->left()){ + pointer y=x->parent()->parent()->right(); + if(y!=pointer(0)&&y->color()==red){ + x->parent()->color()=black; + y->color()=black; + x->parent()->parent()->color()=red; + x=x->parent()->parent(); + } + else{ + if(x==x->parent()->right()){ + x=x->parent(); + rotate_left(x,root); + } + x->parent()->color()=black; + x->parent()->parent()->color()=red; + rotate_right(x->parent()->parent(),root); + } + } + else{ + pointer y=x->parent()->parent()->left(); + if(y!=pointer(0)&&y->color()==red){ + x->parent()->color()=black; + y->color()=black; + x->parent()->parent()->color()=red; + x=x->parent()->parent(); + } + else{ + if(x==x->parent()->left()){ + x=x->parent(); + rotate_right(x,root); + } + x->parent()->color()=black; + x->parent()->parent()->color()=red; + rotate_left(x->parent()->parent(),root); + } + } + } + root->color()=black; + } + + static void link( + pointer x,ordered_index_side side,pointer position,pointer header) + { + if(side==to_left){ + position->left()=x; /* also makes leftmost=x when parent==header */ + if(position==header){ + header->parent()=x; + header->right()=x; + } + else if(position==header->left()){ + header->left()=x; /* maintain leftmost pointing to min node */ + } + } + else{ + position->right()=x; + if(position==header->right()){ + header->right()=x; /* maintain rightmost pointing to max node */ + } + } + x->parent()=position; + x->left()=pointer(0); + x->right()=pointer(0); + ordered_index_node_impl::rebalance(x,header->parent()); + } + + static pointer rebalance_for_erase( + pointer z,parent_ref root,pointer& leftmost,pointer& rightmost) + { + pointer y=z; + pointer x=pointer(0); + pointer x_parent=pointer(0); + if(y->left()==pointer(0)){ /* z has at most one non-null child. y==z. */ + x=y->right(); /* x might be null */ + } + else{ + if(y->right()==pointer(0)){ /* z has exactly one non-null child. y==z. */ + x=y->left(); /* x is not null */ + } + else{ /* z has two non-null children. Set y to */ + y=y->right(); /* z's successor. x might be null. */ + while(y->left()!=pointer(0))y=y->left(); + x=y->right(); + } + } + if(y!=z){ + z->left()->parent()=y; /* relink y in place of z. y is z's successor */ + y->left()=z->left(); + if(y!=z->right()){ + x_parent=y->parent(); + if(x!=pointer(0))x->parent()=y->parent(); + y->parent()->left()=x; /* y must be a child of left */ + y->right()=z->right(); + z->right()->parent()=y; + } + else{ + x_parent=y; + } + + if(root==z) root=y; + else if(z->parent()->left()==z)z->parent()->left()=y; + else z->parent()->right()=y; + y->parent()=z->parent(); + ordered_index_color c=y->color(); + y->color()=z->color(); + z->color()=c; + y=z; /* y now points to node to be actually deleted */ + } + else{ /* y==z */ + x_parent=y->parent(); + if(x!=pointer(0))x->parent()=y->parent(); + if(root==z){ + root=x; + } + else{ + if(z->parent()->left()==z)z->parent()->left()=x; + else z->parent()->right()=x; + } + if(leftmost==z){ + if(z->right()==pointer(0)){ /* z->left() must be null also */ + leftmost=z->parent(); + } + else{ + leftmost=minimum(x); /* makes leftmost==header if z==root */ + } + } + if(rightmost==z){ + if(z->left()==pointer(0)){ /* z->right() must be null also */ + rightmost=z->parent(); + } + else{ /* x==z->left() */ + rightmost=maximum(x); /* makes rightmost==header if z==root */ + } + } + } + if(y->color()!=red){ + while(x!=root&&(x==pointer(0)|| x->color()==black)){ + if(x==x_parent->left()){ + pointer w=x_parent->right(); + if(w->color()==red){ + w->color()=black; + x_parent->color()=red; + rotate_left(x_parent,root); + w=x_parent->right(); + } + if((w->left()==pointer(0)||w->left()->color()==black) && + (w->right()==pointer(0)||w->right()->color()==black)){ + w->color()=red; + x=x_parent; + x_parent=x_parent->parent(); + } + else{ + if(w->right()==pointer(0 ) + || w->right()->color()==black){ + if(w->left()!=pointer(0)) w->left()->color()=black; + w->color()=red; + rotate_right(w,root); + w=x_parent->right(); + } + w->color()=x_parent->color(); + x_parent->color()=black; + if(w->right()!=pointer(0))w->right()->color()=black; + rotate_left(x_parent,root); + break; + } + } + else{ /* same as above,with right <-> left */ + pointer w=x_parent->left(); + if(w->color()==red){ + w->color()=black; + x_parent->color()=red; + rotate_right(x_parent,root); + w=x_parent->left(); + } + if((w->right()==pointer(0)||w->right()->color()==black) && + (w->left()==pointer(0)||w->left()->color()==black)){ + w->color()=red; + x=x_parent; + x_parent=x_parent->parent(); + } + else{ + if(w->left()==pointer(0)||w->left()->color()==black){ + if(w->right()!=pointer(0))w->right()->color()=black; + w->color()=red; + rotate_left(w,root); + w=x_parent->left(); + } + w->color()=x_parent->color(); + x_parent->color()=black; + if(w->left()!=pointer(0))w->left()->color()=black; + rotate_right(x_parent,root); + break; + } + } + } + if(x!=pointer(0))x->color()=black; + } + return y; + } + + static void restore(pointer x,pointer position,pointer header) + { + if(position->left()==pointer(0)||position->left()==header){ + link(x,to_left,position,header); + } + else{ + decrement(position); + link(x,to_right,position,header); + } + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + static std::size_t black_count(pointer node,pointer root) + { + if(node==pointer(0))return 0; + std::size_t sum=0; + for(;;){ + if(node->color()==black)++sum; + if(node==root)break; + node=node->parent(); + } + return sum; + } +#endif +}; + +template<typename Super> +struct ordered_index_node_trampoline: + prevent_eti< + Super, + ordered_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > + >::type +{ + typedef typename prevent_eti< + Super, + ordered_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > + >::type impl_type; +}; + +template<typename Super> +struct ordered_index_node:Super,ordered_index_node_trampoline<Super> +{ +private: + typedef ordered_index_node_trampoline<Super> trampoline; + +public: + typedef typename trampoline::impl_type impl_type; + typedef typename trampoline::color_ref impl_color_ref; + typedef typename trampoline::parent_ref impl_parent_ref; + typedef typename trampoline::pointer impl_pointer; + typedef typename trampoline::const_pointer const_impl_pointer; + + impl_color_ref color(){return trampoline::color();} + ordered_index_color color()const{return trampoline::color();} + impl_parent_ref parent(){return trampoline::parent();} + impl_pointer parent()const{return trampoline::parent();} + impl_pointer& left(){return trampoline::left();} + impl_pointer left()const{return trampoline::left();} + impl_pointer& right(){return trampoline::right();} + impl_pointer right()const{return trampoline::right();} + + impl_pointer impl() + { + return static_cast<impl_pointer>( + static_cast<impl_type*>(static_cast<trampoline*>(this))); + } + + const_impl_pointer impl()const + { + return static_cast<const_impl_pointer>( + static_cast<const impl_type*>(static_cast<const trampoline*>(this))); + } + + static ordered_index_node* from_impl(impl_pointer x) + { + return static_cast<ordered_index_node*>( + static_cast<trampoline*>(&*x)); + } + + static const ordered_index_node* from_impl(const_impl_pointer x) + { + return static_cast<const ordered_index_node*>( + static_cast<const trampoline*>(&*x)); + } + + /* interoperability with bidir_node_iterator */ + + static void increment(ordered_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::increment(xi); + x=from_impl(xi); + } + + static void decrement(ordered_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::decrement(xi); + x=from_impl(xi); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/ord_index_ops.hpp b/3rdParty/Boost/src/boost/multi_index/detail/ord_index_ops.hpp new file mode 100644 index 0000000..caa71aa --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/ord_index_ops.hpp @@ -0,0 +1,147 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + * + * The internal implementation of red-black trees is based on that of SGI STL + * stl_tree.h file: + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <utility> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for index memfuns having templatized and + * non-templatized versions. + */ + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_find( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + Node* y0=y; + + while (top){ + if(!comp(key(top->value()),x)){ + y=top; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + } + + return (y==y0||comp(x,key(y->value())))?y0:y; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_lower_bound( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + while(top){ + if(!comp(key(top->value()),x)){ + y=top; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + } + + return y; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_upper_bound( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + while(top){ + if(comp(x,key(top->value()))){ + y=top; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + } + + return y; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::pair<Node*,Node*> ordered_index_equal_range( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + while(top){ + if(comp(key(top->value()),x)){ + top=Node::from_impl(top->right()); + } + else if(comp(x,key(top->value()))){ + y=top; + top=Node::from_impl(top->left()); + } + else{ + return std::pair<Node*,Node*>( + ordered_index_lower_bound(Node::from_impl(top->left()),top,key,x,comp), + ordered_index_upper_bound(Node::from_impl(top->right()),y,key,x,comp)); + } + } + + return std::pair<Node*,Node*>(y,y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/prevent_eti.hpp b/3rdParty/Boost/src/boost/multi_index/detail/prevent_eti.hpp new file mode 100644 index 0000000..56c067a --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/prevent_eti.hpp @@ -0,0 +1,60 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_PREVENT_ETI_HPP +#define BOOST_MULTI_INDEX_DETAIL_PREVENT_ETI_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) +#include <boost/mpl/if.hpp> +#include <boost/mpl/integral_c.hpp> +#include <boost/mpl/aux_/msvc_never_true.hpp> +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) +/* See + * http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Effective_MPL + * Item 5.6, Beware of the 'early template instantiation' trap. + */ + +template<typename Type,typename Construct> +struct prevent_eti +{ + typedef typename mpl::if_< + mpl::aux::msvc_never_true<Type>, + mpl::integral_c<int,0>, + Construct + >::type type; +}; +#else +template<typename Type,typename Construct> +struct prevent_eti +{ + typedef Construct type; +}; +#endif + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/safe_ctr_proxy.hpp b/3rdParty/Boost/src/boost/multi_index/detail/safe_ctr_proxy.hpp new file mode 100644 index 0000000..c733f96 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/safe_ctr_proxy.hpp @@ -0,0 +1,105 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SAFE_CTR_PROXY_HPP +#define BOOST_MULTI_INDEX_DETAIL_SAFE_CTR_PROXY_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) +#include <boost/multi_index/detail/safe_mode.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* A safe iterator is instantiated in the form + * safe_iterator<Iterator,Container>: MSVC++ 6.0 has serious troubles with + * the resulting symbols names, given that index names (which stand for + * Container) are fairly long themselves. safe_ctr_proxy does not statically + * depend on Container, and provides the necessary methods (begin and end) to + * the safe mode framework via an abstract interface. With safe_ctr_proxy, + * instead of deriving from safe_container<Container> the following base class + * must be used: + * + * safe_ctr_proxy_impl<Iterator,Container> + * + * where Iterator is the type of the *unsafe* iterator being wrapped. + * The corresponding safe iterator instantiation is then + * + * safe_iterator<Iterator,safe_ctr_proxy<Iterator> >, + * + * which does not include the name of Container. + */ + +template<typename Iterator> +class safe_ctr_proxy: + public safe_mode::safe_container<safe_ctr_proxy<Iterator> > +{ +public: + typedef safe_mode::safe_iterator<Iterator,safe_ctr_proxy> iterator; + typedef iterator const_iterator; + + iterator begin(){return begin_impl();} + const_iterator begin()const{return begin_impl();} + iterator end(){return end_impl();} + const_iterator end()const{return end_impl();} + +protected: + virtual iterator begin_impl()=0; + virtual const_iterator begin_impl()const=0; + virtual iterator end_impl()=0; + virtual const_iterator end_impl()const=0; +}; + +template<typename Iterator,typename Container> +class safe_ctr_proxy_impl:public safe_ctr_proxy<Iterator> +{ + typedef safe_ctr_proxy<Iterator> super; + typedef Container container_type; + +public: + typedef typename super::iterator iterator; + typedef typename super::const_iterator const_iterator; + + virtual iterator begin_impl(){return container().begin();} + virtual const_iterator begin_impl()const{return container().begin();} + virtual iterator end_impl(){return container().end();} + virtual const_iterator end_impl()const{return container().end();} + +private: + container_type& container() + { + return *static_cast<container_type*>(this); + } + + const container_type& container()const + { + return *static_cast<const container_type*>(this); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif /* workaround */ + +#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/safe_mode.hpp b/3rdParty/Boost/src/boost/multi_index/detail/safe_mode.hpp new file mode 100644 index 0000000..dbfebd8 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/safe_mode.hpp @@ -0,0 +1,574 @@ +/* Copyright 2003-2009 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +/* Safe mode machinery, in the spirit of Cay Hortmann's "Safe STL" + * (http://www.horstmann.com/safestl.html). + * In this mode, containers of type Container are derived from + * safe_container<Container>, and their corresponding iterators + * are wrapped with safe_iterator. These classes provide + * an internal record of which iterators are at a given moment associated + * to a given container, and properly mark the iterators as invalid + * when the container gets destroyed. + * Iterators are chained in a single attached list, whose header is + * kept by the container. More elaborate data structures would yield better + * performance, but I decided to keep complexity to a minimum since + * speed is not an issue here. + * Safe mode iterators automatically check that only proper operations + * are performed on them: for instance, an invalid iterator cannot be + * dereferenced. Additionally, a set of utilty macros and functions are + * provided that serve to implement preconditions and cooperate with + * the framework within the container. + * Iterators can also be unchecked, i.e. they do not have info about + * which container they belong in. This situation arises when the iterator + * is restored from a serialization archive: only information on the node + * is available, and it is not possible to determine to which container + * the iterator is associated to. The only sensible policy is to assume + * unchecked iterators are valid, though this can certainly generate false + * positive safe mode checks. + * This is not a full-fledged safe mode framework, and is only intended + * for use within the limits of Boost.MultiIndex. + */ + +/* Assertion macros. These resolve to no-ops if + * !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE). + */ + +#if !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#undef BOOST_MULTI_INDEX_SAFE_MODE_ASSERT +#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) ((void)0) +#else +#if !defined(BOOST_MULTI_INDEX_SAFE_MODE_ASSERT) +#include <boost/assert.hpp> +#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) BOOST_ASSERT(expr) +#endif +#endif + +#define BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_valid_iterator(it), \ + safe_mode::invalid_iterator); + +#define BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(it) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_dereferenceable_iterator(it), \ + safe_mode::not_dereferenceable_iterator); + +#define BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(it) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_incrementable_iterator(it), \ + safe_mode::not_incrementable_iterator); + +#define BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(it) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_decrementable_iterator(it), \ + safe_mode::not_decrementable_iterator); + +#define BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,cont) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_is_owner(it,cont), \ + safe_mode::not_owner); + +#define BOOST_MULTI_INDEX_CHECK_SAME_OWNER(it0,it1) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_same_owner(it0,it1), \ + safe_mode::not_same_owner); + +#define BOOST_MULTI_INDEX_CHECK_VALID_RANGE(it0,it1) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_valid_range(it0,it1), \ + safe_mode::invalid_range); + +#define BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(it,it0,it1) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_outside_range(it,it0,it1), \ + safe_mode::inside_range); + +#define BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(it,n) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_in_bounds(it,n), \ + safe_mode::out_of_bounds); + +#define BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(cont0,cont1) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_different_container(cont0,cont1), \ + safe_mode::same_container); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> +#include <boost/detail/iterator.hpp> +#include <boost/multi_index/detail/access_specifier.hpp> +#include <boost/multi_index/detail/iter_adaptor.hpp> +#include <boost/multi_index/safe_mode_errors.hpp> +#include <boost/noncopyable.hpp> + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include <boost/serialization/split_member.hpp> +#endif + +#if defined(BOOST_HAS_THREADS) +#include <boost/detail/lightweight_mutex.hpp> +#endif + +namespace boost{ + +namespace multi_index{ + +namespace safe_mode{ + +/* Checking routines. Assume the best for unchecked iterators + * (i.e. they pass the checking when there is not enough info + * to know.) + */ + +template<typename Iterator> +inline bool check_valid_iterator(const Iterator& it) +{ + return it.valid()||it.unchecked(); +} + +template<typename Iterator> +inline bool check_dereferenceable_iterator(const Iterator& it) +{ + return it.valid()&&it!=it.owner()->end()||it.unchecked(); +} + +template<typename Iterator> +inline bool check_incrementable_iterator(const Iterator& it) +{ + return it.valid()&&it!=it.owner()->end()||it.unchecked(); +} + +template<typename Iterator> +inline bool check_decrementable_iterator(const Iterator& it) +{ + return it.valid()&&it!=it.owner()->begin()||it.unchecked(); +} + +template<typename Iterator> +inline bool check_is_owner( + const Iterator& it,const typename Iterator::container_type& cont) +{ + return it.valid()&&it.owner()==&cont||it.unchecked(); +} + +template<typename Iterator> +inline bool check_same_owner(const Iterator& it0,const Iterator& it1) +{ + return it0.valid()&&it1.valid()&&it0.owner()==it1.owner()|| + it0.unchecked()||it1.unchecked(); +} + +template<typename Iterator> +inline bool check_valid_range(const Iterator& it0,const Iterator& it1) +{ + if(!check_same_owner(it0,it1))return false; + + if(it0.valid()){ + Iterator last=it0.owner()->end(); + if(it1==last)return true; + + for(Iterator first=it0;first!=last;++first){ + if(first==it1)return true; + } + return false; + } + return true; +} + +template<typename Iterator> +inline bool check_outside_range( + const Iterator& it,const Iterator& it0,const Iterator& it1) +{ + if(!check_same_owner(it0,it1))return false; + + if(it0.valid()){ + Iterator last=it0.owner()->end(); + bool found=false; + + Iterator first=it0; + for(;first!=last;++first){ + if(first==it1)break; + + /* crucial that this check goes after previous break */ + + if(first==it)found=true; + } + if(first!=it1)return false; + return !found; + } + return true; +} + +template<typename Iterator,typename Difference> +inline bool check_in_bounds(const Iterator& it,Difference n) +{ + if(it.unchecked())return true; + if(!it.valid()) return false; + if(n>0) return it.owner()->end()-it>=n; + else return it.owner()->begin()-it<=n; +} + +template<typename Container> +inline bool check_different_container( + const Container& cont0,const Container& cont1) +{ + return &cont0!=&cont1; +} + +/* Invalidates all iterators equivalent to that given. Safe containers + * must call this when deleting elements: the safe mode framework cannot + * perform this operation automatically without outside help. + */ + +template<typename Iterator> +inline void detach_equivalent_iterators(Iterator& it) +{ + if(it.valid()){ + { +#if defined(BOOST_HAS_THREADS) + boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex); +#endif + + Iterator *prev_,*next_; + for( + prev_=static_cast<Iterator*>(&it.cont->header); + (next_=static_cast<Iterator*>(prev_->next))!=0;){ + if(next_!=&it&&*next_==it){ + prev_->next=next_->next; + next_->cont=0; + } + else prev_=next_; + } + } + it.detach(); + } +} + +template<typename Container> class safe_container; /* fwd decl. */ + +} /* namespace multi_index::safe_mode */ + +namespace detail{ + +class safe_container_base; /* fwd decl. */ + +class safe_iterator_base +{ +public: + bool valid()const{return cont!=0;} + bool unchecked()const{return unchecked_;} + + inline void detach(); + + void uncheck() + { + detach(); + unchecked_=true; + } + +protected: + safe_iterator_base():cont(0),next(0),unchecked_(false){} + + explicit safe_iterator_base(safe_container_base* cont_): + unchecked_(false) + { + attach(cont_); + } + + safe_iterator_base(const safe_iterator_base& it): + unchecked_(it.unchecked_) + { + attach(it.cont); + } + + safe_iterator_base& operator=(const safe_iterator_base& it) + { + unchecked_=it.unchecked_; + safe_container_base* new_cont=it.cont; + if(cont!=new_cont){ + detach(); + attach(new_cont); + } + return *this; + } + + ~safe_iterator_base() + { + detach(); + } + + const safe_container_base* owner()const{return cont;} + +BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS: + friend class safe_container_base; + +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template<typename> friend class safe_mode::safe_container; + template<typename Iterator> friend + void safe_mode::detach_equivalent_iterators(Iterator&); +#endif + + inline void attach(safe_container_base* cont_); + + safe_container_base* cont; + safe_iterator_base* next; + bool unchecked_; +}; + +class safe_container_base:private noncopyable +{ +public: + safe_container_base(){} + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + friend class safe_iterator_base; + +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template<typename Iterator> friend + void safe_mode::detach_equivalent_iterators(Iterator&); +#endif + + ~safe_container_base() + { + /* Detaches all remaining iterators, which by now will + * be those pointing to the end of the container. + */ + + for(safe_iterator_base* it=header.next;it;it=it->next)it->cont=0; + header.next=0; + } + + void swap(safe_container_base& x) + { + for(safe_iterator_base* it0=header.next;it0;it0=it0->next)it0->cont=&x; + for(safe_iterator_base* it1=x.header.next;it1;it1=it1->next)it1->cont=this; + std::swap(header.cont,x.header.cont); + std::swap(header.next,x.header.next); + } + + safe_iterator_base header; + +#if defined(BOOST_HAS_THREADS) + boost::detail::lightweight_mutex mutex; +#endif +}; + +void safe_iterator_base::attach(safe_container_base* cont_) +{ + cont=cont_; + if(cont){ +#if defined(BOOST_HAS_THREADS) + boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); +#endif + + next=cont->header.next; + cont->header.next=this; + } +} + +void safe_iterator_base::detach() +{ + if(cont){ +#if defined(BOOST_HAS_THREADS) + boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); +#endif + + safe_iterator_base *prev_,*next_; + for(prev_=&cont->header;(next_=prev_->next)!=this;prev_=next_){} + prev_->next=next; + cont=0; + } +} + +} /* namespace multi_index::detail */ + +namespace safe_mode{ + +/* In order to enable safe mode on a container: + * - The container must derive from safe_container<container_type>, + * - iterators must be generated via safe_iterator, which adapts a + * preexistent unsafe iterator class. + */ + +template<typename Container> +class safe_container; + +template<typename Iterator,typename Container> +class safe_iterator: + public detail::iter_adaptor<safe_iterator<Iterator,Container>,Iterator>, + public detail::safe_iterator_base +{ + typedef detail::iter_adaptor<safe_iterator,Iterator> super; + typedef detail::safe_iterator_base safe_super; + +public: + typedef Container container_type; + typedef typename Iterator::reference reference; + typedef typename Iterator::difference_type difference_type; + + safe_iterator(){} + explicit safe_iterator(safe_container<container_type>* cont_): + safe_super(cont_){} + template<typename T0> + safe_iterator(const T0& t0,safe_container<container_type>* cont_): + super(Iterator(t0)),safe_super(cont_){} + template<typename T0,typename T1> + safe_iterator( + const T0& t0,const T1& t1,safe_container<container_type>* cont_): + super(Iterator(t0,t1)),safe_super(cont_){} + + safe_iterator& operator=(const safe_iterator& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); + this->base_reference()=x.base_reference(); + safe_super::operator=(x); + return *this; + } + + const container_type* owner()const + { + return + static_cast<const container_type*>( + static_cast<const safe_container<container_type>*>( + this->safe_super::owner())); + } + + /* get_node is not to be used by the user */ + + typedef typename Iterator::node_type node_type; + + node_type* get_node()const{return this->base_reference().get_node();} + +private: + friend class boost::multi_index::detail::iter_adaptor_access; + + reference dereference()const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this); + return *(this->base_reference()); + } + + bool equal(const safe_iterator& x)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); + BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); + return this->base_reference()==x.base_reference(); + } + + void increment() + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this); + ++(this->base_reference()); + } + + void decrement() + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(*this); + --(this->base_reference()); + } + + void advance(difference_type n) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(*this,n); + this->base_reference()+=n; + } + + difference_type distance_to(const safe_iterator& x)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); + BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); + return x.base_reference()-this->base_reference(); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* Serialization. Note that Iterator::save and Iterator:load + * are assumed to be defined and public: at first sight it seems + * like we could have resorted to the public serialization interface + * for doing the forwarding to the adapted iterator class: + * ar<<base_reference(); + * ar>>base_reference(); + * but this would cause incompatibilities if a saving + * program is in safe mode and the loading program is not, or + * viceversa --in safe mode, the archived iterator data is one layer + * deeper, this is especially relevant with XML archives. + * It'd be nice if Boost.Serialization provided some forwarding + * facility for use by adaptor classes. + */ + + friend class boost::serialization::access; + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + template<class Archive> + void save(Archive& ar,const unsigned int version)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + this->base_reference().save(ar,version); + } + + template<class Archive> + void load(Archive& ar,const unsigned int version) + { + this->base_reference().load(ar,version); + safe_super::uncheck(); + } +#endif +}; + +template<typename Container> +class safe_container:public detail::safe_container_base +{ + typedef detail::safe_container_base super; + +public: + void detach_dereferenceable_iterators() + { + typedef typename Container::iterator iterator; + + iterator end_=static_cast<Container*>(this)->end(); + iterator *prev_,*next_; + for( + prev_=static_cast<iterator*>(&this->header); + (next_=static_cast<iterator*>(prev_->next))!=0;){ + if(*next_!=end_){ + prev_->next=next_->next; + next_->cont=0; + } + else prev_=next_; + } + } + + void swap(safe_container<Container>& x) + { + super::swap(x); + } +}; + +} /* namespace multi_index::safe_mode */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/scope_guard.hpp b/3rdParty/Boost/src/boost/multi_index/detail/scope_guard.hpp new file mode 100644 index 0000000..12624c5 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/scope_guard.hpp @@ -0,0 +1,277 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP +#define BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Until some official version of the ScopeGuard idiom makes it into Boost, + * we locally define our own. This is a merely reformated version of + * ScopeGuard.h as defined in: + * Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You + * Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000, + * http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/ + * with the following modifications: + * - General pretty formatting (pretty to my taste at least.) + * - Naming style changed to standard C++ library requirements. + * - safe_execute does not feature a try-catch protection, so we can + * use this even if BOOST_NO_EXCEPTIONS is defined. + * - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex + * needs them). A better design would provide guards for many more + * arguments through the Boost Preprocessor Library. + * - Added scope_guard_impl_base::touch (see below.) + * - Removed RefHolder and ByRef, whose functionality is provided + * already by Boost.Ref. + * - Removed static make_guard's and make_obj_guard's, so that the code + * will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces + * us to move some private ctors to public, though. + * + * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute + * without an explicit qualification. + */ + +class scope_guard_impl_base +{ +public: + scope_guard_impl_base():dismissed_(false){} + void dismiss()const{dismissed_=true;} + + /* This helps prevent some "unused variable" warnings under, for instance, + * GCC 3.2. + */ + void touch()const{} + +protected: + ~scope_guard_impl_base(){} + + scope_guard_impl_base(const scope_guard_impl_base& other): + dismissed_(other.dismissed_) + { + other.dismiss(); + } + + template<typename J> + static void safe_execute(J& j){if(!j.dismissed_)j.execute();} + + mutable bool dismissed_; + +private: + scope_guard_impl_base& operator=(const scope_guard_impl_base&); +}; + +typedef const scope_guard_impl_base& scope_guard; + +template<typename F> +class scope_guard_impl0:public scope_guard_impl_base +{ +public: + scope_guard_impl0(F fun):fun_(fun){} + ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_();} + +protected: + + F fun_; +}; + +template<typename F> +inline scope_guard_impl0<F> make_guard(F fun) +{ + return scope_guard_impl0<F>(fun); +} + +template<typename F,typename P1> +class scope_guard_impl1:public scope_guard_impl_base +{ +public: + scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){} + ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_(p1_);} + +protected: + F fun_; + const P1 p1_; +}; + +template<typename F,typename P1> +inline scope_guard_impl1<F,P1> make_guard(F fun,P1 p1) +{ + return scope_guard_impl1<F,P1>(fun,p1); +} + +template<typename F,typename P1,typename P2> +class scope_guard_impl2:public scope_guard_impl_base +{ +public: + scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){} + ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_(p1_,p2_);} + +protected: + F fun_; + const P1 p1_; + const P2 p2_; +}; + +template<typename F,typename P1,typename P2> +inline scope_guard_impl2<F,P1,P2> make_guard(F fun,P1 p1,P2 p2) +{ + return scope_guard_impl2<F,P1,P2>(fun,p1,p2); +} + +template<typename F,typename P1,typename P2,typename P3> +class scope_guard_impl3:public scope_guard_impl_base +{ +public: + scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){} + ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_(p1_,p2_,p3_);} + +protected: + F fun_; + const P1 p1_; + const P2 p2_; + const P3 p3_; +}; + +template<typename F,typename P1,typename P2,typename P3> +inline scope_guard_impl3<F,P1,P2,P3> make_guard(F fun,P1 p1,P2 p2,P3 p3) +{ + return scope_guard_impl3<F,P1,P2,P3>(fun,p1,p2,p3); +} + +template<typename F,typename P1,typename P2,typename P3,typename P4> +class scope_guard_impl4:public scope_guard_impl_base +{ +public: + scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4): + fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){} + ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_(p1_,p2_,p3_,p4_);} + +protected: + F fun_; + const P1 p1_; + const P2 p2_; + const P3 p3_; + const P4 p4_; +}; + +template<typename F,typename P1,typename P2,typename P3,typename P4> +inline scope_guard_impl4<F,P1,P2,P3,P4> make_guard( + F fun,P1 p1,P2 p2,P3 p3,P4 p4) +{ + return scope_guard_impl4<F,P1,P2,P3,P4>(fun,p1,p2,p3,p4); +} + +template<class Obj,typename MemFun> +class obj_scope_guard_impl0:public scope_guard_impl_base +{ +public: + obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){} + ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} + void execute(){(obj_.*mem_fun_)();} + +protected: + Obj& obj_; + MemFun mem_fun_; +}; + +template<class Obj,typename MemFun> +inline obj_scope_guard_impl0<Obj,MemFun> make_obj_guard(Obj& obj,MemFun mem_fun) +{ + return obj_scope_guard_impl0<Obj,MemFun>(obj,mem_fun); +} + +template<class Obj,typename MemFun,typename P1> +class obj_scope_guard_impl1:public scope_guard_impl_base +{ +public: + obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1): + obj_(obj),mem_fun_(mem_fun),p1_(p1){} + ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} + void execute(){(obj_.*mem_fun_)(p1_);} + +protected: + Obj& obj_; + MemFun mem_fun_; + const P1 p1_; +}; + +template<class Obj,typename MemFun,typename P1> +inline obj_scope_guard_impl1<Obj,MemFun,P1> make_obj_guard( + Obj& obj,MemFun mem_fun,P1 p1) +{ + return obj_scope_guard_impl1<Obj,MemFun,P1>(obj,mem_fun,p1); +} + +template<class Obj,typename MemFun,typename P1,typename P2> +class obj_scope_guard_impl2:public scope_guard_impl_base +{ +public: + obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2): + obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2) + {} + ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} + void execute(){(obj_.*mem_fun_)(p1_,p2_);} + +protected: + Obj& obj_; + MemFun mem_fun_; + const P1 p1_; + const P2 p2_; +}; + +template<class Obj,typename MemFun,typename P1,typename P2> +inline obj_scope_guard_impl2<Obj,MemFun,P1,P2> +make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) +{ + return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2); +} + +template<class Obj,typename MemFun,typename P1,typename P2,typename P3> +class obj_scope_guard_impl3:public scope_guard_impl_base +{ +public: + obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3): + obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3) + {} + ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} + void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);} + +protected: + Obj& obj_; + MemFun mem_fun_; + const P1 p1_; + const P2 p2_; + const P3 p3_; +}; + +template<class Obj,typename MemFun,typename P1,typename P2,typename P3> +inline obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> +make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) +{ + return obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>(obj,mem_fun,p1,p2,p3); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/seq_index_node.hpp b/3rdParty/Boost/src/boost/multi_index/detail/seq_index_node.hpp new file mode 100644 index 0000000..cf409ed --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/seq_index_node.hpp @@ -0,0 +1,223 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> +#include <boost/detail/allocator_utilities.hpp> +#include <boost/multi_index/detail/prevent_eti.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* doubly-linked node for use by sequenced_index */ + +template<typename Allocator> +struct sequenced_index_node_impl +{ + typedef typename prevent_eti< + Allocator, + typename boost::detail::allocator::rebind_to< + Allocator,sequenced_index_node_impl + >::type + >::type::pointer pointer; + typedef typename prevent_eti< + Allocator, + typename boost::detail::allocator::rebind_to< + Allocator,sequenced_index_node_impl + >::type + >::type::const_pointer const_pointer; + + pointer& prior(){return prior_;} + pointer prior()const{return prior_;} + pointer& next(){return next_;} + pointer next()const{return next_;} + + /* interoperability with bidir_node_iterator */ + + static void increment(pointer& x){x=x->next();} + static void decrement(pointer& x){x=x->prior();} + + /* algorithmic stuff */ + + static void link(pointer x,pointer header) + { + x->prior()=header->prior(); + x->next()=header; + x->prior()->next()=x->next()->prior()=x; + }; + + static void unlink(pointer x) + { + x->prior()->next()=x->next(); + x->next()->prior()=x->prior(); + } + + static void relink(pointer position,pointer x) + { + unlink(x); + x->prior()=position->prior(); + x->next()=position; + x->prior()->next()=x->next()->prior()=x; + } + + static void relink(pointer position,pointer x,pointer y) + { + /* position is assumed not to be in [x,y) */ + + if(x!=y){ + pointer z=y->prior(); + x->prior()->next()=y; + y->prior()=x->prior(); + x->prior()=position->prior(); + z->next()=position; + x->prior()->next()=x; + z->next()->prior()=z; + } + } + + static void reverse(pointer header) + { + pointer x=header; + do{ + pointer y=x->next(); + std::swap(x->prior(),x->next()); + x=y; + }while(x!=header); + } + + static void swap(pointer x,pointer y) + { + /* This swap function does not exchange the header nodes, + * but rather their pointers. This is *not* used for implementing + * sequenced_index::swap. + */ + + if(x->next()!=x){ + if(y->next()!=y){ + std::swap(x->next(),y->next()); + std::swap(x->prior(),y->prior()); + x->next()->prior()=x->prior()->next()=x; + y->next()->prior()=y->prior()->next()=y; + } + else{ + y->next()=x->next(); + y->prior()=x->prior(); + x->next()=x->prior()=x; + y->next()->prior()=y->prior()->next()=y; + } + } + else if(y->next()!=y){ + x->next()=y->next(); + x->prior()=y->prior(); + y->next()=y->prior()=y; + x->next()->prior()=x->prior()->next()=x; + } + } + +private: + pointer prior_; + pointer next_; +}; + +template<typename Super> +struct sequenced_index_node_trampoline: + prevent_eti< + Super, + sequenced_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > + >::type +{ + typedef typename prevent_eti< + Super, + sequenced_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > + >::type impl_type; +}; + +template<typename Super> +struct sequenced_index_node:Super,sequenced_index_node_trampoline<Super> +{ +private: + typedef sequenced_index_node_trampoline<Super> trampoline; + +public: + typedef typename trampoline::impl_type impl_type; + typedef typename trampoline::pointer impl_pointer; + typedef typename trampoline::const_pointer const_impl_pointer; + + impl_pointer& prior(){return trampoline::prior();} + impl_pointer prior()const{return trampoline::prior();} + impl_pointer& next(){return trampoline::next();} + impl_pointer next()const{return trampoline::next();} + + impl_pointer impl() + { + return static_cast<impl_pointer>( + static_cast<impl_type*>(static_cast<trampoline*>(this))); + } + + const_impl_pointer impl()const + { + return static_cast<const_impl_pointer>( + static_cast<const impl_type*>(static_cast<const trampoline*>(this))); + } + + static sequenced_index_node* from_impl(impl_pointer x) + { + return static_cast<sequenced_index_node*>( + static_cast<trampoline*>(&*x)); + } + + static const sequenced_index_node* from_impl(const_impl_pointer x) + { + return static_cast<const sequenced_index_node*>( + static_cast<const trampoline*>(&*x)); + } + + /* interoperability with bidir_node_iterator */ + + static void increment(sequenced_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::increment(xi); + x=from_impl(xi); + } + + static void decrement(sequenced_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::decrement(xi); + x=from_impl(xi); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/seq_index_ops.hpp b/3rdParty/Boost/src/boost/multi_index/detail/seq_index_ops.hpp new file mode 100644 index 0000000..8135074 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/seq_index_ops.hpp @@ -0,0 +1,200 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP +#define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/multi_index/detail/seq_index_node.hpp> +#include <boost/limits.hpp> +#include <boost/type_traits/aligned_storage.hpp> +#include <boost/type_traits/alignment_of.hpp> +#include <cstddef> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for sequenced_index memfuns having templatized and + * non-templatized versions. + */ + +template <typename SequencedIndex,typename Predicate> +void sequenced_index_remove(SequencedIndex& x,Predicate pred) +{ + typedef typename SequencedIndex::iterator iterator; + iterator first=x.begin(),last=x.end(); + while(first!=last){ + if(pred(*first))x.erase(first++); + else ++first; + } +} + +template <typename SequencedIndex,class BinaryPredicate> +void sequenced_index_unique(SequencedIndex& x,BinaryPredicate binary_pred) +{ + typedef typename SequencedIndex::iterator iterator; + iterator first=x.begin(); + iterator last=x.end(); + if(first!=last){ + for(iterator middle=first;++middle!=last;middle=first){ + if(binary_pred(*middle,*first))x.erase(middle); + else first=middle; + } + } +} + +template <typename SequencedIndex,typename Compare> +void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp) +{ + typedef typename SequencedIndex::iterator iterator; + if(&x!=&y){ + iterator first0=x.begin(),last0=x.end(); + iterator first1=y.begin(),last1=y.end(); + while(first0!=last0&&first1!=last1){ + if(comp(*first1,*first0))x.splice(first0,y,first1++); + else ++first0; + } + x.splice(last0,y,first1,last1); + } +} + +/* sorting */ + +/* auxiliary stuff */ + +template<typename Node,typename Compare> +void sequenced_index_collate( + BOOST_DEDUCED_TYPENAME Node::impl_type* x, + BOOST_DEDUCED_TYPENAME Node::impl_type* y, + Compare comp + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node)) +{ + typedef typename Node::impl_type impl_type; + typedef typename Node::impl_pointer impl_pointer; + + impl_pointer first0=x->next(); + impl_pointer last0=x; + impl_pointer first1=y->next(); + impl_pointer last1=y; + while(first0!=last0&&first1!=last1){ + if(comp( + Node::from_impl(first1)->value(),Node::from_impl(first0)->value())){ + impl_pointer tmp=first1->next(); + impl_type::relink(first0,first1); + first1=tmp; + } + else first0=first0->next(); + } + impl_type::relink(last0,first1,last1); +} + +/* Some versions of CGG require a bogus typename in counter_spc + * inside sequenced_index_sort if the following is defined + * also inside sequenced_index_sort. + */ + +BOOST_STATIC_CONSTANT( + std::size_t, + sequenced_index_sort_max_fill= + (std::size_t)std::numeric_limits<std::size_t>::digits+1); + +template<typename Node,typename Compare> +void sequenced_index_sort(Node* header,Compare comp) +{ + /* Musser's mergesort, see http://www.cs.rpi.edu/~musser/gp/List/lists1.html. + * The implementation is a little convoluted: in the original code + * counter elements and carry are std::lists: here we do not want + * to use multi_index instead, so we do things at a lower level, managing + * directly the internal node representation. + * Incidentally, the implementations I've seen of this algorithm (SGI, + * Dinkumware, STLPort) are not exception-safe: this is. Moreover, we do not + * use any dynamic storage. + */ + + if(header->next()==header->impl()|| + header->next()->next()==header->impl())return; + + typedef typename Node::impl_type impl_type; + typedef typename Node::impl_pointer impl_pointer; + + typedef typename aligned_storage< + sizeof(impl_type), + alignment_of<impl_type>::value + >::type carry_spc_type; + carry_spc_type carry_spc; + impl_type& carry= + *static_cast<impl_type*>(static_cast<void*>(&carry_spc)); + typedef typename aligned_storage< + sizeof( + impl_type + [sequenced_index_sort_max_fill]), + alignment_of< + impl_type + [sequenced_index_sort_max_fill] + >::value + >::type counter_spc_type; + counter_spc_type counter_spc; + impl_type* counter= + static_cast<impl_type*>(static_cast<void*>(&counter_spc)); + std::size_t fill=0; + + carry.prior()=carry.next()=static_cast<impl_pointer>(&carry); + counter[0].prior()=counter[0].next()=static_cast<impl_pointer>(&counter[0]); + + BOOST_TRY{ + while(header->next()!=header->impl()){ + impl_type::relink(carry.next(),header->next()); + std::size_t i=0; + while(i<fill&&counter[i].next()!=static_cast<impl_pointer>(&counter[i])){ + sequenced_index_collate<Node>(&carry,&counter[i++],comp); + } + impl_type::swap( + static_cast<impl_pointer>(&carry), + static_cast<impl_pointer>(&counter[i])); + if(i==fill){ + ++fill; + counter[fill].prior()=counter[fill].next()= + static_cast<impl_pointer>(&counter[fill]); + } + } + + for(std::size_t i=1;i<fill;++i){ + sequenced_index_collate<Node>(&counter[i],&counter[i-1],comp); + } + impl_type::swap( + header->impl(),static_cast<impl_pointer>(&counter[fill-1])); + } + BOOST_CATCH(...) + { + impl_type::relink( + header->impl(),carry.next(),static_cast<impl_pointer>(&carry)); + for(std::size_t i=0;i<=fill;++i){ + impl_type::relink( + header->impl(),counter[i].next(), + static_cast<impl_pointer>(&counter[i])); + } + BOOST_RETHROW; + } + BOOST_CATCH_END +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/serialization_version.hpp b/3rdParty/Boost/src/boost/multi_index/detail/serialization_version.hpp new file mode 100644 index 0000000..cced78c --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/serialization_version.hpp @@ -0,0 +1,75 @@ +/* Copyright 2003-2010 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP +#define BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/serialization/split_member.hpp> +#include <boost/serialization/version.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Helper class for storing and retrieving a given type serialization class + * version while avoiding saving the number multiple times in the same + * archive. + * Behavior undefined if template partial specialization is not supported. + */ + +template<typename T> +struct serialization_version +{ + serialization_version(): + value(boost::serialization::version<serialization_version>::value){} + + serialization_version& operator=(unsigned int x){value=x;return *this;}; + + operator unsigned int()const{return value;} + +private: + friend class boost::serialization::access; + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + template<class Archive> + void save(Archive&,const unsigned int)const{} + + template<class Archive> + void load(Archive&,const unsigned int version) + { + this->value=version; + } + + unsigned int value; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +namespace serialization { +template<typename T> +struct version<boost::multi_index::detail::serialization_version<T> > +{ + BOOST_STATIC_CONSTANT(int,value=version<T>::value); +}; +} /* namespace serialization */ +#endif + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/uintptr_type.hpp b/3rdParty/Boost/src/boost/multi_index/detail/uintptr_type.hpp new file mode 100644 index 0000000..529c623 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/uintptr_type.hpp @@ -0,0 +1,76 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP +#define BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/mpl/bool.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* has_uintptr_type is an MPL integral constant determining whether + * there exists an unsigned integral type with the same size as + * void *. + * uintptr_type is such a type if has_uintptr is true, or unsigned int + * otherwise. + * Note that uintptr_type is more restrictive than C99 uintptr_t, + * where an integral type with size greater than that of void * + * would be conformant. + */ + +template<int N>struct uintptr_candidates; +template<>struct uintptr_candidates<-1>{typedef unsigned int type;}; +template<>struct uintptr_candidates<0> {typedef unsigned int type;}; +template<>struct uintptr_candidates<1> {typedef unsigned short type;}; +template<>struct uintptr_candidates<2> {typedef unsigned long type;}; + +#if defined(BOOST_HAS_LONG_LONG) +template<>struct uintptr_candidates<3> {typedef boost::ulong_long_type type;}; +#else +template<>struct uintptr_candidates<3> {typedef unsigned int type;}; +#endif + +#if defined(BOOST_HAS_MS_INT64) +template<>struct uintptr_candidates<4> {typedef unsigned __int64 type;}; +#else +template<>struct uintptr_candidates<4> {typedef unsigned int type;}; +#endif + +struct uintptr_aux +{ + BOOST_STATIC_CONSTANT(int,index= + sizeof(void*)==sizeof(uintptr_candidates<0>::type)?0: + sizeof(void*)==sizeof(uintptr_candidates<1>::type)?1: + sizeof(void*)==sizeof(uintptr_candidates<2>::type)?2: + sizeof(void*)==sizeof(uintptr_candidates<3>::type)?3: + sizeof(void*)==sizeof(uintptr_candidates<4>::type)?4:-1); + + BOOST_STATIC_CONSTANT(bool,has_uintptr_type=(index>=0)); + + typedef uintptr_candidates<index>::type type; +}; + +typedef mpl::bool_<uintptr_aux::has_uintptr_type> has_uintptr_type; +typedef uintptr_aux::type uintptr_type; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/unbounded.hpp b/3rdParty/Boost/src/boost/multi_index/detail/unbounded.hpp new file mode 100644 index 0000000..40c3034 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/unbounded.hpp @@ -0,0 +1,83 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP +#define BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/detail/workaround.hpp> + +namespace boost{ + +namespace multi_index{ + +/* dummy type and variable for use in ordered_index::range() */ + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) +/* The default branch actually works for MSVC 6.0, but seems like + * this implementation of unbounded improves the performance of ordered + * indices! This behavior is hard to explain and probably a test artifact, + * but it does not hurt to have the workaround anyway. + */ + +namespace detail{struct unbounded_type{};} + +namespace{ + +static detail::unbounded_type unbounded_obj=detail::unbounded_type(); +static detail::unbounded_type& unbounded=unbounded_obj; + +} /* unnamed */ +#else +/* ODR-abiding technique shown at the example attached to + * http://lists.boost.org/Archives/boost/2006/07/108355.php + */ + +namespace detail{class unbounded_helper;} + +detail::unbounded_helper unbounded(detail::unbounded_helper); + +namespace detail{ + +class unbounded_helper +{ + unbounded_helper(){} + unbounded_helper(const unbounded_helper&){} + friend unbounded_helper multi_index::unbounded(unbounded_helper); +}; + +typedef unbounded_helper (*unbounded_type)(unbounded_helper); + +} /* namespace multi_index::detail */ + +inline detail::unbounded_helper unbounded(detail::unbounded_helper) +{ + return detail::unbounded_helper(); +} +#endif + +/* tags used in the implementation of range */ + +namespace detail{ + +struct none_unbounded_tag{}; +struct lower_unbounded_tag{}; +struct upper_unbounded_tag{}; +struct both_unbounded_tag{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/detail/value_compare.hpp b/3rdParty/Boost/src/boost/multi_index/detail/value_compare.hpp new file mode 100644 index 0000000..0bd7b4f --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/detail/value_compare.hpp @@ -0,0 +1,53 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP +#define BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/call_traits.hpp> +#include <functional> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template<typename Value,typename KeyFromValue,typename Compare> +struct value_comparison:std::binary_function<Value,Value,bool> +{ + value_comparison( + const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()): + key(key_),comp(comp_) + { + } + + bool operator()( + typename call_traits<Value>::param_type x, + typename call_traits<Value>::param_type y)const + { + return comp(key(x),key(y)); + } + +private: + KeyFromValue key; + Compare comp; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/identity.hpp b/3rdParty/Boost/src/boost/multi_index/identity.hpp new file mode 100644 index 0000000..b402ad7 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/identity.hpp @@ -0,0 +1,147 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_IDENTITY_HPP +#define BOOST_MULTI_INDEX_IDENTITY_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> +#include <boost/mpl/if.hpp> +#include <boost/multi_index/identity_fwd.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/utility/enable_if.hpp> + +#if !defined(BOOST_NO_SFINAE) +#include <boost/type_traits/is_convertible.hpp> +#endif + +namespace boost{ + +template<class Type> class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +namespace detail{ + +/* identity is a do-nothing key extractor that returns the [const] Type& + * object passed. + * Additionally, identity is overloaded to support referece_wrappers + * of Type and "chained pointers" to Type's. By chained pointer to Type we + * mean a type P such that, given a p of type P + * *...n...*x is convertible to Type&, for some n>=1. + * Examples of chained pointers are raw and smart pointers, iterators and + * arbitrary combinations of these (vg. Type** or auto_ptr<Type*>.) + */ + +/* NB. Some overloads of operator() have an extra dummy parameter int=0. + * This disambiguator serves several purposes: + * - Without it, MSVC++ 6.0 incorrectly regards some overloads as + * specializations of a previous member function template. + * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns + * as if they have the same signature. + * - If remove_const is broken due to lack of PTS, int=0 avoids the + * declaration of memfuns with identical signature. + */ + +template<typename Type> +struct const_identity_base +{ + typedef Type result_type; + + template<typename ChainedPtr> + +#if !defined(BOOST_NO_SFINAE) + typename disable_if<is_convertible<const ChainedPtr&,Type&>,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type& operator()(Type& x)const + { + return x; + } + + Type& operator()(const reference_wrapper<Type>& x)const + { + return x.get(); + } + + Type& operator()( + const reference_wrapper<typename remove_const<Type>::type>& x,int=0)const + { + return x.get(); + } +}; + +template<typename Type> +struct non_const_identity_base +{ + typedef Type result_type; + + /* templatized for pointer-like types */ + + template<typename ChainedPtr> + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible<const ChainedPtr&,const Type&>,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Type& x,int=0)const + { + return x; + } + + Type& operator()(Type& x)const + { + return x; + } + + const Type& operator()(const reference_wrapper<const Type>& x,int=0)const + { + return x.get(); + } + + Type& operator()(const reference_wrapper<Type>& x)const + { + return x.get(); + } +}; + +} /* namespace multi_index::detail */ + +template<class Type> +struct identity: + mpl::if_c< + is_const<Type>::value, + detail::const_identity_base<Type>,detail::non_const_identity_base<Type> + >::type +{ +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/identity_fwd.hpp b/3rdParty/Boost/src/boost/multi_index/identity_fwd.hpp new file mode 100644 index 0000000..baafa43 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/identity_fwd.hpp @@ -0,0 +1,26 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_IDENTITY_FWD_HPP +#define BOOST_MULTI_INDEX_IDENTITY_FWD_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +template<class Type> struct identity; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/indexed_by.hpp b/3rdParty/Boost/src/boost/multi_index/indexed_by.hpp new file mode 100644 index 0000000..94a8dcb --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/indexed_by.hpp @@ -0,0 +1,72 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_INDEXED_BY_HPP +#define BOOST_MULTI_INDEX_INDEXED_BY_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/mpl/vector.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/control/expr_if.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> + +/* An alias to mpl::vector used to hide MPL from the user. + * indexed_by contains the index specifiers for instantiation + * of a multi_index_container. + */ + +/* This user_definable macro limits the number of elements of an index list; + * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, + * has problems coping with very long symbol names.) + */ + +#if !defined(BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE) +#if defined(BOOST_MSVC)&&(BOOST_MSVC<1300) +#define BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE 5 +#else +#define BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE +#endif +#endif + +#if BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE<BOOST_MPL_LIMIT_VECTOR_SIZE +#define BOOST_MULTI_INDEX_INDEXED_BY_SIZE \ + BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE +#else +#define BOOST_MULTI_INDEX_INDEXED_BY_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE +#endif + +#define BOOST_MULTI_INDEX_INDEXED_BY_TEMPLATE_PARM(z,n,var) \ + typename BOOST_PP_CAT(var,n) BOOST_PP_EXPR_IF(n,=mpl::na) + +namespace boost{ + +namespace multi_index{ + +template< + BOOST_PP_ENUM( + BOOST_MULTI_INDEX_INDEXED_BY_SIZE, + BOOST_MULTI_INDEX_INDEXED_BY_TEMPLATE_PARM,T) +> +struct indexed_by: + mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_INDEXED_BY_SIZE,T)> +{ +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_INDEXED_BY_TEMPLATE_PARM +#undef BOOST_MULTI_INDEX_INDEXED_BY_SIZE + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/member.hpp b/3rdParty/Boost/src/boost/multi_index/member.hpp new file mode 100644 index 0000000..848e9b2 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/member.hpp @@ -0,0 +1,269 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_MEMBER_HPP +#define BOOST_MULTI_INDEX_MEMBER_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/utility/enable_if.hpp> +#include <cstddef> + +#if !defined(BOOST_NO_SFINAE) +#include <boost/type_traits/is_convertible.hpp> +#endif + +namespace boost{ + +template<class T> class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +namespace detail{ + +/* member is a read/write key extractor for accessing a given + * member of a class. + * Additionally, member is overloaded to support referece_wrappers + * of T and "chained pointers" to T's. By chained pointer to T we mean + * a type P such that, given a p of Type P + * *...n...*x is convertible to T&, for some n>=1. + * Examples of chained pointers are raw and smart pointers, iterators and + * arbitrary combinations of these (vg. T** or auto_ptr<T*>.) + */ + +/* NB. Some overloads of operator() have an extra dummy parameter int=0. + * This disambiguator serves several purposes: + * - Without it, MSVC++ 6.0 incorrectly regards some overloads as + * specializations of a previous member function template. + * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns + * as if they have the same signature. + * - If remove_const is broken due to lack of PTS, int=0 avoids the + * declaration of memfuns with identical signature. + */ + +template<class Class,typename Type,Type Class::*PtrToMember> +struct const_member_base +{ + typedef Type result_type; + + template<typename ChainedPtr> + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible<const ChainedPtr&,const Class&>,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type& operator()(const Class& x)const + { + return x.*PtrToMember; + } + + Type& operator()(const reference_wrapper<const Class>& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper<Class>& x,int=0)const + { + return operator()(x.get()); + } +}; + +template<class Class,typename Type,Type Class::*PtrToMember> +struct non_const_member_base +{ + typedef Type result_type; + + template<typename ChainedPtr> + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible<const ChainedPtr&,const Class&>,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Class& x,int=0)const + { + return x.*PtrToMember; + } + + Type& operator()(Class& x)const + { + return x.*PtrToMember; + } + + const Type& operator()(const reference_wrapper<const Class>& x,int=0)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper<Class>& x)const + { + return operator()(x.get()); + } +}; + +} /* namespace multi_index::detail */ + +template<class Class,typename Type,Type Class::*PtrToMember> +struct member: + mpl::if_c< + is_const<Type>::value, + detail::const_member_base<Class,Type,PtrToMember>, + detail::non_const_member_base<Class,Type,PtrToMember> + >::type +{ +}; + +namespace detail{ + +/* MSVC++ 6.0 does not support properly pointers to members as + * non-type template arguments, as reported in + * http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045 + * A similar problem (though not identical) is shown by MSVC++ 7.0. + * We provide an alternative to member<> accepting offsets instead + * of pointers to members. This happens to work even for non-POD + * types (although the standard forbids use of offsetof on these), + * so it serves as a workaround in this compiler for all practical + * purposes. + * Surprisingly enough, other compilers, like Intel C++ 7.0/7.1 and + * Visual Age 6.0, have similar bugs. This replacement of member<> + * can be used for them too. + */ + +template<class Class,typename Type,std::size_t OffsetOfMember> +struct const_member_offset_base +{ + typedef Type result_type; + + template<typename ChainedPtr> + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible<const ChainedPtr&,const Class&>,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type& operator()(const Class& x)const + { + return *static_cast<const Type*>( + static_cast<const void*>( + static_cast<const char*>( + static_cast<const void *>(&x))+OffsetOfMember)); + } + + Type& operator()(const reference_wrapper<const Class>& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper<Class>& x,int=0)const + { + return operator()(x.get()); + } +}; + +template<class Class,typename Type,std::size_t OffsetOfMember> +struct non_const_member_offset_base +{ + typedef Type result_type; + + template<typename ChainedPtr> + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible<const ChainedPtr&,const Class&>,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Class& x,int=0)const + { + return *static_cast<const Type*>( + static_cast<const void*>( + static_cast<const char*>( + static_cast<const void *>(&x))+OffsetOfMember)); + } + + Type& operator()(Class& x)const + { + return *static_cast<Type*>( + static_cast<void*>( + static_cast<char*>(static_cast<void *>(&x))+OffsetOfMember)); + } + + const Type& operator()(const reference_wrapper<const Class>& x,int=0)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper<Class>& x)const + { + return operator()(x.get()); + } +}; + +} /* namespace multi_index::detail */ + +template<class Class,typename Type,std::size_t OffsetOfMember> +struct member_offset: + mpl::if_c< + is_const<Type>::value, + detail::const_member_offset_base<Class,Type,OffsetOfMember>, + detail::non_const_member_offset_base<Class,Type,OffsetOfMember> + >::type +{ +}; + +/* BOOST_MULTI_INDEX_MEMBER resolves to member in the normal cases, + * and to member_offset as a workaround in those defective compilers for + * which BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is defined. + */ + +#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) +#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ +::boost::multi_index::member_offset< Class,Type,offsetof(Class,MemberName) > +#else +#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ +::boost::multi_index::member< Class,Type,&Class::MemberName > +#endif + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/ordered_index.hpp b/3rdParty/Boost/src/boost/multi_index/ordered_index.hpp new file mode 100644 index 0000000..a49e4cf --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/ordered_index.hpp @@ -0,0 +1,1390 @@ +/* Copyright 2003-2010 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + * + * The internal implementation of red-black trees is based on that of SGI STL + * stl_tree.h file: + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP +#define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> +#include <boost/call_traits.hpp> +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/iterator/reverse_iterator.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/push_front.hpp> +#include <boost/multi_index/detail/access_specifier.hpp> +#include <boost/multi_index/detail/bidir_node_iterator.hpp> +#include <boost/multi_index/detail/index_node_base.hpp> +#include <boost/multi_index/detail/modify_key_adaptor.hpp> +#include <boost/multi_index/detail/ord_index_node.hpp> +#include <boost/multi_index/detail/ord_index_ops.hpp> +#include <boost/multi_index/detail/safe_ctr_proxy.hpp> +#include <boost/multi_index/detail/safe_mode.hpp> +#include <boost/multi_index/detail/scope_guard.hpp> +#include <boost/multi_index/detail/unbounded.hpp> +#include <boost/multi_index/detail/value_compare.hpp> +#include <boost/multi_index/ordered_index_fwd.hpp> +#include <boost/ref.hpp> +#include <boost/tuple/tuple.hpp> +#include <boost/type_traits/is_same.hpp> +#include <utility> + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include <boost/archive/archive_exception.hpp> +#include <boost/bind.hpp> +#include <boost/multi_index/detail/duplicates_iterator.hpp> +#include <boost/throw_exception.hpp> +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(*this,&ordered_index::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#else +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* ordered_index adds a layer of ordered indexing to a given Super */ + +/* Most of the implementation of unique and non-unique indices is + * shared. We tell from one another on instantiation time by using + * these tags. + */ + +struct ordered_unique_tag{}; +struct ordered_non_unique_tag{}; + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category +> +class ordered_index: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) + ,public safe_ctr_proxy_impl< + bidir_node_iterator< + ordered_index_node<typename SuperMeta::type::node_type> >, + ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category> > +#else + ,public safe_mode::safe_container< + ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category> > +#endif +#endif + +{ +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the + * lifetime of const references bound to temporaries --precisely what + * scopeguards are. + */ + +#pragma parse_mfunc_templ off +#endif + + typedef typename SuperMeta::type super; + +protected: + typedef ordered_index_node< + typename super::node_type> node_type; + +private: + typedef typename node_type::impl_type node_impl_type; + typedef typename node_impl_type::pointer node_impl_pointer; + +public: + /* types */ + + typedef typename KeyFromValue::result_type key_type; + typedef typename node_type::value_type value_type; + typedef KeyFromValue key_from_value; + typedef Compare key_compare; + typedef value_comparison< + value_type,KeyFromValue,Compare> value_compare; + typedef tuple<key_from_value,key_compare> ctor_args; + typedef typename super::final_allocator_type allocator_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) + typedef safe_mode::safe_iterator< + bidir_node_iterator<node_type>, + safe_ctr_proxy< + bidir_node_iterator<node_type> > > iterator; +#else + typedef safe_mode::safe_iterator< + bidir_node_iterator<node_type>, + ordered_index> iterator; +#endif +#else + typedef bidir_node_iterator<node_type> iterator; +#endif + + typedef iterator const_iterator; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename + boost::reverse_iterator<iterator> reverse_iterator; + typedef typename + boost::reverse_iterator<const_iterator> const_reverse_iterator; + typedef TagList tag_list; + +protected: + typedef typename super::final_node_type final_node_type; + typedef tuples::cons< + ctor_args, + typename super::ctor_args_list> ctor_args_list; + typedef typename mpl::push_front< + typename super::index_type_list, + ordered_index>::type index_type_list; + typedef typename mpl::push_front< + typename super::iterator_type_list, + iterator>::type iterator_type_list; + typedef typename mpl::push_front< + typename super::const_iterator_type_list, + const_iterator>::type const_iterator_type_list; + typedef typename super::copy_map_type copy_map_type; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + typedef typename super::index_saver_type index_saver_type; + typedef typename super::index_loader_type index_loader_type; +#endif + +private: +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) + typedef safe_ctr_proxy_impl< + bidir_node_iterator<node_type>, + ordered_index> safe_super; +#else + typedef safe_mode::safe_container<ordered_index> safe_super; +#endif +#endif + + typedef typename call_traits< + value_type>::param_type value_param_type; + typedef typename call_traits< + key_type>::param_type key_param_type; + +public: + + /* construct/copy/destroy + * Default and copy ctors are in the protected section as indices are + * not supposed to be created on their own. No range ctor either. + */ + + ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=( + const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x) + { + this->final()=x.final(); + return *this; + } + + allocator_type get_allocator()const + { + return this->final().get_allocator(); + } + + /* iterators */ + + iterator begin(){return make_iterator(leftmost());} + const_iterator begin()const{return make_iterator(leftmost());} + iterator end(){return make_iterator(header());} + const_iterator end()const{return make_iterator(header());} + reverse_iterator rbegin(){return make_reverse_iterator(end());} + const_reverse_iterator rbegin()const{return make_reverse_iterator(end());} + reverse_iterator rend(){return make_reverse_iterator(begin());} + const_reverse_iterator rend()const{return make_reverse_iterator(begin());} + const_iterator cbegin()const{return begin();} + const_iterator cend()const{return end();} + const_reverse_iterator crbegin()const{return rbegin();} + const_reverse_iterator crend()const{return rend();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value<node_type>(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value<node_type>(&x)); + } + + /* capacity */ + + bool empty()const{return this->final_empty_();} + size_type size()const{return this->final_size_();} + size_type max_size()const{return this->final_max_size_();} + + /* modifiers */ + + std::pair<iterator,bool> insert(value_param_type x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair<final_node_type*,bool> p=this->final_insert_(x); + return std::pair<iterator,bool>(make_iterator(p.first),p.second); + } + + iterator insert(iterator position,value_param_type x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair<final_node_type*,bool> p=this->final_insert_( + x,static_cast<final_node_type*>(position.get_node())); + return make_iterator(p.first); + } + + template<typename InputIterator> + void insert(InputIterator first,InputIterator last) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + iterator hint=end(); + for(;first!=last;++first)hint=insert(hint,*first); + } + + iterator erase(iterator position) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + this->final_erase_(static_cast<final_node_type*>(position++.get_node())); + return position; + } + + size_type erase(key_param_type x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair<iterator,iterator> p=equal_range(x); + size_type s=0; + while(p.first!=p.second){ + p.first=erase(p.first); + ++s; + } + return s; + } + + iterator erase(iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + while(first!=last){ + first=erase(first); + } + return first; + } + + bool replace(iterator position,value_param_type x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return this->final_replace_( + x,static_cast<final_node_type*>(position.get_node())); + } + + template<typename Modifier> + bool modify(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,static_cast<final_node_type*>(position.get_node())); + } + + template<typename Modifier,typename Rollback> + bool modify(iterator position,Modifier mod,Rollback back) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,back,static_cast<final_node_type*>(position.get_node())); + } + + template<typename Modifier> + bool modify_key(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return modify( + position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key)); + } + + template<typename Modifier,typename Rollback> + bool modify_key(iterator position,Modifier mod,Rollback back) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return modify( + position, + modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key), + modify_key_adaptor<Rollback,value_type,KeyFromValue>(back,key)); + } + + void swap(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + this->final_swap_(x.final()); + } + + void clear() + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + /* observers */ + + key_from_value key_extractor()const{return key;} + key_compare key_comp()const{return comp;} + value_compare value_comp()const{return value_compare(key,comp);} + + /* set operations */ + + /* Internally, these ops rely on const_iterator being the same + * type as iterator. + */ + + template<typename CompatibleKey> + iterator find(const CompatibleKey& x)const + { + return make_iterator(ordered_index_find(root(),header(),key,x,comp)); + } + + template<typename CompatibleKey,typename CompatibleCompare> + iterator find( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator(ordered_index_find(root(),header(),key,x,comp)); + } + + template<typename CompatibleKey> + size_type count(const CompatibleKey& x)const + { + return count(x,comp); + } + + template<typename CompatibleKey,typename CompatibleCompare> + size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const + { + std::pair<iterator,iterator> p=equal_range(x,comp); + size_type n=std::distance(p.first,p.second); + return n; + } + + template<typename CompatibleKey> + iterator lower_bound(const CompatibleKey& x)const + { + return make_iterator( + ordered_index_lower_bound(root(),header(),key,x,comp)); + } + + template<typename CompatibleKey,typename CompatibleCompare> + iterator lower_bound( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator( + ordered_index_lower_bound(root(),header(),key,x,comp)); + } + + template<typename CompatibleKey> + iterator upper_bound(const CompatibleKey& x)const + { + return make_iterator( + ordered_index_upper_bound(root(),header(),key,x,comp)); + } + + template<typename CompatibleKey,typename CompatibleCompare> + iterator upper_bound( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator( + ordered_index_upper_bound(root(),header(),key,x,comp)); + } + + template<typename CompatibleKey> + std::pair<iterator,iterator> equal_range( + const CompatibleKey& x)const + { + std::pair<node_type*,node_type*> p= + ordered_index_equal_range(root(),header(),key,x,comp); + return std::pair<iterator,iterator>( + make_iterator(p.first),make_iterator(p.second)); + } + + template<typename CompatibleKey,typename CompatibleCompare> + std::pair<iterator,iterator> equal_range( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + std::pair<node_type*,node_type*> p= + ordered_index_equal_range(root(),header(),key,x,comp); + return std::pair<iterator,iterator>( + make_iterator(p.first),make_iterator(p.second)); + } + + /* range */ + + template<typename LowerBounder,typename UpperBounder> + std::pair<iterator,iterator> + range(LowerBounder lower,UpperBounder upper)const + { + typedef typename mpl::if_< + is_same<LowerBounder,unbounded_type>, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same<UpperBounder,unbounded_type>, + both_unbounded_tag, + lower_unbounded_tag + >::type, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same<UpperBounder,unbounded_type>, + upper_unbounded_tag, + none_unbounded_tag + >::type + >::type dispatch; + + return range(lower,upper,dispatch()); + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + ordered_index(const ctor_args_list& args_list,const allocator_type& al): + super(args_list.get_tail(),al), + key(tuples::get<0>(args_list.get_head())), + comp(tuples::get<1>(args_list.get_head())) + { + empty_initialize(); + } + + ordered_index( + const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x): + super(x), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + comp(x.comp) + { + /* Copy ctor just takes the key and compare objects from x. The rest is + * done in subsequent call to copy_(). + */ + } + + ~ordered_index() + { + /* the container is guaranteed to be empty by now */ + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + iterator make_iterator(node_type* node){return iterator(node,this);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node,const_cast<ordered_index*>(this));} +#else + iterator make_iterator(node_type* node){return iterator(node);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node);} +#endif + + void copy_( + const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x, + const copy_map_type& map) + { + if(!x.root()){ + empty_initialize(); + } + else{ + header()->color()=x.header()->color(); + + node_type* root_cpy=map.find(static_cast<final_node_type*>(x.root())); + header()->parent()=root_cpy->impl(); + + node_type* leftmost_cpy=map.find( + static_cast<final_node_type*>(x.leftmost())); + header()->left()=leftmost_cpy->impl(); + + node_type* rightmost_cpy=map.find( + static_cast<final_node_type*>(x.rightmost())); + header()->right()=rightmost_cpy->impl(); + + typedef typename copy_map_type::const_iterator copy_map_iterator; + for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){ + node_type* org=it->first; + node_type* cpy=it->second; + + cpy->color()=org->color(); + + node_impl_pointer parent_org=org->parent(); + if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0); + else{ + node_type* parent_cpy=map.find( + static_cast<final_node_type*>(node_type::from_impl(parent_org))); + cpy->parent()=parent_cpy->impl(); + if(parent_org->left()==org->impl()){ + parent_cpy->left()=cpy->impl(); + } + else if(parent_org->right()==org->impl()){ + /* header() does not satisfy this nor the previous check */ + parent_cpy->right()=cpy->impl(); + } + } + + if(org->left()==node_impl_pointer(0)) + cpy->left()=node_impl_pointer(0); + if(org->right()==node_impl_pointer(0)) + cpy->right()=node_impl_pointer(0); + } + } + + super::copy_(x,map); + } + + node_type* insert_(value_param_type v,node_type* x) + { + link_info inf; + if(!link_point(key(v),inf,Category())){ + return node_type::from_impl(inf.pos); + } + + node_type* res=static_cast<node_type*>(super::insert_(v,x)); + if(res==x){ + node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); + } + return res; + } + + node_type* insert_(value_param_type v,node_type* position,node_type* x) + { + link_info inf; + if(!hinted_link_point(key(v),position,inf,Category())){ + return node_type::from_impl(inf.pos); + } + + node_type* res=static_cast<node_type*>(super::insert_(v,position,x)); + if(res==x){ + node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); + } + return res; + } + + void erase_(node_type* x) + { + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + } + + void delete_all_nodes_() + { + delete_all_nodes(root()); + } + + void clear_() + { + super::clear_(); + empty_initialize(); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::detach_dereferenceable_iterators(); +#endif + } + + void swap_(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x) + { + std::swap(key,x.key); + std::swap(comp,x.comp); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + bool replace_(value_param_type v,node_type* x) + { + if(in_place(v,x,Category())){ + return super::replace_(v,x); + } + + node_type* next=x; + node_type::increment(next); + + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + + BOOST_TRY{ + link_info inf; + if(link_point(key(v),inf,Category())&&super::replace_(v,x)){ + node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); + return true; + } + node_impl_type::restore(x->impl(),next->impl(),header()->impl()); + return false; + } + BOOST_CATCH(...){ + node_impl_type::restore(x->impl(),next->impl(),header()->impl()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_(node_type* x) + { + bool b; + BOOST_TRY{ + b=in_place(x->value(),x,Category()); + } + BOOST_CATCH(...){ + erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + if(!b){ + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + BOOST_TRY{ + link_info inf; + if(!link_point(key(x->value()),inf,Category())){ + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + return false; + } + node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); + } + BOOST_CATCH(...){ + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + BOOST_TRY{ + if(!super::modify_(x)){ + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + return false; + } + else return true; + } + BOOST_CATCH(...){ + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_rollback_(node_type* x) + { + if(in_place(x->value(),x,Category())){ + return super::modify_rollback_(x); + } + + node_type* next=x; + node_type::increment(next); + + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + + BOOST_TRY{ + link_info inf; + if(link_point(key(x->value()),inf,Category())&& + super::modify_rollback_(x)){ + node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); + return true; + } + node_impl_type::restore(x->impl(),next->impl(),header()->impl()); + return false; + } + BOOST_CATCH(...){ + node_impl_type::restore(x->impl(),next->impl(),header()->impl()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template<typename Archive> + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm)const + { + save_(ar,version,sm,Category()); + } + + template<typename Archive> + void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) + { + load_(ar,version,lm,Category()); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + if(size()==0||begin()==end()){ + if(size()!=0||begin()!=end()|| + header()->left()!=header()->impl()|| + header()->right()!=header()->impl())return false; + } + else{ + if((size_type)std::distance(begin(),end())!=size())return false; + + std::size_t len=node_impl_type::black_count( + leftmost()->impl(),root()->impl()); + for(const_iterator it=begin(),it_end=end();it!=it_end;++it){ + node_type* x=it.get_node(); + node_type* left_x=node_type::from_impl(x->left()); + node_type* right_x=node_type::from_impl(x->right()); + + if(x->color()==red){ + if((left_x&&left_x->color()==red)|| + (right_x&&right_x->color()==red))return false; + } + if(left_x&&comp(key(x->value()),key(left_x->value())))return false; + if(right_x&&comp(key(right_x->value()),key(x->value())))return false; + if(!left_x&&!right_x&& + node_impl_type::black_count(x->impl(),root()->impl())!=len) + return false; + } + + if(leftmost()->impl()!=node_impl_type::minimum(root()->impl())) + return false; + if(rightmost()->impl()!=node_impl_type::maximum(root()->impl())) + return false; + } + + return super::invariant_(); + } + + + /* This forwarding function eases things for the boost::mem_fn construct + * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually, + * final_check_invariant is already an inherited member function of + * ordered_index. + */ + void check_invariant_()const{this->final_check_invariant_();} +#endif + +private: + node_type* header()const{return this->final_header();} + node_type* root()const{return node_type::from_impl(header()->parent());} + node_type* leftmost()const{return node_type::from_impl(header()->left());} + node_type* rightmost()const{return node_type::from_impl(header()->right());} + + void empty_initialize() + { + header()->color()=red; + /* used to distinguish header() from root, in iterator.operator++ */ + + header()->parent()=node_impl_pointer(0); + header()->left()=header()->impl(); + header()->right()=header()->impl(); + } + + struct link_info + { + link_info():side(to_left){} + + ordered_index_side side; + node_impl_pointer pos; + }; + + bool link_point(key_param_type k,link_info& inf,ordered_unique_tag) + { + node_type* y=header(); + node_type* x=root(); + bool c=true; + while(x){ + y=x; + c=comp(k,key(x->value())); + x=node_type::from_impl(c?x->left():x->right()); + } + node_type* yy=y; + if(c){ + if(yy==leftmost()){ + inf.side=to_left; + inf.pos=y->impl(); + return true; + } + else node_type::decrement(yy); + } + + if(comp(key(yy->value()),k)){ + inf.side=c?to_left:to_right; + inf.pos=y->impl(); + return true; + } + else{ + inf.pos=yy->impl(); + return false; + } + } + + bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag) + { + node_type* y=header(); + node_type* x=root(); + bool c=true; + while (x){ + y=x; + c=comp(k,key(x->value())); + x=node_type::from_impl(c?x->left():x->right()); + } + inf.side=c?to_left:to_right; + inf.pos=y->impl(); + return true; + } + + bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag) + { + node_type* y=header(); + node_type* x=root(); + bool c=false; + while (x){ + y=x; + c=comp(key(x->value()),k); + x=node_type::from_impl(c?x->right():x->left()); + } + inf.side=c?to_right:to_left; + inf.pos=y->impl(); + return true; + } + + bool hinted_link_point( + key_param_type k,node_type* position,link_info& inf,ordered_unique_tag) + { + if(position->impl()==header()->left()){ + if(size()>0&&comp(k,key(position->value()))){ + inf.side=to_left; + inf.pos=position->impl(); + return true; + } + else return link_point(k,inf,ordered_unique_tag()); + } + else if(position==header()){ + if(comp(key(rightmost()->value()),k)){ + inf.side=to_right; + inf.pos=rightmost()->impl(); + return true; + } + else return link_point(k,inf,ordered_unique_tag()); + } + else{ + node_type* before=position; + node_type::decrement(before); + if(comp(key(before->value()),k)&&comp(k,key(position->value()))){ + if(before->right()==node_impl_pointer(0)){ + inf.side=to_right; + inf.pos=before->impl(); + return true; + } + else{ + inf.side=to_left; + inf.pos=position->impl(); + return true; + } + } + else return link_point(k,inf,ordered_unique_tag()); + } + } + + bool hinted_link_point( + key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag) + { + if(position->impl()==header()->left()){ + if(size()>0&&!comp(key(position->value()),k)){ + inf.side=to_left; + inf.pos=position->impl(); + return true; + } + else return lower_link_point(k,inf,ordered_non_unique_tag()); + } + else if(position==header()){ + if(!comp(k,key(rightmost()->value()))){ + inf.side=to_right; + inf.pos=rightmost()->impl(); + return true; + } + else return link_point(k,inf,ordered_non_unique_tag()); + } + else{ + node_type* before=position; + node_type::decrement(before); + if(!comp(k,key(before->value()))){ + if(!comp(key(position->value()),k)){ + if(before->right()==node_impl_pointer(0)){ + inf.side=to_right; + inf.pos=before->impl(); + return true; + } + else{ + inf.side=to_left; + inf.pos=position->impl(); + return true; + } + } + else return lower_link_point(k,inf,ordered_non_unique_tag()); + } + else return link_point(k,inf,ordered_non_unique_tag()); + } + } + + void delete_all_nodes(node_type* x) + { + if(!x)return; + + delete_all_nodes(node_type::from_impl(x->left())); + delete_all_nodes(node_type::from_impl(x->right())); + this->final_delete_node_(static_cast<final_node_type*>(x)); + } + + bool in_place(value_param_type v,node_type* x,ordered_unique_tag) + { + node_type* y; + if(x!=leftmost()){ + y=x; + node_type::decrement(y); + if(!comp(key(y->value()),key(v)))return false; + } + + y=x; + node_type::increment(y); + return y==header()||comp(key(v),key(y->value())); + } + + bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag) + { + node_type* y; + if(x!=leftmost()){ + y=x; + node_type::decrement(y); + if(comp(key(v),key(y->value())))return false; + } + + y=x; + node_type::increment(y); + return y==header()||!comp(key(y->value()),key(v)); + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + void detach_iterators(node_type* x) + { + iterator it=make_iterator(x); + safe_mode::detach_equivalent_iterators(it); + } +#endif + + template<typename LowerBounder,typename UpperBounder> + std::pair<iterator,iterator> + range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const + { + node_type* y=header(); + node_type* z=root(); + + while(z){ + if(!lower(key(z->value()))){ + z=node_type::from_impl(z->right()); + } + else if(!upper(key(z->value()))){ + y=z; + z=node_type::from_impl(z->left()); + } + else{ + return std::pair<iterator,iterator>( + make_iterator( + lower_range(node_type::from_impl(z->left()),z,lower)), + make_iterator( + upper_range(node_type::from_impl(z->right()),y,upper))); + } + } + + return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y)); + } + + template<typename LowerBounder,typename UpperBounder> + std::pair<iterator,iterator> + range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const + { + return std::pair<iterator,iterator>( + begin(), + make_iterator(upper_range(root(),header(),upper))); + } + + template<typename LowerBounder,typename UpperBounder> + std::pair<iterator,iterator> + range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const + { + return std::pair<iterator,iterator>( + make_iterator(lower_range(root(),header(),lower)), + end()); + } + + template<typename LowerBounder,typename UpperBounder> + std::pair<iterator,iterator> + range(LowerBounder,UpperBounder,both_unbounded_tag)const + { + return std::pair<iterator,iterator>(begin(),end()); + } + + template<typename LowerBounder> + node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const + { + while(top){ + if(lower(key(top->value()))){ + y=top; + top=node_type::from_impl(top->left()); + } + else top=node_type::from_impl(top->right()); + } + + return y; + } + + template<typename UpperBounder> + node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const + { + while(top){ + if(!upper(key(top->value()))){ + y=top; + top=node_type::from_impl(top->left()); + } + else top=node_type::from_impl(top->right()); + } + + return y; + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + template<typename Archive> + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm, + ordered_unique_tag)const + { + super::save_(ar,version,sm); + } + + template<typename Archive> + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm, + ordered_unique_tag) + { + super::load_(ar,version,lm); + } + + template<typename Archive> + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm, + ordered_non_unique_tag)const + { + typedef duplicates_iterator<node_type,value_compare> dup_iterator; + + sm.save( + dup_iterator(begin().get_node(),end().get_node(),value_comp()), + dup_iterator(end().get_node(),value_comp()), + ar,version); + super::save_(ar,version,sm); + } + + template<typename Archive> + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm, + ordered_non_unique_tag) + { + lm.load( + ::boost::bind(&ordered_index::rearranger,this,_1,_2), + ar,version); + super::load_(ar,version,lm); + } + + void rearranger(node_type* position,node_type *x) + { + if(!position||comp(key(position->value()),key(x->value()))){ + position=lower_bound(key(x->value())).get_node(); + } + else if(comp(key(x->value()),key(position->value()))){ + /* inconsistent rearrangement */ + throw_exception( + archive::archive_exception( + archive::archive_exception::other_exception)); + } + else node_type::increment(position); + + if(position!=x){ + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + node_impl_type::restore( + x->impl(),position->impl(),header()->impl()); + } + } +#endif /* serialization */ + + key_from_value key; + key_compare comp; + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +/* comparison */ + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator==( + const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y) +{ + return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator<( + const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y) +{ + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator!=( + const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y) +{ + return !(x==y); +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator>( + const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y) +{ + return y<x; +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator>=( + const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y) +{ + return !(x<y); +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator<=( + const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y) +{ + return !(x>y); +} + +/* specialized algorithms */ + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category +> +void swap( + ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x, + ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +/* ordered_index specifiers */ + +template<typename Arg1,typename Arg2,typename Arg3> +struct ordered_unique +{ + typedef typename detail::ordered_index_args< + Arg1,Arg2,Arg3> index_args; + typedef typename index_args::tag_list_type::type tag_list_type; + typedef typename index_args::key_from_value_type key_from_value_type; + typedef typename index_args::compare_type compare_type; + + template<typename Super> + struct node_class + { + typedef detail::ordered_index_node<Super> type; + }; + + template<typename SuperMeta> + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_unique_tag> type; + }; +}; + +template<typename Arg1,typename Arg2,typename Arg3> +struct ordered_non_unique +{ + typedef detail::ordered_index_args< + Arg1,Arg2,Arg3> index_args; + typedef typename index_args::tag_list_type::type tag_list_type; + typedef typename index_args::key_from_value_type key_from_value_type; + typedef typename index_args::compare_type compare_type; + + template<typename Super> + struct node_class + { + typedef detail::ordered_index_node<Super> type; + }; + + template<typename SuperMeta> + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_non_unique_tag> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/ordered_index_fwd.hpp b/3rdParty/Boost/src/boost/multi_index/ordered_index_fwd.hpp new file mode 100644 index 0000000..6288a71 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/ordered_index_fwd.hpp @@ -0,0 +1,124 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/multi_index/detail/ord_index_args.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category +> +class ordered_index; + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator==( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator<( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator!=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator>( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator>=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2 +> +bool operator<=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y); + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category +> +void swap( + ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x, + ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& y); + +} /* namespace multi_index::detail */ + +/* ordered_index specifiers */ + +template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na> +struct ordered_unique; + +template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na> +struct ordered_non_unique; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/safe_mode_errors.hpp b/3rdParty/Boost/src/boost/multi_index/safe_mode_errors.hpp new file mode 100644 index 0000000..ff6f960 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/safe_mode_errors.hpp @@ -0,0 +1,48 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_SAFE_MODE_ERRORS_HPP +#define BOOST_MULTI_INDEX_SAFE_MODE_ERRORS_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace safe_mode{ + +/* Error codes for Boost.MultiIndex safe mode. These go in a separate + * header so that the user can include it when redefining + * BOOST_MULTI_INDEX_SAFE_MODE_ASSERT prior to the inclusion of + * any other header of Boost.MultiIndex. + */ + +enum error_code +{ + invalid_iterator=0, + not_dereferenceable_iterator, + not_incrementable_iterator, + not_decrementable_iterator, + not_owner, + not_same_owner, + invalid_range, + inside_range, + out_of_bounds, + same_container +}; + +} /* namespace multi_index::safe_mode */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/sequenced_index.hpp b/3rdParty/Boost/src/boost/multi_index/sequenced_index.hpp new file mode 100644 index 0000000..8e09115 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/sequenced_index.hpp @@ -0,0 +1,922 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP +#define BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/call_traits.hpp> +#include <boost/detail/allocator_utilities.hpp> +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/iterator/reverse_iterator.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/push_front.hpp> +#include <boost/multi_index/detail/access_specifier.hpp> +#include <boost/multi_index/detail/bidir_node_iterator.hpp> +#include <boost/multi_index/detail/index_node_base.hpp> +#include <boost/multi_index/detail/safe_ctr_proxy.hpp> +#include <boost/multi_index/detail/safe_mode.hpp> +#include <boost/multi_index/detail/scope_guard.hpp> +#include <boost/multi_index/detail/seq_index_node.hpp> +#include <boost/multi_index/detail/seq_index_ops.hpp> +#include <boost/multi_index/sequenced_index_fwd.hpp> +#include <boost/tuple/tuple.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <cstddef> +#include <functional> +#include <utility> + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include <boost/bind.hpp> +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(*this,&sequenced_index::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#else +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* sequenced_index adds a layer of sequenced indexing to a given Super */ + +template<typename SuperMeta,typename TagList> +class sequenced_index: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) + ,public safe_ctr_proxy_impl< + bidir_node_iterator< + sequenced_index_node<typename SuperMeta::type::node_type> >, + sequenced_index<SuperMeta,TagList> > +#else + ,public safe_mode::safe_container< + sequenced_index<SuperMeta,TagList> > +#endif +#endif + +{ +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the + * lifetime of const references bound to temporaries --precisely what + * scopeguards are. + */ + +#pragma parse_mfunc_templ off +#endif + + typedef typename SuperMeta::type super; + +protected: + typedef sequenced_index_node< + typename super::node_type> node_type; + +private: + typedef typename node_type::impl_type node_impl_type; + +public: + /* types */ + + typedef typename node_type::value_type value_type; + typedef tuples::null_type ctor_args; + typedef typename super::final_allocator_type allocator_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) + typedef safe_mode::safe_iterator< + bidir_node_iterator<node_type>, + safe_ctr_proxy< + bidir_node_iterator<node_type> > > iterator; +#else + typedef safe_mode::safe_iterator< + bidir_node_iterator<node_type>, + sequenced_index> iterator; +#endif +#else + typedef bidir_node_iterator<node_type> iterator; +#endif + + typedef iterator const_iterator; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename + boost::reverse_iterator<iterator> reverse_iterator; + typedef typename + boost::reverse_iterator<const_iterator> const_reverse_iterator; + typedef TagList tag_list; + +protected: + typedef typename super::final_node_type final_node_type; + typedef tuples::cons< + ctor_args, + typename super::ctor_args_list> ctor_args_list; + typedef typename mpl::push_front< + typename super::index_type_list, + sequenced_index>::type index_type_list; + typedef typename mpl::push_front< + typename super::iterator_type_list, + iterator>::type iterator_type_list; + typedef typename mpl::push_front< + typename super::const_iterator_type_list, + const_iterator>::type const_iterator_type_list; + typedef typename super::copy_map_type copy_map_type; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + typedef typename super::index_saver_type index_saver_type; + typedef typename super::index_loader_type index_loader_type; +#endif + +private: +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) + typedef safe_ctr_proxy_impl< + bidir_node_iterator<node_type>, + sequenced_index> safe_super; +#else + typedef safe_mode::safe_container< + sequenced_index> safe_super; +#endif +#endif + + typedef typename call_traits<value_type>::param_type value_param_type; + +public: + + /* construct/copy/destroy + * Default and copy ctors are in the protected section as indices are + * not supposed to be created on their own. No range ctor either. + */ + + sequenced_index<SuperMeta,TagList>& operator=( + const sequenced_index<SuperMeta,TagList>& x) + { + this->final()=x.final(); + return *this; + } + + template <class InputIterator> + void assign(InputIterator first,InputIterator last) + { + assign_iter(first,last,mpl::not_<is_integral<InputIterator> >()); + } + + void assign(size_type n,value_param_type value) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;i<n;++i)push_back(value); + } + + allocator_type get_allocator()const + { + return this->final().get_allocator(); + } + + /* iterators */ + + iterator begin() + {return make_iterator(node_type::from_impl(header()->next()));} + const_iterator begin()const + {return make_iterator(node_type::from_impl(header()->next()));} + iterator end(){return make_iterator(header());} + const_iterator end()const{return make_iterator(header());} + reverse_iterator rbegin(){return make_reverse_iterator(end());} + const_reverse_iterator rbegin()const{return make_reverse_iterator(end());} + reverse_iterator rend(){return make_reverse_iterator(begin());} + const_reverse_iterator rend()const{return make_reverse_iterator(begin());} + const_iterator cbegin()const{return begin();} + const_iterator cend()const{return end();} + const_reverse_iterator crbegin()const{return rbegin();} + const_reverse_iterator crend()const{return rend();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value<node_type>(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value<node_type>(&x)); + } + + /* capacity */ + + bool empty()const{return this->final_empty_();} + size_type size()const{return this->final_size_();} + size_type max_size()const{return this->final_max_size_();} + + void resize(size_type n,value_param_type x=value_type()) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(n>size())insert(end(),n-size(),x); + else if(n<size()){ + iterator it; + if(n<=size()/2){ + it=begin(); + std::advance(it,n); + } + else{ + it=end(); + for(size_type m=size()-n;m--;--it){} + } + erase(it,end()); + } + } + + /* access: no non-const versions provided as sequenced_index + * handles const elements. + */ + + const_reference front()const{return *begin();} + const_reference back()const{return *--end();} + + /* modifiers */ + + std::pair<iterator,bool> push_front(value_param_type x) + {return insert(begin(),x);} + void pop_front(){erase(begin());} + std::pair<iterator,bool> push_back(value_param_type x) + {return insert(end(),x);} + void pop_back(){erase(--end());} + + std::pair<iterator,bool> insert(iterator position,value_param_type x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + std::pair<final_node_type*,bool> p=this->final_insert_(x); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair<iterator,bool>(make_iterator(p.first),p.second); + } + + void insert(iterator position,size_type n,value_param_type x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + for(size_type i=0;i<n;++i)insert(position,x); + } + + template<typename InputIterator> + void insert(iterator position,InputIterator first,InputIterator last) + { + insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >()); + } + + iterator erase(iterator position) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + this->final_erase_(static_cast<final_node_type*>(position++.get_node())); + return position; + } + + iterator erase(iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + while(first!=last){ + first=erase(first); + } + return first; + } + + bool replace(iterator position,value_param_type x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + return this->final_replace_( + x,static_cast<final_node_type*>(position.get_node())); + } + + template<typename Modifier> + bool modify(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,static_cast<final_node_type*>(position.get_node())); + } + + template<typename Modifier,typename Rollback> + bool modify(iterator position,Modifier mod,Rollback back) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,back,static_cast<final_node_type*>(position.get_node())); + } + + void swap(sequenced_index<SuperMeta,TagList>& x) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + this->final_swap_(x.final()); + } + + void clear() + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + /* list operations */ + + void splice(iterator position,sequenced_index<SuperMeta,TagList>& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + iterator first=x.begin(),last=x.end(); + while(first!=last){ + if(insert(position,*first).second)first=x.erase(first); + else ++first; + } + } + + void splice(iterator position,sequenced_index<SuperMeta,TagList>& x,iterator i) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(&x==this){ + if(position!=i)relink(position.get_node(),i.get_node()); + } + else{ + if(insert(position,*i).second){ + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following + * workaround is needed. Left it for all compilers as it does no + * harm. + */ + i.detach(); + x.erase(x.make_iterator(i.get_node())); +#else + x.erase(i); +#endif + + } + } + } + + void splice( + iterator position,sequenced_index<SuperMeta,TagList>& x, + iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(&x==this){ + BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); + if(position!=last)relink( + position.get_node(),first.get_node(),last.get_node()); + } + else{ + while(first!=last){ + if(insert(position,*first).second)first=x.erase(first); + else ++first; + } + } + } + + void remove(value_param_type value) + { + sequenced_index_remove( + *this,std::bind2nd(std::equal_to<value_type>(),value)); + } + + template<typename Predicate> + void remove_if(Predicate pred) + { + sequenced_index_remove(*this,pred); + } + + void unique() + { + sequenced_index_unique(*this,std::equal_to<value_type>()); + } + + template <class BinaryPredicate> + void unique(BinaryPredicate binary_pred) + { + sequenced_index_unique(*this,binary_pred); + } + + void merge(sequenced_index<SuperMeta,TagList>& x) + { + sequenced_index_merge(*this,x,std::less<value_type>()); + } + + template <typename Compare> + void merge(sequenced_index<SuperMeta,TagList>& x,Compare comp) + { + sequenced_index_merge(*this,x,comp); + } + + void sort() + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + sequenced_index_sort(header(),std::less<value_type>()); + } + + template <typename Compare> + void sort(Compare comp) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + sequenced_index_sort(header(),comp); + } + + void reverse() + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + node_impl_type::reverse(header()->impl()); + } + + /* rearrange operations */ + + void relocate(iterator position,iterator i) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(position!=i)relink(position.get_node(),i.get_node()); + } + + void relocate(iterator position,iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(position!=last)relink( + position.get_node(),first.get_node(),last.get_node()); + } + + template<typename InputIterator> + void rearrange(InputIterator first) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + node_type* pos=header(); + for(size_type s=size();s--;){ + const value_type& v=*first++; + relink(pos,node_from_value<node_type>(&v)); + } + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + sequenced_index(const ctor_args_list& args_list,const allocator_type& al): + super(args_list.get_tail(),al) + { + empty_initialize(); + } + + sequenced_index(const sequenced_index<SuperMeta,TagList>& x): + super(x) + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,safe_super() +#endif + + { + /* The actual copying takes place in subsequent call to copy_(). + */ + } + + ~sequenced_index() + { + /* the container is guaranteed to be empty by now */ + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + iterator make_iterator(node_type* node){return iterator(node,this);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node,const_cast<sequenced_index*>(this));} +#else + iterator make_iterator(node_type* node){return iterator(node);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node);} +#endif + + void copy_( + const sequenced_index<SuperMeta,TagList>& x,const copy_map_type& map) + { + node_type* org=x.header(); + node_type* cpy=header(); + do{ + node_type* next_org=node_type::from_impl(org->next()); + node_type* next_cpy=map.find(static_cast<final_node_type*>(next_org)); + cpy->next()=next_cpy->impl(); + next_cpy->prior()=cpy->impl(); + org=next_org; + cpy=next_cpy; + }while(org!=x.header()); + + super::copy_(x,map); + } + + node_type* insert_(value_param_type v,node_type* x) + { + node_type* res=static_cast<node_type*>(super::insert_(v,x)); + if(res==x)link(x); + return res; + } + + node_type* insert_(value_param_type v,node_type* position,node_type* x) + { + node_type* res=static_cast<node_type*>(super::insert_(v,position,x)); + if(res==x)link(x); + return res; + } + + void erase_(node_type* x) + { + unlink(x); + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + } + + void delete_all_nodes_() + { + for(node_type* x=node_type::from_impl(header()->next());x!=header();){ + node_type* y=node_type::from_impl(x->next()); + this->final_delete_node_(static_cast<final_node_type*>(x)); + x=y; + } + } + + void clear_() + { + super::clear_(); + empty_initialize(); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::detach_dereferenceable_iterators(); +#endif + } + + void swap_(sequenced_index<SuperMeta,TagList>& x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + bool replace_(value_param_type v,node_type* x) + { + return super::replace_(v,x); + } + + bool modify_(node_type* x) + { + BOOST_TRY{ + if(!super::modify_(x)){ + unlink(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + return false; + } + else return true; + } + BOOST_CATCH(...){ + unlink(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_rollback_(node_type* x) + { + return super::modify_rollback_(x); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template<typename Archive> + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm)const + { + sm.save(begin(),end(),ar,version); + super::save_(ar,version,sm); + } + + template<typename Archive> + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm) + { + lm.load( + ::boost::bind(&sequenced_index::rearranger,this,_1,_2), + ar,version); + super::load_(ar,version,lm); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + if(size()==0||begin()==end()){ + if(size()!=0||begin()!=end()|| + header()->next()!=header()->impl()|| + header()->prior()!=header()->impl())return false; + } + else{ + size_type s=0; + for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){ + if(it.get_node()->next()->prior()!=it.get_node()->impl())return false; + if(it.get_node()->prior()->next()!=it.get_node()->impl())return false; + } + if(s!=size())return false; + } + + return super::invariant_(); + } + + /* This forwarding function eases things for the boost::mem_fn construct + * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually, + * final_check_invariant is already an inherited member function of index. + */ + void check_invariant_()const{this->final_check_invariant_();} +#endif + +private: + node_type* header()const{return this->final_header();} + + void empty_initialize() + { + header()->prior()=header()->next()=header()->impl(); + } + + void link(node_type* x) + { + node_impl_type::link(x->impl(),header()->impl()); + }; + + static void unlink(node_type* x) + { + node_impl_type::unlink(x->impl()); + } + + static void relink(node_type* position,node_type* x) + { + node_impl_type::relink(position->impl(),x->impl()); + } + + static void relink(node_type* position,node_type* first,node_type* last) + { + node_impl_type::relink( + position->impl(),first->impl(),last->impl()); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + void rearranger(node_type* position,node_type *x) + { + if(!position)position=header(); + node_type::increment(position); + if(position!=x)relink(position,x); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + void detach_iterators(node_type* x) + { + iterator it=make_iterator(x); + safe_mode::detach_equivalent_iterators(it); + } +#endif + + template <class InputIterator> + void assign_iter(InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + clear(); + for(;first!=last;++first)push_back(*first); + } + + void assign_iter(size_type n,value_param_type value,mpl::false_) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;i<n;++i)push_back(value); + } + + template<typename InputIterator> + void insert_iter( + iterator position,InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + for(;first!=last;++first)insert(position,*first); + } + + void insert_iter( + iterator position,size_type n,value_param_type x,mpl::false_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + for(size_type i=0;i<n;++i)insert(position,x); + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +/* comparison */ + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator==( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y) +{ + return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y) +{ + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator!=( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y) +{ + return !(x==y); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y) +{ + return y<x; +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>=( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y) +{ + return !(x<y); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<=( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y) +{ + return !(x>y); +} + +/* specialized algorithms */ + +template<typename SuperMeta,typename TagList> +void swap( + sequenced_index<SuperMeta,TagList>& x, + sequenced_index<SuperMeta,TagList>& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +/* sequenced index specifier */ + +template <typename TagList> +struct sequenced +{ + BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value); + + template<typename Super> + struct node_class + { + typedef detail::sequenced_index_node<Super> type; + }; + + template<typename SuperMeta> + struct index_class + { + typedef detail::sequenced_index<SuperMeta,typename TagList::type> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/sequenced_index_fwd.hpp b/3rdParty/Boost/src/boost/multi_index/sequenced_index_fwd.hpp new file mode 100644 index 0000000..5211390 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/sequenced_index_fwd.hpp @@ -0,0 +1,91 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/multi_index/tag.hpp> + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template<typename SuperMeta,typename TagList> +class sequenced_index; + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator==( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator!=( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>=( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<=( + const sequenced_index<SuperMeta1,TagList1>& x, + const sequenced_index<SuperMeta2,TagList2>& y); + +template<typename SuperMeta,typename TagList> +void swap( + sequenced_index<SuperMeta,TagList>& x, + sequenced_index<SuperMeta,TagList>& y); + +} /* namespace multi_index::detail */ + +/* index specifiers */ + +template <typename TagList=tag<> > +struct sequenced; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index/tag.hpp b/3rdParty/Boost/src/boost/multi_index/tag.hpp new file mode 100644 index 0000000..ba7cab4 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index/tag.hpp @@ -0,0 +1,92 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_TAG_HPP +#define BOOST_MULTI_INDEX_TAG_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/multi_index/detail/no_duplicate_tags.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/transform.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/preprocessor/facilities/intercept.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_base_and_derived.hpp> + +/* A wrapper of mpl::vector used to hide MPL from the user. + * tag contains types used as tag names for indices in get() functions. + */ + +/* This user_definable macro limits the number of elements of a tag; + * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, + * has problems coping with very long symbol names.) + */ + +#if !defined(BOOST_MULTI_INDEX_LIMIT_TAG_SIZE) +#if defined(BOOST_MSVC)&&(BOOST_MSVC<1300) +#define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE 3 +#else +#define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE +#endif +#endif + +#if BOOST_MULTI_INDEX_LIMIT_TAG_SIZE<BOOST_MPL_LIMIT_VECTOR_SIZE +#define BOOST_MULTI_INDEX_TAG_SIZE BOOST_MULTI_INDEX_LIMIT_TAG_SIZE +#else +#define BOOST_MULTI_INDEX_TAG_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +struct tag_marker{}; + +template<typename T> +struct is_tag +{ + BOOST_STATIC_CONSTANT(bool,value=(is_base_and_derived<tag_marker,T>::value)); +}; + +} /* namespace multi_index::detail */ + +template< + BOOST_PP_ENUM_BINARY_PARAMS( + BOOST_MULTI_INDEX_TAG_SIZE, + typename T, + =mpl::na BOOST_PP_INTERCEPT) +> +struct tag:private detail::tag_marker +{ + /* The mpl::transform pass produces shorter symbols (without + * trailing mpl::na's.) + */ + + typedef typename mpl::transform< + mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_TAG_SIZE,T)>, + mpl::identity<mpl::_1> + >::type type; + + BOOST_STATIC_ASSERT(detail::no_duplicate_tags<type>::value); +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_TAG_SIZE + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index_container.hpp b/3rdParty/Boost/src/boost/multi_index_container.hpp new file mode 100644 index 0000000..e1969b9 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index_container.hpp @@ -0,0 +1,1143 @@ +/* Multiply indexed container. + * + * Copyright 2003-2010 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_HPP +#define BOOST_MULTI_INDEX_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <algorithm> +#include <boost/detail/allocator_utilities.hpp> +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/contains.hpp> +#include <boost/mpl/find_if.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/size.hpp> +#include <boost/mpl/deref.hpp> +#include <boost/multi_index_container_fwd.hpp> +#include <boost/multi_index/detail/access_specifier.hpp> +#include <boost/multi_index/detail/adl_swap.hpp> +#include <boost/multi_index/detail/base_type.hpp> +#include <boost/multi_index/detail/converter.hpp> +#include <boost/multi_index/detail/header_holder.hpp> +#include <boost/multi_index/detail/has_tag.hpp> +#include <boost/multi_index/detail/no_duplicate_tags.hpp> +#include <boost/multi_index/detail/prevent_eti.hpp> +#include <boost/multi_index/detail/safe_mode.hpp> +#include <boost/multi_index/detail/scope_guard.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/utility/base_from_member.hpp> + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include <boost/multi_index/detail/archive_constructed.hpp> +#include <boost/multi_index/detail/serialization_version.hpp> +#include <boost/serialization/collection_size_type.hpp> +#include <boost/serialization/nvp.hpp> +#include <boost/serialization/split_member.hpp> +#include <boost/serialization/version.hpp> +#include <boost/throw_exception.hpp> +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#include <boost/multi_index/detail/invariant_assert.hpp> +#define BOOST_MULTI_INDEX_CHECK_INVARIANT \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(*this,&multi_index_container::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#else +#define BOOST_MULTI_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +template<typename Value,typename IndexSpecifierList,typename Allocator> +class multi_index_container: + private ::boost::base_from_member< + typename boost::detail::allocator::rebind_to< + Allocator, + typename detail::multi_index_node_type< + Value,IndexSpecifierList,Allocator>::type + >::type>, + BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder< + typename detail::prevent_eti< + Allocator, + typename boost::detail::allocator::rebind_to< + Allocator, + typename detail::multi_index_node_type< + Value,IndexSpecifierList,Allocator>::type + >::type + >::type::pointer, + multi_index_container<Value,IndexSpecifierList,Allocator> >, + public detail::multi_index_base_type< + Value,IndexSpecifierList,Allocator>::type +{ +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the + * lifetime of const references bound to temporaries --precisely what + * scopeguards are. + */ + +#pragma parse_mfunc_templ off +#endif + +private: +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template <typename,typename,typename> friend class detail::index_base; + template <typename,typename> friend struct detail::header_holder; + template <typename,typename> friend struct detail::converter; +#endif + + typedef typename detail::multi_index_base_type< + Value,IndexSpecifierList,Allocator>::type super; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + typename super::node_type + >::type node_allocator; + typedef ::boost::base_from_member< + node_allocator> bfm_allocator; + typedef detail::header_holder< + typename detail::prevent_eti< + Allocator, + node_allocator + >::type::pointer, + multi_index_container> bfm_header; + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) + /* see definition of index_type_list below */ + typedef typename super::index_type_list super_index_type_list; +#endif + +public: + /* All types are inherited from super, a few are explicitly + * brought forward here to save us some typename's. + */ + + typedef typename super::ctor_args_list ctor_args_list; + typedef IndexSpecifierList index_specifier_type_list; + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) + /* MSVC++ 6.0 chokes on moderately long index lists (around 6 indices + * or more), with errors ranging from corrupt exes to duplicate + * comdats. The following type hiding hack alleviates this condition; + * best results combined with type hiding of the indexed_by construct + * itself, as explained in the "Compiler specifics" section of + * the documentation. + */ + + struct index_type_list:super_index_type_list + { + typedef index_type_list type; + typedef typename super_index_type_list::back back; + typedef mpl::v_iter<type,0> begin; + typedef mpl::v_iter< + type, + mpl::size<super_index_type_list>::value> end; + }; +#else + typedef typename super::index_type_list index_type_list; +#endif + + typedef typename super::iterator_type_list iterator_type_list; + typedef typename super::const_iterator_type_list const_iterator_type_list; + typedef typename super::value_type value_type; + typedef typename super::final_allocator_type allocator_type; + typedef typename super::iterator iterator; + typedef typename super::const_iterator const_iterator; + + BOOST_STATIC_ASSERT( + detail::no_duplicate_tags_in_index_list<index_type_list>::value); + + /* global project() needs to see this publicly */ + + typedef typename super::node_type node_type; + + /* construct/copy/destroy */ + + explicit multi_index_container( + +#if BOOST_WORKAROUND(__IBMCPP__,<=600) + /* VisualAge seems to have an ETI issue with the default values + * for arguments args_list and al. + */ + + const ctor_args_list& args_list= + typename mpl::identity<multi_index_container>::type:: + ctor_args_list(), + const allocator_type& al= + typename mpl::identity<multi_index_container>::type:: + allocator_type()): +#else + const ctor_args_list& args_list=ctor_args_list(), + const allocator_type& al=allocator_type()): +#endif + + bfm_allocator(al), + super(args_list,bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } + + explicit multi_index_container(const allocator_type& al): + bfm_allocator(al), + super(ctor_args_list(),bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } + + template<typename InputIterator> + multi_index_container( + InputIterator first,InputIterator last, + +#if BOOST_WORKAROUND(__IBMCPP__,<=600) + /* VisualAge seems to have an ETI issue with the default values + * for arguments args_list and al. + */ + + const ctor_args_list& args_list= + typename mpl::identity<multi_index_container>::type:: + ctor_args_list(), + const allocator_type& al= + typename mpl::identity<multi_index_container>::type:: + allocator_type()): +#else + const ctor_args_list& args_list=ctor_args_list(), + const allocator_type& al=allocator_type()): +#endif + + bfm_allocator(al), + super(args_list,bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + BOOST_TRY{ + iterator hint=super::end(); + for(;first!=last;++first){ + hint=super::make_iterator(insert_(*first,hint.get_node()).first); + } + } + BOOST_CATCH(...){ + clear_(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + multi_index_container( + const multi_index_container<Value,IndexSpecifierList,Allocator>& x): + bfm_allocator(x.bfm_allocator::member), + bfm_header(), + super(x), + node_count(0) + { + copy_map_type map(bfm_allocator::member,x.size(),x.header(),header()); + for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){ + map.clone(it.get_node()); + } + super::copy_(x,map); + map.release(); + node_count=x.size(); + + /* Not until this point are the indices required to be consistent, + * hence the position of the invariant checker. + */ + + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } + + ~multi_index_container() + { + delete_all_nodes_(); + } + + multi_index_container<Value,IndexSpecifierList,Allocator>& operator=( + multi_index_container<Value,IndexSpecifierList,Allocator> x) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + this->swap(x); + return *this; + } + + allocator_type get_allocator()const + { + return allocator_type(bfm_allocator::member); + } + + /* retrieval of indices by number */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template<int N> + struct nth_index + { + BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value); + typedef typename mpl::at_c<index_type_list,N>::type type; + }; + + template<int N> + typename nth_index<N>::type& get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N)) + { + BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value); + return *this; + } + + template<int N> + const typename nth_index<N>::type& get( + BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N))const + { + BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value); + return *this; + } +#endif + + /* retrieval of indices by tag */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template<typename Tag> + struct index + { + typedef typename mpl::find_if< + index_type_list, + detail::has_tag<Tag> + >::type iter; + + BOOST_STATIC_CONSTANT( + bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value)); + BOOST_STATIC_ASSERT(index_found); + + typedef typename mpl::deref<iter>::type type; + }; + + template<typename Tag> + typename index<Tag>::type& get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) + { + return *this; + } + + template<typename Tag> + const typename index<Tag>::type& get( + BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))const + { + return *this; + } +#endif + + /* projection of iterators by number */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template<int N> + struct nth_index_iterator + { + typedef typename nth_index<N>::type::iterator type; + }; + + template<int N> + struct nth_index_const_iterator + { + typedef typename nth_index<N>::type::const_iterator type; + }; + + template<int N,typename IteratorType> + typename nth_index_iterator<N>::type project( + IteratorType it + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N)) + { + typedef typename nth_index<N>::type index; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT( + (mpl::contains<iterator_type_list,IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast<typename IteratorType::container_type&>(*this)); + + return index::make_iterator(static_cast<node_type*>(it.get_node())); + } + + template<int N,typename IteratorType> + typename nth_index_const_iterator<N>::type project( + IteratorType it + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))const + { + typedef typename nth_index<N>::type index; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains<iterator_type_list,IteratorType>::value|| + mpl::contains<const_iterator_type_list,IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast<const typename IteratorType::container_type&>(*this)); + return index::make_iterator(static_cast<node_type*>(it.get_node())); + } +#endif + + /* projection of iterators by tag */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template<typename Tag> + struct index_iterator + { + typedef typename index<Tag>::type::iterator type; + }; + + template<typename Tag> + struct index_const_iterator + { + typedef typename index<Tag>::type::const_iterator type; + }; + + template<typename Tag,typename IteratorType> + typename index_iterator<Tag>::type project( + IteratorType it + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) + { + typedef typename index<Tag>::type index; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT( + (mpl::contains<iterator_type_list,IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast<typename IteratorType::container_type&>(*this)); + return index::make_iterator(static_cast<node_type*>(it.get_node())); + } + + template<typename Tag,typename IteratorType> + typename index_const_iterator<Tag>::type project( + IteratorType it + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))const + { + typedef typename index<Tag>::type index; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains<iterator_type_list,IteratorType>::value|| + mpl::contains<const_iterator_type_list,IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast<const typename IteratorType::container_type&>(*this)); + return index::make_iterator(static_cast<node_type*>(it.get_node())); + } +#endif + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + typedef typename super::copy_map_type copy_map_type; + + node_type* header()const + { + return &*bfm_header::member; + } + + node_type* allocate_node() + { + return &*bfm_allocator::member.allocate(1); + } + + void deallocate_node(node_type* x) + { + typedef typename node_allocator::pointer node_pointer; + bfm_allocator::member.deallocate(static_cast<node_pointer>(x),1); + } + + bool empty_()const + { + return node_count==0; + } + + std::size_t size_()const + { + return node_count; + } + + std::size_t max_size_()const + { + return static_cast<std::size_t >(-1); + } + + std::pair<node_type*,bool> insert_(const Value& v) + { + node_type* x=allocate_node(); + BOOST_TRY{ + node_type* res=super::insert_(v,x); + if(res==x){ + ++node_count; + return std::pair<node_type*,bool>(res,true); + } + else{ + deallocate_node(x); + return std::pair<node_type*,bool>(res,false); + } + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + std::pair<node_type*,bool> insert_(const Value& v,node_type* position) + { + node_type* x=allocate_node(); + BOOST_TRY{ + node_type* res=super::insert_(v,position,x); + if(res==x){ + ++node_count; + return std::pair<node_type*,bool>(res,true); + } + else{ + deallocate_node(x); + return std::pair<node_type*,bool>(res,false); + } + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + void erase_(node_type* x) + { + --node_count; + super::erase_(x); + deallocate_node(x); + } + + void delete_node_(node_type* x) + { + super::delete_node_(x); + deallocate_node(x); + } + + void delete_all_nodes_() + { + super::delete_all_nodes_(); + } + + void clear_() + { + delete_all_nodes_(); + super::clear_(); + node_count=0; + } + + void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x) + { + if(bfm_allocator::member!=x.bfm_allocator::member){ + detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member); + } + std::swap(bfm_header::member,x.bfm_header::member); + super::swap_(x); + std::swap(node_count,x.node_count); + } + + bool replace_(const Value& k,node_type* x) + { + return super::replace_(k,x); + } + + template<typename Modifier> + bool modify_(Modifier& mod,node_type* x) + { + mod(const_cast<value_type&>(x->value())); + + BOOST_TRY{ + if(!super::modify_(x)){ + deallocate_node(x); + --node_count; + return false; + } + else return true; + } + BOOST_CATCH(...){ + deallocate_node(x); + --node_count; + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + template<typename Modifier,typename Rollback> + bool modify_(Modifier& mod,Rollback& back,node_type* x) + { + mod(const_cast<value_type&>(x->value())); + + bool b; + BOOST_TRY{ + b=super::modify_rollback_(x); + } + BOOST_CATCH(...){ + BOOST_TRY{ + back(const_cast<value_type&>(x->value())); + BOOST_RETHROW; + } + BOOST_CATCH(...){ + this->erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH_END + + BOOST_TRY{ + if(!b){ + back(const_cast<value_type&>(x->value())); + return false; + } + else return true; + } + BOOST_CATCH(...){ + this->erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + friend class boost::serialization::access; + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + typedef typename super::index_saver_type index_saver_type; + typedef typename super::index_loader_type index_loader_type; + + template<class Archive> + void save(Archive& ar,const unsigned int version)const + { + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + const serialization::collection_size_type s(size_()); + const detail::serialization_version<value_type> value_version; + ar<<serialization::make_nvp("count",s); + ar<<serialization::make_nvp("value_version",value_version); +#else + const std::size_t s=size_(); + const unsigned int value_version=0; + ar<<serialization::make_nvp("count",s); +#endif + + index_saver_type sm(bfm_allocator::member,s); + + for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){ + serialization::save_construct_data_adl(ar,&*it,value_version); + ar<<serialization::make_nvp("item",*it); + sm.add(it.get_node(),ar,version); + } + sm.add_track(header(),ar,version); + + super::save_(ar,version,sm); + } + + template<class Archive> + void load(Archive& ar,const unsigned int version) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + + clear_(); + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + serialization::collection_size_type s; + detail::serialization_version<value_type> value_version; + if(version<1){ + std::size_t sz; + ar>>serialization::make_nvp("count",sz); + s=sz; + } + else{ + ar>>serialization::make_nvp("count",s); + } + if(version<2){ + value_version=0; + } + else{ + ar>>serialization::make_nvp("value_version",value_version); + } +#else + std::size_t s; + unsigned int value_version=0; + ar>>serialization::make_nvp("count",s); +#endif + + index_loader_type lm(bfm_allocator::member,s); + + for(std::size_t n=0;n<s;++n){ + detail::archive_constructed<Value> value("item",ar,value_version); + std::pair<node_type*,bool> p=insert_( + value.get(),super::end().get_node()); + if(!p.second)throw_exception( + archive::archive_exception( + archive::archive_exception::other_exception)); + ar.reset_object_address(&p.first->value(),&value.get()); + lm.add(p.first,ar,version); + } + lm.add_track(header(),ar,version); + + super::load_(ar,version,lm); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + return super::invariant_(); + } + + void check_invariant_()const + { + BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_()); + } +#endif + +private: + std::size_t node_count; + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +/* retrieval of indices by number */ + +template<typename MultiIndexContainer,int N> +struct nth_index +{ + BOOST_STATIC_CONSTANT( + int, + M=mpl::size<typename MultiIndexContainer::index_type_list>::type::value); + BOOST_STATIC_ASSERT(N>=0&&N<M); + typedef typename mpl::at_c< + typename MultiIndexContainer::index_type_list,N>::type type; +}; + +template<int N,typename Value,typename IndexSpecifierList,typename Allocator> +typename nth_index< + multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type& +get( + multi_index_container<Value,IndexSpecifierList,Allocator>& m + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N)) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + N + >::type index; + + BOOST_STATIC_ASSERT(N>=0&& + N< + mpl::size< + BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list + >::type::value); + + return detail::converter<multi_index_type,index>::index(m); +} + +template<int N,typename Value,typename IndexSpecifierList,typename Allocator> +const typename nth_index< + multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type& +get( + const multi_index_container<Value,IndexSpecifierList,Allocator>& m + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N)) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + N + >::type index; + + BOOST_STATIC_ASSERT(N>=0&& + N< + mpl::size< + BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list + >::type::value); + + return detail::converter<multi_index_type,index>::index(m); +} + +/* retrieval of indices by tag */ + +template<typename MultiIndexContainer,typename Tag> +struct index +{ + typedef typename MultiIndexContainer::index_type_list index_type_list; + + typedef typename mpl::find_if< + index_type_list, + detail::has_tag<Tag> + >::type iter; + + BOOST_STATIC_CONSTANT( + bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value)); + BOOST_STATIC_ASSERT(index_found); + + typedef typename mpl::deref<iter>::type type; +}; + +template< + typename Tag,typename Value,typename IndexSpecifierList,typename Allocator +> +typename ::boost::multi_index::index< + multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type& +get( + multi_index_container<Value,IndexSpecifierList,Allocator>& m + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + Tag + >::type index; + + return detail::converter<multi_index_type,index>::index(m); +} + +template< + typename Tag,typename Value,typename IndexSpecifierList,typename Allocator +> +const typename ::boost::multi_index::index< + multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type& +get( + const multi_index_container<Value,IndexSpecifierList,Allocator>& m + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + Tag + >::type index; + + return detail::converter<multi_index_type,index>::index(m); +} + +/* projection of iterators by number */ + +template<typename MultiIndexContainer,int N> +struct nth_index_iterator +{ + typedef typename detail::prevent_eti< + nth_index<MultiIndexContainer,N>, + typename nth_index<MultiIndexContainer,N>::type>::type::iterator type; +}; + +template<typename MultiIndexContainer,int N> +struct nth_index_const_iterator +{ + typedef typename detail::prevent_eti< + nth_index<MultiIndexContainer,N>, + typename nth_index<MultiIndexContainer,N>::type + >::type::const_iterator type; +}; + +template< + int N,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename nth_index_iterator< + multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type +project( + multi_index_container<Value,IndexSpecifierList,Allocator>& m, + IteratorType it + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N)) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index<multi_index_type,N>::type index; + +#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\ + (!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, + IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef detail::converter< + multi_index_type, + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); +#endif + + return detail::converter<multi_index_type,index>::iterator( + m,static_cast<typename multi_index_type::node_type*>(it.get_node())); +} + +template< + int N,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename nth_index_const_iterator< + multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type +project( + const multi_index_container<Value,IndexSpecifierList,Allocator>& m, + IteratorType it + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N)) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index<multi_index_type,N>::type index; + +#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\ + (!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, + IteratorType>::value|| + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list, + IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef detail::converter< + multi_index_type, + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); +#endif + + return detail::converter<multi_index_type,index>::const_iterator( + m,static_cast<typename multi_index_type::node_type*>(it.get_node())); +} + +/* projection of iterators by tag */ + +template<typename MultiIndexContainer,typename Tag> +struct index_iterator +{ + typedef typename ::boost::multi_index::index< + MultiIndexContainer,Tag>::type::iterator type; +}; + +template<typename MultiIndexContainer,typename Tag> +struct index_const_iterator +{ + typedef typename ::boost::multi_index::index< + MultiIndexContainer,Tag>::type::const_iterator type; +}; + +template< + typename Tag,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename index_iterator< + multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type +project( + multi_index_container<Value,IndexSpecifierList,Allocator>& m, + IteratorType it + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_type,Tag>::type index; + +#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\ + (!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, + IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef detail::converter< + multi_index_type, + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); +#endif + + return detail::converter<multi_index_type,index>::iterator( + m,static_cast<typename multi_index_type::node_type*>(it.get_node())); +} + +template< + typename Tag,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename index_const_iterator< + multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type +project( + const multi_index_container<Value,IndexSpecifierList,Allocator>& m, + IteratorType it + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_type,Tag>::type index; + +#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\ + (!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, + IteratorType>::value|| + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list, + IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef detail::converter< + multi_index_type, + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); +#endif + + return detail::converter<multi_index_type,index>::const_iterator( + m,static_cast<typename multi_index_type::node_type*>(it.get_node())); +} + +/* Comparison. Simple forward to first index. */ + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator==( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y) +{ + return get<0>(x)==get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y) +{ + return get<0>(x)<get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator!=( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y) +{ + return get<0>(x)!=get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y) +{ + return get<0>(x)>get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>=( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y) +{ + return get<0>(x)>=get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<=( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y) +{ + return get<0>(x)<=get<0>(y); +} + +/* specialized algorithms */ + +template<typename Value,typename IndexSpecifierList,typename Allocator> +void swap( + multi_index_container<Value,IndexSpecifierList,Allocator>& x, + multi_index_container<Value,IndexSpecifierList,Allocator>& y) +{ + x.swap(y); +} + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)&&\ + !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +/* class version = 1 : we now serialize the size through + * boost::serialization::collection_size_type. + * class version = 2 : proper use of {save|load}_construct_data. + */ + +namespace serialization { +template<typename Value,typename IndexSpecifierList,typename Allocator> +struct version< + boost::multi_index_container<Value,IndexSpecifierList,Allocator> +> +{ + BOOST_STATIC_CONSTANT(int,value=2); +}; +} /* namespace serialization */ +#endif + +/* Associated global functions are promoted to namespace boost, except + * comparison operators and swap, which are meant to be Koenig looked-up. + */ + +using multi_index::get; +using multi_index::project; + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_CHECK_INVARIANT + +#endif diff --git a/3rdParty/Boost/src/boost/multi_index_container_fwd.hpp b/3rdParty/Boost/src/boost/multi_index_container_fwd.hpp new file mode 100644 index 0000000..99e8db3 --- /dev/null +++ b/3rdParty/Boost/src/boost/multi_index_container_fwd.hpp @@ -0,0 +1,121 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * 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/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_FWD_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ +#include <boost/multi_index/identity.hpp> +#include <boost/multi_index/indexed_by.hpp> +#include <boost/multi_index/ordered_index_fwd.hpp> +#include <memory> + +namespace boost{ + +namespace multi_index{ + +/* Default value for IndexSpecifierList specifies a container + * equivalent to std::set<Value>. + */ + +template< + typename Value, + typename IndexSpecifierList=indexed_by<ordered_unique<identity<Value> > >, + typename Allocator=std::allocator<Value> > +class multi_index_container; + +template<typename MultiIndexContainer,int N> +struct nth_index; + +template<typename MultiIndexContainer,typename Tag> +struct index; + +template<typename MultiIndexContainer,int N> +struct nth_index_iterator; + +template<typename MultiIndexContainer,int N> +struct nth_index_const_iterator; + +template<typename MultiIndexContainer,typename Tag> +struct index_iterator; + +template<typename MultiIndexContainer,typename Tag> +struct index_const_iterator; + +/* get and project functions not fwd declared due to problems + * with dependent typenames + */ + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator==( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator!=( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>=( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<=( + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y); + +template<typename Value,typename IndexSpecifierList,typename Allocator> +void swap( + multi_index_container<Value,IndexSpecifierList,Allocator>& x, + multi_index_container<Value,IndexSpecifierList,Allocator>& y); + +} /* namespace multi_index */ + +/* multi_index_container, being the main type of this library, is promoted to + * namespace boost. + */ + +using multi_index::multi_index_container; + +} /* namespace boost */ + +#endif diff --git a/3rdParty/Boost/src/boost/optional/optional_io.hpp b/3rdParty/Boost/src/boost/optional/optional_io.hpp new file mode 100644 index 0000000..85a1857 --- /dev/null +++ b/3rdParty/Boost/src/boost/optional/optional_io.hpp @@ -0,0 +1,84 @@ +// Copyright (C) 2005, Fernando Luis Cacciola Carballal. +// +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/optional for documentation. +// +// You are welcome to contact the author at: +// fernando_cacciola@hotmail.com +// +#ifndef BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP +#define BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP + +#if defined __GNUC__ +# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97) +# define BOOST_OPTIONAL_NO_TEMPLATED_STREAMS +# endif +#endif // __GNUC__ + +#if defined BOOST_OPTIONAL_NO_TEMPLATED_STREAMS +# include <iostream> +#else +# include <istream> +# include <ostream> +#endif + + +#include "boost/optional/optional.hpp" +#include "boost/utility/value_init.hpp" + +namespace boost +{ + +#if defined (BOOST_NO_TEMPLATED_STREAMS) +template<class T> +inline std::ostream& operator<<(std::ostream& out, optional<T> const& v) +#else +template<class CharType, class CharTrait, class T> +inline +std::basic_ostream<CharType, CharTrait>& +operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v) +#endif +{ + if ( out.good() ) + { + if ( !v ) + out << "--" ; + else out << ' ' << *v ; + } + + return out; +} + +#if defined (BOOST_NO_TEMPLATED_STREAMS) +template<class T> +inline std::istream& operator>>(std::istream& in, optional<T>& v) +#else +template<class CharType, class CharTrait, class T> +inline +std::basic_istream<CharType, CharTrait>& +operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v) +#endif +{ + if ( in.good() ) + { + int d = in.get(); + if ( d == ' ' ) + { + T x ; + in >> x; + v = x ; + } + else + v = optional<T>() ; + } + + return in; +} + +} // namespace boost + +#endif + diff --git a/3rdParty/Boost/src/boost/property_tree/detail/exception_implementation.hpp b/3rdParty/Boost/src/boost/property_tree/detail/exception_implementation.hpp new file mode 100644 index 0000000..551e10c --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/exception_implementation.hpp @@ -0,0 +1,83 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED + +namespace boost { namespace property_tree +{ + + namespace detail + { + + // Helper for preparing what string in ptree_bad_path exception + template<class P> inline + std::string prepare_bad_path_what(const std::string &what, + const P &path) + { + return what + " (" + path.dump() + ")"; + } + + } + + /////////////////////////////////////////////////////////////////////////// + // ptree_error + + inline ptree_error::ptree_error(const std::string &w): + std::runtime_error(w) + { + } + + inline ptree_error::~ptree_error() throw() + { + } + + /////////////////////////////////////////////////////////////////////////// + // ptree_bad_data + + template<class D> inline + ptree_bad_data::ptree_bad_data(const std::string &w, const D &d): + ptree_error(w), m_data(d) + { + } + + inline ptree_bad_data::~ptree_bad_data() throw() + { + } + + template<class D> inline + D ptree_bad_data::data() + { + return boost::any_cast<D>(m_data); + } + + /////////////////////////////////////////////////////////////////////////// + // ptree_bad_path + + template<class P> inline + ptree_bad_path::ptree_bad_path(const std::string &w, const P &p): + ptree_error(detail::prepare_bad_path_what(w, p)), m_path(p) + { + + } + + inline ptree_bad_path::~ptree_bad_path() throw() + { + } + + template<class P> inline + P ptree_bad_path::path() + { + return boost::any_cast<P>(m_path); + } + +}} + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/file_parser_error.hpp b/3rdParty/Boost/src/boost/property_tree/detail/file_parser_error.hpp new file mode 100644 index 0000000..ff90583 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/file_parser_error.hpp @@ -0,0 +1,88 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED + +#include <boost/property_tree/ptree.hpp> +#include <string> + +namespace boost { namespace property_tree +{ + + //! File parse error + class file_parser_error: public ptree_error + { + + public: + + /////////////////////////////////////////////////////////////////////// + // Construction & destruction + + // Construct error + file_parser_error(const std::string &msg, + const std::string &file, + unsigned long l) : + ptree_error(format_what(msg, file, l)), + m_message(msg), m_filename(file), m_line(l) + { + } + + ~file_parser_error() throw() + // gcc 3.4.2 complains about lack of throw specifier on compiler + // generated dtor + { + } + + /////////////////////////////////////////////////////////////////////// + // Data access + + // Get error message (without line and file - use what() to get + // full message) + std::string message() const + { + return m_message; + } + + // Get error filename + std::string filename() const + { + return m_filename; + } + + // Get error line number + unsigned long line() const + { + return m_line; + } + + private: + + std::string m_message; + std::string m_filename; + unsigned long m_line; + + // Format error message to be returned by std::runtime_error::what() + static std::string format_what(const std::string &msg, + const std::string &file, + unsigned long l) + { + std::stringstream stream; + stream << (file.empty() ? "<unspecified file>" : file.c_str()); + if (l > 0) + stream << '(' << l << ')'; + stream << ": " << msg; + return stream.str(); + } + + }; + +} } + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/ptree_implementation.hpp b/3rdParty/Boost/src/boost/property_tree/detail/ptree_implementation.hpp new file mode 100644 index 0000000..4220002 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/ptree_implementation.hpp @@ -0,0 +1,905 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED + +#include <boost/iterator/iterator_adaptor.hpp> +#include <boost/iterator/reverse_iterator.hpp> +#include <memory> +#include <cassert> + +#if defined(BOOST_MSVC) && \ + (_MSC_FULL_VER >= 160000000 && _MSC_FULL_VER < 170000000) +#define BOOST_PROPERTY_TREE_PAIR_BUG +#endif + +namespace boost { namespace property_tree +{ + template <class K, class D, class C> + struct basic_ptree<K, D, C>::subs + { + struct by_name {}; + // The actual child container. +#if defined(BOOST_PROPERTY_TREE_PAIR_BUG) + // MSVC 10 has moved std::pair's members to a base + // class. Unfortunately this does break the interface. + BOOST_STATIC_CONSTANT(unsigned, + first_offset = offsetof(value_type, first)); + typedef multi_index_container<value_type, + multi_index::indexed_by< + multi_index::sequenced<>, + multi_index::ordered_non_unique<multi_index::tag<by_name>, + multi_index::member_offset<value_type, const key_type, + first_offset>, + key_compare + > + > + > base_container; +#else + typedef multi_index_container<value_type, + multi_index::indexed_by< + multi_index::sequenced<>, + multi_index::ordered_non_unique<multi_index::tag<by_name>, + multi_index::member<value_type, const key_type, + &value_type::first>, + key_compare + > + > + > base_container; +#endif + // The by-name lookup index. + typedef typename base_container::template index<by_name>::type + by_name_index; + + // Access functions for getting to the children of a tree. + static base_container& ch(self_type *s) { + return *static_cast<base_container*>(s->m_children); + } + static const base_container& ch(const self_type *s) { + return *static_cast<const base_container*>(s->m_children); + } + static by_name_index& assoc(self_type *s) { + return ch(s).BOOST_NESTED_TEMPLATE get<by_name>(); + } + static const by_name_index& assoc(const self_type *s) { + return ch(s).BOOST_NESTED_TEMPLATE get<by_name>(); + } + }; + template <class K, class D, class C> + class basic_ptree<K, D, C>::iterator : public boost::iterator_adaptor< + iterator, typename subs::base_container::iterator, value_type> + { + friend class boost::iterator_core_access; + typedef boost::iterator_adaptor< + iterator, typename subs::base_container::iterator, value_type> + baset; + public: + typedef typename baset::reference reference; + iterator() {} + explicit iterator(typename iterator::base_type b) + : iterator::iterator_adaptor_(b) + {} + reference dereference() const + { + // multi_index doesn't allow modification of its values, because + // indexes could sort by anything, and modification screws that up. + // However, we only sort by the key, and it's protected against + // modification in the value_type, so this const_cast is safe. + return const_cast<reference>(*this->base_reference()); + } + }; + template <class K, class D, class C> + class basic_ptree<K, D, C>::const_iterator : public boost::iterator_adaptor< + const_iterator, typename subs::base_container::const_iterator> + { + public: + const_iterator() {} + explicit const_iterator(typename const_iterator::base_type b) + : const_iterator::iterator_adaptor_(b) + {} + const_iterator(iterator b) + : const_iterator::iterator_adaptor_(b.base()) + {} + }; + template <class K, class D, class C> + class basic_ptree<K, D, C>::reverse_iterator + : public boost::reverse_iterator<iterator> + { + public: + reverse_iterator() {} + explicit reverse_iterator(iterator b) + : boost::reverse_iterator<iterator>(b) + {} + }; + template <class K, class D, class C> + class basic_ptree<K, D, C>::const_reverse_iterator + : public boost::reverse_iterator<const_iterator> + { + public: + const_reverse_iterator() {} + explicit const_reverse_iterator(const_iterator b) + : boost::reverse_iterator<const_iterator>(b) + {} + const_reverse_iterator( + typename basic_ptree<K, D, C>::reverse_iterator b) + : boost::reverse_iterator<const_iterator>(b) + {} + }; + template <class K, class D, class C> + class basic_ptree<K, D, C>::assoc_iterator + : public boost::iterator_adaptor<assoc_iterator, + typename subs::by_name_index::iterator, + value_type> + { + friend class boost::iterator_core_access; + typedef boost::iterator_adaptor<assoc_iterator, + typename subs::by_name_index::iterator, + value_type> + baset; + public: + typedef typename baset::reference reference; + assoc_iterator() {} + explicit assoc_iterator(typename assoc_iterator::base_type b) + : assoc_iterator::iterator_adaptor_(b) + {} + reference dereference() const + { + return const_cast<reference>(*this->base_reference()); + } + }; + template <class K, class D, class C> + class basic_ptree<K, D, C>::const_assoc_iterator + : public boost::iterator_adaptor<const_assoc_iterator, + typename subs::by_name_index::const_iterator> + { + public: + const_assoc_iterator() {} + explicit const_assoc_iterator( + typename const_assoc_iterator::base_type b) + : const_assoc_iterator::iterator_adaptor_(b) + {} + const_assoc_iterator(assoc_iterator b) + : const_assoc_iterator::iterator_adaptor_(b.base()) + {} + }; + + + // Big five + + // Perhaps the children collection could be created on-demand only, to + // reduce heap traffic. But that's a lot more work to implement. + + template<class K, class D, class C> inline + basic_ptree<K, D, C>::basic_ptree() + : m_children(new typename subs::base_container) + { + } + + template<class K, class D, class C> inline + basic_ptree<K, D, C>::basic_ptree(const data_type &d) + : m_data(d), m_children(new typename subs::base_container) + { + } + + template<class K, class D, class C> inline + basic_ptree<K, D, C>::basic_ptree(const basic_ptree<K, D, C> &rhs) + : m_data(rhs.m_data), + m_children(new typename subs::base_container(subs::ch(&rhs))) + { + } + + template<class K, class D, class C> + basic_ptree<K, D, C> & + basic_ptree<K, D, C>::operator =(const basic_ptree<K, D, C> &rhs) + { + self_type(rhs).swap(*this); + return *this; + } + + template<class K, class D, class C> + basic_ptree<K, D, C>::~basic_ptree() + { + delete &subs::ch(this); + } + + template<class K, class D, class C> inline + void basic_ptree<K, D, C>::swap(basic_ptree<K, D, C> &rhs) + { + m_data.swap(rhs.m_data); + // Void pointers, no ADL necessary + std::swap(m_children, rhs.m_children); + } + + // Container view + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::size_type + basic_ptree<K, D, C>::size() const + { + return subs::ch(this).size(); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::size_type + basic_ptree<K, D, C>::max_size() const + { + return subs::ch(this).max_size(); + } + + template<class K, class D, class C> inline + bool basic_ptree<K, D, C>::empty() const + { + return subs::ch(this).empty(); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::iterator + basic_ptree<K, D, C>::begin() + { + return iterator(subs::ch(this).begin()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::const_iterator + basic_ptree<K, D, C>::begin() const + { + return const_iterator(subs::ch(this).begin()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::iterator + basic_ptree<K, D, C>::end() + { + return iterator(subs::ch(this).end()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::const_iterator + basic_ptree<K, D, C>::end() const + { + return const_iterator(subs::ch(this).end()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::reverse_iterator + basic_ptree<K, D, C>::rbegin() + { + return reverse_iterator(this->end()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::const_reverse_iterator + basic_ptree<K, D, C>::rbegin() const + { + return const_reverse_iterator(this->end()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::reverse_iterator + basic_ptree<K, D, C>::rend() + { + return reverse_iterator(this->begin()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::const_reverse_iterator + basic_ptree<K, D, C>::rend() const + { + return const_reverse_iterator(this->begin()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::value_type & + basic_ptree<K, D, C>::front() + { + return const_cast<value_type&>(subs::ch(this).front()); + } + + template<class K, class D, class C> inline + const typename basic_ptree<K, D, C>::value_type & + basic_ptree<K, D, C>::front() const + { + return subs::ch(this).front(); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::value_type & + basic_ptree<K, D, C>::back() + { + return const_cast<value_type&>(subs::ch(this).back()); + } + + template<class K, class D, class C> inline + const typename basic_ptree<K, D, C>::value_type & + basic_ptree<K, D, C>::back() const + { + return subs::ch(this).back(); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::iterator + basic_ptree<K, D, C>::insert(iterator where, const value_type &value) + { + return iterator(subs::ch(this).insert(where.base(), value).first); + } + + template<class K, class D, class C> + template<class It> inline + void basic_ptree<K, D, C>::insert(iterator where, It first, It last) + { + subs::ch(this).insert(where.base(), first, last); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::iterator + basic_ptree<K, D, C>::erase(iterator where) + { + return iterator(subs::ch(this).erase(where.base())); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::iterator + basic_ptree<K, D, C>::erase(iterator first, iterator last) + { + return iterator(subs::ch(this).erase(first.base(), last.base())); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::iterator + basic_ptree<K, D, C>::push_front(const value_type &value) + { + return iterator(subs::ch(this).push_front(value).first); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::iterator + basic_ptree<K, D, C>::push_back(const value_type &value) + { + return iterator(subs::ch(this).push_back(value).first); + } + + template<class K, class D, class C> inline + void basic_ptree<K, D, C>::pop_front() + { + subs::ch(this).pop_front(); + } + + template<class K, class D, class C> inline + void basic_ptree<K, D, C>::pop_back() + { + subs::ch(this).pop_back(); + } + + template<class K, class D, class C> inline + void basic_ptree<K, D, C>::reverse() + { + subs::ch(this).reverse(); + } + + template<class K, class D, class C> inline + void basic_ptree<K, D, C>::sort() + { + subs::ch(this).sort(); + } + + template<class K, class D, class C> + template<class Compare> inline + void basic_ptree<K, D, C>::sort(Compare comp) + { + subs::ch(this).sort(comp); + } + + // Equality + + template<class K, class D, class C> inline + bool basic_ptree<K, D, C>::operator ==( + const basic_ptree<K, D, C> &rhs) const + { + // The size test is cheap, so add it as an optimization + return size() == rhs.size() && data() == rhs.data() && + subs::ch(this) == subs::ch(&rhs); + } + + template<class K, class D, class C> inline + bool basic_ptree<K, D, C>::operator !=( + const basic_ptree<K, D, C> &rhs) const + { + return !(*this == rhs); + } + + // Associative view + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::assoc_iterator + basic_ptree<K, D, C>::ordered_begin() + { + return assoc_iterator(subs::assoc(this).begin()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::const_assoc_iterator + basic_ptree<K, D, C>::ordered_begin() const + { + return const_assoc_iterator(subs::assoc(this).begin()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::assoc_iterator + basic_ptree<K, D, C>::not_found() + { + return assoc_iterator(subs::assoc(this).end()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::const_assoc_iterator + basic_ptree<K, D, C>::not_found() const + { + return const_assoc_iterator(subs::assoc(this).end()); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::assoc_iterator + basic_ptree<K, D, C>::find(const key_type &key) + { + return assoc_iterator(subs::assoc(this).find(key)); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::const_assoc_iterator + basic_ptree<K, D, C>::find(const key_type &key) const + { + return const_assoc_iterator(subs::assoc(this).find(key)); + } + + template<class K, class D, class C> inline + std::pair< + typename basic_ptree<K, D, C>::assoc_iterator, + typename basic_ptree<K, D, C>::assoc_iterator + > basic_ptree<K, D, C>::equal_range(const key_type &key) + { + std::pair<typename subs::by_name_index::iterator, + typename subs::by_name_index::iterator> r( + subs::assoc(this).equal_range(key)); + return std::pair<assoc_iterator, assoc_iterator>( + assoc_iterator(r.first), assoc_iterator(r.second)); + } + + template<class K, class D, class C> inline + std::pair< + typename basic_ptree<K, D, C>::const_assoc_iterator, + typename basic_ptree<K, D, C>::const_assoc_iterator + > basic_ptree<K, D, C>::equal_range(const key_type &key) const + { + std::pair<typename subs::by_name_index::const_iterator, + typename subs::by_name_index::const_iterator> r( + subs::assoc(this).equal_range(key)); + return std::pair<const_assoc_iterator, const_assoc_iterator>( + const_assoc_iterator(r.first), const_assoc_iterator(r.second)); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::size_type + basic_ptree<K, D, C>::count(const key_type &key) const + { + return subs::assoc(this).count(key); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::size_type + basic_ptree<K, D, C>::erase(const key_type &key) + { + return subs::assoc(this).erase(key); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::iterator + basic_ptree<K, D, C>::to_iterator(assoc_iterator ai) + { + return iterator(subs::ch(this). + BOOST_NESTED_TEMPLATE project<0>(ai.base())); + } + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::const_iterator + basic_ptree<K, D, C>::to_iterator(const_assoc_iterator ai) const + { + return const_iterator(subs::ch(this). + BOOST_NESTED_TEMPLATE project<0>(ai.base())); + } + + // Property tree view + + template<class K, class D, class C> inline + typename basic_ptree<K, D, C>::data_type & + basic_ptree<K, D, C>::data() + { + return m_data; + } + + template<class K, class D, class C> inline + const typename basic_ptree<K, D, C>::data_type & + basic_ptree<K, D, C>::data() const + { + return m_data; + } + + template<class K, class D, class C> inline + void basic_ptree<K, D, C>::clear() + { + m_data = data_type(); + subs::ch(this).clear(); + } + + template<class K, class D, class C> + basic_ptree<K, D, C> & + basic_ptree<K, D, C>::get_child(const path_type &path) + { + path_type p(path); + self_type *n = walk_path(p); + if (!n) { + BOOST_PROPERTY_TREE_THROW(ptree_bad_path("No such node", path)); + } + return *n; + } + + template<class K, class D, class C> inline + const basic_ptree<K, D, C> & + basic_ptree<K, D, C>::get_child(const path_type &path) const + { + return const_cast<self_type*>(this)->get_child(path); + } + + template<class K, class D, class C> inline + basic_ptree<K, D, C> & + basic_ptree<K, D, C>::get_child(const path_type &path, + self_type &default_value) + { + path_type p(path); + self_type *n = walk_path(p); + return n ? *n : default_value; + } + + template<class K, class D, class C> inline + const basic_ptree<K, D, C> & + basic_ptree<K, D, C>::get_child(const path_type &path, + const self_type &default_value) const + { + return const_cast<self_type*>(this)->get_child(path, + const_cast<self_type&>(default_value)); + } + + + template<class K, class D, class C> + optional<basic_ptree<K, D, C> &> + basic_ptree<K, D, C>::get_child_optional(const path_type &path) + { + path_type p(path); + self_type *n = walk_path(p); + if (!n) { + return optional<self_type&>(); + } + return *n; + } + + template<class K, class D, class C> + optional<const basic_ptree<K, D, C> &> + basic_ptree<K, D, C>::get_child_optional(const path_type &path) const + { + path_type p(path); + self_type *n = walk_path(p); + if (!n) { + return optional<const self_type&>(); + } + return *n; + } + + template<class K, class D, class C> + basic_ptree<K, D, C> & + basic_ptree<K, D, C>::put_child(const path_type &path, + const self_type &value) + { + path_type p(path); + self_type &parent = force_path(p); + // Got the parent. Now get the correct child. + key_type fragment = p.reduce(); + assoc_iterator el = parent.find(fragment); + // If the new child exists, replace it. + if(el != parent.not_found()) { + return el->second = value; + } else { + return parent.push_back(value_type(fragment, value))->second; + } + } + + template<class K, class D, class C> + basic_ptree<K, D, C> & + basic_ptree<K, D, C>::add_child(const path_type &path, + const self_type &value) + { + path_type p(path); + self_type &parent = force_path(p); + // Got the parent. + key_type fragment = p.reduce(); + return parent.push_back(value_type(fragment, value))->second; + } + + template<class K, class D, class C> + template<class Type, class Translator> + typename boost::enable_if<detail::is_translator<Translator>, Type>::type + basic_ptree<K, D, C>::get_value(Translator tr) const + { + if(boost::optional<Type> o = get_value_optional<Type>(tr)) { + return *o; + } + BOOST_PROPERTY_TREE_THROW(ptree_bad_data( + std::string("conversion of data to type \"") + + typeid(Type).name() + "\" failed", data())); + } + + template<class K, class D, class C> + template<class Type> inline + Type basic_ptree<K, D, C>::get_value() const + { + return get_value<Type>( + typename translator_between<data_type, Type>::type()); + } + + template<class K, class D, class C> + template<class Type, class Translator> inline + Type basic_ptree<K, D, C>::get_value(const Type &default_value, + Translator tr) const + { + return get_value_optional<Type>(tr).get_value_or(default_value); + } + + template<class K, class D, class C> + template <class Ch, class Translator> + typename boost::enable_if< + detail::is_character<Ch>, + std::basic_string<Ch> + >::type + basic_ptree<K, D, C>::get_value(const Ch *default_value, Translator tr)const + { + return get_value<std::basic_string<Ch>, Translator>(default_value, tr); + } + + template<class K, class D, class C> + template<class Type> inline + typename boost::disable_if<detail::is_translator<Type>, Type>::type + basic_ptree<K, D, C>::get_value(const Type &default_value) const + { + return get_value(default_value, + typename translator_between<data_type, Type>::type()); + } + + template<class K, class D, class C> + template <class Ch> + typename boost::enable_if< + detail::is_character<Ch>, + std::basic_string<Ch> + >::type + basic_ptree<K, D, C>::get_value(const Ch *default_value) const + { + return get_value< std::basic_string<Ch> >(default_value); + } + + template<class K, class D, class C> + template<class Type, class Translator> inline + optional<Type> basic_ptree<K, D, C>::get_value_optional( + Translator tr) const + { + return tr.get_value(data()); + } + + template<class K, class D, class C> + template<class Type> inline + optional<Type> basic_ptree<K, D, C>::get_value_optional() const + { + return get_value_optional<Type>( + typename translator_between<data_type, Type>::type()); + } + + template<class K, class D, class C> + template<class Type, class Translator> inline + typename boost::enable_if<detail::is_translator<Translator>, Type>::type + basic_ptree<K, D, C>::get(const path_type &path, + Translator tr) const + { + return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>(tr); + } + + template<class K, class D, class C> + template<class Type> inline + Type basic_ptree<K, D, C>::get(const path_type &path) const + { + return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>(); + } + + template<class K, class D, class C> + template<class Type, class Translator> inline + Type basic_ptree<K, D, C>::get(const path_type &path, + const Type &default_value, + Translator tr) const + { + return get_optional<Type>(path, tr).get_value_or(default_value); + } + + template<class K, class D, class C> + template <class Ch, class Translator> + typename boost::enable_if< + detail::is_character<Ch>, + std::basic_string<Ch> + >::type + basic_ptree<K, D, C>::get( + const path_type &path, const Ch *default_value, Translator tr) const + { + return get<std::basic_string<Ch>, Translator>(path, default_value, tr); + } + + template<class K, class D, class C> + template<class Type> inline + typename boost::disable_if<detail::is_translator<Type>, Type>::type + basic_ptree<K, D, C>::get(const path_type &path, + const Type &default_value) const + { + return get_optional<Type>(path).get_value_or(default_value); + } + + template<class K, class D, class C> + template <class Ch> + typename boost::enable_if< + detail::is_character<Ch>, + std::basic_string<Ch> + >::type + basic_ptree<K, D, C>::get( + const path_type &path, const Ch *default_value) const + { + return get< std::basic_string<Ch> >(path, default_value); + } + + template<class K, class D, class C> + template<class Type, class Translator> + optional<Type> basic_ptree<K, D, C>::get_optional(const path_type &path, + Translator tr) const + { + if (optional<const self_type&> child = get_child_optional(path)) + return child.get(). + BOOST_NESTED_TEMPLATE get_value_optional<Type>(tr); + else + return optional<Type>(); + } + + template<class K, class D, class C> + template<class Type> + optional<Type> basic_ptree<K, D, C>::get_optional( + const path_type &path) const + { + if (optional<const self_type&> child = get_child_optional(path)) + return child.get().BOOST_NESTED_TEMPLATE get_value_optional<Type>(); + else + return optional<Type>(); + } + + template<class K, class D, class C> + template<class Type, class Translator> + void basic_ptree<K, D, C>::put_value(const Type &value, Translator tr) + { + if(optional<data_type> o = tr.put_value(value)) { + data() = *o; + } else { + BOOST_PROPERTY_TREE_THROW(ptree_bad_data( + std::string("conversion of type \"") + typeid(Type).name() + + "\" to data failed", boost::any())); + } + } + + template<class K, class D, class C> + template<class Type> inline + void basic_ptree<K, D, C>::put_value(const Type &value) + { + put_value(value, typename translator_between<data_type, Type>::type()); + } + + template<class K, class D, class C> + template<class Type, typename Translator> + basic_ptree<K, D, C> & basic_ptree<K, D, C>::put( + const path_type &path, const Type &value, Translator tr) + { + if(optional<self_type &> child = get_child_optional(path)) { + child.get().put_value(value, tr); + return *child; + } else { + self_type &child2 = put_child(path, self_type()); + child2.put_value(value, tr); + return child2; + } + } + + template<class K, class D, class C> + template<class Type> inline + basic_ptree<K, D, C> & basic_ptree<K, D, C>::put( + const path_type &path, const Type &value) + { + return put(path, value, + typename translator_between<data_type, Type>::type()); + } + + template<class K, class D, class C> + template<class Type, typename Translator> inline + basic_ptree<K, D, C> & basic_ptree<K, D, C>::add( + const path_type &path, const Type &value, Translator tr) + { + self_type &child = add_child(path, self_type()); + child.put_value(value, tr); + return child; + } + + template<class K, class D, class C> + template<class Type> inline + basic_ptree<K, D, C> & basic_ptree<K, D, C>::add( + const path_type &path, const Type &value) + { + return add(path, value, + typename translator_between<data_type, Type>::type()); + } + + + template<class K, class D, class C> + basic_ptree<K, D, C> * + basic_ptree<K, D, C>::walk_path(path_type &p) const + { + if(p.empty()) { + // I'm the child we're looking for. + return const_cast<basic_ptree*>(this); + } + // Recurse down the tree to find the path. + key_type fragment = p.reduce(); + const_assoc_iterator el = find(fragment); + if(el == not_found()) { + // No such child. + return 0; + } + // Not done yet, recurse. + return el->second.walk_path(p); + } + + template<class K, class D, class C> + basic_ptree<K, D, C> & basic_ptree<K, D, C>::force_path(path_type &p) + { + assert(!p.empty() && "Empty path not allowed for put_child."); + if(p.single()) { + // I'm the parent we're looking for. + return *this; + } + key_type fragment = p.reduce(); + assoc_iterator el = find(fragment); + // If we've found an existing child, go down that path. Else + // create a new one. + self_type& child = el == not_found() ? + push_back(value_type(fragment, self_type()))->second : el->second; + return child.force_path(p); + } + + // Free functions + + template<class K, class D, class C> + inline void swap(basic_ptree<K, D, C> &pt1, basic_ptree<K, D, C> &pt2) + { + pt1.swap(pt2); + } + +} } + +#if defined(BOOST_PROPERTY_TREE_PAIR_BUG) +#undef BOOST_PROPERTY_TREE_PAIR_BUG +#endif + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/ptree_utils.hpp b/3rdParty/Boost/src/boost/property_tree/detail/ptree_utils.hpp new file mode 100644 index 0000000..7e56c8f --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/ptree_utils.hpp @@ -0,0 +1,106 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED + +#include <boost/limits.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <boost/mpl/has_xxx.hpp> +#include <boost/mpl/and.hpp> +#include <string> +#include <algorithm> +#include <locale> + +namespace boost { namespace property_tree { namespace detail +{ + + template<class T> + struct less_nocase + { + typedef typename T::value_type Ch; + std::locale m_locale; + inline bool operator()(Ch c1, Ch c2) const + { + return std::toupper(c1, m_locale) < std::toupper(c2, m_locale); + } + inline bool operator()(const T &t1, const T &t2) const + { + return std::lexicographical_compare(t1.begin(), t1.end(), + t2.begin(), t2.end(), *this); + } + }; + + template <typename Ch> + struct is_character : public boost::false_type {}; + template <> + struct is_character<char> : public boost::true_type {}; + template <> + struct is_character<wchar_t> : public boost::true_type {}; + + + BOOST_MPL_HAS_XXX_TRAIT_DEF(internal_type) + BOOST_MPL_HAS_XXX_TRAIT_DEF(external_type) + template <typename T> + struct is_translator : public boost::mpl::and_< + has_internal_type<T>, has_external_type<T> > {}; + + + + // Naively convert narrow string to another character type + template<class Ch> + std::basic_string<Ch> widen(const char *text) + { + std::basic_string<Ch> result; + while (*text) + { + result += Ch(*text); + ++text; + } + return result; + } + + // Naively convert string to narrow character type + template<class Ch> + std::string narrow(const Ch *text) + { + std::string result; + while (*text) + { + if (*text < 0 || *text > (std::numeric_limits<char>::max)()) + result += '*'; + else + result += char(*text); + ++text; + } + return result; + } + + // Remove trailing and leading spaces + template<class Ch> + std::basic_string<Ch> trim(const std::basic_string<Ch> &s, + const std::locale &loc = std::locale()) + { + typename std::basic_string<Ch>::const_iterator first = s.begin(); + typename std::basic_string<Ch>::const_iterator end = s.end(); + while (first != end && std::isspace(*first, loc)) + ++first; + if (first == end) + return std::basic_string<Ch>(); + typename std::basic_string<Ch>::const_iterator last = end; + do --last; while (std::isspace(*last, loc)); + if (first != s.begin() || last + 1 != end) + return std::basic_string<Ch>(first, last + 1); + else + return s; + } + +} } } + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/rapidxml.hpp b/3rdParty/Boost/src/boost/property_tree/detail/rapidxml.hpp new file mode 100644 index 0000000..712bf3f --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/rapidxml.hpp @@ -0,0 +1,2582 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2006, 2009 Marcin Kalicinski +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED + +//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation + +#include <cstdlib> // For std::size_t +#include <cassert> // For assert +#include <new> // For placement new + +// On MSVC, disable "conditional expression is constant" warning (level 4). +// This warning is almost impossible to avoid with certain types of templated code +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable:4127) // Conditional expression is constant +#endif + +/////////////////////////////////////////////////////////////////////////// +// BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR + +#include <exception> // For std::exception + +#define BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where) + +namespace boost { namespace property_tree { namespace detail {namespace rapidxml +{ + + //! Parse error exception. + //! This exception is thrown by the parser when an error occurs. + //! Use what() function to get human-readable error message. + //! Use where() function to get a pointer to position within source text where error was detected. + //! <br><br> + //! If throwing exceptions by the parser is undesirable, + //! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included. + //! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception. + //! This function must be defined by the user. + //! <br><br> + //! This class derives from <code>std::exception</code> class. + class parse_error: public std::exception + { + + public: + + //! Constructs parse error + parse_error(const char *wa, void *we) + : m_what(wa) + , m_where(we) + { + } + + //! Gets human readable description of error. + //! \return Pointer to null terminated description of the error. + virtual const char *what() const throw() + { + return m_what; + } + + //! Gets pointer to character data where error happened. + //! Ch should be the same as char type of xml_document that produced the error. + //! \return Pointer to location within the parsed string where error occured. + template<class Ch> + Ch *where() const + { + return reinterpret_cast<Ch *>(m_where); + } + + private: + + const char *m_what; + void *m_where; + + }; +}}}} + +/////////////////////////////////////////////////////////////////////////// +// Pool sizes + +#ifndef BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE + // Size of static memory block of memory_pool. + // Define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. + // No dynamic memory allocations are performed by memory_pool until static memory is exhausted. + #define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE (64 * 1024) +#endif + +#ifndef BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE + // Size of dynamic memory block of memory_pool. + // Define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. + // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool. + #define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024) +#endif + +#ifndef BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT + // Memory allocation alignment. + // Define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer. + // All memory allocations for nodes, attributes and strings will be aligned to this value. + // This must be a power of 2 and at least 1, otherwise memory_pool will not work. + #define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT sizeof(void *) +#endif + +namespace boost { namespace property_tree { namespace detail {namespace rapidxml +{ + // Forward declarations + template<class Ch> class xml_node; + template<class Ch> class xml_attribute; + template<class Ch> class xml_document; + + //! Enumeration listing all node types produced by the parser. + //! Use xml_node::type() function to query node type. + enum node_type + { + node_document, //!< A document node. Name and value are empty. + node_element, //!< An element node. Name contains element name. Value contains text of first data node. + node_data, //!< A data node. Name is empty. Value contains data text. + node_cdata, //!< A CDATA node. Name is empty. Value contains data text. + node_comment, //!< A comment node. Name is empty. Value contains comment text. + node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes. + node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text. + node_pi //!< A PI node. Name contains target. Value contains instructions. + }; + + /////////////////////////////////////////////////////////////////////// + // Parsing flags + + //! Parse flag instructing the parser to not create data nodes. + //! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_no_data_nodes = 0x1; + + //! Parse flag instructing the parser to not use text of first data node as a value of parent element. + //! Can be combined with other flags by use of | operator. + //! Note that child data nodes of element node take precendence over its value when printing. + //! That is, if element has one or more child data nodes <em>and</em> a value, the value will be ignored. + //! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements. + //! <br><br> + //! See xml_document::parse() function. + const int parse_no_element_values = 0x2; + + //! Parse flag instructing the parser to not place zero terminators after strings in the source text. + //! By default zero terminators are placed, modifying source text. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_no_string_terminators = 0x4; + + //! Parse flag instructing the parser to not translate entities in the source text. + //! By default entities are translated, modifying source text. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_no_entity_translation = 0x8; + + //! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters. + //! By default, UTF-8 handling is enabled. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_no_utf8 = 0x10; + + //! Parse flag instructing the parser to create XML declaration node. + //! By default, declaration node is not created. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_declaration_node = 0x20; + + //! Parse flag instructing the parser to create comments nodes. + //! By default, comment nodes are not created. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_comment_nodes = 0x40; + + //! Parse flag instructing the parser to create DOCTYPE node. + //! By default, doctype node is not created. + //! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_doctype_node = 0x80; + + //! Parse flag instructing the parser to create PI nodes. + //! By default, PI nodes are not created. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_pi_nodes = 0x100; + + //! Parse flag instructing the parser to validate closing tag names. + //! If not set, name inside closing tag is irrelevant to the parser. + //! By default, closing tags are not validated. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_validate_closing_tags = 0x200; + + //! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes. + //! By default, whitespace is not trimmed. + //! This flag does not cause the parser to modify source text. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_trim_whitespace = 0x400; + + //! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character. + //! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag. + //! By default, whitespace is not normalized. + //! If this flag is specified, source text will be modified. + //! Can be combined with other flags by use of | operator. + //! <br><br> + //! See xml_document::parse() function. + const int parse_normalize_whitespace = 0x800; + + // Compound flags + + //! Parse flags which represent default behaviour of the parser. + //! This is always equal to 0, so that all other flags can be simply ored together. + //! Normally there is no need to inconveniently disable flags by anding with their negated (~) values. + //! This also means that meaning of each flag is a <i>negation</i> of the default setting. + //! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is <i>enabled</i> by default, + //! and using the flag will disable it. + //! <br><br> + //! See xml_document::parse() function. + const int parse_default = 0; + + //! A combination of parse flags that forbids any modifications of the source text. + //! This also results in faster parsing. However, note that the following will occur: + //! <ul> + //! <li>names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends</li> + //! <li>entities will not be translated</li> + //! <li>whitespace will not be normalized</li> + //! </ul> + //! See xml_document::parse() function. + const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation; + + //! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data. + //! <br><br> + //! See xml_document::parse() function. + const int parse_fastest = parse_non_destructive | parse_no_data_nodes; + + //! A combination of parse flags resulting in largest amount of data being extracted. + //! This usually results in slowest parsing. + //! <br><br> + //! See xml_document::parse() function. + const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags; + + /////////////////////////////////////////////////////////////////////// + // Internals + + //! \cond internal + namespace internal + { + + // Struct that contains lookup tables for the parser + // It must be a template to allow correct linking (because it has static data members, which are defined in a header file). + template<int Dummy> + struct lookup_tables + { + static const unsigned char lookup_whitespace[256]; // Whitespace table + static const unsigned char lookup_node_name[256]; // Node name table + static const unsigned char lookup_text[256]; // Text table + static const unsigned char lookup_text_pure_no_ws[256]; // Text table + static const unsigned char lookup_text_pure_with_ws[256]; // Text table + static const unsigned char lookup_attribute_name[256]; // Attribute name table + static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote + static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote + static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes + static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes + static const unsigned char lookup_digits[256]; // Digits + static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters + }; + + // Find length of the string + template<class Ch> + inline std::size_t measure(const Ch *p) + { + const Ch *tmp = p; + while (*tmp) + ++tmp; + return tmp - p; + } + + // Compare strings for equality + template<class Ch> + inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive) + { + if (size1 != size2) + return false; + if (case_sensitive) + { + for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) + if (*p1 != *p2) + return false; + } + else + { + for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) + if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)] != lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)]) + return false; + } + return true; + } + + template<class Ch> + inline size_t get_index(const Ch c) + { + // If not ASCII char, its sematic is same as plain 'z' + if (c > 255) + { + return 'z'; + } + return c; + } + } + //! \endcond + + /////////////////////////////////////////////////////////////////////// + // Memory pool + + //! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation. + //! In most cases, you will not need to use this class directly. + //! However, if you need to create nodes manually or modify names/values of nodes, + //! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. + //! Not only is this faster than allocating them by using <code>new</code> operator, + //! but also their lifetime will be tied to the lifetime of document, + //! possibly simplyfing memory management. + //! <br><br> + //! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. + //! You can also call allocate_string() function to allocate strings. + //! Such strings can then be used as names or values of nodes without worrying about their lifetime. + //! Note that there is no <code>free()</code> function -- all allocations are freed at once when clear() function is called, + //! or when the pool is destroyed. + //! <br><br> + //! It is also possible to create a standalone memory_pool, and use it + //! to allocate nodes, whose lifetime will not be tied to any document. + //! <br><br> + //! Pool maintains <code>BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE</code> bytes of statically allocated memory. + //! Until static memory is exhausted, no dynamic memory allocations are done. + //! When static memory is exhausted, pool allocates additional blocks of memory of size <code>BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE</code> each, + //! by using global <code>new[]</code> and <code>delete[]</code> operators. + //! This behaviour can be changed by setting custom allocation routines. + //! Use set_allocator() function to set them. + //! <br><br> + //! Allocations for nodes, attributes and strings are aligned at <code>BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT</code> bytes. + //! This value defaults to the size of pointer on target architecture. + //! <br><br> + //! To obtain absolutely top performance from the parser, + //! it is important that all nodes are allocated from a single, contiguous block of memory. + //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably. + //! If required, you can tweak <code>BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE</code>, <code>BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE</code> and <code>BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT</code> + //! to obtain best wasted memory to performance compromise. + //! To do it, define their values before rapidxml.hpp file is included. + //! \param Ch Character type of created nodes. + template<class Ch = char> + class memory_pool + { + + public: + + //! \cond internal + typedef void *(alloc_func)(std::size_t); // Type of user-defined function used to allocate memory + typedef void (free_func)(void *); // Type of user-defined function used to free memory + //! \endcond + + //! Constructs empty pool with default allocator functions. + memory_pool() + : m_alloc_func(0) + , m_free_func(0) + { + init(); + } + + //! Destroys pool and frees all the memory. + //! This causes memory occupied by nodes allocated by the pool to be freed. + //! Nodes allocated from the pool are no longer valid. + ~memory_pool() + { + clear(); + } + + //! Allocates a new node from the pool, and optionally assigns name and value to it. + //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param type Type of node to create. + //! \param name Name to assign to the node, or 0 to assign no name. + //! \param value Value to assign to the node, or 0 to assign no value. + //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. + //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. + //! \return Pointer to allocated node. This pointer will never be NULL. + xml_node<Ch> *allocate_node(node_type type, + const Ch *name = 0, const Ch *value = 0, + std::size_t name_size = 0, std::size_t value_size = 0) + { + void *memory = allocate_aligned(sizeof(xml_node<Ch>)); + xml_node<Ch> *node = new(memory) xml_node<Ch>(type); + if (name) + { + if (name_size > 0) + node->name(name, name_size); + else + node->name(name); + } + if (value) + { + if (value_size > 0) + node->value(value, value_size); + else + node->value(value); + } + return node; + } + + //! Allocates a new attribute from the pool, and optionally assigns name and value to it. + //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param name Name to assign to the attribute, or 0 to assign no name. + //! \param value Value to assign to the attribute, or 0 to assign no value. + //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. + //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. + //! \return Pointer to allocated attribute. This pointer will never be NULL. + xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0, + std::size_t name_size = 0, std::size_t value_size = 0) + { + void *memory = allocate_aligned(sizeof(xml_attribute<Ch>)); + xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>; + if (name) + { + if (name_size > 0) + attribute->name(name, name_size); + else + attribute->name(name); + } + if (value) + { + if (value_size > 0) + attribute->value(value, value_size); + else + attribute->value(value); + } + return attribute; + } + + //! Allocates a char array of given size from the pool, and optionally copies a given string to it. + //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param source String to initialize the allocated memory with, or 0 to not initialize it. + //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated. + //! \return Pointer to allocated char array. This pointer will never be NULL. + Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) + { + assert(source || size); // Either source or size (or both) must be specified + if (size == 0) + size = internal::measure(source) + 1; + Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch))); + if (source) + for (std::size_t i = 0; i < size; ++i) + result[i] = source[i]; + return result; + } + + //! Clones an xml_node and its hierarchy of child nodes and attributes. + //! Nodes and attributes are allocated from this memory pool. + //! Names and values are not cloned, they are shared between the clone and the source. + //! Result node can be optionally specified as a second parameter, + //! in which case its contents will be replaced with cloned source node. + //! This is useful when you want to clone entire document. + //! \param source Node to clone. + //! \param result Node to put results in, or 0 to automatically allocate result node + //! \return Pointer to cloned node. This pointer will never be NULL. + xml_node<Ch> *clone_node(const xml_node<Ch> *source, xml_node<Ch> *result = 0) + { + // Prepare result node + if (result) + { + result->remove_all_attributes(); + result->remove_all_nodes(); + result->type(source->type()); + } + else + result = allocate_node(source->type()); + + // Clone name and value + result->name(source->name(), source->name_size()); + result->value(source->value(), source->value_size()); + + // Clone child nodes and attributes + for (xml_node<Ch> *child = source->first_node(); child; child = child->next_sibling()) + result->append_node(clone_node(child)); + for (xml_attribute<Ch> *attr = source->first_attribute(); attr; attr = attr->next_attribute()) + result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size())); + + return result; + } + + //! Clears the pool. + //! This causes memory occupied by nodes allocated by the pool to be freed. + //! Any nodes or strings allocated from the pool will no longer be valid. + void clear() + { + while (m_begin != m_static_memory) + { + char *previous_begin = reinterpret_cast<header *>(align(m_begin))->previous_begin; + if (m_free_func) + m_free_func(m_begin); + else + delete[] m_begin; + m_begin = previous_begin; + } + init(); + } + + //! Sets or resets the user-defined memory allocation functions for the pool. + //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined. + //! Allocation function must not return invalid pointer on failure. It should either throw, + //! stop the program, or use <code>longjmp()</code> function to pass control to other place of program. + //! If it returns invalid pointer, results are undefined. + //! <br><br> + //! User defined allocation functions must have the following forms: + //! <br><code> + //! <br>void *allocate(std::size_t size); + //! <br>void free(void *pointer); + //! </code><br> + //! \param af Allocation function, or 0 to restore default function + //! \param ff Free function, or 0 to restore default function + void set_allocator(alloc_func *af, free_func *ff) + { + assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet + m_alloc_func = af; + m_free_func = ff; + } + + private: + + struct header + { + char *previous_begin; + }; + + void init() + { + m_begin = m_static_memory; + m_ptr = align(m_begin); + m_end = m_static_memory + sizeof(m_static_memory); + } + + char *align(char *ptr) + { + std::size_t alignment = ((BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 1))) & (BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 1)); + return ptr + alignment; + } + + char *allocate_raw(std::size_t size) + { + // Allocate + void *memory; + if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[] + { + memory = m_alloc_func(size); + assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp + } + else + { + memory = new char[size]; + } + return static_cast<char *>(memory); + } + + void *allocate_aligned(std::size_t size) + { + // Calculate aligned pointer + char *result = align(m_ptr); + + // If not enough memory left in current pool, allocate a new pool + if (result + size > m_end) + { + // Calculate required pool size (may be bigger than BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE) + std::size_t pool_size = BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE; + if (pool_size < size) + pool_size = size; + + // Allocate + std::size_t alloc_size = sizeof(header) + (2 * BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation + char *raw_memory = allocate_raw(alloc_size); + + // Setup new pool in allocated memory + char *pool = align(raw_memory); + header *new_header = reinterpret_cast<header *>(pool); + new_header->previous_begin = m_begin; + m_begin = raw_memory; + m_ptr = pool + sizeof(header); + m_end = raw_memory + alloc_size; + + // Calculate aligned pointer again using new pool + result = align(m_ptr); + } + + // Update pool and return aligned pointer + m_ptr = result + size; + return result; + } + + char *m_begin; // Start of raw memory making up current pool + char *m_ptr; // First free byte in current pool + char *m_end; // One past last available byte in current pool + char m_static_memory[BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE]; // Static raw memory + alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used + free_func *m_free_func; // Free function, or 0 if default is to be used + }; + + /////////////////////////////////////////////////////////////////////////// + // XML base + + //! Base class for xml_node and xml_attribute implementing common functions: + //! name(), name_size(), value(), value_size() and parent(). + //! \param Ch Character type to use + template<class Ch = char> + class xml_base + { + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + // Construct a base with empty name, value and parent + xml_base() + : m_name(0) + , m_value(0) + , m_parent(0) + { + } + + /////////////////////////////////////////////////////////////////////////// + // Node data access + + //! Gets name of the node. + //! Interpretation of name depends on type of node. + //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. + //! <br><br> + //! Use name_size() function to determine length of the name. + //! \return Name of node, or empty string if node has no name. + Ch *name() const + { + return m_name ? m_name : nullstr(); + } + + //! Gets size of node name, not including terminator character. + //! This function works correctly irrespective of whether name is or is not zero terminated. + //! \return Size of node name, in characters. + std::size_t name_size() const + { + return m_name ? m_name_size : 0; + } + + //! Gets value of node. + //! Interpretation of value depends on type of node. + //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. + //! <br><br> + //! Use value_size() function to determine length of the value. + //! \return Value of node, or empty string if node has no value. + Ch *value() const + { + return m_value ? m_value : nullstr(); + } + + //! Gets size of node value, not including terminator character. + //! This function works correctly irrespective of whether value is or is not zero terminated. + //! \return Size of node value, in characters. + std::size_t value_size() const + { + return m_value ? m_value_size : 0; + } + + /////////////////////////////////////////////////////////////////////////// + // Node modification + + //! Sets name of node to a non zero-terminated string. + //! See \ref ownership_of_strings. + //! <br><br> + //! Note that node does not own its name or value, it only stores a pointer to it. + //! It will not delete or otherwise free the pointer on destruction. + //! It is reponsibility of the user to properly manage lifetime of the string. + //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - + //! on destruction of the document the string will be automatically freed. + //! <br><br> + //! Size of name must be specified separately, because name does not have to be zero terminated. + //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated). + //! \param n Name of node to set. Does not have to be zero terminated. + //! \param size Size of name, in characters. This does not include zero terminator, if one is present. + void name(const Ch *n, std::size_t size) + { + m_name = const_cast<Ch *>(n); + m_name_size = size; + } + + //! Sets name of node to a zero-terminated string. + //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t). + //! \param n Name of node to set. Must be zero terminated. + void name(const Ch *n) + { + name(n, internal::measure(n)); + } + + //! Sets value of node to a non zero-terminated string. + //! See \ref ownership_of_strings. + //! <br><br> + //! Note that node does not own its name or value, it only stores a pointer to it. + //! It will not delete or otherwise free the pointer on destruction. + //! It is reponsibility of the user to properly manage lifetime of the string. + //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - + //! on destruction of the document the string will be automatically freed. + //! <br><br> + //! Size of value must be specified separately, because it does not have to be zero terminated. + //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated). + //! <br><br> + //! If an element has a child node of type node_data, it will take precedence over element value when printing. + //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser. + //! \param val value of node to set. Does not have to be zero terminated. + //! \param size Size of value, in characters. This does not include zero terminator, if one is present. + void value(const Ch *val, std::size_t size) + { + m_value = const_cast<Ch *>(val); + m_value_size = size; + } + + //! Sets value of node to a zero-terminated string. + //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t). + //! \param val Vame of node to set. Must be zero terminated. + void value(const Ch *val) + { + this->value(val, internal::measure(val)); + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets node parent. + //! \return Pointer to parent node, or 0 if there is no parent. + xml_node<Ch> *parent() const + { + return m_parent; + } + + protected: + + // Return empty string + static Ch *nullstr() + { + static Ch zero = Ch('\0'); + return &zero; + } + + Ch *m_name; // Name of node, or 0 if no name + Ch *m_value; // Value of node, or 0 if no value + std::size_t m_name_size; // Length of node name, or undefined of no name + std::size_t m_value_size; // Length of node value, or undefined if no value + xml_node<Ch> *m_parent; // Pointer to parent node, or 0 if none + + }; + + //! Class representing attribute node of XML document. + //! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base). + //! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. + //! Thus, this text must persist in memory for the lifetime of attribute. + //! \param Ch Character type to use. + template<class Ch = char> + class xml_attribute: public xml_base<Ch> + { + + friend class xml_node<Ch>; + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + //! Constructs an empty attribute with the specified type. + //! Consider using memory_pool of appropriate xml_document if allocating attributes manually. + xml_attribute() + { + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets document of which attribute is a child. + //! \return Pointer to document that contains this attribute, or 0 if there is no parent document. + xml_document<Ch> *document() const + { + if (xml_node<Ch> *node = this->parent()) + { + while (node->parent()) + node = node->parent(); + return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0; + } + else + return 0; + } + + //! Gets previous attribute, optionally matching attribute name. + //! \param n Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute<Ch> *previous_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const + { + if (n) + { + if (nsize == 0) + nsize = internal::measure(n); + for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive)) + return attribute; + return 0; + } + else + return this->m_parent ? m_prev_attribute : 0; + } + + //! Gets next attribute, optionally matching attribute name. + //! \param n Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute<Ch> *next_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const + { + if (n) + { + if (nsize == 0) + nsize = internal::measure(n); + for (xml_attribute<Ch> *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive)) + return attribute; + return 0; + } + else + return this->m_parent ? m_next_attribute : 0; + } + + private: + + xml_attribute<Ch> *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero + xml_attribute<Ch> *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero + + }; + + /////////////////////////////////////////////////////////////////////////// + // XML node + + //! Class representing a node of XML document. + //! Each node may have associated name and value strings, which are available through name() and value() functions. + //! Interpretation of name and value depends on type of the node. + //! Type of node can be determined by using type() function. + //! <br><br> + //! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. + //! Thus, this text must persist in the memory for the lifetime of node. + //! \param Ch Character type to use. + template<class Ch = char> + class xml_node: public xml_base<Ch> + { + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + //! Constructs an empty node with the specified type. + //! Consider using memory_pool of appropriate document to allocate nodes manually. + //! \param t Type of node to construct. + xml_node(node_type t) + : m_type(t) + , m_first_node(0) + , m_first_attribute(0) + { + } + + /////////////////////////////////////////////////////////////////////////// + // Node data access + + //! Gets type of node. + //! \return Type of node. + node_type type() const + { + return m_type; + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets document of which node is a child. + //! \return Pointer to document that contains this node, or 0 if there is no parent document. + xml_document<Ch> *document() const + { + xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this); + while (node->parent()) + node = node->parent(); + return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0; + } + + //! Gets first child node, optionally matching node name. + //! \param n Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found child, or 0 if not found. + xml_node<Ch> *first_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const + { + if (n) + { + if (nsize == 0) + nsize = internal::measure(n); + for (xml_node<Ch> *child = m_first_node; child; child = child->next_sibling()) + if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive)) + return child; + return 0; + } + else + return m_first_node; + } + + //! Gets last child node, optionally matching node name. + //! Behaviour is undefined if node has no children. + //! Use first_node() to test if node has children. + //! \param n Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found child, or 0 if not found. + xml_node<Ch> *last_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const + { + assert(m_first_node); // Cannot query for last child if node has no children + if (n) + { + if (nsize == 0) + nsize = internal::measure(n); + for (xml_node<Ch> *child = m_last_node; child; child = child->previous_sibling()) + if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive)) + return child; + return 0; + } + else + return m_last_node; + } + + //! Gets previous sibling node, optionally matching node name. + //! Behaviour is undefined if node has no parent. + //! Use parent() to test if node has a parent. + //! \param n Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found sibling, or 0 if not found. + xml_node<Ch> *previous_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const + { + assert(this->m_parent); // Cannot query for siblings if node has no parent + if (n) + { + if (nsize == 0) + nsize = internal::measure(n); + for (xml_node<Ch> *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling) + if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive)) + return sibling; + return 0; + } + else + return m_prev_sibling; + } + + //! Gets next sibling node, optionally matching node name. + //! Behaviour is undefined if node has no parent. + //! Use parent() to test if node has a parent. + //! \param n Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found sibling, or 0 if not found. + xml_node<Ch> *next_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const + { + assert(this->m_parent); // Cannot query for siblings if node has no parent + if (n) + { + if (nsize == 0) + nsize = internal::measure(n); + for (xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling) + if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive)) + return sibling; + return 0; + } + else + return m_next_sibling; + } + + //! Gets first attribute of node, optionally matching attribute name. + //! \param n Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute<Ch> *first_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const + { + if (n) + { + if (nsize == 0) + nsize = internal::measure(n); + for (xml_attribute<Ch> *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive)) + return attribute; + return 0; + } + else + return m_first_attribute; + } + + //! Gets last attribute of node, optionally matching attribute name. + //! \param n Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if nsize is non-zero + //! \param nsize Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute<Ch> *last_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const + { + if (n) + { + if (nsize == 0) + nsize = internal::measure(n); + for (xml_attribute<Ch> *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive)) + return attribute; + return 0; + } + else + return m_first_attribute ? m_last_attribute : 0; + } + + /////////////////////////////////////////////////////////////////////////// + // Node modification + + //! Sets type of node. + //! \param t Type of node to set. + void type(node_type t) + { + m_type = t; + } + + /////////////////////////////////////////////////////////////////////////// + // Node manipulation + + //! Prepends a new child node. + //! The prepended child becomes the first child, and all existing children are moved one position back. + //! \param child Node to prepend. + void prepend_node(xml_node<Ch> *child) + { + assert(child && !child->parent() && child->type() != node_document); + if (first_node()) + { + child->m_next_sibling = m_first_node; + m_first_node->m_prev_sibling = child; + } + else + { + child->m_next_sibling = 0; + m_last_node = child; + } + m_first_node = child; + child->m_parent = this; + child->m_prev_sibling = 0; + } + + //! Appends a new child node. + //! The appended child becomes the last child. + //! \param child Node to append. + void append_node(xml_node<Ch> *child) + { + assert(child && !child->parent() && child->type() != node_document); + if (first_node()) + { + child->m_prev_sibling = m_last_node; + m_last_node->m_next_sibling = child; + } + else + { + child->m_prev_sibling = 0; + m_first_node = child; + } + m_last_node = child; + child->m_parent = this; + child->m_next_sibling = 0; + } + + //! Inserts a new child node at specified place inside the node. + //! All children after and including the specified node are moved one position back. + //! \param where Place where to insert the child, or 0 to insert at the back. + //! \param child Node to insert. + void insert_node(xml_node<Ch> *where, xml_node<Ch> *child) + { + assert(!where || where->parent() == this); + assert(child && !child->parent() && child->type() != node_document); + if (where == m_first_node) + prepend_node(child); + else if (where == 0) + append_node(child); + else + { + child->m_prev_sibling = where->m_prev_sibling; + child->m_next_sibling = where; + where->m_prev_sibling->m_next_sibling = child; + where->m_prev_sibling = child; + child->m_parent = this; + } + } + + //! Removes first child node. + //! If node has no children, behaviour is undefined. + //! Use first_node() to test if node has children. + void remove_first_node() + { + assert(first_node()); + xml_node<Ch> *child = m_first_node; + m_first_node = child->m_next_sibling; + if (child->m_next_sibling) + child->m_next_sibling->m_prev_sibling = 0; + else + m_last_node = 0; + child->m_parent = 0; + } + + //! Removes last child of the node. + //! If node has no children, behaviour is undefined. + //! Use first_node() to test if node has children. + void remove_last_node() + { + assert(first_node()); + xml_node<Ch> *child = m_last_node; + if (child->m_prev_sibling) + { + m_last_node = child->m_prev_sibling; + child->m_prev_sibling->m_next_sibling = 0; + } + else + m_first_node = 0; + child->m_parent = 0; + } + + //! Removes specified child from the node + // \param where Pointer to child to be removed. + void remove_node(xml_node<Ch> *where) + { + assert(where && where->parent() == this); + assert(first_node()); + if (where == m_first_node) + remove_first_node(); + else if (where == m_last_node) + remove_last_node(); + else + { + where->m_prev_sibling->m_next_sibling = where->m_next_sibling; + where->m_next_sibling->m_prev_sibling = where->m_prev_sibling; + where->m_parent = 0; + } + } + + //! Removes all child nodes (but not attributes). + void remove_all_nodes() + { + for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling) + node->m_parent = 0; + m_first_node = 0; + } + + //! Prepends a new attribute to the node. + //! \param attribute Attribute to prepend. + void prepend_attribute(xml_attribute<Ch> *attribute) + { + assert(attribute && !attribute->parent()); + if (first_attribute()) + { + attribute->m_next_attribute = m_first_attribute; + m_first_attribute->m_prev_attribute = attribute; + } + else + { + attribute->m_next_attribute = 0; + m_last_attribute = attribute; + } + m_first_attribute = attribute; + attribute->m_parent = this; + attribute->m_prev_attribute = 0; + } + + //! Appends a new attribute to the node. + //! \param attribute Attribute to append. + void append_attribute(xml_attribute<Ch> *attribute) + { + assert(attribute && !attribute->parent()); + if (first_attribute()) + { + attribute->m_prev_attribute = m_last_attribute; + m_last_attribute->m_next_attribute = attribute; + } + else + { + attribute->m_prev_attribute = 0; + m_first_attribute = attribute; + } + m_last_attribute = attribute; + attribute->m_parent = this; + attribute->m_next_attribute = 0; + } + + //! Inserts a new attribute at specified place inside the node. + //! All attributes after and including the specified attribute are moved one position back. + //! \param where Place where to insert the attribute, or 0 to insert at the back. + //! \param attribute Attribute to insert. + void insert_attribute(xml_attribute<Ch> *where, xml_attribute<Ch> *attribute) + { + assert(!where || where->parent() == this); + assert(attribute && !attribute->parent()); + if (where == m_first_attribute) + prepend_attribute(attribute); + else if (where == 0) + append_attribute(attribute); + else + { + attribute->m_prev_attribute = where->m_prev_attribute; + attribute->m_next_attribute = where; + where->m_prev_attribute->m_next_attribute = attribute; + where->m_prev_attribute = attribute; + attribute->m_parent = this; + } + } + + //! Removes first attribute of the node. + //! If node has no attributes, behaviour is undefined. + //! Use first_attribute() to test if node has attributes. + void remove_first_attribute() + { + assert(first_attribute()); + xml_attribute<Ch> *attribute = m_first_attribute; + if (attribute->m_next_attribute) + { + attribute->m_next_attribute->m_prev_attribute = 0; + } + else + m_last_attribute = 0; + attribute->m_parent = 0; + m_first_attribute = attribute->m_next_attribute; + } + + //! Removes last attribute of the node. + //! If node has no attributes, behaviour is undefined. + //! Use first_attribute() to test if node has attributes. + void remove_last_attribute() + { + assert(first_attribute()); + xml_attribute<Ch> *attribute = m_last_attribute; + if (attribute->m_prev_attribute) + { + attribute->m_prev_attribute->m_next_attribute = 0; + m_last_attribute = attribute->m_prev_attribute; + } + else + m_first_attribute = 0; + attribute->m_parent = 0; + } + + //! Removes specified attribute from node. + //! \param where Pointer to attribute to be removed. + void remove_attribute(xml_attribute<Ch> *where) + { + assert(first_attribute() && where->parent() == this); + if (where == m_first_attribute) + remove_first_attribute(); + else if (where == m_last_attribute) + remove_last_attribute(); + else + { + where->m_prev_attribute->m_next_attribute = where->m_next_attribute; + where->m_next_attribute->m_prev_attribute = where->m_prev_attribute; + where->m_parent = 0; + } + } + + //! Removes all attributes of node. + void remove_all_attributes() + { + for (xml_attribute<Ch> *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute) + attribute->m_parent = 0; + m_first_attribute = 0; + } + + private: + + /////////////////////////////////////////////////////////////////////////// + // Restrictions + + // No copying + xml_node(const xml_node &); + void operator =(const xml_node &); + + /////////////////////////////////////////////////////////////////////////// + // Data members + + // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0. + // This is required for maximum performance, as it allows the parser to omit initialization of + // unneded/redundant values. + // + // The rules are as follows: + // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively + // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage + // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage + + node_type m_type; // Type of node; always valid + xml_node<Ch> *m_first_node; // Pointer to first child node, or 0 if none; always valid + xml_node<Ch> *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero + xml_attribute<Ch> *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid + xml_attribute<Ch> *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero + xml_node<Ch> *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero + xml_node<Ch> *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero + + }; + + /////////////////////////////////////////////////////////////////////////// + // XML document + + //! This class represents root of the DOM hierarchy. + //! It is also an xml_node and a memory_pool through public inheritance. + //! Use parse() function to build a DOM tree from a zero-terminated XML text string. + //! parse() function allocates memory for nodes and attributes by using functions of xml_document, + //! which are inherited from memory_pool. + //! To access root node of the document, use the document itself, as if it was an xml_node. + //! \param Ch Character type to use. + template<class Ch = char> + class xml_document: public xml_node<Ch>, public memory_pool<Ch> + { + + public: + + //! Constructs empty XML document + xml_document() + : xml_node<Ch>(node_document) + { + } + + //! Parses zero-terminated XML string according to given flags. + //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used. + //! The string must persist for the lifetime of the document. + //! In case of error, rapidxml::parse_error exception will be thrown. + //! <br><br> + //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning. + //! Make sure that data is zero-terminated. + //! <br><br> + //! Document can be parsed into multiple times. + //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool. + //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser. + template<int Flags> + void parse(Ch *text) + { + assert(text); + + // Remove current contents + this->remove_all_nodes(); + this->remove_all_attributes(); + + // Parse BOM, if any + parse_bom<Flags>(text); + + // Parse children + while (1) + { + // Skip whitespace before node + skip<whitespace_pred, Flags>(text); + if (*text == 0) + break; + + // Parse and append new child + if (*text == Ch('<')) + { + ++text; // Skip '<' + if (xml_node<Ch> *node = parse_node<Flags>(text)) + this->append_node(node); + } + else + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected <", text); + } + + } + + //! Clears the document by deleting all nodes and clearing the memory pool. + //! All nodes owned by document pool are destroyed. + void clear() + { + this->remove_all_nodes(); + this->remove_all_attributes(); + memory_pool<Ch>::clear(); + } + + private: + + /////////////////////////////////////////////////////////////////////// + // Internal character utility functions + + // Detect whitespace character + struct whitespace_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_whitespace[internal::get_index(ch)]; + } + }; + + // Detect node name character + struct node_name_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_node_name[internal::get_index(ch)]; + } + }; + + // Detect attribute name character + struct attribute_name_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_attribute_name[internal::get_index(ch)]; + } + }; + + // Detect text character (PCDATA) + struct text_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text[internal::get_index(ch)]; + } + }; + + // Detect text character (PCDATA) that does not require processing + struct text_pure_no_ws_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text_pure_no_ws[internal::get_index(ch)]; + } + }; + + // Detect text character (PCDATA) that does not require processing + struct text_pure_with_ws_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text_pure_with_ws[internal::get_index(ch)]; + } + }; + + // Detect attribute value character + template<Ch Quote> + struct attribute_value_pred + { + static unsigned char test(Ch ch) + { + if (Quote == Ch('\'')) + return internal::lookup_tables<0>::lookup_attribute_data_1[internal::get_index(ch)]; + if (Quote == Ch('\"')) + return internal::lookup_tables<0>::lookup_attribute_data_2[internal::get_index(ch)]; + return 0; // Should never be executed, to avoid warnings on Comeau + } + }; + + // Detect attribute value character + template<Ch Quote> + struct attribute_value_pure_pred + { + static unsigned char test(Ch ch) + { + if (Quote == Ch('\'')) + return internal::lookup_tables<0>::lookup_attribute_data_1_pure[internal::get_index(ch)]; + if (Quote == Ch('\"')) + return internal::lookup_tables<0>::lookup_attribute_data_2_pure[internal::get_index(ch)]; + return 0; // Should never be executed, to avoid warnings on Comeau + } + }; + + // Insert coded character, using UTF8 or 8-bit ASCII + template<int Flags> + static void insert_coded_character(Ch *&text, unsigned long code) + { + if (Flags & parse_no_utf8) + { + // Insert 8-bit ASCII character + // Todo: possibly verify that code is less than 256 and use replacement char otherwise? + text[0] = static_cast<unsigned char>(code); + text += 1; + } + else + { + // Insert UTF8 sequence + if (code < 0x80) // 1 byte sequence + { + text[0] = static_cast<unsigned char>(code); + text += 1; + } + else if (code < 0x800) // 2 byte sequence + { + text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast<unsigned char>(code | 0xC0); + text += 2; + } + else if (code < 0x10000) // 3 byte sequence + { + text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6; + text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast<unsigned char>(code | 0xE0); + text += 3; + } + else if (code < 0x110000) // 4 byte sequence + { + text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6; + text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6; + text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast<unsigned char>(code | 0xF0); + text += 4; + } + else // Invalid, only codes up to 0x10FFFF are allowed in Unicode + { + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid numeric character entity", text); + } + } + } + + // Skip characters until predicate evaluates to true + template<class StopPred, int Flags> + static void skip(Ch *&text) + { + Ch *tmp = text; + while (StopPred::test(*tmp)) + ++tmp; + text = tmp; + } + + // Skip characters until predicate evaluates to true while doing the following: + // - replacing XML character entity references with proper characters (' & " < > &#...;) + // - condensing whitespace sequences to single space character + template<class StopPred, class StopPredPure, int Flags> + static Ch *skip_and_expand_character_refs(Ch *&text) + { + // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip + if (Flags & parse_no_entity_translation && + !(Flags & parse_normalize_whitespace) && + !(Flags & parse_trim_whitespace)) + { + skip<StopPred, Flags>(text); + return text; + } + + // Use simple skip until first modification is detected + skip<StopPredPure, Flags>(text); + + // Use translation skip + Ch *src = text; + Ch *dest = src; + while (StopPred::test(*src)) + { + // If entity translation is enabled + if (!(Flags & parse_no_entity_translation)) + { + // Test if replacement is needed + if (src[0] == Ch('&')) + { + switch (src[1]) + { + + // & ' + case Ch('a'): + if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) + { + *dest = Ch('&'); + ++dest; + src += 5; + continue; + } + if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';')) + { + *dest = Ch('\''); + ++dest; + src += 6; + continue; + } + break; + + // " + case Ch('q'): + if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';')) + { + *dest = Ch('"'); + ++dest; + src += 6; + continue; + } + break; + + // > + case Ch('g'): + if (src[2] == Ch('t') && src[3] == Ch(';')) + { + *dest = Ch('>'); + ++dest; + src += 4; + continue; + } + break; + + // < + case Ch('l'): + if (src[2] == Ch('t') && src[3] == Ch(';')) + { + *dest = Ch('<'); + ++dest; + src += 4; + continue; + } + break; + + // &#...; - assumes ASCII + case Ch('#'): + if (src[2] == Ch('x')) + { + unsigned long code = 0; + src += 3; // Skip &#x + while (1) + { + unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)]; + if (digit == 0xFF) + break; + code = code * 16 + digit; + ++src; + } + insert_coded_character<Flags>(dest, code); // Put character in output + } + else + { + unsigned long code = 0; + src += 2; // Skip &# + while (1) + { + unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)]; + if (digit == 0xFF) + break; + code = code * 10 + digit; + ++src; + } + insert_coded_character<Flags>(dest, code); // Put character in output + } + if (*src == Ch(';')) + ++src; + else + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ;", src); + continue; + + // Something else + default: + // Ignore, just copy '&' verbatim + break; + + } + } + } + + // If whitespace condensing is enabled + if (Flags & parse_normalize_whitespace) + { + // Test if condensing is needed + if (whitespace_pred::test(*src)) + { + *dest = Ch(' '); ++dest; // Put single space in dest + ++src; // Skip first whitespace char + // Skip remaining whitespace chars + while (whitespace_pred::test(*src)) + ++src; + continue; + } + } + + // No replacement, only copy character + *dest++ = *src++; + + } + + // Return new end + text = src; + return dest; + + } + + /////////////////////////////////////////////////////////////////////// + // Internal parsing functions + + // Parse BOM, if any + template<int Flags> + void parse_bom(Ch *&text) + { + // UTF-8? + if (static_cast<unsigned char>(text[0]) == 0xEF && + static_cast<unsigned char>(text[1]) == 0xBB && + static_cast<unsigned char>(text[2]) == 0xBF) + { + text += 3; // Skip utf-8 bom + } + } + + // Parse XML declaration (<?xml...) + template<int Flags> + xml_node<Ch> *parse_xml_declaration(Ch *&text) + { + // If parsing of declaration is disabled + if (!(Flags & parse_declaration_node)) + { + // Skip until end of declaration + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (!text[0]) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 2; // Skip '?>' + return 0; + } + + // Create declaration + xml_node<Ch> *declaration = this->allocate_node(node_declaration); + + // Skip whitespace before attributes or ?> + skip<whitespace_pred, Flags>(text); + + // Parse declaration attributes + parse_node_attributes<Flags>(text, declaration); + + // Skip ?> + if (text[0] != Ch('?') || text[1] != Ch('>')) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ?>", text); + text += 2; + + return declaration; + } + + // Parse XML comment (<!--...) + template<int Flags> + xml_node<Ch> *parse_comment(Ch *&text) + { + // If parsing of comments is disabled + if (!(Flags & parse_comment_nodes)) + { + // Skip until end of comment + while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) + { + if (!text[0]) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 3; // Skip '-->' + return 0; // Do not produce comment node + } + + // Remember value start + Ch *val = text; + + // Skip until end of comment + while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) + { + if (!text[0]) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Create comment node + xml_node<Ch> *comment = this->allocate_node(node_comment); + comment->value(val, text - val); + + // Place zero terminator after comment value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 3; // Skip '-->' + return comment; + } + + // Parse DOCTYPE + template<int Flags> + xml_node<Ch> *parse_doctype(Ch *&text) + { + // Remember value start + Ch *val = text; + + // Skip to > + while (*text != Ch('>')) + { + // Determine character type + switch (*text) + { + + // If '[' encountered, scan for matching ending ']' using naive algorithm with depth + // This works for all W3C test files except for 2 most wicked + case Ch('['): + { + ++text; // Skip '[' + int depth = 1; + while (depth > 0) + { + switch (*text) + { + case Ch('['): ++depth; break; + case Ch(']'): --depth; break; + case 0: BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + default: break; + } + ++text; + } + break; + } + + // Error on end of text + case Ch('\0'): + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + + // Other character, skip it + default: + ++text; + + } + } + + // If DOCTYPE nodes enabled + if (Flags & parse_doctype_node) + { + // Create a new doctype node + xml_node<Ch> *doctype = this->allocate_node(node_doctype); + doctype->value(val, text - val); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 1; // skip '>' + return doctype; + } + else + { + text += 1; // skip '>' + return 0; + } + + } + + // Parse PI + template<int Flags> + xml_node<Ch> *parse_pi(Ch *&text) + { + // If creation of PI nodes is enabled + if (Flags & parse_pi_nodes) + { + // Create pi node + xml_node<Ch> *pi = this->allocate_node(node_pi); + + // Extract PI target name + Ch *n = text; + skip<node_name_pred, Flags>(text); + if (text == n) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected PI target", text); + pi->name(n, text - n); + + // Skip whitespace between pi target and pi + skip<whitespace_pred, Flags>(text); + + // Remember start of pi + Ch *val = text; + + // Skip to '?>' + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (*text == Ch('\0')) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Set pi value (verbatim, no entity expansion or whitespace normalization) + pi->value(val, text - val); + + // Place zero terminator after name and value + if (!(Flags & parse_no_string_terminators)) + { + pi->name()[pi->name_size()] = Ch('\0'); + pi->value()[pi->value_size()] = Ch('\0'); + } + + text += 2; // Skip '?>' + return pi; + } + else + { + // Skip to '?>' + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (*text == Ch('\0')) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 2; // Skip '?>' + return 0; + } + } + + // Parse and append data + // Return character that ends data. + // This is necessary because this character might have been overwritten by a terminating 0 + template<int Flags> + Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start) + { + // Backup to contents start if whitespace trimming is disabled + if (!(Flags & parse_trim_whitespace)) + text = contents_start; + + // Skip until end of data + Ch *val = text, *end; + if (Flags & parse_normalize_whitespace) + end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred, Flags>(text); + else + end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred, Flags>(text); + + // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after > + if (Flags & parse_trim_whitespace) + { + if (Flags & parse_normalize_whitespace) + { + // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end + if (*(end - 1) == Ch(' ')) + --end; + } + else + { + // Backup until non-whitespace character is found + while (whitespace_pred::test(*(end - 1))) + --end; + } + } + + // If characters are still left between end and value (this test is only necessary if normalization is enabled) + // Create new data node + if (!(Flags & parse_no_data_nodes)) + { + xml_node<Ch> *data = this->allocate_node(node_data); + data->value(val, end - val); + node->append_node(data); + } + + // Add data to parent node if no data exists yet + if (!(Flags & parse_no_element_values)) + if (*node->value() == Ch('\0')) + node->value(val, end - val); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + { + Ch ch = *text; + *end = Ch('\0'); + return ch; // Return character that ends data; this is required because zero terminator overwritten it + } + + // Return character that ends data + return *text; + } + + // Parse CDATA + template<int Flags> + xml_node<Ch> *parse_cdata(Ch *&text) + { + // If CDATA is disabled + if (Flags & parse_no_data_nodes) + { + // Skip until end of cdata + while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) + { + if (!text[0]) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 3; // Skip ]]> + return 0; // Do not produce CDATA node + } + + // Skip until end of cdata + Ch *val = text; + while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) + { + if (!text[0]) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Create new cdata node + xml_node<Ch> *cdata = this->allocate_node(node_cdata); + cdata->value(val, text - val); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 3; // Skip ]]> + return cdata; + } + + // Parse element node + template<int Flags> + xml_node<Ch> *parse_element(Ch *&text) + { + // Create element node + xml_node<Ch> *element = this->allocate_node(node_element); + + // Extract element name + Ch *n = text; + skip<node_name_pred, Flags>(text); + if (text == n) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected element name", text); + element->name(n, text - n); + + // Skip whitespace between element name and attributes or > + skip<whitespace_pred, Flags>(text); + + // Parse attributes, if any + parse_node_attributes<Flags>(text, element); + + // Determine ending type + if (*text == Ch('>')) + { + ++text; + parse_node_contents<Flags>(text, element); + } + else if (*text == Ch('/')) + { + ++text; + if (*text != Ch('>')) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text); + ++text; + } + else + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text); + + // Place zero terminator after name + if (!(Flags & parse_no_string_terminators)) + element->name()[element->name_size()] = Ch('\0'); + + // Return parsed element + return element; + } + + // Determine node type, and parse it + template<int Flags> + xml_node<Ch> *parse_node(Ch *&text) + { + // Parse proper node type + switch (text[0]) + { + + // <... + default: + // Parse and append element node + return parse_element<Flags>(text); + + // <?... + case Ch('?'): + ++text; // Skip ? + if ((text[0] == Ch('x') || text[0] == Ch('X')) && + (text[1] == Ch('m') || text[1] == Ch('M')) && + (text[2] == Ch('l') || text[2] == Ch('L')) && + whitespace_pred::test(text[3])) + { + // '<?xml ' - xml declaration + text += 4; // Skip 'xml ' + return parse_xml_declaration<Flags>(text); + } + else + { + // Parse PI + return parse_pi<Flags>(text); + } + + // <!... + case Ch('!'): + + // Parse proper subset of <! node + switch (text[1]) + { + + // <!- + case Ch('-'): + if (text[2] == Ch('-')) + { + // '<!--' - xml comment + text += 3; // Skip '!--' + return parse_comment<Flags>(text); + } + break; + + // <![ + case Ch('['): + if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A') && + text[5] == Ch('T') && text[6] == Ch('A') && text[7] == Ch('[')) + { + // '<![CDATA[' - cdata + text += 8; // Skip '![CDATA[' + return parse_cdata<Flags>(text); + } + break; + + // <!D + case Ch('D'): + if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T') && + text[5] == Ch('Y') && text[6] == Ch('P') && text[7] == Ch('E') && + whitespace_pred::test(text[8])) + { + // '<!DOCTYPE ' - doctype + text += 9; // skip '!DOCTYPE ' + return parse_doctype<Flags>(text); + } + break; + + default: break; + + } // switch + + // Attempt to skip other, unrecognized node types starting with <! + ++text; // Skip ! + while (*text != Ch('>')) + { + if (*text == 0) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + ++text; // Skip '>' + return 0; // No node recognized + + } + } + + // Parse contents of the node - children, data etc. + template<int Flags> + void parse_node_contents(Ch *&text, xml_node<Ch> *node) + { + // For all children and text + while (1) + { + // Skip whitespace between > and node contents + Ch *contents_start = text; // Store start of node contents before whitespace is skipped + if (Flags & parse_trim_whitespace) + skip<whitespace_pred, Flags>(text); + Ch next_char = *text; + + // After data nodes, instead of continuing the loop, control jumps here. + // This is because zero termination inside parse_and_append_data() function + // would wreak havoc with the above code. + // Also, skipping whitespace after data nodes is unnecessary. + after_data_node: + + // Determine what comes next: node closing, child node, data node, or 0? + switch (next_char) + { + + // Node closing or child node + case Ch('<'): + if (text[1] == Ch('/')) + { + // Node closing + text += 2; // Skip '</' + if (Flags & parse_validate_closing_tags) + { + // Skip and validate closing tag name + Ch *closing_name = text; + skip<node_name_pred, Flags>(text); + if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true)) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid closing tag name", text); + } + else + { + // No validation, just skip name + skip<node_name_pred, Flags>(text); + } + // Skip remaining whitespace after node name + skip<whitespace_pred, Flags>(text); + if (*text != Ch('>')) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text); + ++text; // Skip '>' + return; // Node closed, finished parsing contents + } + else + { + // Child node + ++text; // Skip '<' + if (xml_node<Ch> *child = parse_node<Flags>(text)) + node->append_node(child); + } + break; + + // End of data - error + case Ch('\0'): + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text); + + // Data node + default: + next_char = parse_and_append_data<Flags>(node, text, contents_start); + goto after_data_node; // Bypass regular processing after data nodes + + } + } + } + + // Parse XML attributes of the node + template<int Flags> + void parse_node_attributes(Ch *&text, xml_node<Ch> *node) + { + // For all attributes + while (attribute_name_pred::test(*text)) + { + // Extract attribute name + Ch *n = text; + ++text; // Skip first character of attribute name + skip<attribute_name_pred, Flags>(text); + if (text == n) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected attribute name", n); + + // Create new attribute + xml_attribute<Ch> *attribute = this->allocate_attribute(); + attribute->name(n, text - n); + node->append_attribute(attribute); + + // Skip whitespace after attribute name + skip<whitespace_pred, Flags>(text); + + // Skip = + if (*text != Ch('=')) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected =", text); + ++text; + + // Add terminating zero after name + if (!(Flags & parse_no_string_terminators)) + attribute->name()[attribute->name_size()] = 0; + + // Skip whitespace after = + skip<whitespace_pred, Flags>(text); + + // Skip quote and remember if it was ' or " + Ch quote = *text; + if (quote != Ch('\'') && quote != Ch('"')) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text); + ++text; + + // Extract attribute value and expand char refs in it + Ch *val = text, *end; + const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes + if (quote == Ch('\'')) + end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>, attribute_value_pure_pred<Ch('\'')>, AttFlags>(text); + else + end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>, attribute_value_pure_pred<Ch('"')>, AttFlags>(text); + + // Set attribute value + attribute->value(val, end - val); + + // Make sure that end quote is present + if (*text != quote) + BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text); + ++text; // Skip quote + + // Add terminating zero after value + if (!(Flags & parse_no_string_terminators)) + attribute->value()[attribute->value_size()] = 0; + + // Skip whitespace after attribute value + skip<whitespace_pred, Flags>(text); + } + } + + }; + + //! \cond internal + namespace internal + { + + // Whitespace (space \n \r \t) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F + }; + + // Node name (anything but space \n \r \t / > ? \0) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_node_name[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) (anything but < \0) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_text[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled + // (anything but < \0 &) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled + // (anything but < \0 & space \n \r \t) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute name (anything but space \n \r \t / < > = ? ! \0) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with single quote (anything but ' \0) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with single quote that does not require processing (anything but ' \0 &) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with double quote (anything but " \0) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with double quote that does not require processing (anything but " \0 &) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Digits (dec and hex, 255 denotes end of numeric character reference) + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_digits[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 1 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 2 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255, // 3 + 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 4 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 5 + 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 6 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 7 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 8 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 9 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // A + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // B + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // C + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // D + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // E + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 // F + }; + + // Upper case conversion + template<int Dummy> + const unsigned char lookup_tables<Dummy>::lookup_upcase[256] = + { + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A B C D E F + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 + 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 6 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123,124,125,126,127, // 7 + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8 + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9 + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C + 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D + 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F + }; + } + //! \endcond + +}}}} + +// Undefine internal macros +#undef BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR + +// On MSVC, restore warnings state +#ifdef _MSC_VER + #pragma warning(pop) +#endif + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_error.hpp b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_error.hpp new file mode 100644 index 0000000..c79835c --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_error.hpp @@ -0,0 +1,33 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED + +#include <boost/property_tree/detail/file_parser_error.hpp> +#include <string> + +namespace boost { namespace property_tree { namespace xml_parser +{ + + //! Xml parser error + class xml_parser_error: public file_parser_error + { + public: + xml_parser_error(const std::string &msg, + const std::string &file, + unsigned long l): + file_parser_error(msg, file, l) + { + } + }; + +} } } + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_flags.hpp b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_flags.hpp new file mode 100644 index 0000000..9340fe2 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_flags.hpp @@ -0,0 +1,31 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED + +namespace boost { namespace property_tree { namespace xml_parser +{ + + /// Text elements should be put in separate keys, + /// not concatenated in parent data. + static const int no_concat_text = 0x1; + /// Comments should be omitted. + static const int no_comments = 0x2; + /// Whitespace should be collapsed and trimmed. + static const int trim_whitespace = 0x4; + + inline bool validate_flags(int flags) + { + return (flags & ~(no_concat_text | no_comments | trim_whitespace)) == 0; + } + +} } } + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_read_rapidxml.hpp b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_read_rapidxml.hpp new file mode 100644 index 0000000..acec34d9 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_read_rapidxml.hpp @@ -0,0 +1,144 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2007 Marcin Kalicinski +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED + +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/detail/xml_parser_error.hpp> +#include <boost/property_tree/detail/xml_parser_flags.hpp> +#include <boost/property_tree/detail/xml_parser_utils.hpp> +#include <boost/property_tree/detail/rapidxml.hpp> +#include <vector> + +namespace boost { namespace property_tree { namespace xml_parser +{ + + template<class Ptree, class Ch> + void read_xml_node(detail::rapidxml::xml_node<Ch> *node, + Ptree &pt, int flags) + { + using namespace detail::rapidxml; + switch (node->type()) + { + // Element nodes + case node_element: + { + // Create node + Ptree &pt_node = pt.push_back(std::make_pair(node->name(), + Ptree()))->second; + + // Copy attributes + if (node->first_attribute()) + { + Ptree &pt_attr_root = pt_node.push_back( + std::make_pair(xmlattr<Ch>(), Ptree()))->second; + for (xml_attribute<Ch> *attr = node->first_attribute(); + attr; attr = attr->next_attribute()) + { + Ptree &pt_attr = pt_attr_root.push_back( + std::make_pair(attr->name(), Ptree()))->second; + pt_attr.data() = attr->value(); + } + } + + // Copy children + for (xml_node<Ch> *child = node->first_node(); + child; child = child->next_sibling()) + read_xml_node(child, pt_node, flags); + } + break; + + // Data nodes + case node_data: + case node_cdata: + { + if (flags & no_concat_text) + pt.push_back(std::make_pair(xmltext<Ch>(), + Ptree(node->value()))); + else + pt.data() += node->value(); + } + break; + + // Comment nodes + case node_comment: + { + if (!(flags & no_comments)) + pt.push_back(std::make_pair(xmlcomment<Ch>(), + Ptree(node->value()))); + } + break; + + default: + // Skip other node types + break; + } + } + + template<class Ptree> + void read_xml_internal(std::basic_istream< + typename Ptree::key_type::value_type> &stream, + Ptree &pt, + int flags, + const std::string &filename) + { + typedef typename Ptree::key_type::value_type Ch; + using namespace detail::rapidxml; + + // Load data into vector + stream.unsetf(std::ios::skipws); + std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()), + std::istreambuf_iterator<Ch>()); + if (!stream.good()) + BOOST_PROPERTY_TREE_THROW( + xml_parser_error("read error", filename, 0)); + v.push_back(0); // zero-terminate + + try { + // Parse using appropriate flags + const int f_tws = parse_normalize_whitespace + | parse_trim_whitespace; + const int f_c = parse_comment_nodes; + // Some compilers don't like the bitwise or in the template arg. + const int f_tws_c = parse_normalize_whitespace + | parse_trim_whitespace + | parse_comment_nodes; + xml_document<Ch> doc; + if (flags & no_comments) { + if (flags & trim_whitespace) + doc.BOOST_NESTED_TEMPLATE parse<f_tws>(&v.front()); + else + doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front()); + } else { + if (flags & trim_whitespace) + doc.BOOST_NESTED_TEMPLATE parse<f_tws_c>(&v.front()); + else + doc.BOOST_NESTED_TEMPLATE parse<f_c>(&v.front()); + } + + // Create ptree from nodes + Ptree local; + for (xml_node<Ch> *child = doc.first_node(); + child; child = child->next_sibling()) + read_xml_node(child, local, flags); + + // Swap local and result ptrees + pt.swap(local); + } catch (parse_error &e) { + long line = static_cast<long>( + std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1); + BOOST_PROPERTY_TREE_THROW( + xml_parser_error(e.what(), filename, line)); + } + } + +} } } + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_utils.hpp b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_utils.hpp new file mode 100644 index 0000000..7c8a6e1 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_utils.hpp @@ -0,0 +1,136 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED + +#include <boost/property_tree/detail/ptree_utils.hpp> +#include <boost/property_tree/detail/xml_parser_error.hpp> +#include <boost/property_tree/detail/xml_parser_writer_settings.hpp> +#include <string> +#include <algorithm> +#include <locale> + +namespace boost { namespace property_tree { namespace xml_parser +{ + + template<class Ch> + std::basic_string<Ch> condense(const std::basic_string<Ch> &s) + { + std::basic_string<Ch> r; + std::locale loc; + bool space = false; + typename std::basic_string<Ch>::const_iterator end = s.end(); + for (typename std::basic_string<Ch>::const_iterator it = s.begin(); + it != end; ++it) + { + if (isspace(*it, loc) || *it == Ch('\n')) + { + if (!space) + r += Ch(' '), space = true; + } + else + r += *it, space = false; + } + return r; + } + + template<class Ch> + std::basic_string<Ch> encode_char_entities(const std::basic_string<Ch> &s) + { + // Don't do anything for empty strings. + if(s.empty()) return s; + + typedef typename std::basic_string<Ch> Str; + Str r; + // To properly round-trip spaces and not uglify the XML beyond + // recognition, we have to encode them IF the text contains only spaces. + Str sp(1, Ch(' ')); + if(s.find_first_not_of(sp) == Str::npos) { + // The first will suffice. + r = detail::widen<Ch>(" "); + r += Str(s.size() - 1, Ch(' ')); + } else { + typename Str::const_iterator end = s.end(); + for (typename Str::const_iterator it = s.begin(); it != end; ++it) + { + switch (*it) + { + case Ch('<'): r += detail::widen<Ch>("<"); break; + case Ch('>'): r += detail::widen<Ch>(">"); break; + case Ch('&'): r += detail::widen<Ch>("&"); break; + case Ch('"'): r += detail::widen<Ch>("""); break; + case Ch('\''): r += detail::widen<Ch>("'"); break; + default: r += *it; break; + } + } + } + return r; + } + + template<class Ch> + std::basic_string<Ch> decode_char_entities(const std::basic_string<Ch> &s) + { + typedef typename std::basic_string<Ch> Str; + Str r; + typename Str::const_iterator end = s.end(); + for (typename Str::const_iterator it = s.begin(); it != end; ++it) + { + if (*it == Ch('&')) + { + typename Str::const_iterator semicolon = std::find(it + 1, end, Ch(';')); + if (semicolon == end) + BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0)); + Str ent(it + 1, semicolon); + if (ent == detail::widen<Ch>("lt")) r += Ch('<'); + else if (ent == detail::widen<Ch>("gt")) r += Ch('>'); + else if (ent == detail::widen<Ch>("amp")) r += Ch('&'); + else if (ent == detail::widen<Ch>("quot")) r += Ch('"'); + else if (ent == detail::widen<Ch>("apos")) r += Ch('\''); + else + BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0)); + it = semicolon; + } + else + r += *it; + } + return r; + } + + template<class Ch> + const std::basic_string<Ch> &xmldecl() + { + static std::basic_string<Ch> s = detail::widen<Ch>("<?xml>"); + return s; + } + + template<class Ch> + const std::basic_string<Ch> &xmlattr() + { + static std::basic_string<Ch> s = detail::widen<Ch>("<xmlattr>"); + return s; + } + + template<class Ch> + const std::basic_string<Ch> &xmlcomment() + { + static std::basic_string<Ch> s = detail::widen<Ch>("<xmlcomment>"); + return s; + } + + template<class Ch> + const std::basic_string<Ch> &xmltext() + { + static std::basic_string<Ch> s = detail::widen<Ch>("<xmltext>"); + return s; + } + +} } } + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_write.hpp b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_write.hpp new file mode 100644 index 0000000..614854e --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_write.hpp @@ -0,0 +1,194 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED + +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/detail/xml_parser_utils.hpp> +#include <string> +#include <ostream> +#include <iomanip> + +namespace boost { namespace property_tree { namespace xml_parser +{ + template<class Ch> + void write_xml_indent(std::basic_ostream<Ch> &stream, + int indent, + const xml_writer_settings<Ch> & settings + ) + { + stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char); + } + + template<class Ch> + void write_xml_comment(std::basic_ostream<Ch> &stream, + const std::basic_string<Ch> &s, + int indent, + bool separate_line, + const xml_writer_settings<Ch> & settings + ) + { + typedef typename std::basic_string<Ch> Str; + if (separate_line) + write_xml_indent(stream,indent,settings); + stream << Ch('<') << Ch('!') << Ch('-') << Ch('-'); + stream << s; + stream << Ch('-') << Ch('-') << Ch('>'); + if (separate_line) + stream << Ch('\n'); + } + + template<class Ch> + void write_xml_text(std::basic_ostream<Ch> &stream, + const std::basic_string<Ch> &s, + int indent, + bool separate_line, + const xml_writer_settings<Ch> & settings + ) + { + if (separate_line) + write_xml_indent(stream,indent,settings); + stream << encode_char_entities(s); + if (separate_line) + stream << Ch('\n'); + } + + template<class Ptree> + void write_xml_element(std::basic_ostream<typename Ptree::key_type::value_type> &stream, + const std::basic_string<typename Ptree::key_type::value_type> &key, + const Ptree &pt, + int indent, + const xml_writer_settings<typename Ptree::key_type::value_type> & settings) + { + + typedef typename Ptree::key_type::value_type Ch; + typedef typename std::basic_string<Ch> Str; + typedef typename Ptree::const_iterator It; + + bool want_pretty = settings.indent_count > 0; + // Find if elements present + bool has_elements = false; + bool has_attrs_only = pt.data().empty(); + for (It it = pt.begin(), end = pt.end(); it != end; ++it) + { + if (it->first != xmlattr<Ch>() ) + { + has_attrs_only = false; + if (it->first != xmltext<Ch>()) + { + has_elements = true; + break; + } + } + } + + // Write element + if (pt.data().empty() && pt.empty()) // Empty key + { + if (indent >= 0) + { + write_xml_indent(stream,indent,settings); + stream << Ch('<') << key << + Ch('/') << Ch('>'); + if (want_pretty) + stream << Ch('\n'); + } + } + else // Nonempty key + { + + // Write opening tag, attributes and data + if (indent >= 0) + { + + // Write opening brace and key + write_xml_indent(stream,indent,settings); + stream << Ch('<') << key; + + // Write attributes + if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Ch>())) + for (It it = attribs.get().begin(); it != attribs.get().end(); ++it) + stream << Ch(' ') << it->first << Ch('=') << + Ch('"') << it->second.template get_value<std::basic_string<Ch> >() << Ch('"'); + + if ( has_attrs_only ) + { + // Write closing brace + stream << Ch('/') << Ch('>'); + if (want_pretty) + stream << Ch('\n'); + } + else + { + // Write closing brace + stream << Ch('>'); + + // Break line if needed and if we want pretty-printing + if (has_elements && want_pretty) + stream << Ch('\n'); + } + } + + // Write data text, if present + if (!pt.data().empty()) + write_xml_text(stream, + pt.template get_value<std::basic_string<Ch> >(), + indent + 1, has_elements && want_pretty, settings); + + // Write elements, comments and texts + for (It it = pt.begin(); it != pt.end(); ++it) + { + if (it->first == xmlattr<Ch>()) + continue; + else if (it->first == xmlcomment<Ch>()) + write_xml_comment(stream, + it->second.template get_value<std::basic_string<Ch> >(), + indent + 1, want_pretty, settings); + else if (it->first == xmltext<Ch>()) + write_xml_text(stream, + it->second.template get_value<std::basic_string<Ch> >(), + indent + 1, has_elements && want_pretty, settings); + else + write_xml_element(stream, it->first, it->second, + indent + 1, settings); + } + + // Write closing tag + if (indent >= 0 && !has_attrs_only) + { + if (has_elements) + write_xml_indent(stream,indent,settings); + stream << Ch('<') << Ch('/') << key << Ch('>'); + if (want_pretty) + stream << Ch('\n'); + } + + } + } + + template<class Ptree> + void write_xml_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream, + const Ptree &pt, + const std::string &filename, + const xml_writer_settings<typename Ptree::key_type::value_type> & settings) + { + typedef typename Ptree::key_type::value_type Ch; + typedef typename std::basic_string<Ch> Str; + stream << detail::widen<Ch>("<?xml version=\"1.0\" encoding=\"") + << settings.encoding + << detail::widen<Ch>("\"?>\n"); + write_xml_element(stream, Str(), pt, -1, settings); + if (!stream) + BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename, 0)); + } + +} } } + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_writer_settings.hpp b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_writer_settings.hpp new file mode 100644 index 0000000..f22d85e --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/detail/xml_parser_writer_settings.hpp @@ -0,0 +1,62 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2007 Marcin Kalicinski +// Copyright (C) 2007 Alexey Baskakov +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED + +#include <string> +#include <boost/property_tree/detail/ptree_utils.hpp> + +namespace boost { namespace property_tree { namespace xml_parser +{ + + // Naively convert narrow string to another character type + template<class Ch> + std::basic_string<Ch> widen(const char *text) + { + std::basic_string<Ch> result; + while (*text) + { + result += Ch(*text); + ++text; + } + return result; + } + + //! Xml writer settings. The default settings lead to no pretty printing. + template<class Ch> + class xml_writer_settings + { + public: + xml_writer_settings(Ch inchar = Ch(' '), + typename std::basic_string<Ch>::size_type incount = 0, + const std::basic_string<Ch> &enc = widen<Ch>("utf-8")) + : indent_char(inchar) + , indent_count(incount) + , encoding(enc) + { + } + + Ch indent_char; + typename std::basic_string<Ch>::size_type indent_count; + std::basic_string<Ch> encoding; + }; + + template <class Ch> + xml_writer_settings<Ch> xml_writer_make_settings(Ch indent_char = Ch(' '), + typename std::basic_string<Ch>::size_type indent_count = 0, + const std::basic_string<Ch> &encoding = widen<Ch>("utf-8")) + { + return xml_writer_settings<Ch>(indent_char, indent_count, encoding); + } + +} } } + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/exceptions.hpp b/3rdParty/Boost/src/boost/property_tree/exceptions.hpp new file mode 100644 index 0000000..42e2cbd --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/exceptions.hpp @@ -0,0 +1,84 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- + +#ifndef BOOST_PROPERTY_TREE_EXCEPTIONS_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_EXCEPTIONS_HPP_INCLUDED + +#include <boost/property_tree/ptree_fwd.hpp> + +#include <boost/any.hpp> +#include <string> +#include <stdexcept> + +namespace boost { namespace property_tree +{ + + /// Base class for all property tree errors. Derives from + /// @c std::runtime_error. Call member function @c what to get human + /// readable message associated with the error. + class ptree_error : public std::runtime_error + { + public: + /// Instantiate a ptree_error instance with the given message. + /// @param what The message to associate with this error. + ptree_error(const std::string &what); + + ~ptree_error() throw(); + }; + + + /// Error indicating that translation from given value to the property tree + /// data_type (or vice versa) failed. Derives from ptree_error. + class ptree_bad_data : public ptree_error + { + public: + /// Instantiate a ptree_bad_data instance with the given message and + /// data. + /// @param what The message to associate with this error. + /// @param data The value associated with this error that was the source + /// of the translation failure. + template<class T> ptree_bad_data(const std::string &what, + const T &data); + + ~ptree_bad_data() throw(); + + /// Retrieve the data associated with this error. This is the source + /// value that failed to be translated. + template<class T> T data(); + private: + boost::any m_data; + }; + + + /// Error indicating that specified path does not exist. Derives from + /// ptree_error. + class ptree_bad_path : public ptree_error + { + public: + /// Instantiate a ptree_bad_path with the given message and path data. + /// @param what The message to associate with this error. + /// @param path The path that could not be found in the property_tree. + template<class T> ptree_bad_path(const std::string &what, + const T &path); + + ~ptree_bad_path() throw(); + + /// Retrieve the invalid path. + template<class T> T path(); + private: + boost::any m_path; + }; + +}} + +#include <boost/property_tree/detail/exception_implementation.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/id_translator.hpp b/3rdParty/Boost/src/boost/property_tree/id_translator.hpp new file mode 100644 index 0000000..02fdf44 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/id_translator.hpp @@ -0,0 +1,51 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- + +#ifndef BOOST_PROPERTY_TREE_ID_TRANSLATOR_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_ID_TRANSLATOR_HPP_INCLUDED + +#include <boost/property_tree/ptree_fwd.hpp> + +#include <boost/optional.hpp> +#include <string> + +namespace boost { namespace property_tree +{ + + /// Simple implementation of the Translator concept. It does no translation. + template <typename T> + struct id_translator + { + typedef T internal_type; + typedef T external_type; + + boost::optional<T> get_value(const T &v) { return v; } + boost::optional<T> put_value(const T &v) { return v; } + }; + + // This is the default translator whenever you get two equal types. + template <typename T> + struct translator_between<T, T> + { + typedef id_translator<T> type; + }; + + // A more specific specialization for std::basic_string. Otherwise, + // stream_translator's specialization wins. + template <typename Ch, typename Traits, typename Alloc> + struct translator_between< std::basic_string<Ch, Traits, Alloc>, + std::basic_string<Ch, Traits, Alloc> > + { + typedef id_translator< std::basic_string<Ch, Traits, Alloc> > type; + }; + +}} + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/ptree.hpp b/3rdParty/Boost/src/boost/property_tree/ptree.hpp new file mode 100644 index 0000000..243a9b6 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/ptree.hpp @@ -0,0 +1,517 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- + +#ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED + +#include <boost/property_tree/ptree_fwd.hpp> +#include <boost/property_tree/string_path.hpp> +#include <boost/property_tree/stream_translator.hpp> +#include <boost/property_tree/exceptions.hpp> +#include <boost/property_tree/detail/ptree_utils.hpp> + +#include <boost/multi_index_container.hpp> +#include <boost/multi_index/indexed_by.hpp> +#include <boost/multi_index/sequenced_index.hpp> +#include <boost/multi_index/ordered_index.hpp> +#include <boost/multi_index/member.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/throw_exception.hpp> +#include <boost/optional.hpp> +#include <utility> // for std::pair + +namespace boost { namespace property_tree +{ + + /** + * Property tree main structure. A property tree is a hierarchical data + * structure which has one element of type @p Data in each node, as well + * as an ordered sequence of sub-nodes, which are additionally identified + * by a non-unique key of type @p Key. + * + * Key equivalency is defined by @p KeyCompare, a predicate defining a + * strict weak ordering. + * + * Property tree defines a Container-like interface to the (key-node) pairs + * of its direct sub-nodes. The iterators are bidirectional. The sequence + * of nodes is held in insertion order, not key order. + */ + template<class Key, class Data, class KeyCompare> + class basic_ptree + { +#if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED) + public: +#endif + // Internal types + /** + * Simpler way to refer to this basic_ptree\<C,K,P,A\> type. + * Note that this is private, and made public only for doxygen. + */ + typedef basic_ptree<Key, Data, KeyCompare> self_type; + + public: + // Basic types + typedef Key key_type; + typedef Data data_type; + typedef KeyCompare key_compare; + + // Container view types + typedef std::pair<const Key, self_type> value_type; + typedef std::size_t size_type; + + // The problem with the iterators is that I can't make them complete + // until the container is complete. Sucks. Especially for the reverses. + class iterator; + class const_iterator; + class reverse_iterator; + class const_reverse_iterator; + + // Associative view types + class assoc_iterator; + class const_assoc_iterator; + + // Property tree view types + typedef typename path_of<Key>::type path_type; + + + // The big five + + /** Creates a node with no children and default-constructed data. */ + basic_ptree(); + /** Creates a node with no children and a copy of the given data. */ + explicit basic_ptree(const data_type &data); + basic_ptree(const self_type &rhs); + ~basic_ptree(); + /** Basic guarantee only. */ + self_type &operator =(const self_type &rhs); + + /** Swap with other tree. Only constant-time and nothrow if the + * data type's swap is. + */ + void swap(self_type &rhs); + + // Container view functions + + /** The number of direct children of this node. */ + size_type size() const; + size_type max_size() const; + /** Whether there are any direct children. */ + bool empty() const; + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; + reverse_iterator rend(); + const_reverse_iterator rend() const; + + value_type &front(); + const value_type &front() const; + value_type &back(); + const value_type &back() const; + + /** Insert a copy of the given tree with its key just before the given + * position in this node. This operation invalidates no iterators. + * @return An iterator to the newly created child. + */ + iterator insert(iterator where, const value_type &value); + + /** Range insert. Equivalent to: + * @code + * for(; first != last; ++first) insert(where, *first); + * @endcode + */ + template<class It> void insert(iterator where, It first, It last); + + /** Erase the child pointed at by the iterator. This operation + * invalidates the given iterator, as well as its equivalent + * assoc_iterator. + * @return A valid iterator pointing to the element after the erased. + */ + iterator erase(iterator where); + + /** Range erase. Equivalent to: + * @code + * while(first != last;) first = erase(first); + * @endcode + */ + iterator erase(iterator first, iterator last); + + /** Equivalent to insert(begin(), value). */ + iterator push_front(const value_type &value); + + /** Equivalent to insert(end(), value). */ + iterator push_back(const value_type &value); + + /** Equivalent to erase(begin()). */ + void pop_front(); + + /** Equivalent to erase(boost::prior(end())). */ + void pop_back(); + + /** Reverses the order of direct children in the property tree. */ + void reverse(); + + /** Sorts the direct children of this node according to the predicate. + * The predicate is passed the whole pair of key and child. + */ + template<class Compare> void sort(Compare comp); + + /** Sorts the direct children of this node according to key order. */ + void sort(); + + // Equality + + /** Two property trees are the same if they have the same data, the keys + * and order of their children are the same, and the children compare + * equal, recursively. + */ + bool operator ==(const self_type &rhs) const; + bool operator !=(const self_type &rhs) const; + + // Associative view + + /** Returns an iterator to the first child, in order. */ + assoc_iterator ordered_begin(); + /** Returns an iterator to the first child, in order. */ + const_assoc_iterator ordered_begin() const; + + /** Returns the not-found iterator. Equivalent to end() in a real + * associative container. + */ + assoc_iterator not_found(); + /** Returns the not-found iterator. Equivalent to end() in a real + * associative container. + */ + const_assoc_iterator not_found() const; + + /** Find a child with the given key, or not_found() if there is none. + * There is no guarantee about which child is returned if multiple have + * the same key. + */ + assoc_iterator find(const key_type &key); + + /** Find a child with the given key, or not_found() if there is none. + * There is no guarantee about which child is returned if multiple have + * the same key. + */ + const_assoc_iterator find(const key_type &key) const; + + /** Find the range of children that have the given key. */ + std::pair<assoc_iterator, assoc_iterator> + equal_range(const key_type &key); + + /** Find the range of children that have the given key. */ + std::pair<const_assoc_iterator, const_assoc_iterator> + equal_range(const key_type &key) const; + + /** Count the number of direct children with the given key. */ + size_type count(const key_type &key) const; + + /** Erase all direct children with the given key and return the count. + */ + size_type erase(const key_type &key); + + /** Get the iterator that points to the same element as the argument. + * @note A valid assoc_iterator range (a, b) does not imply that + * (to_iterator(a), to_iterator(b)) is a valid range. + */ + iterator to_iterator(assoc_iterator it); + + /** Get the iterator that points to the same element as the argument. + * @note A valid const_assoc_iterator range (a, b) does not imply that + * (to_iterator(a), to_iterator(b)) is a valid range. + */ + const_iterator to_iterator(const_assoc_iterator it) const; + + // Property tree view + + /** Reference to the actual data in this node. */ + data_type &data(); + + /** Reference to the actual data in this node. */ + const data_type &data() const; + + /** Clear this tree completely, of both data and children. */ + void clear(); + + /** Get the child at the given path, or throw @c ptree_bad_path. + * @note Depending on the path, the result at each level may not be + * completely determinate, i.e. if the same key appears multiple + * times, which child is chosen is not specified. This can lead + * to the path not being resolved even though there is a + * descendant with this path. Example: + * @code + * a -> b -> c + * -> b + * @endcode + * The path "a.b.c" will succeed if the resolution of "b" chooses + * the first such node, but fail if it chooses the second. + */ + self_type &get_child(const path_type &path); + + /** Get the child at the given path, or throw @c ptree_bad_path. */ + const self_type &get_child(const path_type &path) const; + + /** Get the child at the given path, or return @p default_value. */ + self_type &get_child(const path_type &path, self_type &default_value); + + /** Get the child at the given path, or return @p default_value. */ + const self_type &get_child(const path_type &path, + const self_type &default_value) const; + + /** Get the child at the given path, or return boost::null. */ + optional<self_type &> get_child_optional(const path_type &path); + + /** Get the child at the given path, or return boost::null. */ + optional<const self_type &> + get_child_optional(const path_type &path) const; + + /** Set the node at the given path to the given value. Create any + * missing parents. If the node at the path already exists, replace it. + * @return A reference to the inserted subtree. + * @note Because of the way paths work, it is not generally guaranteed + * that a node newly created can be accessed using the same path. + * @note If the path could refer to multiple nodes, it is unspecified + * which one gets replaced. + */ + self_type &put_child(const path_type &path, const self_type &value); + + /** Add the node at the given path. Create any missing parents. If there + * already is a node at the path, add another one with the same key. + * @param path Path to the child. The last fragment must not have an + * index. + * @return A reference to the inserted subtree. + * @note Because of the way paths work, it is not generally guaranteed + * that a node newly created can be accessed using the same path. + */ + self_type &add_child(const path_type &path, const self_type &value); + + /** Take the value of this node and attempt to translate it to a + * @c Type object using the supplied translator. + * @throw ptree_bad_data if the conversion fails. + */ + template<class Type, class Translator> + typename boost::enable_if<detail::is_translator<Translator>, Type>::type + get_value(Translator tr) const; + + /** Take the value of this node and attempt to translate it to a + * @c Type object using the default translator. + * @throw ptree_bad_data if the conversion fails. + */ + template<class Type> + Type get_value() const; + + /** Take the value of this node and attempt to translate it to a + * @c Type object using the supplied translator. Return @p default_value + * if this fails. + */ + template<class Type, class Translator> + Type get_value(const Type &default_value, Translator tr) const; + + /** Make get_value do the right thing for string literals. */ + template <class Ch, class Translator> + typename boost::enable_if< + detail::is_character<Ch>, + std::basic_string<Ch> + >::type + get_value(const Ch *default_value, Translator tr) const; + + /** Take the value of this node and attempt to translate it to a + * @c Type object using the default translator. Return @p default_value + * if this fails. + */ + template<class Type> + typename boost::disable_if<detail::is_translator<Type>, Type>::type + get_value(const Type &default_value) const; + + /** Make get_value do the right thing for string literals. */ + template <class Ch> + typename boost::enable_if< + detail::is_character<Ch>, + std::basic_string<Ch> + >::type + get_value(const Ch *default_value) const; + + /** Take the value of this node and attempt to translate it to a + * @c Type object using the supplied translator. Return boost::null if + * this fails. + */ + template<class Type, class Translator> + optional<Type> get_value_optional(Translator tr) const; + + /** Take the value of this node and attempt to translate it to a + * @c Type object using the default translator. Return boost::null if + * this fails. + */ + template<class Type> + optional<Type> get_value_optional() const; + + /** Replace the value at this node with the given value, translated + * to the tree's data type using the supplied translator. + * @throw ptree_bad_data if the conversion fails. + */ + template<class Type, class Translator> + void put_value(const Type &value, Translator tr); + + /** Replace the value at this node with the given value, translated + * to the tree's data type using the default translator. + * @throw ptree_bad_data if the conversion fails. + */ + template<class Type> + void put_value(const Type &value); + + /** Shorthand for get_child(path).get_value(tr). */ + template<class Type, class Translator> + typename boost::enable_if<detail::is_translator<Translator>, Type>::type + get(const path_type &path, Translator tr) const; + + /** Shorthand for get_child(path).get_value\<Type\>(). */ + template<class Type> + Type get(const path_type &path) const; + + /** Shorthand for get_child(path, empty_ptree()) + * .get_value(default_value, tr). + * That is, return the translated value if possible, and the default + * value if the node doesn't exist or conversion fails. + */ + template<class Type, class Translator> + Type get(const path_type &path, + const Type &default_value, + Translator tr) const; + + /** Make get do the right thing for string literals. */ + template <class Ch, class Translator> + typename boost::enable_if< + detail::is_character<Ch>, + std::basic_string<Ch> + >::type + get(const path_type &path, const Ch *default_value, Translator tr)const; + + /** Shorthand for get_child(path, empty_ptree()) + * .get_value(default_value). + * That is, return the translated value if possible, and the default + * value if the node doesn't exist or conversion fails. + */ + template<class Type> + typename boost::disable_if<detail::is_translator<Type>, Type>::type + get(const path_type &path, const Type &default_value) const; + + /** Make get do the right thing for string literals. */ + template <class Ch> + typename boost::enable_if< + detail::is_character<Ch>, + std::basic_string<Ch> + >::type + get(const path_type &path, const Ch *default_value) const; + + /** Shorthand for: + * @code + * if(optional\<self_type&\> node = get_child_optional(path)) + * return node->get_value_optional(tr); + * return boost::null; + * @endcode + * That is, return the value if it exists and can be converted, or nil. + */ + template<class Type, class Translator> + optional<Type> get_optional(const path_type &path, Translator tr) const; + + /** Shorthand for: + * @code + * if(optional\<const self_type&\> node = get_child_optional(path)) + * return node->get_value_optional(); + * return boost::null; + * @endcode + */ + template<class Type> + optional<Type> get_optional(const path_type &path) const; + + /** Set the value of the node at the given path to the supplied value, + * translated to the tree's data type. If the node doesn't exist, it is + * created, including all its missing parents. + * @return The node that had its value changed. + * @throw ptree_bad_data if the conversion fails. + */ + template<class Type, class Translator> + self_type &put(const path_type &path, const Type &value, Translator tr); + + /** Set the value of the node at the given path to the supplied value, + * translated to the tree's data type. If the node doesn't exist, it is + * created, including all its missing parents. + * @return The node that had its value changed. + * @throw ptree_bad_data if the conversion fails. + */ + template<class Type> + self_type &put(const path_type &path, const Type &value); + + /** If the node identified by the path does not exist, create it, + * including all its missing parents. + * If the node already exists, add a sibling with the same key. + * Set the newly created node's value to the given paremeter, + * translated with the supplied translator. + * @param path Path to the child. The last fragment must not have an + * index. + * @param value The value to add. + * @param tr The translator to use. + * @return The node that was added. + * @throw ptree_bad_data if the conversion fails. + */ + template<class Type, class Translator> + self_type &add(const path_type &path, + const Type &value, + Translator tr); + + /** If the node identified by the path does not exist, create it, + * including all its missing parents. + * If the node already exists, add a sibling with the same key. + * Set the newly created node's value to the given paremeter, + * translated with the supplied translator. + * @param path Path to the child. The last fragment must not have an + * index. + * @param value The value to add. + * @return The node that was added. + * @throw ptree_bad_data if the conversion fails. + */ + template<class Type> + self_type &add(const path_type &path, const Type &value); + + private: + // Hold the data of this node + data_type m_data; + // Hold the children - this is a void* because we can't complete the + // container type within the class. + void* m_children; + + // Getter tree-walk. Not const-safe! Gets the node the path refers to, + // or null. Destroys p's value. + self_type* walk_path(path_type& p) const; + + // Modifer tree-walk. Gets the parent of the node referred to by the + // path, creating nodes as necessary. p is the path to the remaining + // child. + self_type& force_path(path_type& p); + + // This struct contains typedefs for the concrete types. + struct subs; + friend struct subs; + friend class iterator; + friend class const_iterator; + friend class reverse_iterator; + friend class const_reverse_iterator; + }; + +}} + +#include <boost/property_tree/detail/ptree_implementation.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/ptree_fwd.hpp b/3rdParty/Boost/src/boost/property_tree/ptree_fwd.hpp new file mode 100644 index 0000000..fe36741 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/ptree_fwd.hpp @@ -0,0 +1,143 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED + +#include <boost/config.hpp> +#include <boost/optional/optional_fwd.hpp> +#include <boost/throw_exception.hpp> +#include <functional> // for std::less +#include <memory> // for std::allocator +#include <string> + +namespace boost { namespace property_tree +{ + namespace detail { + template <typename T> struct less_nocase; + } + + // Classes + + template < class Key, class Data, class KeyCompare = std::less<Key> > + class basic_ptree; + + template <typename T> + struct id_translator; + + template <typename String, typename Translator> + class string_path; + + // Texas-style concepts for documentation only. +#if 0 + concept PropertyTreePath<class Path> { + // The key type for which this path works. + typename key_type; + // Return the key that the first segment of the path names. + // Split the head off the state. + key_type Path::reduce(); + + // Return true if the path is empty. + bool Path::empty() const; + + // Return true if the path contains a single element. + bool Path::single() const; + + // Dump as a std::string, for exception messages. + std::string Path::dump() const; + } + concept PropertyTreeKey<class Key> { + PropertyTreePath path; + requires SameType<Key, PropertyTreePath<path>::key_type>; + } + concept PropertyTreeTranslator<class Tr> { + typename internal_type; + typename external_type; + + boost::optional<external_type> Tr::get_value(internal_type); + boost::optional<internal_type> Tr::put_value(external_type); + } +#endif + /// If you want to use a custom key type, specialize this struct for it + /// and give it a 'type' typedef that specifies your path type. The path + /// type must conform to the Path concept described in the documentation. + /// This is already specialized for std::basic_string. + template <typename Key> + struct path_of; + + /// Specialize this struct to specify a default translator between the data + /// in a tree whose data_type is Internal, and the external data_type + /// specified in a get_value, get, put_value or put operation. + /// This is already specialized for Internal being std::basic_string. + template <typename Internal, typename External> + struct translator_between; + + class ptree_error; + class ptree_bad_data; + class ptree_bad_path; + + // Typedefs + + /** Implements a path using a std::string as the key. */ + typedef string_path<std::string, id_translator<std::string> > path; + + /** + * A property tree with std::string for key and data, and default + * comparison. + */ + typedef basic_ptree<std::string, std::string> ptree; + + /** + * A property tree with std::string for key and data, and case-insensitive + * comparison. + */ + typedef basic_ptree<std::string, std::string, + detail::less_nocase<std::string> > + iptree; + +#ifndef BOOST_NO_STD_WSTRING + /** Implements a path using a std::wstring as the key. */ + typedef string_path<std::wstring, id_translator<std::wstring> > wpath; + + /** + * A property tree with std::wstring for key and data, and default + * comparison. + * @note The type only exists if the platform supports @c wchar_t. + */ + typedef basic_ptree<std::wstring, std::wstring> wptree; + + /** + * A property tree with std::wstring for key and data, and case-insensitive + * comparison. + * @note The type only exists if the platform supports @c wchar_t. + */ + typedef basic_ptree<std::wstring, std::wstring, + detail::less_nocase<std::wstring> > + wiptree; +#endif + + // Free functions + + /** + * Swap two property tree instances. + */ + template<class K, class D, class C> + void swap(basic_ptree<K, D, C> &pt1, + basic_ptree<K, D, C> &pt2); + +} } + + +#if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED) + // Throwing macro to avoid no return warnings portably +# define BOOST_PROPERTY_TREE_THROW(e) BOOST_THROW_EXCEPTION(e) +#endif + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/stream_translator.hpp b/3rdParty/Boost/src/boost/property_tree/stream_translator.hpp new file mode 100644 index 0000000..c7fabfa --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/stream_translator.hpp @@ -0,0 +1,221 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- + +#ifndef BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED + +#include <boost/property_tree/ptree_fwd.hpp> + +#include <boost/optional.hpp> +#include <boost/optional/optional_io.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/decay.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <sstream> +#include <string> +#include <locale> +#include <limits> + +namespace boost { namespace property_tree +{ + + template <typename Ch, typename Traits, typename E, typename Enabler = void> + struct customize_stream + { + static void insert(std::basic_ostream<Ch, Traits>& s, const E& e) { + s << e; + } + static void extract(std::basic_istream<Ch, Traits>& s, E& e) { + s >> e; + if(!s.eof()) { + s >> std::ws; + } + } + }; + + // No whitespace skipping for single characters. + template <typename Ch, typename Traits> + struct customize_stream<Ch, Traits, Ch, void> + { + static void insert(std::basic_ostream<Ch, Traits>& s, Ch e) { + s << e; + } + static void extract(std::basic_istream<Ch, Traits>& s, Ch& e) { + s.unsetf(std::ios_base::skipws); + s >> e; + } + }; + + // Ugly workaround for numeric_traits that don't have members when not + // specialized, e.g. MSVC. + namespace detail + { + template <bool is_specialized> + struct is_inexact_impl + { + template <typename T> + struct test + { + typedef boost::false_type type; + }; + }; + template <> + struct is_inexact_impl<true> + { + template <typename T> + struct test + { + typedef boost::integral_constant<bool, + !std::numeric_limits<T>::is_exact> type; + }; + }; + + template <typename F> + struct is_inexact + { + typedef typename boost::decay<F>::type decayed; + typedef typename is_inexact_impl< + std::numeric_limits<decayed>::is_specialized + >::BOOST_NESTED_TEMPLATE test<decayed>::type type; + static const bool value = type::value; + }; + } + + template <typename Ch, typename Traits, typename F> + struct customize_stream<Ch, Traits, F, + typename boost::enable_if< detail::is_inexact<F> >::type + > + { + static void insert(std::basic_ostream<Ch, Traits>& s, const F& e) { + s.precision(std::numeric_limits<F>::digits10 + 1); + s << e; + } + static void extract(std::basic_istream<Ch, Traits>& s, F& e) { + s >> e; + if(!s.eof()) { + s >> std::ws; + } + } + }; + + template <typename Ch, typename Traits> + struct customize_stream<Ch, Traits, bool, void> + { + static void insert(std::basic_ostream<Ch, Traits>& s, bool e) { + s.setf(std::ios_base::boolalpha); + s << e; + } + static void extract(std::basic_istream<Ch, Traits>& s, bool& e) { + s >> e; + if(s.fail()) { + // Try again in word form. + s.clear(); + s.setf(std::ios_base::boolalpha); + s >> e; + } + if(!s.eof()) { + s >> std::ws; + } + } + }; + + template <typename Ch, typename Traits> + struct customize_stream<Ch, Traits, signed char, void> + { + static void insert(std::basic_ostream<Ch, Traits>& s, signed char e) { + s << (int)e; + } + static void extract(std::basic_istream<Ch, Traits>& s, signed char& e) { + int i; + s >> i; + // out of range? + if(i > (std::numeric_limits<signed char>::max)() || + i < (std::numeric_limits<signed char>::min)()) + { + s.clear(); // guarantees eof to be unset + return; + } + e = (signed char)i; + if(!s.eof()) { + s >> std::ws; + } + } + }; + + template <typename Ch, typename Traits> + struct customize_stream<Ch, Traits, unsigned char, void> + { + static void insert(std::basic_ostream<Ch, Traits>& s, unsigned char e) { + s << (unsigned)e; + } + static void extract(std::basic_istream<Ch,Traits>& s, unsigned char& e){ + unsigned i; + s >> i; + // out of range? + if(i > (std::numeric_limits<unsigned char>::max)()) { + s.clear(); // guarantees eof to be unset + return; + } + e = (unsigned char)i; + if(!s.eof()) { + s >> std::ws; + } + } + }; + + /// Implementation of Translator that uses the stream overloads. + template <typename Ch, typename Traits, typename Alloc, typename E> + class stream_translator + { + typedef customize_stream<Ch, Traits, E> customized; + public: + typedef std::basic_string<Ch, Traits, Alloc> internal_type; + typedef E external_type; + + explicit stream_translator(std::locale loc = std::locale()) + : m_loc(loc) + {} + + boost::optional<E> get_value(const internal_type &v) { + std::basic_istringstream<Ch, Traits, Alloc> iss(v); + iss.imbue(m_loc); + E e; + customized::extract(iss, e); + if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) { + return boost::optional<E>(); + } + return e; + } + boost::optional<internal_type> put_value(const E &v) { + std::basic_ostringstream<Ch, Traits, Alloc> oss; + oss.imbue(m_loc); + customized::insert(oss, v); + if(oss) { + return oss.str(); + } + return boost::optional<internal_type>(); + } + + private: + std::locale m_loc; + }; + + // This is the default translator when basic_string is the internal type. + // Unless the external type is also basic_string, in which case + // id_translator takes over. + template <typename Ch, typename Traits, typename Alloc, typename E> + struct translator_between<std::basic_string<Ch, Traits, Alloc>, E> + { + typedef stream_translator<Ch, Traits, Alloc, E> type; + }; + +}} + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/string_path.hpp b/3rdParty/Boost/src/boost/property_tree/string_path.hpp new file mode 100644 index 0000000..07ec6b0 --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/string_path.hpp @@ -0,0 +1,273 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- + +#ifndef BOOST_PROPERTY_TREE_STRING_PATH_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_STRING_PATH_HPP_INCLUDED + +#include <boost/property_tree/ptree_fwd.hpp> +#include <boost/property_tree/id_translator.hpp> +#include <boost/property_tree/exceptions.hpp> +#include <boost/property_tree/detail/ptree_utils.hpp> + +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/optional.hpp> +#include <boost/throw_exception.hpp> +#include <algorithm> +#include <string> +#include <iterator> +#include <cassert> + +namespace boost { namespace property_tree +{ + namespace detail + { + template <typename Sequence, typename Iterator> + void append_and_preserve_iter(Sequence &s, const Sequence &r, + Iterator &, std::forward_iterator_tag) + { + // Here we boldly assume that anything that is not random-access + // preserves validity. This is valid for the STL sequences. + s.insert(s.end(), r.begin(), r.end()); + } + template <typename Sequence, typename Iterator> + void append_and_preserve_iter(Sequence &s, const Sequence &r, + Iterator &it, + std::random_access_iterator_tag) + { + // Convert the iterator to an index, and later back. + typename std::iterator_traits<Iterator>::difference_type idx = + it - s.begin(); + s.insert(s.end(), r.begin(), r.end()); + it = s.begin() + idx; + } + + template <typename Sequence> + inline std::string dump_sequence(const Sequence &) + { + return "<undumpable sequence>"; + } + inline std::string dump_sequence(const std::string &s) + { + return s; + } +#ifndef BOOST_NO_STD_WSTRING + inline std::string dump_sequence(const std::wstring &s) + { + return narrow(s.c_str()); + } +#endif + } + + /// Default path class. A path is a sequence of values. Groups of values + /// are separated by the separator value, which defaults to '.' cast to + /// the sequence's value type. The group of values is then passed to the + /// translator to get a key. + /// + /// If instantiated with std::string and id_translator\<std::string\>, + /// it accepts paths of the form "one.two.three.four". + /// + /// @tparam String Any Sequence. If the sequence does not support random- + /// access iteration, concatenation of paths assumes that + /// insertions at the end preserve iterator validity. + /// @tparam Translator A translator with internal_type == String. + template <typename String, typename Translator> + class string_path + { + BOOST_STATIC_ASSERT((is_same<String, + typename Translator::internal_type>::value)); + public: + typedef typename Translator::external_type key_type; + typedef typename String::value_type char_type; + + /// Create an empty path. + explicit string_path(char_type separator = char_type('.')); + /// Create a path by parsing the given string. + /// @param value A sequence, possibly with separators, that describes + /// the path, e.g. "one.two.three". + /// @param separator The separator used in parsing. Defaults to '.'. + /// @param tr The translator used by this path to convert the individual + /// parts to keys. + string_path(const String &value, char_type separator = char_type('.'), + Translator tr = Translator()); + /// Create a path by parsing the given string. + /// @param value A zero-terminated array of values. Only use if zero- + /// termination makes sense for your type, and your + /// sequence supports construction from it. Intended for + /// string literals. + /// @param separator The separator used in parsing. Defaults to '.'. + /// @param tr The translator used by this path to convert the individual + /// parts to keys. + string_path(const char_type *value, + char_type separator = char_type('.'), + Translator tr = Translator()); + + // Default copying doesn't do the right thing with the iterator + string_path(const string_path &o); + string_path& operator =(const string_path &o); + + /// Take a single element off the path at the front and return it. + key_type reduce(); + + /// Test if the path is empty. + bool empty() const; + + /// Test if the path contains a single element, i.e. no separators. + bool single() const; + + std::string dump() const { + return detail::dump_sequence(m_value); + } + + /// Append a second path to this one. + /// @pre o's separator is the same as this one's, or o has no separators + string_path& operator /=(const string_path &o) { + // If it's single, there's no separator. This allows to do + // p /= "piece"; + // even for non-default separators. + assert((m_separator == o.m_separator || o.empty() || o.single()) + && "Incompatible paths."); + if(!o.empty()) { + String sub; + if(!this->empty()) { + sub.push_back(m_separator); + } + sub.insert(sub.end(), o.cstart(), o.m_value.end()); + detail::append_and_preserve_iter(m_value, sub, m_start, + typename std::iterator_traits<s_iter>::iterator_category()); + } + return *this; + } + + private: + typedef typename String::iterator s_iter; + typedef typename String::const_iterator s_c_iter; + String m_value; + char_type m_separator; + Translator m_tr; + s_iter m_start; + s_c_iter cstart() const { return m_start; } + }; + + template <typename String, typename Translator> inline + string_path<String, Translator>::string_path(char_type separator) + : m_separator(separator), m_start(m_value.begin()) + {} + + template <typename String, typename Translator> inline + string_path<String, Translator>::string_path(const String &value, + char_type separator, + Translator tr) + : m_value(value), m_separator(separator), + m_tr(tr), m_start(m_value.begin()) + {} + + template <typename String, typename Translator> inline + string_path<String, Translator>::string_path(const char_type *value, + char_type separator, + Translator tr) + : m_value(value), m_separator(separator), + m_tr(tr), m_start(m_value.begin()) + {} + + template <typename String, typename Translator> inline + string_path<String, Translator>::string_path(const string_path &o) + : m_value(o.m_value), m_separator(o.m_separator), + m_tr(o.m_tr), m_start(m_value.begin()) + { + std::advance(m_start, std::distance(o.m_value.begin(), o.cstart())); + } + + template <typename String, typename Translator> inline + string_path<String, Translator>& + string_path<String, Translator>::operator =(const string_path &o) + { + m_value = o.m_value; + m_separator = o.m_separator; + m_tr = o.m_tr; + m_start = m_value.begin(); + std::advance(m_start, std::distance(o.m_value.begin(), o.cstart())); + return *this; + } + + template <typename String, typename Translator> + typename Translator::external_type string_path<String, Translator>::reduce() + { + assert(!empty() && "Reducing empty path"); + + s_iter next_sep = std::find(m_start, m_value.end(), m_separator); + String part(m_start, next_sep); + m_start = next_sep; + if(!empty()) { + // Unless we're at the end, skip the separator we found. + ++m_start; + } + + if(optional<key_type> key = m_tr.get_value(part)) { + return *key; + } + BOOST_PROPERTY_TREE_THROW(ptree_bad_path("Path syntax error", *this)); + } + + template <typename String, typename Translator> inline + bool string_path<String, Translator>::empty() const + { + return m_start == m_value.end(); + } + + template <typename String, typename Translator> inline + bool string_path<String, Translator>::single() const + { + return std::find(static_cast<s_c_iter>(m_start), + m_value.end(), m_separator) + == m_value.end(); + } + + // By default, this is the path for strings. You can override this by + // specializing path_of for a more specific form of std::basic_string. + template <typename Ch, typename Traits, typename Alloc> + struct path_of< std::basic_string<Ch, Traits, Alloc> > + { + typedef std::basic_string<Ch, Traits, Alloc> _string; + typedef string_path< _string, id_translator<_string> > type; + }; + + template <typename String, typename Translator> inline + string_path<String, Translator> operator /( + string_path<String, Translator> p1, + const string_path<String, Translator> &p2) + { + p1 /= p2; + return p1; + } + + // These shouldn't be necessary, but GCC won't find the one above. + template <typename String, typename Translator> inline + string_path<String, Translator> operator /( + string_path<String, Translator> p1, + const typename String::value_type *p2) + { + p1 /= p2; + return p1; + } + + template <typename String, typename Translator> inline + string_path<String, Translator> operator /( + const typename String::value_type *p1, + const string_path<String, Translator> &p2) + { + string_path<String, Translator> t(p1); + t /= p2; + return t; + } + +}} + +#endif diff --git a/3rdParty/Boost/src/boost/property_tree/xml_parser.hpp b/3rdParty/Boost/src/boost/property_tree/xml_parser.hpp new file mode 100644 index 0000000..4f36e9a --- /dev/null +++ b/3rdParty/Boost/src/boost/property_tree/xml_parser.hpp @@ -0,0 +1,153 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// Copyright (C) 2009 Sebastian Redl +// +// 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) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- +#ifndef BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED +#define BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED + +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/detail/xml_parser_write.hpp> +#include <boost/property_tree/detail/xml_parser_error.hpp> +#include <boost/property_tree/detail/xml_parser_writer_settings.hpp> +#include <boost/property_tree/detail/xml_parser_flags.hpp> +#include <boost/property_tree/detail/xml_parser_read_rapidxml.hpp> + +#include <fstream> +#include <string> +#include <locale> + +namespace boost { namespace property_tree { namespace xml_parser +{ + + /** + * Reads XML from an input stream and translates it to property tree. + * @note Clears existing contents of property tree. In case of error the + * property tree unmodified. + * @note XML attributes are placed under keys named @c \<xmlattr\>. + * @throw xml_parser_error In case of error deserializing the property tree. + * @param stream Stream from which to read in the property tree. + * @param[out] pt The property tree to populate. + * @param flags Flags controlling the behaviour of the parser. + * The following flags are supported: + * @li @c no_concat_text -- Prevents concatenation of text nodes into + * datastring of property tree. Puts them in + * separate @c \<xmltext\> strings instead. + * @li @c no_comments -- Skip XML comments. + * @li @c trim_whitespace -- Trim leading and trailing whitespace from text, + * and collapse sequences of whitespace. + */ + template<class Ptree> + void read_xml(std::basic_istream< + typename Ptree::key_type::value_type + > &stream, + Ptree &pt, + int flags = 0) + { + read_xml_internal(stream, pt, flags, std::string()); + } + + /** + * Reads XML from a file using the given locale and translates it to + * property tree. + * @note Clears existing contents of property tree. In case of error the + * property tree unmodified. + * @note XML attributes are placed under keys named @c \<xmlattr\>. + * @throw xml_parser_error In case of error deserializing the property tree. + * @param filename The file from which to read in the property tree. + * @param[out] pt The property tree to populate. + * @param flags Flags controlling the bahviour of the parser. + * The following flags are supported: + * @li @c no_concat_text -- Prevents concatenation of text nodes into + * datastring of property tree. Puts them in + * separate @c \<xmltext\> strings instead. + * @li @c no_comments -- Skip XML comments. + * @param loc The locale to use when reading in the file contents. + */ + template<class Ptree> + void read_xml(const std::string &filename, + Ptree &pt, + int flags = 0, + const std::locale &loc = std::locale()) + { + BOOST_ASSERT(validate_flags(flags)); + std::basic_ifstream<typename Ptree::key_type::value_type> + stream(filename.c_str()); + if (!stream) + BOOST_PROPERTY_TREE_THROW(xml_parser_error( + "cannot open file", filename, 0)); + stream.imbue(loc); + read_xml_internal(stream, pt, flags, filename); + } + + /** + * Translates the property tree to XML and writes it the given output + * stream. + * @throw xml_parser_error In case of error translating the property tree to + * XML or writing to the output stream. + * @param stream The stream to which to write the XML representation of the + * property tree. + * @param pt The property tree to tranlsate to XML and output. + * @param settings The settings to use when writing out the property tree as + * XML. + */ + template<class Ptree> + void write_xml(std::basic_ostream< + typename Ptree::key_type::value_type + > &stream, + const Ptree &pt, + const xml_writer_settings< + typename Ptree::key_type::value_type + > & settings = xml_writer_settings< + typename Ptree::key_type::value_type>() ) + { + write_xml_internal(stream, pt, std::string(), settings); + } + + /** + * Translates the property tree to XML and writes it the given file. + * @throw xml_parser_error In case of error translating the property tree to + * XML or writing to the output stream. + * @param filename The file to which to write the XML representation of the + * property tree. + * @param pt The property tree to tranlsate to XML and output. + * @param loc The locale to use when writing the output to file. + * @param settings The settings to use when writing out the property tree as + * XML. + */ + template<class Ptree> + void write_xml(const std::string &filename, + const Ptree &pt, + const std::locale &loc = std::locale(), + const xml_writer_settings< + typename Ptree::key_type::value_type + > & settings = xml_writer_settings< + typename Ptree::key_type::value_type>()) + { + std::basic_ofstream<typename Ptree::key_type::value_type> + stream(filename.c_str()); + if (!stream) + BOOST_PROPERTY_TREE_THROW(xml_parser_error( + "cannot open file", filename, 0)); + stream.imbue(loc); + write_xml_internal(stream, pt, filename, settings); + } + +} } } + +namespace boost { namespace property_tree +{ + using xml_parser::read_xml; + using xml_parser::write_xml; + using xml_parser::xml_parser_error; + + using xml_parser::xml_writer_settings; + using xml_parser::xml_writer_make_settings; +} } + +#endif diff --git a/3rdParty/Boost/src/boost/serialization/access.hpp b/3rdParty/Boost/src/boost/serialization/access.hpp new file mode 100644 index 0000000..40256d6 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/access.hpp @@ -0,0 +1,147 @@ +#ifndef BOOST_SERIALIZATION_ACCESS_HPP +#define BOOST_SERIALIZATION_ACCESS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// access.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> + +#include <boost/serialization/pfto.hpp> + +namespace boost { + +namespace archive { +namespace detail { + template<class Archive, class T> + class iserializer; + template<class Archive, class T> + class oserializer; +} // namespace detail +} // namespace archive + +namespace serialization { + +// forward declarations +template<class Archive, class T> +inline void serialize_adl(Archive &, T &, const unsigned int); +namespace detail { + template<class Archive, class T> + struct member_saver; + template<class Archive, class T> + struct member_loader; +} // namespace detail + +// use an "accessor class so that we can use: +// "friend class boost::serialization::access;" +// in any serialized class to permit clean, safe access to private class members +// by the serialization system + +class access { +public: + // grant access to "real" serialization defaults +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + template<class Archive, class T> + friend struct detail::member_saver; + template<class Archive, class T> + friend struct detail::member_loader; + template<class Archive, class T> + friend class archive::detail::iserializer; + template<class Archive, class T> + friend class archive::detail::oserializer; + template<class Archive, class T> + friend inline void serialize( + Archive & ar, + T & t, + const BOOST_PFTO unsigned int file_version + ); + template<class Archive, class T> + friend inline void save_construct_data( + Archive & ar, + const T * t, + const BOOST_PFTO unsigned int file_version + ); + template<class Archive, class T> + friend inline void load_construct_data( + Archive & ar, + T * t, + const BOOST_PFTO unsigned int file_version + ); +#endif + + // pass calls to users's class implementation + template<class Archive, class T> + static void member_save( + Archive & ar, + //const T & t, + T & t, + const unsigned int file_version + ){ + t.save(ar, file_version); + } + template<class Archive, class T> + static void member_load( + Archive & ar, + T & t, + const unsigned int file_version + ){ + t.load(ar, file_version); + } + template<class Archive, class T> + static void serialize( + Archive & ar, + T & t, + const unsigned int file_version + ){ + // note: if you get a compile time error here with a + // message something like: + // cannot convert parameter 1 from <file type 1> to <file type 2 &> + // a likely possible cause is that the class T contains a + // serialize function - but that serialize function isn't + // a template and corresponds to a file type different than + // the class Archive. To resolve this, don't include an + // archive type other than that for which the serialization + // function is defined!!! + t.serialize(ar, file_version); + } + template<class T> + static void destroy( const T * t) // const appropriate here? + { + // the const business is an MSVC 6.0 hack that should be + // benign on everything else + delete const_cast<T *>(t); + } + template<class T> + static void construct(T * t){ + // default is inplace invocation of default constructor + // Note the :: before the placement new. Required if the + // class doesn't have a class-specific placement new defined. + ::new(t)T; + } + template<class T, class U> + static T & cast_reference(U & u){ + return static_cast<T &>(u); + } + template<class T, class U> + static T * cast_pointer(U * u){ + return static_cast<T *>(u); + } +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_ACCESS_HPP diff --git a/3rdParty/Boost/src/boost/serialization/base_object.hpp b/3rdParty/Boost/src/boost/serialization/base_object.hpp new file mode 100644 index 0000000..b840d25 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/base_object.hpp @@ -0,0 +1,112 @@ +#ifndef BOOST_SERIALIZATION_BASE_OBJECT_HPP +#define BOOST_SERIALIZATION_BASE_OBJECT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// base_object.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// if no archive headers have been included this is a no op +// this is to permit BOOST_EXPORT etc to be included in a +// file declaration header + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/identity.hpp> + +#include <boost/type_traits/is_base_and_derived.hpp> +#include <boost/type_traits/is_pointer.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/type_traits/is_polymorphic.hpp> + +#include <boost/static_assert.hpp> +#include <boost/serialization/access.hpp> +#include <boost/serialization/force_include.hpp> +#include <boost/serialization/void_cast_fwd.hpp> + +namespace boost { +namespace serialization { + +namespace detail +{ + // get the base type for a given derived type + // preserving the const-ness + template<class B, class D> + struct base_cast + { + typedef BOOST_DEDUCED_TYPENAME + mpl::if_< + is_const<D>, + const B, + B + >::type type; + BOOST_STATIC_ASSERT(is_const<type>::value == is_const<D>::value); + }; + + // only register void casts if the types are polymorphic + template<class Base, class Derived> + struct base_register + { + struct polymorphic { + static void const * invoke(){ + Base const * const b = 0; + Derived const * const d = 0; + return & void_cast_register(d, b); + } + }; + struct non_polymorphic { + static void const * invoke(){ + return 0; + } + }; + static void const * invoke(){ + typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_polymorphic<Base>, + mpl::identity<polymorphic>, + mpl::identity<non_polymorphic> + >::type type; + return type::invoke(); + } + }; + +} // namespace detail +#if defined(__BORLANDC__) && __BORLANDC__ < 0x610 +template<class Base, class Derived> +const Base & +base_object(const Derived & d) +{ + BOOST_STATIC_ASSERT(! is_pointer<Derived>::value); + detail::base_register<Base, Derived>::invoke(); + return access::cast_reference<const Base, Derived>(d); +} +#else +template<class Base, class Derived> +BOOST_DEDUCED_TYPENAME detail::base_cast<Base, Derived>::type & +base_object(Derived &d) +{ + BOOST_STATIC_ASSERT(( is_base_and_derived<Base,Derived>::value)); + BOOST_STATIC_ASSERT(! is_pointer<Derived>::value); + typedef BOOST_DEDUCED_TYPENAME detail::base_cast<Base, Derived>::type type; + detail::base_register<type, Derived>::invoke(); + return access::cast_reference<type, Derived>(d); +} +#endif + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP diff --git a/3rdParty/Boost/src/boost/serialization/collection_size_type.hpp b/3rdParty/Boost/src/boost/serialization/collection_size_type.hpp new file mode 100644 index 0000000..2dd8fa7 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/collection_size_type.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP +#define BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP + +// (C) Copyright 2005 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <cstddef> // size_t +#include <boost/serialization/strong_typedef.hpp> +#include <boost/serialization/level.hpp> +#include <boost/serialization/split_free.hpp> +#include <boost/serialization/is_bitwise_serializable.hpp> + +namespace boost { +namespace serialization { + +//BOOST_STRONG_TYPEDEF(std::size_t, collection_size_type) + +class collection_size_type { +private: + typedef std::size_t base_type; + base_type t; +public: + collection_size_type(): t(0) {}; + explicit collection_size_type(const std::size_t & t_) : + t(t_) + {} + collection_size_type(const collection_size_type & t_) : + t(t_.t) + {} + collection_size_type & operator=(const collection_size_type & rhs){ + t = rhs.t; + return *this; + } + collection_size_type & operator=(const unsigned int & rhs){ + t = rhs; + return *this; + } + // used for text output + operator base_type () const { + return t; + } + // used for text input + operator base_type & () { + return t; + } + bool operator==(const collection_size_type & rhs) const { + return t == rhs.t; + } + bool operator<(const collection_size_type & rhs) const { + return t < rhs.t; + } +}; + + +} } // end namespace boost::serialization + +BOOST_CLASS_IMPLEMENTATION(collection_size_type, primitive_type) +BOOST_IS_BITWISE_SERIALIZABLE(collection_size_type) + +#endif //BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP diff --git a/3rdParty/Boost/src/boost/serialization/force_include.hpp b/3rdParty/Boost/src/boost/serialization/force_include.hpp new file mode 100644 index 0000000..a18a8a1 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/force_include.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_SERIALIZATION_FORCE_INCLUDE_HPP +#define BOOST_SERIALIZATION_FORCE_INCLUDE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// force_include.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> + +// the following help macro is to guarentee that certain coded +// is not removed by over-eager linker optimiser. In certain cases +// we create static objects must be created but are actually never +// referenced - creation has a side-effect such as global registration +// which is important to us. We make an effort to refer these objects +// so that a smart linker won't remove them as being unreferenced. +// In microsoft compilers, inlining the code that does the referring +// means the code gets lost and the static object is not included +// in the library and hence never registered. This manifests itself +// in an ungraceful crash at runtime when (and only when) built in +// release mode. + +#if defined(BOOST_HAS_DECLSPEC) && !defined(__COMO__) +# if defined(__BORLANDC__) +# define BOOST_DLLEXPORT __export +# else +# define BOOST_DLLEXPORT __declspec(dllexport) +# endif +#elif ! defined(_WIN32) && ! defined(_WIN64) +# if defined(__MWERKS__) +# define BOOST_DLLEXPORT __declspec(dllexport) +# elif defined(__GNUC__) && (__GNUC__ >= 3) +# define BOOST_USED __attribute__ ((used)) +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 1110) +# define BOOST_USED __attribute__ ((used)) +# elif defined(__INTEL_COMPILER) && (BOOST_INTEL_CXX_VERSION >= 800) +# define BOOST_USED __attribute__ ((used)) +# endif +#endif + +#ifndef BOOST_USED +# define BOOST_USED +#endif + +#ifndef BOOST_DLLEXPORT +# define BOOST_DLLEXPORT +#endif + +#endif // BOOST_SERIALIZATION_FORCE_INCLUDE_HPP diff --git a/3rdParty/Boost/src/boost/serialization/is_bitwise_serializable.hpp b/3rdParty/Boost/src/boost/serialization/is_bitwise_serializable.hpp new file mode 100644 index 0000000..34eec40 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/is_bitwise_serializable.hpp @@ -0,0 +1,46 @@ +// (C) Copyright 2007 Matthias Troyer + +// 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) + +// Authors: Matthias Troyer + +/** @file is_bitwise_serializable.hpp + * + * This header provides a traits class for determining whether a class + * can be serialized (in a non-portable way) just by copying the bits. + */ + + +#ifndef BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP +#define BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/is_arithmetic.hpp> + +namespace boost { +namespace serialization { + template<class T> + struct is_bitwise_serializable + : public is_arithmetic< T > + {}; +} // namespace serialization +} // namespace boost + + +// define a macro to make explicit designation of this more transparent +#define BOOST_IS_BITWISE_SERIALIZABLE(T) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct is_bitwise_serializable< T > : mpl::true_ {}; \ +}} \ +/**/ + +#endif //BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP diff --git a/3rdParty/Boost/src/boost/serialization/level.hpp b/3rdParty/Boost/src/boost/serialization/level.hpp new file mode 100644 index 0000000..ce507b2 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/level.hpp @@ -0,0 +1,125 @@ +#ifndef BOOST_SERIALIZATION_LEVEL_HPP +#define BOOST_SERIALIZATION_LEVEL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// level.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +#include <boost/type_traits/is_fundamental.hpp> +#include <boost/type_traits/is_enum.hpp> +#include <boost/type_traits/is_array.hpp> +#include <boost/type_traits/is_class.hpp> +#include <boost/type_traits/is_base_and_derived.hpp> + +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/integral_c.hpp> +#include <boost/mpl/integral_c_tag.hpp> +#include <boost/mpl/aux_/nttp_decl.hpp> + +#include <boost/serialization/level_enum.hpp> + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default serialization implementation level +template<class T> +struct implementation_level_impl { + template<class U> + struct traits_class_level { + typedef BOOST_DEDUCED_TYPENAME U::level type; + }; + + typedef mpl::integral_c_tag tag; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_base_and_derived<boost::serialization::basic_traits, T>, + traits_class_level< T >, + //else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_fundamental< T >, + mpl::int_<primitive_type>, + //else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_class< T >, + mpl::int_<object_class_info>, + //else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_array< T >, + #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560)) + mpl::int_<not_serializable>, + #else + mpl::int_<object_serializable>, + #endif + //else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_enum< T >, + //#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560)) + // mpl::int_<not_serializable>, + //#else + mpl::int_<primitive_type>, + //#endif + //else + mpl::int_<not_serializable> + > + > + > + > + >::type type; + // vc 7.1 doesn't like enums here + BOOST_STATIC_CONSTANT(int, value = type::value); +}; + +template<class T> +struct implementation_level : + public implementation_level_impl<const T> +{ +}; + +template<class T, BOOST_MPL_AUX_NTTP_DECL(int, L) > +inline bool operator>=(implementation_level< T > t, enum level_type l) +{ + return t.value >= (int)l; +} + +} // namespace serialization +} // namespace boost + +// specify the level of serialization implementation for the class +// require that class info saved when versioning is used +#define BOOST_CLASS_IMPLEMENTATION(T, E) \ + namespace boost { \ + namespace serialization { \ + template <> \ + struct implementation_level_impl< const T > \ + { \ + typedef mpl::integral_c_tag tag; \ + typedef mpl::int_< E > type; \ + BOOST_STATIC_CONSTANT( \ + int, \ + value = implementation_level_impl::type::value \ + ); \ + }; \ + } \ + } + /**/ + +#endif // BOOST_SERIALIZATION_LEVEL_HPP diff --git a/3rdParty/Boost/src/boost/serialization/level_enum.hpp b/3rdParty/Boost/src/boost/serialization/level_enum.hpp new file mode 100644 index 0000000..11bd17f --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/level_enum.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_SERIALIZATION_LEVEL_ENUM_HPP +#define BOOST_SERIALIZATION_LEVEL_ENUM_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// level_enum.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +namespace boost { +namespace serialization { + +// for each class used in the program, specify which level +// of serialization should be implemented + +// names for each level +enum level_type +{ + // Don't serialize this type. An attempt to do so should + // invoke a compile time assertion. + not_serializable = 0, + // write/read this type directly to the archive. In this case + // serialization code won't be called. This is the default + // case for fundamental types. It presumes a member function or + // template in the archive class that can handle this type. + // there is no runtime overhead associated reading/writing + // instances of this level + primitive_type = 1, + // Serialize the objects of this type using the objects "serialize" + // function or template. This permits values to be written/read + // to/from archives but includes no class or version information. + object_serializable = 2, + /////////////////////////////////////////////////////////////////// + // once an object is serialized at one of the above levels, the + // corresponding archives cannot be read if the implementation level + // for the archive object is changed. + /////////////////////////////////////////////////////////////////// + // Add class information to the archive. Class information includes + // implementation level, class version and class name if available + object_class_info = 3 +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_LEVEL_ENUM_HPP diff --git a/3rdParty/Boost/src/boost/serialization/nvp.hpp b/3rdParty/Boost/src/boost/serialization/nvp.hpp new file mode 100644 index 0000000..2d7f4ed --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/nvp.hpp @@ -0,0 +1,144 @@ +#ifndef BOOST_SERIALIZATION_NVP_HPP +#define BOOST_SERIALIZATION_NVP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// nvp.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <utility> + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> +// supress noise +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <boost/mpl/integral_c.hpp> +#include <boost/mpl/integral_c_tag.hpp> + +#include <boost/serialization/level.hpp> +#include <boost/serialization/tracking.hpp> +#include <boost/serialization/split_member.hpp> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/traits.hpp> +#include <boost/serialization/wrapper.hpp> + +namespace boost { +namespace serialization { + +template<class T> +struct nvp : + public std::pair<const char *, T *>, + public wrapper_traits<const nvp< T > > +{ + explicit nvp(const char * name_, T & t) : + // note: redundant cast works around borland issue + // note: added _ to suppress useless gcc warning + std::pair<const char *, T *>(name_, (T*)(& t)) + {} + nvp(const nvp & rhs) : + // note: redundant cast works around borland issue + std::pair<const char *, T *>(rhs.first, (T*)rhs.second) + {} + + const char * name() const { + return this->first; + } + T & value() const { + return *(this->second); + } + + const T & const_value() const { + return *(this->second); + } + + // True64 compiler complains with a warning about the use of + // the name "Archive" hiding some higher level usage. I'm sure this + // is an error but I want to accomodated as it generates a long warning + // listing and might be related to a lot of test failures. + // default treatment for name-value pairs. The name is + // just discarded and only the value is serialized. + template<class Archivex> + void save( + Archivex & ar, + const unsigned int /* file_version */ + ) const { + // CodeWarrior 8.x can't seem to resolve the << op for a rhs of "const T *" + ar.operator<<(const_value()); + } + template<class Archivex> + void load( + Archivex & ar, + const unsigned int /* file_version */ + ){ + // CodeWarrior 8.x can't seem to resolve the >> op for a rhs of "const T *" + ar.operator>>(value()); + } + BOOST_SERIALIZATION_SPLIT_MEMBER() +}; + +template<class T> +inline +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +const +#endif +nvp< T > make_nvp(const char * name, T & t){ + return nvp< T >(name, t); +} + +// to maintain efficiency and portability, we want to assign +// specific serialization traits to all instances of this wrappers. +// we can't strait forward method below as it depends upon +// Partial Template Specialization and doing so would mean that wrappers +// wouldn't be treated the same on different platforms. This would +// break archive portability. Leave this here as reminder not to use it !!! +#if 0 // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +template <class T> +struct implementation_level<nvp< T > > +{ + typedef mpl::integral_c_tag tag; + typedef mpl::int_<object_serializable> type; + BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value); +}; + +// nvp objects are generally created on the stack and are never tracked +template<class T> +struct tracking_level<nvp< T > > +{ + typedef mpl::integral_c_tag tag; + typedef mpl::int_<track_never> type; + BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); +}; + +#endif + +} // seralization +} // boost + +#include <boost/preprocessor/stringize.hpp> + +#define BOOST_SERIALIZATION_NVP(name) \ + boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), name) +/**/ + +#define BOOST_SERIALIZATION_BASE_OBJECT_NVP(name) \ + boost::serialization::make_nvp( \ + BOOST_PP_STRINGIZE(name), \ + boost::serialization::base_object<name >(*this) \ + ) +/**/ + +#endif // BOOST_SERIALIZATION_NVP_HPP diff --git a/3rdParty/Boost/src/boost/serialization/pfto.hpp b/3rdParty/Boost/src/boost/serialization/pfto.hpp new file mode 100644 index 0000000..8d98463 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/pfto.hpp @@ -0,0 +1,78 @@ +#ifndef BOOST_SERIALIZATION_PFTO_HPP +#define BOOST_SERIALIZATION_PFTO_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// pfto.hpp: workarounds for compilers which have problems supporting +// Partial Function Template Ordering (PFTO). + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. +// PFTO version is used to specify the last argument of certain functions +// Function it is used to support compilers that fail to support correct Partial +// Template Ordering +#include <boost/config.hpp> + +// some compilers can use an exta argument and use function overloading +// to choose desired function. This extra argument is long in the default +// function implementation and int for the rest. The function is called +// with an int argument. This first attempts to match functions with an +// int argument before the default one (with a long argument). This is +// known to function with VC 6.0. On other compilers this fails (Borland) +// or causes other problems (GCC). note: this + +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + #define BOOST_PFTO long +#else + #define BOOST_PFTO +#endif + +// here's another approach. Rather than use a default function - make sure +// there is no default at all by requiring that all function invocations +// have a "wrapped" argument type. This solves a problem with VC 6.0 +// (and perhaps others) while implementing templated constructors. + +namespace boost { +namespace serialization { + +template<class T> +struct pfto_wrapper { + const T & t; + operator const T & (){ + return t; + } + pfto_wrapper (const T & rhs) : t(rhs) {} +}; + +template<class T> +pfto_wrapper< T > make_pfto_wrapper(const T & t, BOOST_PFTO int){ + return pfto_wrapper< T >(t); +} + +template<class T> +pfto_wrapper< T > make_pfto_wrapper(const pfto_wrapper< T > & t, int){ + return t; +} + +} // namespace serialization +} // namespace boost + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + #define BOOST_PFTO_WRAPPER(T) \ + boost::serialization::pfto_wrapper< T > + #define BOOST_MAKE_PFTO_WRAPPER(t) \ + boost::serialization::make_pfto_wrapper(t, 0) +#else + #define BOOST_PFTO_WRAPPER(T) T + #define BOOST_MAKE_PFTO_WRAPPER(t) t +#endif + +#endif // BOOST_SERIALIZATION_PFTO_HPP diff --git a/3rdParty/Boost/src/boost/serialization/serialization.hpp b/3rdParty/Boost/src/boost/serialization/serialization.hpp new file mode 100644 index 0000000..f17e8dd --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/serialization.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_SERIALIZATION_SERIALIZATION_HPP +#define BOOST_SERIALIZATION_SERIALIZATION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1310) +# pragma warning (disable : 4675) // suppress ADL warning +#endif + +#include <boost/config.hpp> +#include <boost/serialization/strong_typedef.hpp> +#include <boost/serialization/pfto.hpp> + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +////////////////////////////////////////////////////////////////////// +// public interface to serialization. + +///////////////////////////////////////////////////////////////////////////// +// layer 0 - intrusive verison +// declared and implemented for each user defined class to be serialized +// +// template<Archive> +// serialize(Archive &ar, const unsigned int file_version){ +// ar & base_object<base>(*this) & member1 & member2 ... ; +// } + +///////////////////////////////////////////////////////////////////////////// +// layer 1 - layer that routes member access through the access class. +// this is what permits us to grant access to private class member functions +// by specifying friend class boost::serialization::access + +#include <boost/serialization/access.hpp> + +///////////////////////////////////////////////////////////////////////////// +// layer 2 - default implementation of non-intrusive serialization. +// +// note the usage of function overloading to compensate that C++ does not +// currently support Partial Template Specialization for function templates +// We have declared the version number as "const unsigned long". +// Overriding templates for specific data types should declare the version +// number as "const unsigned int". Template matching will first be applied +// to functions with the same version types - that is the overloads. +// If there is no declared function prototype that matches, the second argument +// will be converted to "const unsigned long" and a match will be made with +// one of the default template functions below. + +namespace boost { +namespace serialization { + +BOOST_STRONG_TYPEDEF(unsigned int, version_type) + +// default implementation - call the member function "serialize" +template<class Archive, class T> +inline void serialize( + Archive & ar, T & t, const BOOST_PFTO unsigned int file_version +){ + access::serialize(ar, t, static_cast<unsigned int>(file_version)); +} + +// save data required for construction +template<class Archive, class T> +inline void save_construct_data( + Archive & /*ar*/, + const T * /*t*/, + const BOOST_PFTO unsigned int /*file_version */ +){ + // default is to save no data because default constructor + // requires no arguments. +} + +// load data required for construction and invoke constructor in place +template<class Archive, class T> +inline void load_construct_data( + Archive & /*ar*/, + T * t, + const BOOST_PFTO unsigned int /*file_version*/ +){ + // default just uses the default constructor. going + // through access permits usage of otherwise private default + // constructor + access::construct(t); +} + +///////////////////////////////////////////////////////////////////////////// +// layer 3 - move call into serialization namespace so that ADL will function +// in the manner we desire. +// +// on compilers which don't implement ADL. only the current namespace +// i.e. boost::serialization will be searched. +// +// on compilers which DO implement ADL +// serialize overrides can be in any of the following +// +// 1) same namepace as Archive +// 2) same namespace as T +// 3) boost::serialization +// +// Due to Martin Ecker + +template<class Archive, class T> +inline void serialize_adl( + Archive & ar, + T & t, + const unsigned int file_version +){ + // note usage of function overloading to delay final resolution + // until the point of instantiation. This works around the two-phase + // lookup "feature" which inhibits redefintion of a default function + // template implementation. Due to Robert Ramey + // + // Note that this trick generates problems for compiles which don't support + // PFTO, suppress it here. As far as we know, there are no compilers + // which fail to support PFTO while supporting two-phase lookup. + #if ! defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + const version_type v(file_version); + serialize(ar, t, v); + #else + serialize(ar, t, file_version); + #endif +} + +template<class Archive, class T> +inline void save_construct_data_adl( + Archive & ar, + const T * t, + const unsigned int file_version +){ + // see above + #if ! defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + const version_type v(file_version); + save_construct_data(ar, t, v); + #else + save_construct_data(ar, t, file_version); + #endif +} + +template<class Archive, class T> +inline void load_construct_data_adl( + Archive & ar, + T * t, + const unsigned int file_version +){ + // see above comment + #if ! defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + const version_type v(file_version); + load_construct_data(ar, t, v); + #else + load_construct_data(ar, t, file_version); + #endif +} + +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_SERIALIZATION_HPP diff --git a/3rdParty/Boost/src/boost/serialization/split_free.hpp b/3rdParty/Boost/src/boost/serialization/split_free.hpp new file mode 100644 index 0000000..9dbcd2f --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/split_free.hpp @@ -0,0 +1,93 @@ +#ifndef BOOST_SERIALIZATION_SPLIT_FREE_HPP +#define BOOST_SERIALIZATION_SPLIT_FREE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// split_free.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/serialization/serialization.hpp> + +namespace boost { +namespace archive { + namespace detail { + template<class Archive> class interface_oarchive; + template<class Archive> class interface_iarchive; + } // namespace detail +} // namespace archive + +namespace serialization { + +//namespace detail { +template<class Archive, class T> +struct free_saver { + static void invoke( + Archive & ar, + const T & t, + const unsigned int file_version + ){ + // use function overload (version_type) to workaround + // two-phase lookup issue + const version_type v(file_version); + save(ar, t, v); + } +}; +template<class Archive, class T> +struct free_loader { + static void invoke( + Archive & ar, + T & t, + const unsigned int file_version + ){ + // use function overload (version_type) to workaround + // two-phase lookup issue + const version_type v(file_version); + load(ar, t, v); + } +}; +//} // namespace detail + +template<class Archive, class T> +inline void split_free( + Archive & ar, + T & t, + const unsigned int file_version +){ + typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< + BOOST_DEDUCED_TYPENAME Archive::is_saving, + mpl::identity</* detail:: */ free_saver<Archive, T> >, + mpl::identity</* detail:: */ free_loader<Archive, T> > + >::type typex; + typex::invoke(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#define BOOST_SERIALIZATION_SPLIT_FREE(T) \ +namespace boost { namespace serialization { \ +template<class Archive> \ +inline void serialize( \ + Archive & ar, \ + T & t, \ + const unsigned int file_version \ +){ \ + split_free(ar, t, file_version); \ +} \ +}} +/**/ + +#endif // BOOST_SERIALIZATION_SPLIT_FREE_HPP diff --git a/3rdParty/Boost/src/boost/serialization/split_member.hpp b/3rdParty/Boost/src/boost/serialization/split_member.hpp new file mode 100644 index 0000000..6987945 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/split_member.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_SERIALIZATION_SPLIT_MEMBER_HPP +#define BOOST_SERIALIZATION_SPLIT_MEMBER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// split_member.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/identity.hpp> + +#include <boost/serialization/access.hpp> + +namespace boost { +namespace archive { + namespace detail { + template<class Archive> class interface_oarchive; + template<class Archive> class interface_iarchive; + } // namespace detail +} // namespace archive + +namespace serialization { +namespace detail { + + template<class Archive, class T> + struct member_saver { + static void invoke( + Archive & ar, + const T & t, + const unsigned int file_version + ){ + access::member_save(ar, t, file_version); + } + }; + + template<class Archive, class T> + struct member_loader { + static void invoke( + Archive & ar, + T & t, + const unsigned int file_version + ){ + access::member_load(ar, t, file_version); + } + }; + +} // detail + +template<class Archive, class T> +inline void split_member( + Archive & ar, T & t, const unsigned int file_version +){ + typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< + BOOST_DEDUCED_TYPENAME Archive::is_saving, + mpl::identity<detail::member_saver<Archive, T> >, + mpl::identity<detail::member_loader<Archive, T> > + >::type typex; + typex::invoke(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +// split member function serialize funcition into save/load +#define BOOST_SERIALIZATION_SPLIT_MEMBER() \ +template<class Archive> \ +void serialize( \ + Archive &ar, \ + const unsigned int file_version \ +){ \ + boost::serialization::split_member(ar, *this, file_version); \ +} \ +/**/ + +#endif // BOOST_SERIALIZATION_SPLIT_MEMBER_HPP diff --git a/3rdParty/Boost/src/boost/serialization/strong_typedef.hpp b/3rdParty/Boost/src/boost/serialization/strong_typedef.hpp new file mode 100644 index 0000000..647c302 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/strong_typedef.hpp @@ -0,0 +1,66 @@ +#ifndef BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP +#define BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// strong_typedef.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. + +// macro used to implement a strong typedef. strong typedef +// guarentees that two types are distinguised even though the +// share the same underlying implementation. typedef does not create +// a new type. BOOST_STRONG_TYPEDEF(T, D) creates a new type named D +// that operates as a type T. + +#include <boost/config.hpp> +#include <boost/operators.hpp> + +#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x590 + #define BOOST_STRONG_TYPEDEF(T, D) \ + struct D \ + : boost::totally_ordered1< D \ + , boost::totally_ordered2< D, T \ + > > \ + { \ + T t; \ + explicit D(const T t_) : t(t_) {}; \ + D(){}; \ + D(const D & t_) : t(t_.t){} \ + D & operator=(const D & rhs) { t = rhs.t; return *this;} \ + D & operator=(const T & rhs) { t = rhs; return *this;} \ + operator const T & () const {return t; } \ + operator T & () { return t; } \ + bool operator==(const D & rhs) const { return t == rhs.t; } \ + bool operator<(const D & rhs) const { return t < rhs.t; } \ + }; +#else + #define BOOST_STRONG_TYPEDEF(T, D) \ + struct D \ + : boost::totally_ordered1< D \ + , boost::totally_ordered2< D, T \ + > > \ + { \ + T t; \ + explicit D(const T t_) : t(t_) {}; \ + D(){}; \ + D(const D & t_) : t(t_.t){} \ + D & operator=(const D & rhs) { t = rhs.t; return *this;} \ + D & operator=(const T & rhs) { t = rhs; return *this;} \ + /*operator const T & () const {return t; }*/ \ + operator T & () { return t; } \ + bool operator==(const D & rhs) const { return t == rhs.t; } \ + bool operator<(const D & rhs) const { return t < rhs.t; } \ + }; +#endif // !defined(__BORLANDC) || __BORLANDC__ >= 0x590 + +#endif // BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP diff --git a/3rdParty/Boost/src/boost/serialization/tracking.hpp b/3rdParty/Boost/src/boost/serialization/tracking.hpp new file mode 100644 index 0000000..fadcbd0 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/tracking.hpp @@ -0,0 +1,118 @@ +#ifndef BOOST_SERIALIZATION_TRACKING_HPP +#define BOOST_SERIALIZATION_TRACKING_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// tracking.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> +#include <boost/static_assert.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/greater.hpp> +#include <boost/mpl/integral_c_tag.hpp> + +#include <boost/type_traits/is_base_and_derived.hpp> +#include <boost/type_traits/is_pointer.hpp> +#include <boost/serialization/level.hpp> +#include <boost/serialization/tracking_enum.hpp> +#include <boost/serialization/type_info_implementation.hpp> + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default tracking level +template<class T> +struct tracking_level_impl { + template<class U> + struct traits_class_tracking { + typedef BOOST_DEDUCED_TYPENAME U::tracking type; + }; + typedef mpl::integral_c_tag tag; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_base_and_derived<boost::serialization::basic_traits, T>, + traits_class_tracking< T >, + //else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_pointer< T >, + // pointers are not tracked by default + mpl::int_<track_never>, + //else + BOOST_DEDUCED_TYPENAME mpl::eval_if< + // for primitives + BOOST_DEDUCED_TYPENAME mpl::equal_to< + implementation_level< T >, + mpl::int_<primitive_type> + >, + // is never + mpl::int_<track_never>, + // otherwise its selective + mpl::int_<track_selectively> + > > >::type type; + BOOST_STATIC_CONSTANT(int, value = type::value); +}; + +template<class T> +struct tracking_level : + public tracking_level_impl<const T> +{ +}; + +template<class T, enum tracking_type L> +inline bool operator>=(tracking_level< T > t, enum tracking_type l) +{ + return t.value >= (int)l; +} + +} // namespace serialization +} // namespace boost + + +// The STATIC_ASSERT is prevents one from setting tracking for a primitive type. +// This almost HAS to be an error. Doing this will effect serialization of all +// char's in your program which is almost certainly what you don't want to do. +// If you want to track all instances of a given primitive type, You'll have to +// wrap it in your own type so its not a primitive anymore. Then it will compile +// without problem. +#define BOOST_CLASS_TRACKING(T, E) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct tracking_level< T > \ +{ \ + typedef mpl::integral_c_tag tag; \ + typedef mpl::int_< E> type; \ + BOOST_STATIC_CONSTANT( \ + int, \ + value = tracking_level::type::value \ + ); \ + /* tracking for a class */ \ + BOOST_STATIC_ASSERT(( \ + mpl::greater< \ + /* that is a prmitive */ \ + implementation_level< T >, \ + mpl::int_<primitive_type> \ + >::value \ + )); \ +}; \ +}} + +#endif // BOOST_SERIALIZATION_TRACKING_HPP diff --git a/3rdParty/Boost/src/boost/serialization/tracking_enum.hpp b/3rdParty/Boost/src/boost/serialization/tracking_enum.hpp new file mode 100644 index 0000000..e4e4e21 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/tracking_enum.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_SERIALIZATION_TRACKING_ENUM_HPP +#define BOOST_SERIALIZATION_TRACKING_ENUM_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// tracking_enum.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +namespace boost { +namespace serialization { + +// addresses of serialized objects may be tracked to avoid saving/loading +// redundant copies. This header defines a class trait that can be used +// to specify when objects should be tracked + +// names for each tracking level +enum tracking_type +{ + // never track this type + track_never = 0, + // track objects of this type if the object is serialized through a + // pointer. + track_selectively = 1, + // always track this type + track_always = 2 +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_TRACKING_ENUM_HPP diff --git a/3rdParty/Boost/src/boost/serialization/traits.hpp b/3rdParty/Boost/src/boost/serialization/traits.hpp new file mode 100644 index 0000000..da80009 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/traits.hpp @@ -0,0 +1,65 @@ +#ifndef BOOST_SERIALIZATION_TRAITS_HPP +#define BOOST_SERIALIZATION_TRAITS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// traits.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// This header is used to apply serialization traits to templates. The +// standard system can't be used for platforms which don't support +// Partial Templlate Specialization. + +// The motivation for this is the Name-Value Pair (NVP) template. +// it has to work the same on all platforms in order for archives +// to be portable accross platforms. + +#include <boost/config.hpp> +#include <boost/static_assert.hpp> + +#include <boost/mpl/int.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/serialization/level_enum.hpp> +#include <boost/serialization/tracking_enum.hpp> + +namespace boost { +namespace serialization { + +// common base class used to detect appended traits class +struct basic_traits {}; + +template <class T> +struct extended_type_info_impl; + +template< + class T, + int Level, + int Tracking, + unsigned int Version = 0, + class ETII = extended_type_info_impl< T >, + class Wrapper = mpl::false_ +> +struct traits : public basic_traits { + BOOST_STATIC_ASSERT(Version == 0 || Level >= object_class_info); + BOOST_STATIC_ASSERT(Tracking == track_never || Level >= object_serializable); + typedef BOOST_DEDUCED_TYPENAME mpl::int_<Level> level; + typedef BOOST_DEDUCED_TYPENAME mpl::int_<Tracking> tracking; + typedef BOOST_DEDUCED_TYPENAME mpl::int_<Version> version; + typedef ETII type_info_implementation; + typedef Wrapper is_wrapper; +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_TRAITS_HPP diff --git a/3rdParty/Boost/src/boost/serialization/type_info_implementation.hpp b/3rdParty/Boost/src/boost/serialization/type_info_implementation.hpp new file mode 100644 index 0000000..00eb152 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/type_info_implementation.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP +#define BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// type_info_implementation.hpp: interface for portable version of type_info + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +#include <boost/static_assert.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/type_traits/is_base_and_derived.hpp> +#include <boost/serialization/traits.hpp> + +namespace boost { +namespace serialization { + +// note that T and const T are folded into const T so that +// there is only one table entry per type +template<class T> +struct type_info_implementation { + template<class U> + struct traits_class_typeinfo_implementation { + typedef BOOST_DEDUCED_TYPENAME U::type_info_implementation::type type; + }; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_base_and_derived<boost::serialization::basic_traits, T>, + traits_class_typeinfo_implementation< T >, + //else + mpl::identity< + BOOST_DEDUCED_TYPENAME extended_type_info_impl< T >::type + > + >::type type; +}; + +} // namespace serialization +} // namespace boost + +// define a macro to assign a particular derivation of extended_type_info +// to a specified a class. +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560)) +#define BOOST_CLASS_TYPE_INFO(T, ETI) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct type_info_implementation< T > { \ + typedef const ETI type; \ +}; \ +} \ +} \ +/**/ +#else +#define BOOST_CLASS_TYPE_INFO(T, ETI) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct type_info_implementation< T > { \ + typedef ETI type; \ +}; \ +template<> \ +struct type_info_implementation< const T > { \ + typedef ETI type; \ +}; \ +} \ +} \ +/**/ +#endif + +#endif /// BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP diff --git a/3rdParty/Boost/src/boost/serialization/version.hpp b/3rdParty/Boost/src/boost/serialization/version.hpp new file mode 100644 index 0000000..72862fa --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/version.hpp @@ -0,0 +1,102 @@ +#ifndef BOOST_SERIALIZATION_VERSION_HPP +#define BOOST_SERIALIZATION_VERSION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// version.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/integral_c_tag.hpp> + +#include <boost/type_traits/is_base_and_derived.hpp> + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default version number is 0. Override with higher version +// when class definition changes. +template<class T> +struct version +{ + template<class U> + struct traits_class_version { + typedef BOOST_DEDUCED_TYPENAME U::version type; + }; + + typedef mpl::integral_c_tag tag; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + BOOST_DEDUCED_TYPENAME mpl::eval_if< + is_base_and_derived<boost::serialization::basic_traits,T>, + traits_class_version< T >, + mpl::int_<0> + >::type type; + BOOST_STATIC_CONSTANT(int, value = version::type::value); +}; + +} // namespace serialization +} // namespace boost + +/* note: at first it seemed that this would be a good place to trap + * as an error an attempt to set a version # for a class which doesn't + * save its class information (including version #) in the archive. + * However, this imposes a requirement that the version be set after + * the implemention level which would be pretty confusing. If this + * is to be done, do this check in the input or output operators when + * ALL the serialization traits are available. Included the implementation + * here with this comment as a reminder not to do this! + */ +//#include <boost/serialization/level.hpp> +//#include <boost/mpl/equal_to.hpp> + +#include <boost/mpl/less.hpp> +#include <boost/mpl/comparison.hpp> + +// specify the current version number for the class +// version numbers limited to 8 bits !!! +#define BOOST_CLASS_VERSION(T, N) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct version<T > \ +{ \ + typedef mpl::int_<N> type; \ + typedef mpl::integral_c_tag tag; \ + BOOST_STATIC_CONSTANT(int, value = version::type::value); \ + BOOST_MPL_ASSERT(( \ + boost::mpl::less< \ + boost::mpl::int_<N>, \ + boost::mpl::int_<256> \ + > \ + )); \ + /* \ + BOOST_MPL_ASSERT(( \ + mpl::equal_to< \ + :implementation_level<T >, \ + mpl::int_<object_class_info> \ + >::value \ + )); \ + */ \ +}; \ +} \ +} + +#endif // BOOST_SERIALIZATION_VERSION_HPP diff --git a/3rdParty/Boost/src/boost/serialization/void_cast_fwd.hpp b/3rdParty/Boost/src/boost/serialization/void_cast_fwd.hpp new file mode 100644 index 0000000..c94adb2 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/void_cast_fwd.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_SERIALIZATION_VOID_CAST_FWD_HPP +#define BOOST_SERIALIZATION_VOID_CAST_FWD_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// void_cast_fwd.hpp: interface for run-time casting of void pointers. + +// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// gennadiy.rozental@tfn.com + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <cstddef> // NULL +#include <boost/serialization/force_include.hpp> + +namespace boost { +namespace serialization { +namespace void_cast_detail{ +class void_caster; +} // namespace void_cast_detail +template<class Derived, class Base> +BOOST_DLLEXPORT +inline const void_cast_detail::void_caster & void_cast_register( + const Derived * dnull = NULL, + const Base * bnull = NULL +) BOOST_USED; +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_VOID_CAST_HPP diff --git a/3rdParty/Boost/src/boost/serialization/wrapper.hpp b/3rdParty/Boost/src/boost/serialization/wrapper.hpp new file mode 100644 index 0000000..eeb4333 --- /dev/null +++ b/3rdParty/Boost/src/boost/serialization/wrapper.hpp @@ -0,0 +1,60 @@ +#ifndef BOOST_SERIALIZATION_WRAPPER_HPP +#define BOOST_SERIALIZATION_WRAPPER_HPP + +// (C) Copyright 2005-2006 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/serialization/traits.hpp> +#include <boost/type_traits/is_base_and_derived.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/bool.hpp> + +namespace boost { namespace serialization { + +/// the base class for serialization wrappers +/// +/// wrappers need to be treated differently at various places in the serialization library, +/// e.g. saving of non-const wrappers has to be possible. Since partial specialization +// is not supported by all compilers, we derive all wrappers from wrapper_traits. + +template< + class T, + int Level = object_serializable, + int Tracking = track_never, + unsigned int Version = 0, + class ETII = extended_type_info_impl< T > +> +struct wrapper_traits : + public traits<T,Level,Tracking,Version,ETII,mpl::true_> +{}; + +template<class T> +struct is_wrapper_impl : + boost::mpl::eval_if< + boost::is_base_and_derived<basic_traits,T>, + boost::mpl::true_, + boost::mpl::false_ + >::type +{}; + +template<class T> +struct is_wrapper { + typedef BOOST_DEDUCED_TYPENAME is_wrapper_impl<const T>::type type; +}; + +} // serialization +} // boost + +// A macro to define that a class is a wrapper +#define BOOST_CLASS_IS_WRAPPER(T) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct is_wrapper_impl<const T> : boost::mpl::true_ {}; \ +} \ +} \ +/**/ + +#endif //BOOST_SERIALIZATION_WRAPPER_HPP diff --git a/3rdParty/Boost/src/boost/utility/value_init.hpp b/3rdParty/Boost/src/boost/utility/value_init.hpp new file mode 100644 index 0000000..5de9585 --- /dev/null +++ b/3rdParty/Boost/src/boost/utility/value_init.hpp @@ -0,0 +1,258 @@ +// (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal. +// +// 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) +// +// 21 Ago 2002 (Created) Fernando Cacciola +// 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker +// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola +// 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola +// 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola +// 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker +// 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker +// +#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP +#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP + +// Note: The implementation of boost::value_initialized had to deal with the +// fact that various compilers haven't fully implemented value-initialization. +// The constructor of boost::value_initialized<T> works around these compiler +// issues, by clearing the bytes of T, before constructing the T object it +// contains. More details on these issues are at libs/utility/value_init.htm + +#include <boost/aligned_storage.hpp> +#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION. +#include <boost/detail/workaround.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/cv_traits.hpp> +#include <boost/type_traits/alignment_of.hpp> +#include <boost/swap.hpp> +#include <cstring> +#include <new> + +#ifdef BOOST_MSVC +#pragma warning(push) +#if _MSC_VER >= 1310 +// It is safe to ignore the following warning from MSVC 7.1 or higher: +// "warning C4351: new behavior: elements of array will be default initialized" +#pragma warning(disable: 4351) +// It is safe to ignore the following MSVC warning, which may pop up when T is +// a const type: "warning C4512: assignment operator could not be generated". +#pragma warning(disable: 4512) +#endif +#endif + +#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION + // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED + // suggests that a workaround should be applied, because of compiler issues + // regarding value-initialization. + #define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED +#endif + +// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND +// switches the value-initialization workaround either on or off. +#ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND + #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED + #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1 + #else + #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0 + #endif +#endif + +namespace boost { + +template<class T> +class initialized +{ + private : + struct wrapper + { +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) + typename +#endif + remove_const<T>::type data; + + wrapper() + : + data() + { + } + + wrapper(T const & arg) + : + data(arg) + { + } + }; + + mutable +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) + typename +#endif + aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x; + + wrapper * wrapper_address() const + { + return static_cast<wrapper *>( static_cast<void*>(&x)); + } + + public : + + initialized() + { +#if BOOST_DETAIL_VALUE_INIT_WORKAROUND + std::memset(&x, 0, sizeof(x)); +#endif + new (wrapper_address()) wrapper(); + } + + initialized(initialized const & arg) + { + new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address()))); + } + + explicit initialized(T const & arg) + { + new (wrapper_address()) wrapper(arg); + } + + initialized & operator=(initialized const & arg) + { + // Assignment is only allowed when T is non-const. + BOOST_STATIC_ASSERT( ! is_const<T>::value ); + *wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address())); + return *this; + } + + ~initialized() + { + wrapper_address()->wrapper::~wrapper(); + } + + T const & data() const + { + return wrapper_address()->data; + } + + T& data() + { + return wrapper_address()->data; + } + + void swap(initialized & arg) + { + ::boost::swap( this->data(), arg.data() ); + } + + operator T const &() const + { + return wrapper_address()->data; + } + + operator T&() + { + return wrapper_address()->data; + } + +} ; + +template<class T> +T const& get ( initialized<T> const& x ) +{ + return x.data() ; +} + +template<class T> +T& get ( initialized<T>& x ) +{ + return x.data() ; +} + +template<class T> +void swap ( initialized<T> & lhs, initialized<T> & rhs ) +{ + lhs.swap(rhs) ; +} + +template<class T> +class value_initialized +{ + private : + + // initialized<T> does value-initialization by default. + initialized<T> m_data; + + public : + + value_initialized() + : + m_data() + { } + + T const & data() const + { + return m_data.data(); + } + + T& data() + { + return m_data.data(); + } + + void swap(value_initialized & arg) + { + m_data.swap(arg.m_data); + } + + operator T const &() const + { + return m_data; + } + + operator T&() + { + return m_data; + } +} ; + + +template<class T> +T const& get ( value_initialized<T> const& x ) +{ + return x.data() ; +} + +template<class T> +T& get ( value_initialized<T>& x ) +{ + return x.data() ; +} + +template<class T> +void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs ) +{ + lhs.swap(rhs) ; +} + + +class initialized_value_t +{ + public : + + template <class T> operator T() const + { + return initialized<T>().data(); + } +}; + +initialized_value_t const initialized_value = {} ; + + +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif diff --git a/3rdParty/Boost/update.sh b/3rdParty/Boost/update.sh index 6344d72..80b515b 100755 --- a/3rdParty/Boost/update.sh +++ b/3rdParty/Boost/update.sh @@ -35,6 +35,8 @@ fi boost/algorithm/string.hpp \ boost/format.hpp \ assign/list_of.hpp \ + property_tree/ptree.hpp \ + property_tree/xml_parser.hpp \ $TARGET_DIR rm -rf $TARGET_DIR/libs/config diff --git a/Swiften/Avatars/AvatarFileStorage.cpp b/Swiften/Avatars/AvatarFileStorage.cpp index 046ac16..44a6a7f 100644 --- a/Swiften/Avatars/AvatarFileStorage.cpp +++ b/Swiften/Avatars/AvatarFileStorage.cpp @@ -4,14 +4,39 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Avatars/AvatarFileStorage.h" +#include <Swiften/Avatars/AvatarFileStorage.h> #include <iostream> #include <boost/filesystem/fstream.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/xml_parser.hpp> + +#include <Swiften/Base/foreach.h> namespace Swift { -AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& path) : path_(path) { +AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile) : avatarsDir(avatarsDir), avatarsFile(avatarsFile) { + if (boost::filesystem::exists(avatarsFile)) { + boost::property_tree::ptree tree; + try { + boost::property_tree::xml_parser::read_xml(avatarsFile.string(), tree); + } + catch (const boost::property_tree::xml_parser::xml_parser_error& e) { + std::cerr << "Error reading avatars file: " << e.filename() << ":" << e.line() << ": " << e.message() << std::endl; + } + foreach(const boost::property_tree::ptree::value_type &v, tree.get_child("avatars")) { + try { + JID jid(v.second.get<std::string>("jid")); + std::string hash(v.second.get<std::string>("hash")); + if (jid.isValid()) { + jidAvatars.insert(std::make_pair(jid, hash)); + } + } + catch (const boost::property_tree::ptree_error& e) { + std::cerr << "Invalid avatar value: " << e.what() << std::endl; + } + } + } } bool AvatarFileStorage::hasAvatar(const std::string& hash) const { @@ -34,7 +59,7 @@ void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avat } boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const { - return path_ / hash; + return avatarsDir / hash; } ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const { @@ -43,5 +68,36 @@ ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const { return data; } +void AvatarFileStorage::setAvatarForJID(const JID& jid, const std::string& hash) { + std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash)); + if (r.second) { + saveJIDAvatars(); + } + else if (r.first->second != hash) { + r.first->second = hash; + saveJIDAvatars(); + } +} + +std::string AvatarFileStorage::getAvatarForJID(const JID& jid) const { + JIDAvatarMap::const_iterator i = jidAvatars.find(jid); + return i == jidAvatars.end() ? "" : i->second; +} + +void AvatarFileStorage::saveJIDAvatars() { + boost::property_tree::ptree tree; + for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) { + boost::property_tree::ptree entry; + entry.put("jid", i->first.toString()); + entry.put("hash", i->second); + tree.add_child("avatars.avatar", entry); + } + try { + boost::property_tree::xml_parser::write_xml(avatarsFile.string(), tree); + } + catch (const boost::property_tree::xml_parser::xml_parser_error& e) { + std::cerr << "Error writing avatars file: " << e.filename() << ": " << e.message() << std::endl; + } +} } diff --git a/Swiften/Avatars/AvatarFileStorage.h b/Swiften/Avatars/AvatarFileStorage.h index e803430..e736230 100644 --- a/Swiften/Avatars/AvatarFileStorage.h +++ b/Swiften/Avatars/AvatarFileStorage.h @@ -7,16 +7,17 @@ #pragma once #include <map> +#include <string> #include <boost/filesystem.hpp> -#include <string> +#include <Swiften/JID/JID.h> #include "Swiften/Base/ByteArray.h" #include "Swiften/Avatars/AvatarStorage.h" namespace Swift { class AvatarFileStorage : public AvatarStorage { public: - AvatarFileStorage(const boost::filesystem::path& path); + AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile); virtual bool hasAvatar(const std::string& hash) const; virtual void addAvatar(const std::string& hash, const ByteArray& avatar); @@ -24,8 +25,17 @@ namespace Swift { virtual boost::filesystem::path getAvatarPath(const std::string& hash) const; + virtual void setAvatarForJID(const JID& jid, const std::string& hash); + virtual std::string getAvatarForJID(const JID& jid) const; + + private: + void saveJIDAvatars(); + private: - boost::filesystem::path path_; + boost::filesystem::path avatarsDir; + boost::filesystem::path avatarsFile; + typedef std::map<JID, std::string> JIDAvatarMap; + JIDAvatarMap jidAvatars; }; } diff --git a/Swiften/Avatars/AvatarManager.cpp b/Swiften/Avatars/AvatarManager.cpp index a2b7200..ce7d372 100644 --- a/Swiften/Avatars/AvatarManager.cpp +++ b/Swiften/Avatars/AvatarManager.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/Avatars/AvatarManager.h" +#include <Swiften/Avatars/AvatarManager.h> namespace Swift { diff --git a/Swiften/Avatars/AvatarManager.h b/Swiften/Avatars/AvatarManager.h index d40c3c0..e1af451 100644 --- a/Swiften/Avatars/AvatarManager.h +++ b/Swiften/Avatars/AvatarManager.h @@ -8,8 +8,8 @@ #include <boost/filesystem.hpp> -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { class JID; diff --git a/Swiften/Avatars/AvatarManagerImpl.cpp b/Swiften/Avatars/AvatarManagerImpl.cpp index 6b77f8d..509ff47 100644 --- a/Swiften/Avatars/AvatarManagerImpl.cpp +++ b/Swiften/Avatars/AvatarManagerImpl.cpp @@ -11,6 +11,7 @@ #include "Swiften/Avatars/VCardUpdateAvatarManager.h" #include "Swiften/Avatars/VCardAvatarManager.h" #include "Swiften/Avatars/AvatarStorage.h" +#include <Swiften/Avatars/OfflineAvatarManager.h> #include "Swiften/Base/ByteArray.h" namespace Swift { @@ -22,10 +23,17 @@ AvatarManagerImpl::AvatarManagerImpl(VCardManager* vcardManager, StanzaChannel* vcardAvatarManager = new VCardAvatarManager(vcardManager, avatarStorage, mucRegistry); combinedAvatarProvider.addProvider(vcardAvatarManager); - combinedAvatarProvider.onAvatarChanged.connect(boost::ref(onAvatarChanged)); + offlineAvatarManager = new OfflineAvatarManager(avatarStorage); + combinedAvatarProvider.addProvider(offlineAvatarManager); + + combinedAvatarProvider.onAvatarChanged.connect(boost::bind(&AvatarManagerImpl::handleCombinedAvatarChanged, this, _1)); } AvatarManagerImpl::~AvatarManagerImpl() { + combinedAvatarProvider.onAvatarChanged.disconnect(boost::bind(&AvatarManagerImpl::handleCombinedAvatarChanged, this, _1)); + + combinedAvatarProvider.removeProvider(offlineAvatarManager); + delete offlineAvatarManager; combinedAvatarProvider.removeProvider(vcardAvatarManager); delete vcardAvatarManager; combinedAvatarProvider.removeProvider(vcardUpdateAvatarManager); @@ -48,4 +56,9 @@ ByteArray AvatarManagerImpl::getAvatar(const JID& jid) const { return ByteArray(); } +void AvatarManagerImpl::handleCombinedAvatarChanged(const JID& jid) { + offlineAvatarManager->setAvatar(jid, combinedAvatarProvider.getAvatarHash(jid)); + onAvatarChanged(jid); +} + } diff --git a/Swiften/Avatars/AvatarManagerImpl.h b/Swiften/Avatars/AvatarManagerImpl.h index a28d490..c2b8956 100644 --- a/Swiften/Avatars/AvatarManagerImpl.h +++ b/Swiften/Avatars/AvatarManagerImpl.h @@ -6,18 +6,8 @@ #pragma once -#include <boost/filesystem.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/optional.hpp> -#include <map> - -#include "Swiften/Avatars/AvatarManager.h" -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/VCard.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/Avatars/CombinedAvatarProvider.h" +#include <Swiften/Avatars/AvatarManager.h> +#include <Swiften/Avatars/CombinedAvatarProvider.h> namespace Swift { class MUCRegistry; @@ -26,6 +16,7 @@ namespace Swift { class VCardManager; class VCardUpdateAvatarManager; class VCardAvatarManager; + class OfflineAvatarManager; class AvatarManagerImpl : public AvatarManager { public: @@ -36,9 +27,14 @@ namespace Swift { virtual ByteArray getAvatar(const JID&) const; private: + void handleCombinedAvatarChanged(const JID& jid); + + + private: CombinedAvatarProvider combinedAvatarProvider; AvatarStorage* avatarStorage; VCardUpdateAvatarManager* vcardUpdateAvatarManager; VCardAvatarManager* vcardAvatarManager; + OfflineAvatarManager* offlineAvatarManager; }; } diff --git a/Swiften/Avatars/AvatarMemoryStorage.h b/Swiften/Avatars/AvatarMemoryStorage.h index 3fa770a..095b144 100644 --- a/Swiften/Avatars/AvatarMemoryStorage.h +++ b/Swiften/Avatars/AvatarMemoryStorage.h @@ -7,10 +7,11 @@ #pragma once #include <map> - #include <string> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Avatars/AvatarStorage.h" + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Avatars/AvatarStorage.h> +#include <Swiften/JID/JID.h> namespace Swift { class AvatarMemoryStorage : public AvatarStorage { @@ -26,7 +27,17 @@ namespace Swift { return boost::filesystem::path("/avatars") / hash; } + virtual void setAvatarForJID(const JID& jid, const std::string& hash) { + jidAvatars[jid] = hash; + } + + virtual std::string getAvatarForJID(const JID& jid) const { + std::map<JID, std::string>::const_iterator i = jidAvatars.find(jid); + return i == jidAvatars.end() ? "" : i->second; + } + private: std::map<std::string, ByteArray> avatars; + std::map<JID, std::string> jidAvatars; }; } diff --git a/Swiften/Avatars/AvatarStorage.h b/Swiften/Avatars/AvatarStorage.h index 826a648..48fc885 100644 --- a/Swiften/Avatars/AvatarStorage.h +++ b/Swiften/Avatars/AvatarStorage.h @@ -7,9 +7,10 @@ #pragma once #include <boost/filesystem.hpp> +#include <string> namespace Swift { - + class JID; class ByteArray; class AvatarStorage { @@ -20,6 +21,9 @@ namespace Swift { virtual void addAvatar(const std::string& hash, const ByteArray& avatar) = 0; virtual ByteArray getAvatar(const std::string& hash) const = 0; virtual boost::filesystem::path getAvatarPath(const std::string& hash) const = 0; + + virtual void setAvatarForJID(const JID& jid, const std::string& hash) = 0; + virtual std::string getAvatarForJID(const JID& jid) const = 0; }; } diff --git a/Swiften/Avatars/CombinedAvatarProvider.cpp b/Swiften/Avatars/CombinedAvatarProvider.cpp index 6ac31e3..ae0fde3 100644 --- a/Swiften/Avatars/CombinedAvatarProvider.cpp +++ b/Swiften/Avatars/CombinedAvatarProvider.cpp @@ -9,15 +9,20 @@ #include <algorithm> #include <boost/bind.hpp> +#include <Swiften/Base/Log.h> + namespace Swift { std::string CombinedAvatarProvider::getAvatarHash(const JID& jid) const { + SWIFT_LOG(debug) << "JID: " << jid << std::endl; for (size_t i = 0; i < providers.size(); ++i) { std::string hash = providers[i]->getAvatarHash(jid); + SWIFT_LOG(debug) << "Provider " << providers[i] << ": " << hash << std::endl; if (!hash.empty()) { return hash; } } + SWIFT_LOG(debug) << "No hash found" << std::endl; return std::string(); } diff --git a/Swiften/Avatars/OfflineAvatarManager.cpp b/Swiften/Avatars/OfflineAvatarManager.cpp new file mode 100644 index 0000000..02c6a35 --- /dev/null +++ b/Swiften/Avatars/OfflineAvatarManager.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Avatars/OfflineAvatarManager.h> + +#include <boost/bind.hpp> + +#include <Swiften/Avatars/AvatarStorage.h> + +namespace Swift { + +OfflineAvatarManager::OfflineAvatarManager(AvatarStorage* avatarStorage) : avatarStorage(avatarStorage) { +} + +OfflineAvatarManager::~OfflineAvatarManager() { +} + +std::string OfflineAvatarManager::getAvatarHash(const JID& jid) const { + return avatarStorage->getAvatarForJID(jid); +} + +void OfflineAvatarManager::setAvatar(const JID& jid, const std::string& hash) { + if (getAvatarHash(jid) != hash) { + avatarStorage->setAvatarForJID(jid, hash); + onAvatarChanged(jid); + } +} + +} diff --git a/Swiften/Avatars/OfflineAvatarManager.h b/Swiften/Avatars/OfflineAvatarManager.h new file mode 100644 index 0000000..2098990 --- /dev/null +++ b/Swiften/Avatars/OfflineAvatarManager.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Avatars/AvatarProvider.h> + +namespace Swift { + class AvatarStorage; + + class OfflineAvatarManager : public AvatarProvider { + public: + OfflineAvatarManager(AvatarStorage*); + ~OfflineAvatarManager(); + + virtual std::string getAvatarHash(const JID&) const; + void setAvatar(const JID&, const std::string& hash); + + private: + AvatarStorage* avatarStorage; + }; +} diff --git a/Swiften/Avatars/SConscript b/Swiften/Avatars/SConscript index 7922a51..acf2592 100644 --- a/Swiften/Avatars/SConscript +++ b/Swiften/Avatars/SConscript @@ -4,6 +4,7 @@ objects = swiften_env.StaticObject([ "AvatarFileStorage.cpp", "VCardUpdateAvatarManager.cpp", "VCardAvatarManager.cpp", + "OfflineAvatarManager.cpp", "AvatarManager.cpp", "AvatarManagerImpl.cpp", "AvatarStorage.cpp", diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.cpp b/Swiften/Avatars/VCardUpdateAvatarManager.cpp index 08d026b..ea074cc 100644 --- a/Swiften/Avatars/VCardUpdateAvatarManager.cpp +++ b/Swiften/Avatars/VCardUpdateAvatarManager.cpp @@ -16,6 +16,7 @@ #include "Swiften/Avatars/AvatarStorage.h" #include "Swiften/MUC/MUCRegistry.h" #include "Swiften/VCards/VCardManager.h" +#include <Swiften/Base/Log.h> namespace Swift { @@ -34,6 +35,7 @@ void VCardUpdateAvatarManager::handlePresenceReceived(boost::shared_ptr<Presence if (getAvatarHash(from) == update->getPhotoHash()) { return; } + SWIFT_LOG(debug) << "Updated hash: " << from << " -> " << update->getPhotoHash() << std::endl; if (avatarStorage_->hasAvatar(update->getPhotoHash())) { setAvatarHash(from, update->getPhotoHash()); } @@ -61,6 +63,7 @@ void VCardUpdateAvatarManager::handleVCardChanged(const JID& from, VCard::ref vC } void VCardUpdateAvatarManager::setAvatarHash(const JID& from, const std::string& hash) { + SWIFT_LOG(debug) << "Updating hash: " << from << " -> " << hash << std::endl; avatarHashes_[from] = hash; onAvatarChanged(from); } diff --git a/Swiften/Base/Log.h b/Swiften/Base/Log.h index 5296860..5e13a20 100644 --- a/Swiften/Base/Log.h +++ b/Swiften/Base/Log.h @@ -6,7 +6,8 @@ #pragma once -#include "Swiften/Base/Platform.h" +#include <iostream> + namespace Swift { extern bool logging; } diff --git a/Swiften/Client/FileStorages.cpp b/Swiften/Client/FileStorages.cpp index ad8b130..54a109d 100644 --- a/Swiften/Client/FileStorages.cpp +++ b/Swiften/Client/FileStorages.cpp @@ -15,7 +15,7 @@ FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& ji std::string profile = jid.toBare(); vcardStorage = new VCardFileStorage(baseDir / profile / "vcards"); capsStorage = new CapsFileStorage(baseDir / "caps"); - avatarStorage = new AvatarFileStorage(baseDir / "avatars"); + avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars.xml"); } FileStorages::~FileStorages() { |