diff --git a/CHANGELOG.md b/CHANGELOG.md index 76c148339ce..e8ae1f1d5bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# ClickHouse release 1.1.54318 +* This is bugfix release for previous 1.1.54310 release. + # ClickHouse release 1.1.54310 ## New features: diff --git a/CHANGELOG_RU.md b/CHANGELOG_RU.md index 71773723d07..41524038ce5 100644 --- a/CHANGELOG_RU.md +++ b/CHANGELOG_RU.md @@ -1,3 +1,12 @@ +# Релиз ClickHouse 1.1.54318 + +* Релиз содержит изменения к предыдущему релизу 1.1.54310 с исправлением следующих багов: + * Исправлено некорректное удаление строк при слияниях в движке SummingMergeTree + * Исправлена утечка памяти в нереплицированных MergeTree-движках + * Исправлена деградация производительности при частых вставках в MergeTree-движках + * Исправлена проблема, приводящая к остановке выполнения очереди репликации + * Исправлено ротирование и архивация логов сервера + # Релиз ClickHouse 1.1.54310 ## Новые возможности: diff --git a/CMakeLists.txt b/CMakeLists.txt index 49e817afff5..65924b378ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,8 +55,12 @@ if ( ( ARCH_ARM AND NOT ARCH_AARCH64 ) OR ARCH_I386) message (WARNING "Support 32bit platforms is highly experimental") endif () -set (COMMON_WARNING_FLAGS "-Wall") # -Werror is also added inside directories with our own code. -set (CXX_WARNING_FLAGS "-Wnon-virtual-dtor") +set (COMMON_WARNING_FLAGS "${COMMON_WARNING_FLAGS} -Wall") # -Werror is also added inside directories with our own code. +set (CXX_WARNING_FLAGS "${CXX_WARNING_FLAGS} -Wnon-virtual-dtor") +if (CCACHE_FOUND) + # clang-6.0: warning: argument unused during compilation: '-stdlib=libc++' + set (CXX_WARNING_FLAGS "${CXX_WARNING_FLAGS} -Wno-unused-command-line-argument") +endif () set (CXX11_ABI "ENABLE" CACHE STRING "Use C++11 ABI: DEFAULT, ENABLE, DISABLE") option (TEST_COVERAGE "Enables flags for test coverage" OFF) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index c6b0c03aad1..79bc822e5bb 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -50,6 +50,11 @@ if (USE_INTERNAL_ZLIB_LIBRARY) # We should use same defines when including zlib.h as used when zlib compiled target_compile_definitions (zlib PUBLIC ZLIB_COMPAT WITH_GZFILEOP) target_compile_definitions (zlibstatic PUBLIC ZLIB_COMPAT WITH_GZFILEOP) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64") + target_compile_definitions (zlib PUBLIC X86_64) + target_compile_definitions (zlibstatic PUBLIC X86_64) + endif () + set_target_properties(example PROPERTIES EXCLUDE_FROM_ALL 1) set_target_properties(minigzip PROPERTIES EXCLUDE_FROM_ALL 1) if (TARGET example64) diff --git a/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp new file mode 100644 index 00000000000..fabcdb5fa71 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp @@ -0,0 +1,100 @@ +#ifndef BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP +#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 +#include +#include + +#include +#include + +// 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 +#endif + +#include // must be the last header + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by archives +// +class BOOST_SYMBOL_VISIBLE archive_exception : + public virtual std::exception +{ +private: + char m_buffer[128]; +protected: + BOOST_ARCHIVE_DECL unsigned int + append(unsigned int l, const char * a); + BOOST_ARCHIVE_DECL + archive_exception() BOOST_NOEXCEPT; +public: + typedef enum { + no_exception, // initialized without code + other_exception, // any excepton not listed below + unregistered_class, // attempt to serialize a pointer of + // 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 serialized through a pointer. + // Were this permitted, 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 program + // 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; + exception_code code; + + BOOST_ARCHIVE_DECL archive_exception( + exception_code c, + const char * e1 = NULL, + const char * e2 = NULL + ) BOOST_NOEXCEPT; + BOOST_ARCHIVE_DECL archive_exception(archive_exception const &) BOOST_NOEXCEPT ; + virtual BOOST_ARCHIVE_DECL ~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW ; + virtual BOOST_ARCHIVE_DECL const char * what() const BOOST_NOEXCEPT_OR_NOTHROW ; +}; + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp new file mode 100644 index 00000000000..ce7ac99a6dd --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp @@ -0,0 +1,304 @@ +#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_archive.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 // count +#include +#include +#include // size_t +#include +#include + +#include +#include // must be the last header + +namespace boost { +namespace archive { + +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4244 4267 ) +#endif + +/* NOTE : Warning : Warning : Warning : Warning : Warning + * Don't ever changes this. If you do, they previously created + * binary archives won't be readable !!! + */ +class library_version_type { +private: + typedef uint_least16_t base_type; + base_type t; +public: + library_version_type(): t(0) {}; + explicit library_version_type(const unsigned int & t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + library_version_type(const library_version_type & t_) : + t(t_.t) + {} + library_version_type & operator=(const library_version_type & rhs){ + t = rhs.t; + return *this; + } + // used for text output + operator base_type () const { + return t; + } + // used for text input + operator base_type & (){ + return t; + } + bool operator==(const library_version_type & rhs) const { + return t == rhs.t; + } + bool operator<(const library_version_type & rhs) const { + return t < rhs.t; + } +}; + +BOOST_ARCHIVE_DECL library_version_type +BOOST_ARCHIVE_VERSION(); + +class version_type { +private: + typedef uint_least32_t base_type; + base_type t; +public: + // should be private - but MPI fails if it's not!!! + version_type(): t(0) {}; + explicit version_type(const unsigned int & t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + version_type(const version_type & t_) : + t(t_.t) + {} + version_type & operator=(const version_type & rhs){ + t = rhs.t; + return *this; + } + // used for text output + operator base_type () const { + return t; + } + // used for text intput + operator base_type & (){ + return t; + } + bool operator==(const version_type & rhs) const { + return t == rhs.t; + } + bool operator<(const version_type & rhs) const { + return t < rhs.t; + } +}; + +class class_id_type { +private: + typedef int_least16_t base_type; + base_type t; +public: + // should be private - but then can't use BOOST_STRONG_TYPE below + class_id_type() : t(0) {}; + explicit class_id_type(const int t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + explicit class_id_type(const std::size_t t_) : t(t_){ + // BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + class_id_type(const class_id_type & t_) : + t(t_.t) + {} + class_id_type & operator=(const class_id_type & rhs){ + t = rhs.t; + return *this; + } + + // used for text output + operator int () const { + return t; + } + // used for text input + operator int_least16_t &() { + return t; + } + bool operator==(const class_id_type & rhs) const { + return t == rhs.t; + } + bool operator<(const class_id_type & rhs) const { + return t < rhs.t; + } +}; + +#define NULL_POINTER_TAG boost::archive::class_id_type(-1) + +class object_id_type { +private: + typedef uint_least32_t base_type; + base_type t; +public: + object_id_type(): t(0) {}; + // note: presumes that size_t >= unsigned int. + explicit object_id_type(const std::size_t & t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + object_id_type(const object_id_type & t_) : + t(t_.t) + {} + object_id_type & operator=(const object_id_type & rhs){ + t = rhs.t; + return *this; + } + // used for text output + operator uint_least32_t () const { + return t; + } + // used for text input + operator uint_least32_t & () { + return t; + } + bool operator==(const object_id_type & rhs) const { + return t == rhs.t; + } + bool operator<(const object_id_type & rhs) const { + return t < rhs.t; + } +}; + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + +struct tracking_type { + bool t; + explicit tracking_type(const bool t_ = false) + : t(t_) + {}; + tracking_type(const tracking_type & t_) + : t(t_.t) + {} + operator bool () const { + return t; + }; + operator bool & () { + return t; + }; + tracking_type & operator=(const bool t_){ + t = t_; + return *this; + } + bool operator==(const tracking_type & rhs) const { + return t == rhs.t; + } + bool operator==(const bool & rhs) const { + return t == rhs; + } + tracking_type & operator=(const tracking_type & rhs){ + t = rhs.t; + return *this; + } +}; + +struct class_name_type : + private boost::noncopyable +{ + char *t; + operator const char * & () const { + return const_cast(t); + } + operator char * () { + return t; + } + std::size_t size() const { + return std::strlen(t); + } + explicit class_name_type(const char *key_) + : t(const_cast(key_)){} + explicit class_name_type(char *key_) + : t(key_){} + class_name_type & operator=(const class_name_type & rhs){ + t = rhs.t; + return *this; + } +}; + +enum archive_flags { + no_header = 1, // suppress archive header info + no_codecvt = 2, // suppress alteration of codecvt facet + no_xml_tag_checking = 4, // suppress checking of xml tags + no_tracking = 8, // suppress ALL tracking + flags_last = 8 +}; + +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_SIGNATURE(); + +/* NOTE : Warning : Warning : Warning : Warning : Warning + * If any of these are changed to different sized types, + * binary_iarchive won't be able to read older archives + * unless you rev the library version and include conditional + * code based on the library version. There is nothing + * inherently wrong in doing this - but you have to be super + * careful because it's easy to get wrong and start breaking + * old archives !!! + */ + +#define BOOST_ARCHIVE_STRONG_TYPEDEF(T, D) \ + class D : public T { \ + public: \ + explicit D(const T tt) : T(tt){} \ + }; \ +/**/ + +BOOST_ARCHIVE_STRONG_TYPEDEF(class_id_type, class_id_reference_type) +BOOST_ARCHIVE_STRONG_TYPEDEF(class_id_type, class_id_optional_type) +BOOST_ARCHIVE_STRONG_TYPEDEF(object_id_type, object_reference_type) + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#include + +// set implementation level to primitive for all types +// used internally by the serialization library + +BOOST_CLASS_IMPLEMENTATION(boost::archive::library_version_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::version_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_reference_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_optional_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_name_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::object_id_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::object_reference_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::tracking_type, primitive_type) + +#include + +// set types used internally by the serialization library +// to be bitwise serializable + +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::library_version_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::version_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_reference_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_optional_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_name_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::object_id_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::object_reference_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::tracking_type) + +#endif //BOOST_ARCHIVE_BASIC_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp new file mode 100644 index 00000000000..c0cc655c997 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp @@ -0,0 +1,204 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iarchive.hpp +// +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON + +// (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 +#include + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +#include // must be the last header + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +///////////////////////////////////////////////////////////////////////// +// class basic_binary_iarchive - read serialized objects from a input binary stream +template +class BOOST_SYMBOL_VISIBLE basic_binary_iarchive : + public detail::common_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; + #else + friend class detail::interface_iarchive; + #endif +#endif + // intermediate level to support override of operators + // fot templates in the absence of partial function + // template ordering. If we get here pass to base class + // note extra nonsense to sneak it pass the borland compiers + typedef detail::common_iarchive detail_common_iarchive; + template + void load_override(T & t){ + this->detail_common_iarchive::load_override(t); + } + + // include these to trap a change in binary format which + // isn't specifically handled + // upto 32K classes + BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); + BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); + // upto 2G objects + BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); + BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); + + // binary files don't include the optional information + void load_override(class_id_optional_type & /* t */){} + + void load_override(tracking_type & t, int /*version*/){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(6) < lvt){ + int_least8_t x=0; + * this->This() >> x; + t = boost::archive::tracking_type(x); + } + else{ + bool x=0; + * this->This() >> x; + t = boost::archive::tracking_type(x); + } + } + void load_override(class_id_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_iarchive::load_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + int_least16_t x=0; + * this->This() >> x; + t = boost::archive::class_id_type(x); + } + else{ + int x=0; + * this->This() >> x; + t = boost::archive::class_id_type(x); + } + } + void load_override(class_id_reference_type & t){ + load_override(static_cast(t)); + } + + void load_override(version_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_iarchive::load_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + uint_least8_t x=0; + * this->This() >> x; + t = boost::archive::version_type(x); + } + else + if(boost::archive::library_version_type(5) < lvt){ + uint_least16_t x=0; + * this->This() >> x; + t = boost::archive::version_type(x); + } + else + if(boost::archive::library_version_type(2) < lvt){ + // upto 255 versions + unsigned char x=0; + * this->This() >> x; + t = version_type(x); + } + else{ + unsigned int x=0; + * this->This() >> x; + t = boost::archive::version_type(x); + } + } + + void load_override(boost::serialization::item_version_type & t){ + library_version_type lvt = this->get_library_version(); +// if(boost::archive::library_version_type(7) < lvt){ + if(boost::archive::library_version_type(6) < lvt){ + this->detail_common_iarchive::load_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + uint_least16_t x=0; + * this->This() >> x; + t = boost::serialization::item_version_type(x); + } + else{ + unsigned int x=0; + * this->This() >> x; + t = boost::serialization::item_version_type(x); + } + } + + void load_override(serialization::collection_size_type & t){ + if(boost::archive::library_version_type(5) < this->get_library_version()){ + this->detail_common_iarchive::load_override(t); + } + else{ + unsigned int x=0; + * this->This() >> x; + t = serialization::collection_size_type(x); + } + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(class_name_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + + basic_binary_iarchive(unsigned int flags) : + detail::common_iarchive(flags) + {} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp new file mode 100644 index 00000000000..665d3e81e1f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp @@ -0,0 +1,198 @@ +#ifndef BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP +#define BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(_MSC_VER) +#pragma warning( disable : 4800 ) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iprimitive.hpp +// +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON + +// (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 +#include +#include +#include // std::memcpy +#include // std::size_t +#include // basic_streambuf +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include + +//#include +#include +#include + +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////////// +// class binary_iarchive - read serialized objects from a input binary stream +template +class BOOST_SYMBOL_VISIBLE basic_binary_iprimitive { +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + friend class load_access; +protected: +#else +public: +#endif + std::basic_streambuf & m_sb; + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + #ifndef BOOST_NO_STD_LOCALE + // note order! - if you change this, libstd++ will fail! + // a) create new locale with new codecvt facet + // b) save current locale + // c) change locale to new one + // d) use stream buffer + // e) change locale back to original + // f) destroy new codecvt facet + boost::archive::codecvt_null codecvt_null_facet; + basic_streambuf_locale_saver locale_saver; + std::locale archive_locale; + #endif + + // main template for serilization of primitive types + template + void load(T & t){ + load_binary(& t, sizeof(T)); + } + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + + // trap usage of invalid uninitialized boolean + void load(bool & t){ + load_binary(& t, sizeof(t)); + int i = t; + BOOST_ASSERT(0 == i || 1 == i); + (void)i; // warning suppression for release builds. + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load(std::wstring &ws); + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load(char * t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load(wchar_t * t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_binary_iprimitive( + std::basic_streambuf & sb, + bool no_codecvt + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_binary_iprimitive(); +public: + // we provide an optimized load for all fundamental types + // typedef serialization::is_bitwise_serializable + // use_array_optimization; + struct use_array_optimization { + template + #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) + struct apply { + typedef typename boost::serialization::is_bitwise_serializable< T >::type type; + }; + #else + struct apply : public boost::serialization::is_bitwise_serializable< T > {}; + #endif + }; + + // the optimized load_array dispatches to load_binary + template + void load_array(serialization::array_wrapper& a, unsigned int) + { + load_binary(a.address(),a.count()*sizeof(ValueType)); + } + + void + load_binary(void *address, std::size_t count); +}; + +template +inline void +basic_binary_iprimitive::load_binary( + void *address, + std::size_t count +){ + // note: an optimizer should eliminate the following for char files + BOOST_ASSERT( + static_cast(count / sizeof(Elem)) + <= boost::integer_traits::const_max + ); + std::streamsize s = static_cast(count / sizeof(Elem)); + std::streamsize scount = m_sb.sgetn( + static_cast(address), + s + ); + if(scount != s) + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + // note: an optimizer should eliminate the following for char files + BOOST_ASSERT(count % sizeof(Elem) <= boost::integer_traits::const_max); + s = static_cast(count % sizeof(Elem)); + if(0 < s){ +// if(is.fail()) +// boost::serialization::throw_exception( +// archive_exception(archive_exception::stream_error) +// ); + Elem t; + scount = m_sb.sgetn(& t, 1); + if(scount != 1) + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + std::memcpy(static_cast(address) + (count - s), &t, static_cast(s)); + } +} + +} // namespace archive +} // namespace boost + +#include // pop pragmas + +#endif // BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp new file mode 100644 index 00000000000..f05f2f86d55 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp @@ -0,0 +1,185 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +////////////////////////////////////////////////////////////////////// +// class basic_binary_oarchive - write serialized objects to a binary output stream +// note: this archive has no pretensions to portability. Archive format +// may vary across machine architectures and compilers. About the only +// guarentee is that an archive created with this code will be readable +// by a program built with the same tools for the same machne. This class +// does have the virtue of buiding the smalles archive in the minimum amount +// of time. So under some circumstances it may be he right choice. +template +class BOOST_SYMBOL_VISIBLE basic_binary_oarchive : + public detail::common_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + #else + friend class detail::interface_oarchive; + #endif +#endif + // any datatype not specifed below will be handled by base class + typedef detail::common_oarchive detail_common_oarchive; + template + void save_override(const T & t){ + this->detail_common_oarchive::save_override(t); + } + + // include these to trap a change in binary format which + // isn't specifically handled + BOOST_STATIC_ASSERT(sizeof(tracking_type) == sizeof(bool)); + // upto 32K classes + BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); + BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); + // upto 2G objects + BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); + BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); + + // binary files don't include the optional information + void save_override(const class_id_optional_type & /* t */){} + + // enable this if we decide to support generation of previous versions + #if 0 + void save_override(const boost::archive::version_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_oarchive::save_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + const boost::uint_least16_t x = t; + * this->This() << x; + } + else{ + const unsigned int x = t; + * this->This() << x; + } + } + void save_override(const boost::serialization::item_version_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_oarchive::save_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + const boost::uint_least16_t x = t; + * this->This() << x; + } + else{ + const unsigned int x = t; + * this->This() << x; + } + } + + void save_override(class_id_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_oarchive::save_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + const boost::int_least16_t x = t; + * this->This() << x; + } + else{ + const int x = t; + * this->This() << x; + } + } + void save_override(class_id_reference_type & t){ + save_override(static_cast(t)); + } + + #endif + + // explicitly convert to char * to avoid compile ambiguities + void save_override(const class_name_type & t){ + const std::string s(t); + * this->This() << s; + } + + #if 0 + void save_override(const serialization::collection_size_type & t){ + if (get_library_version() < boost::archive::library_version_type(6)){ + unsigned int x=0; + * this->This() >> x; + t = serialization::collection_size_type(x); + } + else{ + * this->This() >> t; + } + } + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + + basic_binary_oarchive(unsigned int flags) : + detail::common_oarchive(flags) + {} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp new file mode 100644 index 00000000000..6dc770c60e8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp @@ -0,0 +1,188 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oprimitive.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. + +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON + +#include +#include +#include +#include // basic_streambuf +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_binary_oprimitive - binary output of prmitives + +template +class BOOST_SYMBOL_VISIBLE basic_binary_oprimitive { +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + friend class save_access; +protected: +#else +public: +#endif + std::basic_streambuf & m_sb; + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + #ifndef BOOST_NO_STD_LOCALE + // note order! - if you change this, libstd++ will fail! + // a) create new locale with new codecvt facet + // b) save current locale + // c) change locale to new one + // d) use stream buffer + // e) change locale back to original + // f) destroy new codecvt facet + boost::archive::codecvt_null codecvt_null_facet; + basic_streambuf_locale_saver locale_saver; + std::locale archive_locale; + #endif + // default saving of primitives. + template + void save(const T & t) + { + save_binary(& t, sizeof(T)); + } + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + + // trap usage of invalid uninitialized boolean which would + // otherwise crash on load. + void save(const bool t){ + BOOST_ASSERT(0 == static_cast(t) || 1 == static_cast(t)); + save_binary(& t, sizeof(t)); + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save(const char * t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save(const wchar_t * t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_binary_oprimitive( + std::basic_streambuf & sb, + bool no_codecvt + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_binary_oprimitive(); +public: + + // we provide an optimized save for all fundamental types + // typedef serialization::is_bitwise_serializable + // use_array_optimization; + // workaround without using mpl lambdas + struct use_array_optimization { + template + #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) + struct apply { + typedef typename boost::serialization::is_bitwise_serializable< T >::type type; + }; + #else + struct apply : public boost::serialization::is_bitwise_serializable< T > {}; + #endif + }; + + // the optimized save_array dispatches to save_binary + template + void save_array(boost::serialization::array_wrapper const& a, unsigned int) + { + save_binary(a.address(),a.count()*sizeof(ValueType)); + } + + void save_binary(const void *address, std::size_t count); +}; + +template +inline void +basic_binary_oprimitive::save_binary( + const void *address, + std::size_t count +){ + // BOOST_ASSERT(count <= std::size_t(boost::integer_traits::const_max)); + // note: if the following assertions fail + // a likely cause is that the output stream is set to "text" + // mode where by cr characters recieve special treatment. + // be sure that the output stream is opened with ios::binary + //if(os.fail()) + // boost::serialization::throw_exception( + // archive_exception(archive_exception::output_stream_error) + // ); + // figure number of elements to output - round up + count = ( count + sizeof(Elem) - 1) / sizeof(Elem); + std::streamsize scount = m_sb.sputn( + static_cast(address), + static_cast(count) + ); + if(count != static_cast(scount)) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + //os.write( + // static_cast(address), + // count + //); + //BOOST_ASSERT(os.good()); +} + +} //namespace boost +} //namespace archive + +#include // pop pragmas + +#endif // BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp new file mode 100644 index 00000000000..5cd4b36f081 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp @@ -0,0 +1,108 @@ +#ifndef BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP +#define BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_streambuf_locale_saver.hpp + +// (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) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note derived from boost/io/ios_state.hpp +// Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution +// are subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or a copy at .) + +// See for the library's home page. + +#ifndef BOOST_NO_STD_LOCALE + +#include // for std::locale +#include +#include // for std::basic_streambuf + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost{ +namespace archive{ + +template < typename Ch, class Tr > +class basic_streambuf_locale_saver : + private boost::noncopyable +{ +public: + explicit basic_streambuf_locale_saver(std::basic_streambuf &s) : + m_streambuf(s), + m_locale(s.getloc()) + {} + ~basic_streambuf_locale_saver(){ + m_streambuf.pubsync(); + m_streambuf.pubimbue(m_locale); + } +private: + std::basic_streambuf & m_streambuf; + std::locale const m_locale; +}; + +template < typename Ch, class Tr > +class basic_istream_locale_saver : + private boost::noncopyable +{ +public: + explicit basic_istream_locale_saver(std::basic_istream &s) : + m_istream(s), + m_locale(s.getloc()) + {} + ~basic_istream_locale_saver(){ + // libstdc++ crashes without this + m_istream.sync(); + m_istream.imbue(m_locale); + } +private: + std::basic_istream & m_istream; + std::locale const m_locale; +}; + +template < typename Ch, class Tr > +class basic_ostream_locale_saver : + private boost::noncopyable +{ +public: + explicit basic_ostream_locale_saver(std::basic_ostream &s) : + m_ostream(s), + m_locale(s.getloc()) + {} + ~basic_ostream_locale_saver(){ + m_ostream.flush(); + m_ostream.imbue(m_locale); + } +private: + std::basic_ostream & m_ostream; + std::locale const m_locale; +}; + + +} // archive +} // boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_NO_STD_LOCALE +#endif // BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp new file mode 100644 index 00000000000..48a646cc1f7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp @@ -0,0 +1,96 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_istream but rather +// use two template parameters + +#include +#include + +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +///////////////////////////////////////////////////////////////////////// +// class basic_text_iarchive - read serialized objects from a input text stream +template +class BOOST_SYMBOL_VISIBLE basic_text_iarchive : + public detail::common_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; + #else + friend class detail::interface_iarchive; + #endif +#endif + // intermediate level to support override of operators + // fot templates in the absence of partial function + // template ordering + typedef detail::common_iarchive detail_common_iarchive; + template + void load_override(T & t){ + this->detail_common_iarchive::load_override(t); + } + // text file don't include the optional information + void load_override(class_id_optional_type & /*t*/){} + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(class_name_type & t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(void); + + basic_text_iarchive(unsigned int flags) : + detail::common_iarchive(flags) + {} + ~basic_text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp new file mode 100644 index 00000000000..bf936b55546 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp @@ -0,0 +1,142 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iprimitive.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. + +// archives stored as text - note these are templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// Note the fact that on libraries without wide characters, ostream is +// not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) + using ::locale; + #endif +} // namespace std +#endif + +#include +#include + +#include +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_text_iarchive - load serialized objects from a input text stream +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4244 4267 ) +#endif + +template +class BOOST_SYMBOL_VISIBLE basic_text_iprimitive { +protected: + IStream &is; + io::ios_flags_saver flags_saver; + io::ios_precision_saver precision_saver; + + #ifndef BOOST_NO_STD_LOCALE + // note order! - if you change this, libstd++ will fail! + // a) create new locale with new codecvt facet + // b) save current locale + // c) change locale to new one + // d) use stream buffer + // e) change locale back to original + // f) destroy new codecvt facet + boost::archive::codecvt_null codecvt_null_facet; + std::locale archive_locale; + basic_istream_locale_saver< + typename IStream::char_type, + typename IStream::traits_type + > locale_saver; + #endif + + template + void load(T & t) + { + if(is >> t) + return; + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + } + + void load(char & t) + { + short int i; + load(i); + t = i; + } + void load(signed char & t) + { + short int i; + load(i); + t = i; + } + void load(unsigned char & t) + { + unsigned short int i; + load(i); + t = i; + } + + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + void load(wchar_t & t) + { + BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int)); + int i; + load(i); + t = i; + } + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_text_iprimitive(IStream &is, bool no_codecvt); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_text_iprimitive(); +public: + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_binary(void *address, std::size_t count); +}; + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + +} // namespace archive +} // namespace boost + +#include // pop pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp new file mode 100644 index 00000000000..6f7f8fb167d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +///////////////////////////////////////////////////////////////////////// +// class basic_text_oarchive +template +class BOOST_SYMBOL_VISIBLE basic_text_oarchive : + public detail::common_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + #else + friend class detail::interface_oarchive; + #endif +#endif + + enum { + none, + eol, + space + } delimiter; + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + newtoken(); + + void newline(){ + delimiter = eol; + } + + // default processing - kick back to base class. Note the + // extra stuff to get it passed borland compilers + typedef detail::common_oarchive detail_common_oarchive; + template + void save_override(T & t){ + this->detail_common_oarchive::save_override(t); + } + + // start new objects on a new line + void save_override(const object_id_type & t){ + this->This()->newline(); + this->detail_common_oarchive::save_override(t); + } + + // text file don't include the optional information + void save_override(const class_id_optional_type & /* t */){} + + void save_override(const class_name_type & t){ + const std::string s(t); + * this->This() << s; + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + + basic_text_oarchive(unsigned int flags) : + detail::common_oarchive(flags), + delimiter(none) + {} + ~basic_text_oarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp new file mode 100644 index 00000000000..45f09358ece --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp @@ -0,0 +1,209 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oprimitive.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. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include +#include // size_t + +#include +#include +#include + +#include +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) + using ::locale; + #endif +} // namespace std +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_text_oprimitive - output of prmitives to stream +template +class BOOST_SYMBOL_VISIBLE basic_text_oprimitive +{ +protected: + OStream &os; + io::ios_flags_saver flags_saver; + io::ios_precision_saver precision_saver; + + #ifndef BOOST_NO_STD_LOCALE + // note order! - if you change this, libstd++ will fail! + // a) create new locale with new codecvt facet + // b) save current locale + // c) change locale to new one + // d) use stream buffer + // e) change locale back to original + // f) destroy new codecvt facet + boost::archive::codecvt_null codecvt_null_facet; + std::locale archive_locale; + basic_ostream_locale_saver< + typename OStream::char_type, + typename OStream::traits_type + > locale_saver; + #endif + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + void save(const bool t){ + // trap usage of invalid uninitialized boolean which would + // otherwise crash on load. + BOOST_ASSERT(0 == static_cast(t) || 1 == static_cast(t)); + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + os << t; + } + void save(const signed char t) + { + save(static_cast(t)); + } + void save(const unsigned char t) + { + save(static_cast(t)); + } + void save(const char t) + { + save(static_cast(t)); + } + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + void save(const wchar_t t) + { + BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int)); + save(static_cast(t)); + } + #endif + + ///////////////////////////////////////////////////////// + // saving of any types not listed above + + template + void save_impl(const T &t, boost::mpl::bool_ &){ + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + os << t; + } + + ///////////////////////////////////////////////////////// + // floating point types need even more special treatment + // the following determines whether the type T is some sort + // of floating point type. Note that we then assume that + // the stream << operator is defined on that type - if not + // we'll get a compile time error. This is meant to automatically + // support synthesized types which support floating point + // operations. Also it should handle compiler dependent types + // such long double. Due to John Maddock. + + template + struct is_float { + typedef typename mpl::bool_< + boost::is_floating_point::value + || (std::numeric_limits::is_specialized + && !std::numeric_limits::is_integer + && !std::numeric_limits::is_exact + && std::numeric_limits::max_exponent) + >::type type; + }; + + template + void save_impl(const T &t, boost::mpl::bool_ &){ + // must be a user mistake - can't serialize un-initialized data + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + // The formulae for the number of decimla digits required is given in + // http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf + // which is derived from Kahan's paper: + // www.eecs.berkeley.edu/~wkahan/ieee754status/ieee754.ps + // const unsigned int digits = (std::numeric_limits::digits * 3010) / 10000; + // note: I've commented out the above because I didn't get good results. e.g. + // in one case I got a difference of 19 units. + #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS + const unsigned int digits = std::numeric_limits::max_digits10; + #else + const unsigned int digits = std::numeric_limits::digits10 + 2; + #endif + os << std::setprecision(digits) << std::scientific << t; + } + + template + void save(const T & t){ + typename is_float::type tf; + save_impl(t, tf); + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_text_oprimitive(OStream & os, bool no_codecvt); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_text_oprimitive(); +public: + // unformatted append of one character + void put(typename OStream::char_type c){ + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + os.put(c); + } + // unformatted append of null terminated string + void put(const char * s){ + while('\0' != *s) + os.put(*s++); + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_binary(const void *address, std::size_t count); +}; + +} //namespace boost +} //namespace archive + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp new file mode 100644 index 00000000000..bef368b973b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp @@ -0,0 +1,67 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_archive.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 + +#include +#include // must be the last header + +namespace boost { +namespace archive { + +// constant strings used in xml i/o + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_OBJECT_ID(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_OBJECT_REFERENCE(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_CLASS_ID(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_CLASS_NAME(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_TRACKING(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_VERSION(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_SIGNATURE(); + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp new file mode 100644 index 00000000000..e9f7482f744 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +///////////////////////////////////////////////////////////////////////// +// class basic_xml_iarchive - read serialized objects from a input text stream +template +class BOOST_SYMBOL_VISIBLE basic_xml_iarchive : + public detail::common_iarchive +{ + unsigned int depth; +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_iarchive; +#endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_start(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_end(const char *name); + + // Anything not an attribute and not a name-value pair is an + // should be trapped here. + template + void load_override(T & t) + { + // If your program fails to compile here, its most likely due to + // not specifying an nvp wrapper around the variable to + // be serialized. + BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); + this->detail_common_iarchive::load_override(t); + } + + // Anything not an attribute - see below - should be a name value + // pair and be processed here + typedef detail::common_iarchive detail_common_iarchive; + template + void load_override( + const boost::serialization::nvp< T > & t + ){ + this->This()->load_start(t.name()); + this->detail_common_iarchive::load_override(t.value()); + this->This()->load_end(t.name()); + } + + // specific overrides for attributes - handle as + // primitives. These are not name-value pairs + // so they have to be intercepted here and passed on to load. + // although the class_id is included in the xml text file in order + // to make the file self describing, it isn't used when loading + // an xml archive. So we can skip it here. Note: we MUST override + // it otherwise it will be loaded as a normal primitive w/o tag and + // leaving the archive in an undetermined state + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(class_id_type & t); + void load_override(class_id_optional_type & /* t */){} + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(object_id_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(version_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(tracking_type & t); + // class_name_type can't be handled here as it depends upon the + // char type used by the stream. So require the derived implementation + // handle this. + // void load_override(class_name_type & t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_xml_iarchive(unsigned int flags); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_xml_iarchive(); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp new file mode 100644 index 00000000000..107fca4ec65 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp @@ -0,0 +1,138 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +////////////////////////////////////////////////////////////////////// +// class basic_xml_oarchive - write serialized objects to a xml output stream +template +class BOOST_SYMBOL_VISIBLE basic_xml_oarchive : + public detail::common_oarchive +{ + // special stuff for xml output + unsigned int depth; + bool pending_preamble; +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_oarchive; +#endif + bool indent_next; + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + indent(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + windup(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + write_attribute( + const char *attribute_name, + int t, + const char *conjunction = "=\"" + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + write_attribute( + const char *attribute_name, + const char *key + ); + // helpers used below + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_start(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_end(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + end_preamble(); + + // Anything not an attribute and not a name-value pair is an + // error and should be trapped here. + template + void save_override(T & t) + { + // If your program fails to compile here, its most likely due to + // not specifying an nvp wrapper around the variable to + // be serialized. + BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); + this->detail_common_oarchive::save_override(t); + } + + // special treatment for name-value pairs. + typedef detail::common_oarchive detail_common_oarchive; + template + void save_override( + const ::boost::serialization::nvp< T > & t + ){ + this->This()->save_start(t.name()); + this->detail_common_oarchive::save_override(t.const_value()); + this->This()->save_end(t.name()); + } + + // specific overrides for attributes - not name value pairs so we + // want to trap them before the above "fall through" + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const class_id_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const class_id_optional_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const class_id_reference_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const object_id_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const object_reference_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const version_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const class_name_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const tracking_type & t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_xml_oarchive(unsigned int flags); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_xml_oarchive(); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp new file mode 100644 index 00000000000..785ce7610b1 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_iarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE binary_iarchive : + public binary_iarchive_impl< + boost::archive::binary_iarchive, + std::istream::char_type, + std::istream::traits_type + >{ +public: + binary_iarchive(std::istream & is, unsigned int flags = 0) : + binary_iarchive_impl< + binary_iarchive, std::istream::char_type, std::istream::traits_type + >(is, flags) + {} + binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) : + binary_iarchive_impl< + binary_iarchive, std::istream::char_type, std::istream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_iarchive) +BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_iarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp new file mode 100644 index 00000000000..b4747c98ece --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp @@ -0,0 +1,105 @@ +#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP +#define BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_iarchive_impl.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 +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE binary_iarchive_impl : + public basic_binary_iprimitive, + public basic_binary_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; + friend basic_binary_iarchive; + friend load_access; + #else + friend class detail::interface_iarchive; + friend class basic_binary_iarchive; + friend class load_access; + #endif +#endif + template + void load_override(T & t){ + this->basic_binary_iarchive::load_override(t); + } + void init(unsigned int flags){ + if(0 != (flags & no_header)){ + return; + } + #if ! defined(__MWERKS__) + this->basic_binary_iarchive::init(); + this->basic_binary_iprimitive::init(); + #else + basic_binary_iarchive::init(); + basic_binary_iprimitive::init(); + #endif + } + binary_iarchive_impl( + std::basic_streambuf & bsb, + unsigned int flags + ) : + basic_binary_iprimitive( + bsb, + 0 != (flags & no_codecvt) + ), + basic_binary_iarchive(flags) + { + init(flags); + } + binary_iarchive_impl( + std::basic_istream & is, + unsigned int flags + ) : + basic_binary_iprimitive( + * is.rdbuf(), + 0 != (flags & no_codecvt) + ), + basic_binary_iarchive(flags) + { + init(flags); + } +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp new file mode 100644 index 00000000000..e8313fd7c95 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_oarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE binary_oarchive : + public binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + > +{ +public: + binary_oarchive(std::ostream & os, unsigned int flags = 0) : + binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + >(os, flags) + {} + binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) : + binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_oarchive) +BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_oarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp new file mode 100644 index 00000000000..6b4d018a564 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp @@ -0,0 +1,106 @@ +#ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP +#define BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_oarchive_impl.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 +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE binary_oarchive_impl : + public basic_binary_oprimitive, + public basic_binary_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + friend basic_binary_oarchive; + friend save_access; + #else + friend class detail::interface_oarchive; + friend class basic_binary_oarchive; + friend class save_access; + #endif +#endif + template + void save_override(T & t){ + this->basic_binary_oarchive::save_override(t); + } + void init(unsigned int flags) { + if(0 != (flags & no_header)){ + return; + } + #if ! defined(__MWERKS__) + this->basic_binary_oarchive::init(); + this->basic_binary_oprimitive::init(); + #else + basic_binary_oarchive::init(); + basic_binary_oprimitive::init(); + #endif + } + binary_oarchive_impl( + std::basic_streambuf & bsb, + unsigned int flags + ) : + basic_binary_oprimitive( + bsb, + 0 != (flags & no_codecvt) + ), + basic_binary_oarchive(flags) + { + init(flags); + } + binary_oarchive_impl( + std::basic_ostream & os, + unsigned int flags + ) : + basic_binary_oprimitive( + * os.rdbuf(), + 0 != (flags & no_codecvt) + ), + basic_binary_oarchive(flags) + { + init(flags); + } +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp new file mode 100644 index 00000000000..775d8f82726 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include // wistream +#include +#include + +namespace boost { +namespace archive { + +class binary_wiarchive : + public binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + > +{ +public: + binary_wiarchive(std::wistream & is, unsigned int flags = 0) : + binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + >(is, flags) + {} + binary_wiarchive(std::wstreambuf & bsb, unsigned int flags = 0) : + binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_wiarchive) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp new file mode 100644 index 00000000000..a8817d6f8b4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include +#include + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_oarchive_impl instead. This will +// preserve correct static polymorphism. +class binary_woarchive : + public binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + > +{ +public: + binary_woarchive(std::wostream & os, unsigned int flags = 0) : + binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + >(os, flags) + {} + binary_woarchive(std::wstreambuf & bsb, unsigned int flags = 0) : + binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_woarchive) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp b/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp new file mode 100644 index 00000000000..7bce2b9b329 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp @@ -0,0 +1,109 @@ +#ifndef BOOST_ARCHIVE_CODECVT_NULL_HPP +#define BOOST_ARCHIVE_CODECVT_NULL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// codecvt_null.hpp: + +// (C) Copyright 2004 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 +#include // NULL, size_t +#ifndef BOOST_NO_CWCHAR +#include // for mbstate_t +#endif +#include +#include +#include +#include // must be the last header + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std { +// For STLport on WinCE, BOOST_NO_STDC_NAMESPACE can get defined if STLport is putting symbols in its own namespace. +// In the case of codecvt, however, this does not mean that codecvt is in the global namespace (it will be in STLport's namespace) +# if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) + using ::codecvt; +# endif + using ::mbstate_t; + using ::size_t; +} // namespace +#endif + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +template +class codecvt_null; + +template<> +class codecvt_null : public std::codecvt +{ + virtual bool do_always_noconv() const throw() { + return true; + } +public: + explicit codecvt_null(std::size_t no_locale_manage = 0) : + std::codecvt(no_locale_manage) + {} + virtual ~codecvt_null(){}; +}; + +template<> +class BOOST_SYMBOL_VISIBLE codecvt_null : public std::codecvt +{ + virtual BOOST_WARCHIVE_DECL BOOST_DLLEXPORT std::codecvt_base::result + do_out( + std::mbstate_t & state, + const wchar_t * first1, + const wchar_t * last1, + const wchar_t * & next1, + char * first2, + char * last2, + char * & next2 + ) const BOOST_USED; + virtual BOOST_WARCHIVE_DECL BOOST_DLLEXPORT std::codecvt_base::result + do_in( + std::mbstate_t & state, + const char * first1, + const char * last1, + const char * & next1, + wchar_t * first2, + wchar_t * last2, + wchar_t * & next2 + ) const BOOST_USED; + virtual int do_encoding( ) const throw( ){ + return sizeof(wchar_t) / sizeof(char); + } + virtual int do_max_length( ) const throw( ){ + return do_encoding(); + } +public: + BOOST_DLLEXPORT explicit codecvt_null(std::size_t no_locale_manage = 0) : + std::codecvt(no_locale_manage) + {} + virtual ~codecvt_null(){}; +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif +#include // pop pragmas + +#endif //BOOST_ARCHIVE_CODECVT_NULL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp new file mode 100644 index 00000000000..debf79e9f0b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp @@ -0,0 +1,16 @@ +/////////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 // must be the last header +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp new file mode 100644 index 00000000000..4e054d66214 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp @@ -0,0 +1,15 @@ +/////////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 // pops abi_suffix.hpp pragmas + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp new file mode 100644 index 00000000000..5432bfc73e7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_SERIALIZER_MAP_HPP +#define BOOST_ARCHIVE_SERIALIZER_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_serializer_map.hpp: extenstion of type_info required for +// serialization. + +// (C) Copyright 2009 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. + +// note: this is nothing more than the thinest of wrappers around +// basic_serializer_map so we can have a one map / archive type. + +#include +#include +#include // must be the last header + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_serializer; + +template +class BOOST_SYMBOL_VISIBLE archive_serializer_map { +public: + static BOOST_ARCHIVE_OR_WARCHIVE_DECL bool insert(const basic_serializer * bs); + static BOOST_ARCHIVE_OR_WARCHIVE_DECL void erase(const basic_serializer * bs); + static BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * find( + const boost::serialization::extended_type_info & type_ + ); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // must be the last header + +#endif //BOOST_ARCHIVE_SERIALIZER_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp new file mode 100644 index 00000000000..79b0e490d65 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// auto_link_archive.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 + +// enable automatic library variant selection ------------------------------// + +#include + +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ +&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ +&& !defined(BOOST_SERIALIZATION_SOURCE) + + // Set the name of our library, this will get undef'ed by auto_link.hpp + // once it's done with it: + // + #define BOOST_LIB_NAME boost_serialization + // + // If we're importing code from a dll, then tell auto_link.hpp about it: + // + #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) + # define BOOST_DYN_LINK + #endif + // + // And include the header that does the work: + // + #include +#endif // auto-linking disabled + +#endif // BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp new file mode 100644 index 00000000000..683d191c20d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp @@ -0,0 +1,47 @@ +#ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// auto_link_warchive.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 + +// enable automatic library variant selection ------------------------------// + +#include + +#if !defined(BOOST_WARCHIVE_SOURCE) \ +&& !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_wserialization +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#endif // ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp new file mode 100644 index 00000000000..1f5a8bf63bf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp @@ -0,0 +1,105 @@ +#ifndef BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_iarchive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// can't use this - much as I'd like to as borland doesn't support it + +#include +#include +#include + +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_iarchive_impl; +class basic_iserializer; +class basic_pointer_iserializer; + +////////////////////////////////////////////////////////////////////// +// class basic_iarchive - read serialized objects from a input stream +class BOOST_SYMBOL_VISIBLE basic_iarchive : + private boost::noncopyable, + public boost::archive::detail::helper_collection +{ + friend class basic_iarchive_impl; + // hide implementation of this class to minimize header conclusion + boost::scoped_ptr pimpl; + + virtual void vload(version_type &t) = 0; + virtual void vload(object_id_type &t) = 0; + virtual void vload(class_id_type &t) = 0; + virtual void vload(class_id_optional_type &t) = 0; + virtual void vload(class_name_type &t) = 0; + virtual void vload(tracking_type &t) = 0; +protected: + BOOST_ARCHIVE_DECL basic_iarchive(unsigned int flags); + boost::archive::detail::helper_collection & + get_helper_collection(){ + return *this; + } +public: + // some msvc versions require that the following function be public + // otherwise it should really protected. + virtual BOOST_ARCHIVE_DECL ~basic_iarchive(); + // note: NOT part of the public API. + BOOST_ARCHIVE_DECL void next_object_pointer(void *t); + BOOST_ARCHIVE_DECL void register_basic_serializer( + const basic_iserializer & bis + ); + BOOST_ARCHIVE_DECL void load_object( + void *t, + const basic_iserializer & bis + ); + BOOST_ARCHIVE_DECL const basic_pointer_iserializer * + load_pointer( + void * & t, + const basic_pointer_iserializer * bpis_ptr, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & eti + ) + ); + // real public API starts here + BOOST_ARCHIVE_DECL void + set_library_version(library_version_type archive_library_version); + BOOST_ARCHIVE_DECL library_version_type + get_library_version() const; + BOOST_ARCHIVE_DECL unsigned int + get_flags() const; + BOOST_ARCHIVE_DECL void + reset_object_address(const void * new_address, const void * old_address); + BOOST_ARCHIVE_DECL void + delete_created_pointers(); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp new file mode 100644 index 00000000000..0d66674c349 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp @@ -0,0 +1,91 @@ +#ifndef BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP +#define BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_iserializer.hpp: extenstion of type_info required for serialization. + +// (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 // NULL +#include + +#include +#include +#include +#include +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class basic_iarchive; +class basic_pointer_iserializer; + +class BOOST_SYMBOL_VISIBLE basic_iserializer : + public basic_serializer +{ +private: + basic_pointer_iserializer *m_bpis; +protected: + explicit BOOST_ARCHIVE_DECL basic_iserializer( + const boost::serialization::extended_type_info & type + ); + virtual BOOST_ARCHIVE_DECL ~basic_iserializer(); +public: + bool serialized_as_pointer() const { + return m_bpis != NULL; + } + void set_bpis(basic_pointer_iserializer *bpis){ + m_bpis = bpis; + } + const basic_pointer_iserializer * get_bpis_ptr() const { + return m_bpis; + } + virtual void load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version + ) const = 0; + // returns true if class_info should be saved + virtual bool class_info() const = 0 ; + // returns true if objects should be tracked + virtual bool tracking(const unsigned int) const = 0 ; + // returns class version + virtual version_type version() const = 0 ; + // returns true if this class is polymorphic + virtual bool is_polymorphic() const = 0; + virtual void destroy(/*const*/ void *address) const = 0 ; +}; + +} // namespae detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp new file mode 100644 index 00000000000..c379108d584 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp @@ -0,0 +1,94 @@ +#ifndef BOOST_ARCHIVE_BASIC_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oarchive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include +#include +#include + +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_oarchive_impl; +class basic_oserializer; +class basic_pointer_oserializer; + +////////////////////////////////////////////////////////////////////// +// class basic_oarchive - write serialized objects to an output stream +class BOOST_SYMBOL_VISIBLE basic_oarchive : + private boost::noncopyable, + public boost::archive::detail::helper_collection +{ + friend class basic_oarchive_impl; + // hide implementation of this class to minimize header conclusion + boost::scoped_ptr pimpl; + + // overload these to bracket object attributes. Used to implement + // xml archives + virtual void vsave(const version_type t) = 0; + virtual void vsave(const object_id_type t) = 0; + virtual void vsave(const object_reference_type t) = 0; + virtual void vsave(const class_id_type t) = 0; + virtual void vsave(const class_id_optional_type t) = 0; + virtual void vsave(const class_id_reference_type t) = 0; + virtual void vsave(const class_name_type & t) = 0; + virtual void vsave(const tracking_type t) = 0; +protected: + BOOST_ARCHIVE_DECL basic_oarchive(unsigned int flags = 0); + BOOST_ARCHIVE_DECL boost::archive::detail::helper_collection & + get_helper_collection(); + virtual BOOST_ARCHIVE_DECL ~basic_oarchive(); +public: + // note: NOT part of the public interface + BOOST_ARCHIVE_DECL void register_basic_serializer( + const basic_oserializer & bos + ); + BOOST_ARCHIVE_DECL void save_object( + const void *x, + const basic_oserializer & bos + ); + BOOST_ARCHIVE_DECL void save_pointer( + const void * t, + const basic_pointer_oserializer * bpos_ptr + ); + void save_null_pointer(){ + vsave(NULL_POINTER_TAG); + } + // real public interface starts here + BOOST_ARCHIVE_DECL void end_preamble(); // default implementation does nothing + BOOST_ARCHIVE_DECL library_version_type get_library_version() const; + BOOST_ARCHIVE_DECL unsigned int get_flags() const; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_BASIC_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp new file mode 100644 index 00000000000..94247e90056 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp @@ -0,0 +1,89 @@ +#ifndef BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP +#define BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oserializer.hpp: extenstion of type_info required for serialization. + +// (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 // NULL +#include +#include + +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class basic_oarchive; +class basic_pointer_oserializer; + +class BOOST_SYMBOL_VISIBLE basic_oserializer : + public basic_serializer +{ +private: + basic_pointer_oserializer *m_bpos; +protected: + explicit BOOST_ARCHIVE_DECL basic_oserializer( + const boost::serialization::extended_type_info & type_ + ); + virtual BOOST_ARCHIVE_DECL ~basic_oserializer(); +public: + bool serialized_as_pointer() const { + return m_bpos != NULL; + } + void set_bpos(basic_pointer_oserializer *bpos){ + m_bpos = bpos; + } + const basic_pointer_oserializer * get_bpos() const { + return m_bpos; + } + virtual void save_object_data( + basic_oarchive & ar, const void * x + ) const = 0; + // returns true if class_info should be saved + virtual bool class_info() const = 0; + // returns true if objects should be tracked + virtual bool tracking(const unsigned int flags) const = 0; + // returns class version + virtual version_type version() const = 0; + // returns true if this class is polymorphic + virtual bool is_polymorphic() const = 0; +}; + +} // namespace detail +} // namespace serialization +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp new file mode 100644 index 00000000000..1fc4b14d6e9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp @@ -0,0 +1,70 @@ +#ifndef BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_oserializer.hpp: extenstion of type_info required for +// serialization. + +// (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 +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class basic_iarchive; +class basic_iserializer; + +class BOOST_SYMBOL_VISIBLE basic_pointer_iserializer + : public basic_serializer { +protected: + explicit BOOST_ARCHIVE_DECL basic_pointer_iserializer( + const boost::serialization::extended_type_info & type_ + ); + virtual BOOST_ARCHIVE_DECL ~basic_pointer_iserializer(); +public: + virtual void * heap_allocation() const = 0; + virtual const basic_iserializer & get_basic_serializer() const = 0; + virtual void load_object_ptr( + basic_iarchive & ar, + void * x, + const unsigned int file_version + ) const = 0; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp new file mode 100644 index 00000000000..1a5d9549eab --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_oserializer.hpp: extenstion of type_info required for +// serialization. + +// (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 +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_oarchive; +class basic_oserializer; + +class BOOST_SYMBOL_VISIBLE basic_pointer_oserializer : + public basic_serializer +{ +protected: + explicit BOOST_ARCHIVE_DECL basic_pointer_oserializer( + const boost::serialization::extended_type_info & type_ + ); +public: + virtual BOOST_ARCHIVE_DECL ~basic_pointer_oserializer(); + virtual const basic_oserializer & get_basic_serializer() const = 0; + virtual void save_object_ptr( + basic_oarchive & ar, + const void * x + ) const = 0; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp new file mode 100644 index 00000000000..f9c4203f862 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp @@ -0,0 +1,77 @@ +#ifndef BOOST_ARCHIVE_BASIC_SERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_SERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_serializer.hpp: extenstion of type_info required for serialization. + +// (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 +#include // NULL + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { +namespace detail { + +class basic_serializer : + private boost::noncopyable +{ + const boost::serialization::extended_type_info * m_eti; +protected: + explicit basic_serializer( + const boost::serialization::extended_type_info & eti + ) : + m_eti(& eti) + {} +public: + inline bool + operator<(const basic_serializer & rhs) const { + // can't compare address since there can be multiple eti records + // for the same type in different execution modules (that is, DLLS) + // leave this here as a reminder not to do this! + // return & lhs.get_eti() < & rhs.get_eti(); + return get_eti() < rhs.get_eti(); + } + const char * get_debug_info() const { + return m_eti->get_debug_info(); + } + const boost::serialization::extended_type_info & get_eti() const { + return * m_eti; + } +}; + +class basic_serializer_arg : public basic_serializer { +public: + basic_serializer_arg(const serialization::extended_type_info & eti) : + basic_serializer(eti) + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BASIC_SERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp new file mode 100644 index 00000000000..79341803367 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_SERIALIZER_MAP_HPP +#define BOOST_SERIALIZER_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_serializer_map.hpp: extenstion of type_info required for serialization. + +// (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 + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} + +namespace archive { +namespace detail { + +class basic_serializer; + +class BOOST_SYMBOL_VISIBLE +basic_serializer_map : public + boost::noncopyable +{ + struct type_info_pointer_compare + { + bool operator()( + const basic_serializer * lhs, const basic_serializer * rhs + ) const ; + }; + typedef std::set< + const basic_serializer *, + type_info_pointer_compare + > map_type; + map_type m_map; +public: + BOOST_ARCHIVE_DECL bool insert(const basic_serializer * bs); + BOOST_ARCHIVE_DECL void erase(const basic_serializer * bs); + BOOST_ARCHIVE_DECL const basic_serializer * find( + const boost::serialization::extended_type_info & type_ + ) const; +private: + // cw 8.3 requires this + basic_serializer_map& operator=(basic_serializer_map const&); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // must be the last header + +#endif // BOOST_SERIALIZER_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp new file mode 100644 index 00000000000..10034e7d101 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp @@ -0,0 +1,169 @@ +#ifndef BOOST_ARCHIVE_DETAIL_CHECK_HPP +#define BOOST_ARCHIVE_DETAIL_CHECK_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// check.hpp: interface for serialization system. + +// (C) Copyright 2009 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 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +// checks for objects + +template +inline void check_object_level(){ + typedef + typename mpl::greater_equal< + serialization::implementation_level< T >, + mpl::int_ + >::type typex; + + // trap attempts to serialize objects marked + // not_serializable + BOOST_STATIC_ASSERT(typex::value); +} + +template +inline void check_object_versioning(){ + typedef + typename mpl::or_< + typename mpl::greater< + serialization::implementation_level< T >, + mpl::int_ + >, + typename mpl::equal_to< + serialization::version< T >, + mpl::int_<0> + > + > typex; + // trap attempts to serialize with objects that don't + // save class information in the archive with versioning. + BOOST_STATIC_ASSERT(typex::value); +} + +template +inline void check_object_tracking(){ + // presume it has already been determined that + // T is not a const + BOOST_STATIC_ASSERT(! boost::is_const< T >::value); + typedef typename mpl::equal_to< + serialization::tracking_level< T >, + mpl::int_ + >::type typex; + // saving an non-const object of a type not marked "track_never) + + // may be an indicator of an error usage of the + // serialization library and should be double checked. + // See documentation on object tracking. Also, see the + // "rationale" section of the documenation + // for motivation for this checking. + + BOOST_STATIC_WARNING(typex::value); +} + +// checks for pointers + +template +inline void check_pointer_level(){ + // we should only invoke this once we KNOW that T + // has been used as a pointer!! + typedef + typename mpl::or_< + typename mpl::greater< + serialization::implementation_level< T >, + mpl::int_ + >, + typename mpl::not_< + typename mpl::equal_to< + serialization::tracking_level< T >, + mpl::int_ + > + > + > typex; + // Address the following when serializing to a pointer: + + // a) This type doesn't save class information in the + // archive. That is, the serialization trait implementation + // level <= object_serializable. + // b) Tracking for this type is set to "track selectively" + + // in this case, indication that an object is tracked is + // not stored in the archive itself - see level == object_serializable + // but rather the existence of the operation ar >> T * is used to + // infer that an object of this type should be tracked. So, if + // you save via a pointer but don't load via a pointer the operation + // will fail on load without given any valid reason for the failure. + + // So if your program traps here, consider changing the + // tracking or implementation level traits - or not + // serializing via a pointer. + BOOST_STATIC_WARNING(typex::value); +} + +template +void inline check_pointer_tracking(){ + typedef typename mpl::greater< + serialization::tracking_level< T >, + mpl::int_ + >::type typex; + // serializing an object of a type marked "track_never" through a pointer + // could result in creating more objects than were saved! + BOOST_STATIC_WARNING(typex::value); +} + +template +inline void check_const_loading(){ + typedef + typename mpl::or_< + typename boost::serialization::is_wrapper< T >, + typename mpl::not_< + typename boost::is_const< T > + > + >::type typex; + // cannot load data into a "const" object unless it's a + // wrapper around some other non-const object. + BOOST_STATIC_ASSERT(typex::value); +} + +} // detail +} // archive +} // boost + +#endif // BOOST_ARCHIVE_DETAIL_CHECK_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp new file mode 100644 index 00000000000..82304f1e5ac --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp @@ -0,0 +1,88 @@ +#ifndef BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// common_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { +namespace detail { + +class extended_type_info; + +// note: referred to as Curiously Recurring Template Patter (CRTP) +template +class BOOST_SYMBOL_VISIBLE common_iarchive : + public basic_iarchive, + public interface_iarchive +{ + friend class interface_iarchive; +private: + virtual void vload(version_type & t){ + * this->This() >> t; + } + virtual void vload(object_id_type & t){ + * this->This() >> t; + } + virtual void vload(class_id_type & t){ + * this->This() >> t; + } + virtual void vload(class_id_optional_type & t){ + * this->This() >> t; + } + virtual void vload(tracking_type & t){ + * this->This() >> t; + } + virtual void vload(class_name_type &s){ + * this->This() >> s; + } +protected: + // default processing - invoke serialization library + template + void load_override(T & t){ + archive::load(* this->This(), t); + } + // default implementations of functions which emit start/end tags for + // archive types that require them. + void load_start(const char * /*name*/){} + void load_end(const char * /*name*/){} + // default archive initialization + common_iarchive(unsigned int flags = 0) : + basic_iarchive(flags), + interface_iarchive() + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp new file mode 100644 index 00000000000..ee42bbe5976 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp @@ -0,0 +1,88 @@ +#ifndef BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// common_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { +namespace detail { + +// note: referred to as Curiously Recurring Template Patter (CRTP) +template + +class BOOST_SYMBOL_VISIBLE common_oarchive : + public basic_oarchive, + public interface_oarchive +{ + friend class interface_oarchive; +private: + virtual void vsave(const version_type t){ + * this->This() << t; + } + virtual void vsave(const object_id_type t){ + * this->This() << t; + } + virtual void vsave(const object_reference_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_reference_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_optional_type t){ + * this->This() << t; + } + virtual void vsave(const class_name_type & t){ + * this->This() << t; + } + virtual void vsave(const tracking_type t){ + * this->This() << t; + } +protected: + // default processing - invoke serialization library + template + void save_override(T & t){ + archive::save(* this->This(), t); + } + void save_start(const char * /*name*/){} + void save_end(const char * /*name*/){} + common_oarchive(unsigned int flags = 0) : + basic_oarchive(flags), + interface_oarchive() + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp new file mode 100644 index 00000000000..4f731cded37 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp @@ -0,0 +1,57 @@ +#ifndef BOOST_ARCHIVE_DETAIL_DECL_HPP +#define BOOST_ARCHIVE_DETAIL_DECL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 + +#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)) + #if defined(BOOST_ARCHIVE_SOURCE) + #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_EXPORT + #else + #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_IMPORT + #endif + + #if defined(BOOST_WARCHIVE_SOURCE) + #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_EXPORT + #else + #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_IMPORT + #endif + + #if defined(BOOST_WARCHIVE_SOURCE) || defined(BOOST_ARCHIVE_SOURCE) + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_EXPORT + #else + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_IMPORT + #endif + +#endif + +#if ! defined(BOOST_ARCHIVE_DECL) + #define BOOST_ARCHIVE_DECL +#endif +#if ! defined(BOOST_WARCHIVE_DECL) + #define BOOST_WARCHIVE_DECL +#endif +#if ! defined(BOOST_ARCHIVE_OR_WARCHIVE_DECL) + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL +#endif + +#endif // BOOST_ARCHIVE_DETAIL_DECL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp new file mode 100644 index 00000000000..edb4125e308 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp @@ -0,0 +1,99 @@ +#ifndef BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP +#define BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_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 +// helper_collection.hpp: archive support for run-time helpers + +// (C) Copyright 2002-2008 Robert Ramey and Joaquin M Lopez Munoz +// 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 // NULL +#include +#include +#include +#include + +#include + +#include +#include + +namespace boost { + +namespace archive { +namespace detail { + +class helper_collection +{ + helper_collection(const helper_collection&); // non-copyable + helper_collection& operator = (const helper_collection&); // non-copyable + + // note: we dont' actually "share" the function object pointer + // we only use shared_ptr to make sure that it get's deleted + + typedef std::pair< + const void *, + boost::shared_ptr + > helper_value_type; + template + boost::shared_ptr make_helper_ptr(){ + // use boost::shared_ptr rather than std::shared_ptr to maintain + // c++03 compatibility + return boost::make_shared(); + } + + typedef std::vector collection; + collection m_collection; + + struct predicate { + BOOST_DELETED_FUNCTION(predicate & operator=(const predicate & rhs)) + public: + const void * const m_ti; + bool operator()(helper_value_type const &rhs) const { + return m_ti == rhs.first; + } + predicate(const void * ti) : + m_ti(ti) + {} + }; +protected: + helper_collection(){} + ~helper_collection(){} +public: + template + Helper& find_helper(void * const id = 0) { + collection::const_iterator it = + std::find_if( + m_collection.begin(), + m_collection.end(), + predicate(id) + ); + + void * rval = 0; + if(it == m_collection.end()){ + m_collection.push_back( + std::make_pair(id, make_helper_ptr()) + ); + rval = m_collection.back().second.get(); + } + else{ + rval = it->second.get(); + } + return *static_cast(rval); + } +}; + +} // namespace detail +} // namespace serialization +} // namespace boost + +#endif // BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp new file mode 100644 index 00000000000..4a99e28b59f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// interface_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include // NULL +#include +#include +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { +namespace detail { + +class basic_pointer_iserializer; + +template +class interface_iarchive +{ +protected: + interface_iarchive(){}; +public: + ///////////////////////////////////////////////////////// + // archive public interface + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + template + const basic_pointer_iserializer * + register_type(T * = NULL){ + const basic_pointer_iserializer & bpis = + boost::serialization::singleton< + pointer_iserializer + >::get_const_instance(); + this->This()->register_basic_serializer(bpis.get_basic_serializer()); + return & bpis; + } + template + Helper & + get_helper(void * const id = 0){ + helper_collection & hc = this->This()->get_helper_collection(); + return hc.template find_helper(id); + } + + template + Archive & operator>>(T & t){ + this->This()->load_override(t); + return * this->This(); + } + + // the & operator + template + Archive & operator&(T & t){ + return *(this->This()) >> t; + } +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp new file mode 100644 index 00000000000..359463ed9d8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// interface_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include // NULL +#include +#include + +#include +#include +#include // must be the last header + +#include + +namespace boost { +namespace archive { +namespace detail { + +class basic_pointer_oserializer; + +template +class interface_oarchive +{ +protected: + interface_oarchive(){}; +public: + ///////////////////////////////////////////////////////// + // archive public interface + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + template + const basic_pointer_oserializer * + register_type(const T * = NULL){ + const basic_pointer_oserializer & bpos = + boost::serialization::singleton< + pointer_oserializer + >::get_const_instance(); + this->This()->register_basic_serializer(bpos.get_basic_serializer()); + return & bpos; + } + + template + Helper & + get_helper(void * const id = 0){ + helper_collection & hc = this->This()->get_helper_collection(); + return hc.template find_helper(id); + } + + template + Archive & operator<<(const T & t){ + this->This()->save_override(t); + return * this->This(); + } + + // the & operator + template + Archive & operator&(const T & t){ + return * this ->This() << t; + } +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp new file mode 100644 index 00000000000..193e98a82e4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp @@ -0,0 +1,631 @@ +#ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP +#define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// iserializer.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 // for placement new +#include // size_t, NULL + +#include +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include +#include +#include +#include +#include + +#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #include +#endif +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifndef BOOST_MSVC + #define DONT_USE_HAS_NEW_OPERATOR ( \ + BOOST_WORKAROUND(__IBMCPP__, < 1210) \ + || defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \ + ) +#else + #define DONT_USE_HAS_NEW_OPERATOR 0 +#endif + +#if ! DONT_USE_HAS_NEW_OPERATOR +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// the following is need only for dynamic cast of polymorphic pointers +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { + +// an accessor to permit friend access to archives. Needed because +// some compilers don't handle friend templates completely +class load_access { +public: + template + static void load_primitive(Archive &ar, T &t){ + ar.load(t); + } +}; + +namespace detail { + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class iserializer : public basic_iserializer +{ +private: + virtual void destroy(/*const*/ void *address) const { + boost::serialization::access::destroy(static_cast(address)); + } +protected: + // protected constructor since it's always created by singleton + explicit iserializer() : + basic_iserializer( + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance() + ) + {} +public: + virtual BOOST_DLLEXPORT void load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version + ) const BOOST_USED; + virtual bool class_info() const { + return boost::serialization::implementation_level< T >::value + >= boost::serialization::object_class_info; + } + virtual bool tracking(const unsigned int /* flags */) const { + return boost::serialization::tracking_level< T >::value + == boost::serialization::track_always + || ( boost::serialization::tracking_level< T >::value + == boost::serialization::track_selectively + && serialized_as_pointer()); + } + virtual version_type version() const { + return version_type(::boost::serialization::version< T >::value); + } + virtual bool is_polymorphic() const { + return boost::is_polymorphic< T >::value; + } + virtual ~iserializer(){}; +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +template +BOOST_DLLEXPORT void iserializer::load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version +) const { + // note: we now comment this out. Before we permited archive + // version # to be very large. Now we don't. To permit + // readers of these old archives, we have to suppress this + // code. Perhaps in the future we might re-enable it but + // permit its suppression with a runtime switch. + #if 0 + // trap case where the program cannot handle the current version + if(file_version > static_cast(version())) + boost::serialization::throw_exception( + archive::archive_exception( + boost::archive::archive_exception::unsupported_class_version, + get_debug_info() + ) + ); + #endif + // make sure call is routed through the higest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + boost::serialization::smart_cast_reference(ar), + * static_cast(x), + file_version + ); +} + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +// the purpose of this code is to allocate memory for an object +// without requiring the constructor to be called. Presumably +// the allocated object will be subsequently initialized with +// "placement new". +// note: we have the boost type trait has_new_operator but we +// have no corresponding has_delete_operator. So we presume +// that the former being true would imply that the a delete +// operator is also defined for the class T. + +template +struct heap_allocation { + // boost::has_new_operator< T > doesn't work on these compilers + #if DONT_USE_HAS_NEW_OPERATOR + // This doesn't handle operator new overload for class T + static T * invoke_new(){ + return static_cast(operator new(sizeof(T))); + } + static void invoke_delete(T *t){ + (operator delete(t)); + } + #else + // note: we presume that a true value for has_new_operator + // implies the existence of a class specific delete operator as well + // as a class specific new operator. + struct has_new_operator { + static T * invoke_new() { + return static_cast((T::operator new)(sizeof(T))); + } + static void invoke_delete(T * t) { + // if compilation fails here, the likely cause that the class + // T has a class specific new operator but no class specific + // delete operator which matches the following signature. + // note that this solution addresses the issue that two + // possible signatures. But it doesn't address the possibility + // that the class might have class specific new with NO + // class specific delete at all. Patches (compatible with + // C++03) welcome! + delete t; + } + }; + struct doesnt_have_new_operator { + static T* invoke_new() { + return static_cast(operator new(sizeof(T))); + } + static void invoke_delete(T * t) { + // Note: I'm reliance upon automatic conversion from T * to void * here + delete t; + } + }; + static T * invoke_new() { + typedef typename + mpl::eval_if< + boost::has_new_operator< T >, + mpl::identity, + mpl::identity + >::type typex; + return typex::invoke_new(); + } + static void invoke_delete(T *t) { + typedef typename + mpl::eval_if< + boost::has_new_operator< T >, + mpl::identity, + mpl::identity + >::type typex; + typex::invoke_delete(t); + } + #endif + explicit heap_allocation(){ + m_p = invoke_new(); + } + ~heap_allocation(){ + if (0 != m_p) + invoke_delete(m_p); + } + T* get() const { + return m_p; + } + + T* release() { + T* p = m_p; + m_p = 0; + return p; + } +private: + T* m_p; +}; + +template +class pointer_iserializer : + public basic_pointer_iserializer +{ +private: + virtual void * heap_allocation() const { + detail::heap_allocation h; + T * t = h.get(); + h.release(); + return t; + } + virtual const basic_iserializer & get_basic_serializer() const { + return boost::serialization::singleton< + iserializer + >::get_const_instance(); + } + BOOST_DLLEXPORT virtual void load_object_ptr( + basic_iarchive & ar, + void * x, + const unsigned int file_version + ) const BOOST_USED; +protected: + // this should alway be a singleton so make the constructor protected + pointer_iserializer(); + ~pointer_iserializer(); +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +// note: BOOST_DLLEXPORT is so that code for polymorphic class +// serialized only through base class won't get optimized out +template +BOOST_DLLEXPORT void pointer_iserializer::load_object_ptr( + basic_iarchive & ar, + void * t, + const unsigned int file_version +) const +{ + Archive & ar_impl = + boost::serialization::smart_cast_reference(ar); + + // note that the above will throw std::bad_alloc if the allocation + // fails so we don't have to address this contingency here. + + // catch exception during load_construct_data so that we don't + // automatically delete the t which is most likely not fully + // constructed + BOOST_TRY { + // this addresses an obscure situation that occurs when + // load_constructor de-serializes something through a pointer. + ar.next_object_pointer(t); + boost::serialization::load_construct_data_adl( + ar_impl, + static_cast(t), + file_version + ); + } + BOOST_CATCH(...){ + // if we get here the load_construct failed. The heap_allocation + // will be automatically deleted so we don't have to do anything + // special here. + BOOST_RETHROW; + } + BOOST_CATCH_END + + ar_impl >> boost::serialization::make_nvp(NULL, * static_cast(t)); +} + +template +pointer_iserializer::pointer_iserializer() : + basic_pointer_iserializer( + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance() + ) +{ + boost::serialization::singleton< + iserializer + >::get_mutable_instance().set_bpis(this); + archive_serializer_map::insert(this); +} + +template +pointer_iserializer::~pointer_iserializer(){ + archive_serializer_map::erase(this); +} + +template +struct load_non_pointer_type { + // note this bounces the call right back to the archive + // with no runtime overhead + struct load_primitive { + template + static void invoke(Archive & ar, T & t){ + load_access::load_primitive(ar, t); + } + }; + // note this bounces the call right back to the archive + // with no runtime overhead + struct load_only { + template + static void invoke(Archive & ar, const T & t){ + // short cut to user's serializer + // make sure call is routed through the higest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + ar, + const_cast(t), + boost::serialization::version< T >::value + ); + } + }; + + // note this save class information including version + // and serialization level to the archive + struct load_standard { + template + static void invoke(Archive &ar, const T & t){ + void * x = & const_cast(t); + ar.load_object( + x, + boost::serialization::singleton< + iserializer + >::get_const_instance() + ); + } + }; + + struct load_conditional { + template + static void invoke(Archive &ar, T &t){ + //if(0 == (ar.get_flags() & no_tracking)) + load_standard::invoke(ar, t); + //else + // load_only::invoke(ar, t); + } + }; + + template + static void invoke(Archive & ar, T &t){ + typedef typename mpl::eval_if< + // if its primitive + mpl::equal_to< + boost::serialization::implementation_level< T >, + mpl::int_ + >, + mpl::identity, + // else + typename mpl::eval_if< + // class info / version + mpl::greater_equal< + boost::serialization::implementation_level< T >, + mpl::int_ + >, + // do standard load + mpl::identity, + // else + typename mpl::eval_if< + // no tracking + mpl::equal_to< + boost::serialization::tracking_level< T >, + mpl::int_ + >, + // do a fast load + mpl::identity, + // else + // do a fast load only tracking is turned off + mpl::identity + > > >::type typex; + check_object_versioning< T >(); + check_object_level< T >(); + typex::invoke(ar, t); + } +}; + +template +struct load_pointer_type { + struct abstract + { + template + static const basic_pointer_iserializer * register_type(Archive & /* ar */){ + // it has? to be polymorphic + BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value); + return static_cast(NULL); + } + }; + + struct non_abstract + { + template + static const basic_pointer_iserializer * register_type(Archive & ar){ + return ar.register_type(static_cast(NULL)); + } + }; + + template + static const basic_pointer_iserializer * register_type(Archive &ar, const T & /*t*/){ + // there should never be any need to load an abstract polymorphic + // class pointer. Inhibiting code generation for this + // permits abstract base classes to be used - note: exception + // virtual serialize functions used for plug-ins + typedef typename + mpl::eval_if< + boost::serialization::is_abstract, + boost::mpl::identity, + boost::mpl::identity + >::type typex; + return typex::template register_type< T >(ar); + } + + template + static T * pointer_tweak( + const boost::serialization::extended_type_info & eti, + void const * const t, + const T & + ) { + // tweak the pointer back to the base class + void * upcast = const_cast( + boost::serialization::void_upcast( + eti, + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance(), + t + ) + ); + if(NULL == upcast) + boost::serialization::throw_exception( + archive_exception(archive_exception::unregistered_class) + ); + return static_cast(upcast); + } + + template + static void check_load(T & /* t */){ + check_pointer_level< T >(); + check_pointer_tracking< T >(); + } + + static const basic_pointer_iserializer * + find(const boost::serialization::extended_type_info & type){ + return static_cast( + archive_serializer_map::find(type) + ); + } + + template + static void invoke(Archive & ar, Tptr & t){ + check_load(*t); + const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t); + const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer( + // note major hack here !!! + // I tried every way to convert Tptr &t (where Tptr might + // include const) to void * &. This is the only way + // I could make it work. RR + (void * & )t, + bpis_ptr, + find + ); + // if the pointer isn't that of the base class + if(newbpis_ptr != bpis_ptr){ + t = pointer_tweak(newbpis_ptr->get_eti(), t, *t); + } + } +}; + +template +struct load_enum_type { + template + static void invoke(Archive &ar, T &t){ + // convert integers to correct enum to load + int i; + ar >> boost::serialization::make_nvp(NULL, i); + t = static_cast< T >(i); + } +}; + +template +struct load_array_type { + template + static void invoke(Archive &ar, T &t){ + typedef typename remove_extent< T >::type value_type; + + // convert integers to correct enum to load + // determine number of elements in the array. Consider the + // fact that some machines will align elements on boundries + // other than characters. + std::size_t current_count = sizeof(t) / ( + static_cast(static_cast(&t[1])) + - static_cast(static_cast(&t[0])) + ); + boost::serialization::collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(static_cast(count) > current_count) + boost::serialization::throw_exception( + archive::archive_exception( + boost::archive::archive_exception::array_size_too_short + ) + ); + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array< + value_type, + boost::serialization::collection_size_type + >( + static_cast(&t[0]), + count + ); + } +}; + +} // detail + +template +inline void load(Archive & ar, T &t){ + // if this assertion trips. It means we're trying to load a + // const object with a compiler that doesn't have correct + // function template ordering. On other compilers, this is + // handled below. + detail::check_const_loading< T >(); + typedef + typename mpl::eval_if, + mpl::identity > + ,//else + typename mpl::eval_if, + mpl::identity > + ,//else + typename mpl::eval_if, + mpl::identity > + ,//else + mpl::identity > + > + > + >::type typex; + typex::invoke(ar, t); +} + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp new file mode 100644 index 00000000000..c120ec55073 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp @@ -0,0 +1,540 @@ +#ifndef BOOST_ARCHIVE_OSERIALIZER_HPP +#define BOOST_ARCHIVE_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// oserializer.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 +#include // NULL + +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #include +#endif +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { + +// an accessor to permit friend access to archives. Needed because +// some compilers don't handle friend templates completely +class save_access { +public: + template + static void end_preamble(Archive & ar){ + ar.end_preamble(); + } + template + static void save_primitive(Archive & ar, const T & t){ + ar.end_preamble(); + ar.save(t); + } +}; + +namespace detail { + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class oserializer : public basic_oserializer +{ +private: + // private constructor to inhibit any existence other than the + // static one +public: + explicit BOOST_DLLEXPORT oserializer() : + basic_oserializer( + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance() + ) + {} + virtual BOOST_DLLEXPORT void save_object_data( + basic_oarchive & ar, + const void *x + ) const BOOST_USED; + virtual bool class_info() const { + return boost::serialization::implementation_level< T >::value + >= boost::serialization::object_class_info; + } + virtual bool tracking(const unsigned int /* flags */) const { + return boost::serialization::tracking_level< T >::value == boost::serialization::track_always + || (boost::serialization::tracking_level< T >::value == boost::serialization::track_selectively + && serialized_as_pointer()); + } + virtual version_type version() const { + return version_type(::boost::serialization::version< T >::value); + } + virtual bool is_polymorphic() const { + return boost::is_polymorphic< T >::value; + } + virtual ~oserializer(){} +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +template +BOOST_DLLEXPORT void oserializer::save_object_data( + basic_oarchive & ar, + const void *x +) const { + // make sure call is routed through the highest interface that might + // be specialized by the user. + BOOST_STATIC_ASSERT(boost::is_const< T >::value == false); + boost::serialization::serialize_adl( + boost::serialization::smart_cast_reference(ar), + * static_cast(const_cast(x)), + version() + ); +} + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class pointer_oserializer : + public basic_pointer_oserializer +{ +private: + const basic_oserializer & + get_basic_serializer() const { + return boost::serialization::singleton< + oserializer + >::get_const_instance(); + } + virtual BOOST_DLLEXPORT void save_object_ptr( + basic_oarchive & ar, + const void * x + ) const BOOST_USED; +public: + pointer_oserializer(); + ~pointer_oserializer(); +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +template +BOOST_DLLEXPORT void pointer_oserializer::save_object_ptr( + basic_oarchive & ar, + const void * x +) const { + BOOST_ASSERT(NULL != x); + // make sure call is routed through the highest interface that might + // be specialized by the user. + T * t = static_cast(const_cast(x)); + const unsigned int file_version = boost::serialization::version< T >::value; + Archive & ar_impl + = boost::serialization::smart_cast_reference(ar); + boost::serialization::save_construct_data_adl( + ar_impl, + t, + file_version + ); + ar_impl << boost::serialization::make_nvp(NULL, * t); +} + +template +pointer_oserializer::pointer_oserializer() : + basic_pointer_oserializer( + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance() + ) +{ + // make sure appropriate member function is instantiated + boost::serialization::singleton< + oserializer + >::get_mutable_instance().set_bpos(this); + archive_serializer_map::insert(this); +} + +template +pointer_oserializer::~pointer_oserializer(){ + archive_serializer_map::erase(this); +} + +template +struct save_non_pointer_type { + // note this bounces the call right back to the archive + // with no runtime overhead + struct save_primitive { + template + static void invoke(Archive & ar, const T & t){ + save_access::save_primitive(ar, t); + } + }; + // same as above but passes through serialization + struct save_only { + template + static void invoke(Archive & ar, const T & t){ + // make sure call is routed through the highest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + ar, + const_cast(t), + ::boost::serialization::version< T >::value + ); + } + }; + // adds class information to the archive. This includes + // serialization level and class version + struct save_standard { + template + static void invoke(Archive &ar, const T & t){ + ar.save_object( + & t, + boost::serialization::singleton< + oserializer + >::get_const_instance() + ); + } + }; + + // adds class information to the archive. This includes + // serialization level and class version + struct save_conditional { + template + static void invoke(Archive &ar, const T &t){ + //if(0 == (ar.get_flags() & no_tracking)) + save_standard::invoke(ar, t); + //else + // save_only::invoke(ar, t); + } + }; + + + template + static void invoke(Archive & ar, const T & t){ + typedef + typename mpl::eval_if< + // if its primitive + mpl::equal_to< + boost::serialization::implementation_level< T >, + mpl::int_ + >, + mpl::identity, + // else + typename mpl::eval_if< + // class info / version + mpl::greater_equal< + boost::serialization::implementation_level< T >, + mpl::int_ + >, + // do standard save + mpl::identity, + // else + typename mpl::eval_if< + // no tracking + mpl::equal_to< + boost::serialization::tracking_level< T >, + mpl::int_ + >, + // do a fast save + mpl::identity, + // else + // do a fast save only tracking is turned off + mpl::identity + > > >::type typex; + check_object_versioning< T >(); + typex::invoke(ar, t); + } + template + static void invoke(Archive & ar, T & t){ + check_object_level< T >(); + check_object_tracking< T >(); + invoke(ar, const_cast(t)); + } +}; + +template +struct save_pointer_type { + struct abstract + { + template + static const basic_pointer_oserializer * register_type(Archive & /* ar */){ + // it has? to be polymorphic + BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value); + return NULL; + } + }; + + struct non_abstract + { + template + static const basic_pointer_oserializer * register_type(Archive & ar){ + return ar.register_type(static_cast(NULL)); + } + }; + + template + static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){ + // there should never be any need to save an abstract polymorphic + // class pointer. Inhibiting code generation for this + // permits abstract base classes to be used - note: exception + // virtual serialize functions used for plug-ins + typedef + typename mpl::eval_if< + boost::serialization::is_abstract< T >, + mpl::identity, + mpl::identity + >::type typex; + return typex::template register_type< T >(ar); + } + + struct non_polymorphic + { + template + static void save( + Archive &ar, + T & t + ){ + const basic_pointer_oserializer & bpos = + boost::serialization::singleton< + pointer_oserializer + >::get_const_instance(); + // save the requested pointer type + ar.save_pointer(& t, & bpos); + } + }; + + struct polymorphic + { + template + static void save( + Archive &ar, + T & t + ){ + typename + boost::serialization::type_info_implementation< T >::type const + & i = boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance(); + + boost::serialization::extended_type_info const * const this_type = & i; + + // retrieve the true type of the object pointed to + // if this assertion fails its an error in this library + BOOST_ASSERT(NULL != this_type); + + const boost::serialization::extended_type_info * true_type = + i.get_derived_extended_type_info(t); + + // note:if this exception is thrown, be sure that derived pointer + // is either registered or exported. + if(NULL == true_type){ + boost::serialization::throw_exception( + archive_exception( + archive_exception::unregistered_class, + "derived class not registered or exported" + ) + ); + } + + // if its not a pointer to a more derived type + const void *vp = static_cast(&t); + if(*this_type == *true_type){ + const basic_pointer_oserializer * bpos = register_type(ar, t); + ar.save_pointer(vp, bpos); + return; + } + // convert pointer to more derived type. if this is thrown + // it means that the base/derived relationship hasn't be registered + vp = serialization::void_downcast( + *true_type, + *this_type, + static_cast(&t) + ); + if(NULL == vp){ + boost::serialization::throw_exception( + archive_exception( + archive_exception::unregistered_cast, + true_type->get_debug_info(), + this_type->get_debug_info() + ) + ); + } + + // since true_type is valid, and this only gets made if the + // pointer oserializer object has been created, this should never + // fail + const basic_pointer_oserializer * bpos + = static_cast( + boost::serialization::singleton< + archive_serializer_map + >::get_const_instance().find(*true_type) + ); + BOOST_ASSERT(NULL != bpos); + if(NULL == bpos) + boost::serialization::throw_exception( + archive_exception( + archive_exception::unregistered_class, + "derived class not registered or exported" + ) + ); + ar.save_pointer(vp, bpos); + } + }; + + template + static void save( + Archive & ar, + const T & t + ){ + check_pointer_level< T >(); + check_pointer_tracking< T >(); + typedef typename mpl::eval_if< + is_polymorphic< T >, + mpl::identity, + mpl::identity + >::type type; + type::save(ar, const_cast(t)); + } + + template + static void invoke(Archive &ar, const TPtr t){ + register_type(ar, * t); + if(NULL == t){ + basic_oarchive & boa + = boost::serialization::smart_cast_reference(ar); + boa.save_null_pointer(); + save_access::end_preamble(ar); + return; + } + save(ar, * t); + } +}; + +template +struct save_enum_type +{ + template + static void invoke(Archive &ar, const T &t){ + // convert enum to integers on save + const int i = static_cast(t); + ar << boost::serialization::make_nvp(NULL, i); + } +}; + +template +struct save_array_type +{ + template + static void invoke(Archive &ar, const T &t){ + typedef typename boost::remove_extent< T >::type value_type; + + save_access::end_preamble(ar); + // consider alignment + std::size_t c = sizeof(t) / ( + static_cast(static_cast(&t[1])) + - static_cast(static_cast(&t[0])) + ); + boost::serialization::collection_size_type count(c); + ar << BOOST_SERIALIZATION_NVP(count); + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array< + const value_type, + boost::serialization::collection_size_type + >( + static_cast(&t[0]), + count + ); + } +}; + +} // detail + +template +inline void save(Archive & ar, /*const*/ T &t){ + typedef + typename mpl::eval_if, + mpl::identity >, + //else + typename mpl::eval_if, + mpl::identity >, + //else + typename mpl::eval_if, + mpl::identity >, + //else + mpl::identity > + > + > + >::type typex; + typex::invoke(ar, t); +} + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp new file mode 100644 index 00000000000..105685ebbd8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp @@ -0,0 +1,218 @@ +#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP +#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_iarchive_route.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail{ + +class basic_iserializer; +class basic_pointer_iserializer; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class polymorphic_iarchive_route : + public polymorphic_iarchive, + // note: gcc dynamic cross cast fails if the the derivation below is + // not public. I think this is a mistake. + public /*protected*/ ArchiveImplementation +{ +private: + // these are used by the serialization library. + virtual void load_object( + void *t, + const basic_iserializer & bis + ){ + ArchiveImplementation::load_object(t, bis); + } + virtual const basic_pointer_iserializer * load_pointer( + void * & t, + const basic_pointer_iserializer * bpis_ptr, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type + ) + ){ + return ArchiveImplementation::load_pointer(t, bpis_ptr, finder); + } + virtual void set_library_version(library_version_type archive_library_version){ + ArchiveImplementation::set_library_version(archive_library_version); + } + virtual library_version_type get_library_version() const{ + return ArchiveImplementation::get_library_version(); + } + virtual unsigned int get_flags() const { + return ArchiveImplementation::get_flags(); + } + virtual void delete_created_pointers(){ + ArchiveImplementation::delete_created_pointers(); + } + virtual void reset_object_address( + const void * new_address, + const void * old_address + ){ + ArchiveImplementation::reset_object_address(new_address, old_address); + } + virtual void load_binary(void * t, std::size_t size){ + ArchiveImplementation::load_binary(t, size); + } + // primitive types the only ones permitted by polymorphic archives + virtual void load(bool & t){ + ArchiveImplementation::load(t); + } + virtual void load(char & t){ + ArchiveImplementation::load(t); + } + virtual void load(signed char & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned char & t){ + ArchiveImplementation::load(t); + } + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void load(wchar_t & t){ + ArchiveImplementation::load(t); + } + #endif + #endif + virtual void load(short & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned short & t){ + ArchiveImplementation::load(t); + } + virtual void load(int & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned int & t){ + ArchiveImplementation::load(t); + } + virtual void load(long & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned long & t){ + ArchiveImplementation::load(t); + } + #if defined(BOOST_HAS_LONG_LONG) + virtual void load(boost::long_long_type & t){ + ArchiveImplementation::load(t); + } + virtual void load(boost::ulong_long_type & t){ + ArchiveImplementation::load(t); + } + #elif defined(BOOST_HAS_MS_INT64) + virtual void load(__int64 & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned __int64 & t){ + ArchiveImplementation::load(t); + } + #endif + virtual void load(float & t){ + ArchiveImplementation::load(t); + } + virtual void load(double & t){ + ArchiveImplementation::load(t); + } + virtual void load(std::string & t){ + ArchiveImplementation::load(t); + } + #ifndef BOOST_NO_STD_WSTRING + virtual void load(std::wstring & t){ + ArchiveImplementation::load(t); + } + #endif + // used for xml and other tagged formats default does nothing + virtual void load_start(const char * name){ + ArchiveImplementation::load_start(name); + } + virtual void load_end(const char * name){ + ArchiveImplementation::load_end(name); + } + virtual void register_basic_serializer(const basic_iserializer & bis){ + ArchiveImplementation::register_basic_serializer(bis); + } + virtual helper_collection & + get_helper_collection(){ + return ArchiveImplementation::get_helper_collection(); + } +public: + // this can't be inheriteded because they appear in mulitple + // parents + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + // the >> operator + template + polymorphic_iarchive & operator>>(T & t){ + return polymorphic_iarchive::operator>>(t); + } + // the & operator + template + polymorphic_iarchive & operator&(T & t){ + return polymorphic_iarchive::operator&(t); + } + // register type function + template + const basic_pointer_iserializer * + register_type(T * t = NULL){ + return ArchiveImplementation::register_type(t); + } + // all current archives take a stream as constructor argument + template + polymorphic_iarchive_route( + std::basic_istream<_Elem, _Tr> & is, + unsigned int flags = 0 + ) : + ArchiveImplementation(is, flags) + {} + virtual ~polymorphic_iarchive_route(){}; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp new file mode 100644 index 00000000000..b23fd6bf39d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp @@ -0,0 +1,209 @@ +#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP +#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_oarchive_route.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail{ + +class basic_oserializer; +class basic_pointer_oserializer; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class polymorphic_oarchive_route : + public polymorphic_oarchive, + // note: gcc dynamic cross cast fails if the the derivation below is + // not public. I think this is a mistake. + public /*protected*/ ArchiveImplementation +{ +private: + // these are used by the serialization library. + virtual void save_object( + const void *x, + const detail::basic_oserializer & bos + ){ + ArchiveImplementation::save_object(x, bos); + } + virtual void save_pointer( + const void * t, + const detail::basic_pointer_oserializer * bpos_ptr + ){ + ArchiveImplementation::save_pointer(t, bpos_ptr); + } + virtual void save_null_pointer(){ + ArchiveImplementation::save_null_pointer(); + } + // primitive types the only ones permitted by polymorphic archives + virtual void save(const bool t){ + ArchiveImplementation::save(t); + } + virtual void save(const char t){ + ArchiveImplementation::save(t); + } + virtual void save(const signed char t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned char t){ + ArchiveImplementation::save(t); + } + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void save(const wchar_t t){ + ArchiveImplementation::save(t); + } + #endif + #endif + virtual void save(const short t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned short t){ + ArchiveImplementation::save(t); + } + virtual void save(const int t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned int t){ + ArchiveImplementation::save(t); + } + virtual void save(const long t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned long t){ + ArchiveImplementation::save(t); + } + #if defined(BOOST_HAS_LONG_LONG) + virtual void save(const boost::long_long_type t){ + ArchiveImplementation::save(t); + } + virtual void save(const boost::ulong_long_type t){ + ArchiveImplementation::save(t); + } + #elif defined(BOOST_HAS_MS_INT64) + virtual void save(const boost::int64_t t){ + ArchiveImplementation::save(t); + } + virtual void save(const boost::uint64_t t){ + ArchiveImplementation::save(t); + } + #endif + virtual void save(const float t){ + ArchiveImplementation::save(t); + } + virtual void save(const double t){ + ArchiveImplementation::save(t); + } + virtual void save(const std::string & t){ + ArchiveImplementation::save(t); + } + #ifndef BOOST_NO_STD_WSTRING + virtual void save(const std::wstring & t){ + ArchiveImplementation::save(t); + } + #endif + virtual library_version_type get_library_version() const{ + return ArchiveImplementation::get_library_version(); + } + virtual unsigned int get_flags() const { + return ArchiveImplementation::get_flags(); + } + virtual void save_binary(const void * t, std::size_t size){ + ArchiveImplementation::save_binary(t, size); + } + // used for xml and other tagged formats default does nothing + virtual void save_start(const char * name){ + ArchiveImplementation::save_start(name); + } + virtual void save_end(const char * name){ + ArchiveImplementation::save_end(name); + } + virtual void end_preamble(){ + ArchiveImplementation::end_preamble(); + } + virtual void register_basic_serializer(const detail::basic_oserializer & bos){ + ArchiveImplementation::register_basic_serializer(bos); + } + virtual helper_collection & + get_helper_collection(){ + return ArchiveImplementation::get_helper_collection(); + } +public: + // this can't be inheriteded because they appear in mulitple + // parents + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + // the << operator + template + polymorphic_oarchive & operator<<(T & t){ + return polymorphic_oarchive::operator<<(t); + } + // the & operator + template + polymorphic_oarchive & operator&(T & t){ + return polymorphic_oarchive::operator&(t); + } + // register type function + template + const basic_pointer_oserializer * + register_type(T * t = NULL){ + return ArchiveImplementation::register_type(t); + } + // all current archives take a stream as constructor argument + template + polymorphic_oarchive_route( + std::basic_ostream<_Elem, _Tr> & os, + unsigned int flags = 0 + ) : + ArchiveImplementation(os, flags) + {} + virtual ~polymorphic_oarchive_route(){}; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp new file mode 100644 index 00000000000..5ffecc702ce --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp @@ -0,0 +1,91 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP +# define BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP + +namespace boost { namespace archive { namespace detail { + +// No instantiate_ptr_serialization overloads generated by +// BOOST_SERIALIZATION_REGISTER_ARCHIVE that lexically follow the call +// will be seen *unless* they are in an associated namespace of one of +// the arguments, so we pass one of these along to make sure this +// namespace is considered. See temp.dep.candidate (14.6.4.2) in the +// standard. +struct adl_tag {}; + +template +struct ptr_serialization_support; + +// We could've just used ptr_serialization_support, above, but using +// it with only a forward declaration causes vc6/7 to complain about a +// missing instantiate member, even if it has one. This is just a +// friendly layer of indirection. +template +struct _ptr_serialization_support + : ptr_serialization_support +{ + typedef int type; +}; + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5130) + +template +struct counter : counter {}; +template<> +struct counter<0> {}; + +template +void instantiate_ptr_serialization(Serializable* s, int, adl_tag) { + instantiate_ptr_serialization(s, counter<20>()); +} + +template +struct get_counter { + static const int value = sizeof(adjust_counter(counter<20>())); + typedef counter type; + typedef counter prior; + typedef char (&next)[value+1]; +}; + +char adjust_counter(counter<0>); +template +void instantiate_ptr_serialization(Serializable*, counter<0>) {} + +#define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ +namespace boost { namespace archive { namespace detail { \ + get_counter::next adjust_counter(get_counter::type);\ + template \ + void instantiate_ptr_serialization(Serializable* s, \ + get_counter::type) { \ + ptr_serialization_support x; \ + instantiate_ptr_serialization(s, get_counter::prior()); \ + }\ +}}} + + +#else + +// This function gets called, but its only purpose is to participate +// in overload resolution with the functions declared by +// BOOST_SERIALIZATION_REGISTER_ARCHIVE, below. +template +void instantiate_ptr_serialization(Serializable*, int, adl_tag ) {} + +// The function declaration generated by this macro never actually +// gets called, but its return type gets instantiated, and that's +// enough to cause registration of serialization functions between +// Archive and any exported Serializable type. See also: +// boost/serialization/export.hpp +# define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ +namespace boost { namespace archive { namespace detail { \ + \ +template \ +typename _ptr_serialization_support::type \ +instantiate_ptr_serialization( Serializable*, Archive*, adl_tag ); \ + \ +}}} +#endif +}}} // namespace boost::archive::detail + +#endif // BOOST_ARCHIVE_DETAIL_INSTANTIATE_SERIALIZE_DWA2006521_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp new file mode 100644 index 00000000000..a40104abea6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP +#define BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP + +#include + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#endif + +// std::codecvt_utf8 doesn't seem to work for any versions of msvc + +#if defined(_MSC_VER) || defined(BOOST_NO_CXX11_HDR_CODECVT) + // use boost's utf8 codecvt facet + #include + #define BOOST_UTF8_BEGIN_NAMESPACE \ + namespace boost { namespace archive { namespace detail { + #define BOOST_UTF8_DECL BOOST_ARCHIVE_DECL + #define BOOST_UTF8_END_NAMESPACE }}} + + #include + + #undef BOOST_UTF8_END_NAMESPACE + #undef BOOST_UTF8_DECL + #undef BOOST_UTF8_BEGIN_NAMESPACE +#else + // use the standard vendor supplied facet + #include + namespace boost { namespace archive { namespace detail { + typedef std::codecvt_utf8 utf8_codecvt_facet; + } } } +#endif + +#endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp b/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp new file mode 100644 index 00000000000..90ba6271cdd --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp @@ -0,0 +1,224 @@ +#ifndef BOOST_ARCHIVE_DINKUMWARE_HPP +#define BOOST_ARCHIVE_DINKUMWARE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dinkumware.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 file adds a couple of things that are missing from the dinkumware +// implementation of the standard library. + +#include +#include + +#include +#include + +namespace std { + +// define i/o operators for 64 bit integers +template +basic_ostream & +operator<<(basic_ostream & os, boost::uint64_t t){ + // octal rendering of 64 bit number would be 22 octets + eos + CharType d[23]; + unsigned int radix; + + if(os.flags() & (int)std::ios_base::hex) + radix = 16; + else + if(os.flags() & (int)std::ios_base::oct) + radix = 8; + else + //if(s.flags() & (int)std::ios_base::dec) + radix = 10; + unsigned int i = 0; + do{ + unsigned int j = t % radix; + d[i++] = j + ((j < 10) ? '0' : ('a' - 10)); + t /= radix; + } + while(t > 0); + d[i--] = '\0'; + + // reverse digits + unsigned int j = 0; + while(j < i){ + CharType k = d[i]; + d[i] = d[j]; + d[j] = k; + --i;++j; + } + os << d; + return os; + +} + +template +basic_ostream & +operator<<(basic_ostream &os, boost::int64_t t){ + if(0 <= t){ + os << static_cast(t); + } + else{ + os.put('-'); + os << -t; + } + return os; +} + +template +basic_istream & +operator>>(basic_istream &is, boost::int64_t & t){ + CharType d; + do{ + d = is.get(); + } + while(::isspace(d)); + bool negative = (d == '-'); + if(negative) + d = is.get(); + unsigned int radix; + if(is.flags() & (int)std::ios_base::hex) + radix = 16; + else + if(is.flags() & (int)std::ios_base::oct) + radix = 8; + else + //if(s.flags() & (int)std::ios_base::dec) + radix = 10; + t = 0; + do{ + if('0' <= d && d <= '9') + t = t * radix + (d - '0'); + else + if('a' <= d && d <= 'f') + t = t * radix + (d - 'a' + 10); + else + break; + d = is.get(); + } + while(!is.fail()); + // restore the delimiter + is.putback(d); + is.clear(); + if(negative) + t = -t; + return is; +} + +template +basic_istream & +operator>>(basic_istream &is, boost::uint64_t & t){ + boost::int64_t it; + is >> it; + t = it; + return is; +} + +//#endif + +template<> +class back_insert_iterator > : public + iterator +{ +public: + typedef basic_string container_type; + typedef container_type::reference reference; + + explicit back_insert_iterator(container_type & s) + : container(& s) + {} // construct with container + + back_insert_iterator & operator=( + container_type::const_reference Val_ + ){ // push value into container + //container->push_back(Val_); + *container += Val_; + return (*this); + } + + back_insert_iterator & operator*(){ + return (*this); + } + + back_insert_iterator & operator++(){ + // pretend to preincrement + return (*this); + } + + back_insert_iterator operator++(int){ + // pretend to postincrement + return (*this); + } + +protected: + container_type *container; // pointer to container +}; + +template +inline back_insert_iterator > back_inserter( + basic_string & s +){ + return (std::back_insert_iterator >(s)); +} + +template<> +class back_insert_iterator > : public + iterator +{ +public: + typedef basic_string container_type; + typedef container_type::reference reference; + + explicit back_insert_iterator(container_type & s) + : container(& s) + {} // construct with container + + back_insert_iterator & operator=( + container_type::const_reference Val_ + ){ // push value into container + //container->push_back(Val_); + *container += Val_; + return (*this); + } + + back_insert_iterator & operator*(){ + return (*this); + } + + back_insert_iterator & operator++(){ + // pretend to preincrement + return (*this); + } + + back_insert_iterator operator++(int){ + // pretend to postincrement + return (*this); + } + +protected: + container_type *container; // pointer to container +}; + +template +inline back_insert_iterator > back_inserter( + basic_string & s +){ + return (std::back_insert_iterator >(s)); +} + +} // namespace std + +#endif //BOOST_ARCHIVE_DINKUMWARE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp new file mode 100644 index 00000000000..7f163ec4076 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp @@ -0,0 +1,75 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_serializer_map.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +////////////////////////////////////////////////////////////////////// +// implementation of basic_text_iprimitive overrides for the combination +// of template parameters used to implement a text_iprimitive + +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace extra_detail { // anon + template + class map : public basic_serializer_map + {}; +} + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL bool +archive_serializer_map::insert(const basic_serializer * bs){ + return boost::serialization::singleton< + extra_detail::map + >::get_mutable_instance().insert(bs); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +archive_serializer_map::erase(const basic_serializer * bs){ + BOOST_ASSERT(! boost::serialization::singleton< + extra_detail::map + >::is_destroyed() + ); + if(boost::serialization::singleton< + extra_detail::map + >::is_destroyed()) + return; + boost::serialization::singleton< + extra_detail::map + >::get_mutable_instance().erase(bs); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * +archive_serializer_map::find( + const boost::serialization::extended_type_info & eti +) { + return boost::serialization::singleton< + extra_detail::map + >::get_const_instance().find(eti); +} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp new file mode 100644 index 00000000000..d5619ab6cf3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp @@ -0,0 +1,134 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iarchive.ipp: + +// (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 +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; + using ::strlen; + using ::size_t; +} +#endif + +#include +#include + +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of binary_binary_archive +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iarchive::load_override(class_name_type & t){ + std::string cn; + cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); + load_override(cn); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + std::memcpy(t, cn.data(), cn.size()); + // borland tweak + t.t[cn.size()] = '\0'; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iarchive::init(void){ + // read signature in an archive version independent manner + std::string file_signature; + + #if 0 // commented out since it interfers with derivation + BOOST_TRY { + std::size_t l; + this->This()->load(l); + if(l == std::strlen(BOOST_ARCHIVE_SIGNATURE())) { + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != file_signature.data()) + #endif + file_signature.resize(l); + // note breaking a rule here - could be a problem on some platform + if(0 < l) + this->This()->load_binary(&(*file_signature.begin()), l); + } + } + BOOST_CATCH(archive_exception const &) { // catch stream_error archive exceptions + // will cause invalid_signature archive exception to be thrown below + file_signature = ""; + } + BOOST_CATCH_END + #else + // https://svn.boost.org/trac/boost/ticket/7301 + * this->This() >> file_signature; + #endif + + if(file_signature != BOOST_ARCHIVE_SIGNATURE()) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_signature) + ); + + // make sure the version of the reading archive library can + // support the format of the archive being read + library_version_type input_library_version; + //* this->This() >> input_library_version; + { + int v = 0; + v = this->This()->m_sb.sbumpc(); + #if defined(BOOST_LITTLE_ENDIAN) + if(v < 6){ + ; + } + else + if(v < 7){ + // version 6 - next byte should be zero + this->This()->m_sb.sbumpc(); + } + else + if(v < 8){ + int x1; + // version 7 = might be followed by zero or some other byte + x1 = this->This()->m_sb.sgetc(); + // it's =a zero, push it back + if(0 == x1) + this->This()->m_sb.sbumpc(); + } + else{ + // version 8+ followed by a zero + this->This()->m_sb.sbumpc(); + } + #elif defined(BOOST_BIG_ENDIAN) + if(v == 0) + v = this->This()->m_sb.sbumpc(); + #endif + input_library_version = static_cast(v); + } + + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->set_library_version(input_library_version); + #else + detail::basic_iarchive::set_library_version(input_library_version); + #endif + + if(BOOST_ARCHIVE_VERSION() < input_library_version) + boost::serialization::throw_exception( + archive_exception(archive_exception::unsupported_version) + ); +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp new file mode 100644 index 00000000000..bbe933ccf63 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp @@ -0,0 +1,171 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iprimitive.ipp: + +// (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 +#include // size_t, NULL +#include // memcpy + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + using ::memcpy; +} // namespace std +#endif + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_binary_iprimitive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::init() +{ + // Detect attempts to pass native binary archives across + // incompatible platforms. This is not fool proof but its + // better than nothing. + unsigned char size; + this->This()->load(size); + if(sizeof(int) != size) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "size of int" + ) + ); + this->This()->load(size); + if(sizeof(long) != size) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "size of long" + ) + ); + this->This()->load(size); + if(sizeof(float) != size) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "size of float" + ) + ); + this->This()->load(size); + if(sizeof(double) != size) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "size of double" + ) + ); + + // for checking endian + int i; + this->This()->load(i); + if(1 != i) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "endian setting" + ) + ); +} + +#ifndef BOOST_NO_CWCHAR +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::load(wchar_t * ws) +{ + std::size_t l; // number of wchar_t !!! + this->This()->load(l); + load_binary(ws, l * sizeof(wchar_t) / sizeof(char)); + ws[l] = L'\0'; +} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::load(std::string & s) +{ + std::size_t l; + this->This()->load(l); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(l); + // note breaking a rule here - could be a problem on some platform + if(0 < l) + load_binary(&(*s.begin()), l); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::load(char * s) +{ + std::size_t l; + this->This()->load(l); + load_binary(s, l); + s[l] = '\0'; +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::load(std::wstring & ws) +{ + std::size_t l; + this->This()->load(l); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(l); + // note breaking a rule here - is could be a problem on some platform + load_binary(const_cast(ws.data()), l * sizeof(wchar_t) / sizeof(char)); +} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_binary_iprimitive::basic_binary_iprimitive( + std::basic_streambuf & sb, + bool no_codecvt +) : +#ifndef BOOST_NO_STD_LOCALE + m_sb(sb), + codecvt_null_facet(1), + locale_saver(m_sb), + archive_locale(sb.getloc(), & codecvt_null_facet) +{ + if(! no_codecvt){ + m_sb.pubsync(); + m_sb.pubimbue(archive_locale); + } +} +#else + m_sb(sb) +{} +#endif + +// scoped_ptr requires that g be a complete type at time of +// destruction so define destructor here rather than in the header +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_binary_iprimitive::~basic_binary_iprimitive(){} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp new file mode 100644 index 00000000000..d5a019d32bc --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp @@ -0,0 +1,42 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oarchive.ipp: + +// (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 +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of binary_binary_oarchive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oarchive::init(){ + // write signature in an archive version independent manner + const std::string file_signature(BOOST_ARCHIVE_SIGNATURE()); + * this->This() << file_signature; + // write library version + const library_version_type v(BOOST_ARCHIVE_VERSION()); + * this->This() << v; +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp new file mode 100644 index 00000000000..7b042173a48 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp @@ -0,0 +1,126 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oprimitive.ipp: + +// (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 +#include // NULL +#include + +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif +#endif + +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_binary_oprimitive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::init() +{ + // record native sizes of fundamental types + // this is to permit detection of attempts to pass + // native binary archives accross incompatible machines. + // This is not foolproof but its better than nothing. + this->This()->save(static_cast(sizeof(int))); + this->This()->save(static_cast(sizeof(long))); + this->This()->save(static_cast(sizeof(float))); + this->This()->save(static_cast(sizeof(double))); + // for checking endianness + this->This()->save(int(1)); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::save(const char * s) +{ + std::size_t l = std::strlen(s); + this->This()->save(l); + save_binary(s, l); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::save(const std::string &s) +{ + std::size_t l = static_cast(s.size()); + this->This()->save(l); + save_binary(s.data(), l); +} + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::save(const wchar_t * ws) +{ + std::size_t l = std::wcslen(ws); + this->This()->save(l); + save_binary(ws, l * sizeof(wchar_t) / sizeof(char)); +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::save(const std::wstring &ws) +{ + std::size_t l = ws.size(); + this->This()->save(l); + save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char)); +} +#endif +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_binary_oprimitive::basic_binary_oprimitive( + std::basic_streambuf & sb, + bool no_codecvt +) : +#ifndef BOOST_NO_STD_LOCALE + m_sb(sb), + codecvt_null_facet(1), + locale_saver(m_sb), + archive_locale(sb.getloc(), & codecvt_null_facet) +{ + if(! no_codecvt){ + m_sb.pubsync(); + m_sb.pubimbue(archive_locale); + } +} +#else + m_sb(sb) +{} +#endif + +// scoped_ptr requires that g be a complete type at time of +// destruction so define destructor here rather than in the header +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_binary_oprimitive::~basic_binary_oprimitive(){} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp new file mode 100644 index 00000000000..9ec8c6588c8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp @@ -0,0 +1,76 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iarchive.ipp: + +// (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 +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of text_text_archive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_iarchive::load_override(class_name_type & t){ + std::string cn; + cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); + load_override(cn); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + std::memcpy(t, cn.data(), cn.size()); + // borland tweak + t.t[cn.size()] = '\0'; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_iarchive::init(void){ + // read signature in an archive version independent manner + std::string file_signature; + * this->This() >> file_signature; + if(file_signature != BOOST_ARCHIVE_SIGNATURE()) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_signature) + ); + + // make sure the version of the reading archive library can + // support the format of the archive being read + library_version_type input_library_version; + * this->This() >> input_library_version; + + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->set_library_version(input_library_version); + #else + detail::basic_iarchive::set_library_version(input_library_version); + #endif + + // extra little .t is to get around borland quirk + if(BOOST_ARCHIVE_VERSION() < input_library_version) + boost::serialization::throw_exception( + archive_exception(archive_exception::unsupported_version) + ); +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp new file mode 100644 index 00000000000..4e44728068d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp @@ -0,0 +1,137 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t, NULL +#include // NULL + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +namespace detail { + template + static inline bool is_whitespace(CharType c); + + template<> + inline bool is_whitespace(char t){ + return 0 != std::isspace(t); + } + + #ifndef BOOST_NO_CWCHAR + template<> + inline bool is_whitespace(wchar_t t){ + return 0 != std::iswspace(t); + } + #endif +} // detail + +// translate base64 text into binary and copy into buffer +// until buffer is full. +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_iprimitive::load_binary( + void *address, + std::size_t count +){ + typedef typename IStream::char_type CharType; + + if(0 == count) + return; + + BOOST_ASSERT( + static_cast((std::numeric_limits::max)()) + > (count + sizeof(CharType) - 1)/sizeof(CharType) + ); + + if(is.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + // convert from base64 to binary + typedef typename + iterators::transform_width< + iterators::binary_from_base64< + iterators::remove_whitespace< + iterators::istream_iterator + > + ,typename IStream::int_type + > + ,8 + ,6 + ,CharType + > + binary; + + binary i = binary(iterators::istream_iterator(is)); + + char * caddr = static_cast(address); + + // take care that we don't increment anymore than necessary + while(count-- > 0){ + *caddr++ = static_cast(*i++); + } + + // skip over any excess input + for(;;){ + typename IStream::int_type r; + r = is.get(); + if(is.eof()) + break; + if(detail::is_whitespace(static_cast(r))) + break; + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_text_iprimitive::basic_text_iprimitive( + IStream &is_, + bool no_codecvt +) : + is(is_), + flags_saver(is_), + precision_saver(is_), +#ifndef BOOST_NO_STD_LOCALE + codecvt_null_facet(1), + archive_locale(is.getloc(), & codecvt_null_facet), + locale_saver(is) +{ + if(! no_codecvt){ + is_.sync(); + is_.imbue(archive_locale); + } + is_ >> std::noboolalpha; +} +#else +{} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_text_iprimitive::~basic_text_iprimitive(){ +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp new file mode 100644 index 00000000000..44bc1401fd6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp @@ -0,0 +1,62 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oarchive.ipp: + +// (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 +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of basic_text_oarchive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_oarchive::newtoken() +{ + switch(delimiter){ + default: + BOOST_ASSERT(false); + break; + case eol: + this->This()->put('\n'); + delimiter = space; + break; + case space: + this->This()->put(' '); + break; + case none: + delimiter = space; + break; + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_oarchive::init(){ + // write signature in an archive version independent manner + const std::string file_signature(BOOST_ARCHIVE_SIGNATURE()); + * this->This() << file_signature; + // write library version + const library_version_type v(BOOST_ARCHIVE_VERSION()); + * this->This() << v; +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp new file mode 100644 index 00000000000..6030fd44c57 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp @@ -0,0 +1,115 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oprimitive.ipp: + +// (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 // NULL +#include // std::copy +#include // std::uncaught_exception +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +// translate to base64 and copy in to buffer. +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_oprimitive::save_binary( + const void *address, + std::size_t count +){ + typedef typename OStream::char_type CharType; + + if(0 == count) + return; + + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + + os.put('\n'); + + typedef + boost::archive::iterators::insert_linebreaks< + boost::archive::iterators::base64_from_binary< + boost::archive::iterators::transform_width< + const char *, + 6, + 8 + > + > + ,76 + ,const char // cwpro8 needs this + > + base64_text; + + boost::archive::iterators::ostream_iterator oi(os); + std::copy( + base64_text(static_cast(address)), + base64_text( + static_cast(address) + count + ), + oi + ); + + std::size_t tail = count % 3; + if(tail > 0){ + *oi++ = '='; + if(tail < 2) + *oi = '='; + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_text_oprimitive::basic_text_oprimitive( + OStream & os_, + bool no_codecvt +) : + os(os_), + flags_saver(os_), + precision_saver(os_), +#ifndef BOOST_NO_STD_LOCALE + codecvt_null_facet(1), + archive_locale(os.getloc(), & codecvt_null_facet), + locale_saver(os) +{ + if(! no_codecvt){ + os_.flush(); + os_.imbue(archive_locale); + } + os_ << std::noboolalpha; +} +#else +{} +#endif + + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_text_oprimitive::~basic_text_oprimitive(){ + if(std::uncaught_exception()) + return; + os << std::endl; +} + +} //namespace boost +} //namespace archive diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp new file mode 100644 index 00000000000..6d4e4683f6a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp @@ -0,0 +1,173 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP +#define BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_grammar.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 module is derived from simplexml.cpp - an example shipped as part of +// the spirit parser. This example contains the following notice: +/*============================================================================= + simplexml.cpp + + Spirit V1.3 + URL: http://spirit.sourceforge.net/ + + Copyright (c) 2001, Daniel C. Nuffer + + This software is provided 'as-is', without any express or implied + warranty. In no event will the copyright holder be held liable for + any damages arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product documentation + would be appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +=============================================================================*/ +#include + +#include +#include + +#include +#include + +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// XML grammar parsing + +template +class basic_xml_grammar { +public: + // The following is not necessary according to DR45, but at least + // one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise. + struct return_values; + friend struct return_values; + +private: + typedef typename std::basic_istream IStream; + typedef typename std::basic_string StringType; + typedef typename boost::spirit::classic::chset chset_t; + typedef typename boost::spirit::classic::chlit chlit_t; + typedef typename boost::spirit::classic::scanner< + typename std::basic_string::iterator + > scanner_t; + typedef typename boost::spirit::classic::rule rule_t; + // Start grammar definition + rule_t + Reference, + Eq, + STag, + ETag, + LetterOrUnderscoreOrColon, + AttValue, + CharRef1, + CharRef2, + CharRef, + AmpRef, + LTRef, + GTRef, + AposRef, + QuoteRef, + CharData, + CharDataChars, + content, + AmpName, + LTName, + GTName, + ClassNameChar, + ClassName, + Name, + XMLDecl, + XMLDeclChars, + DocTypeDecl, + DocTypeDeclChars, + ClassIDAttribute, + ObjectIDAttribute, + ClassNameAttribute, + TrackingAttribute, + VersionAttribute, + UnusedAttribute, + Attribute, + SignatureAttribute, + SerializationWrapper, + NameHead, + NameTail, + AttributeList, + S; + + // XML Character classes + chset_t + BaseChar, + Ideographic, + Char, + Letter, + Digit, + CombiningChar, + Extender, + Sch, + NameChar; + + void init_chset(); + + bool my_parse( + IStream & is, + const rule_t &rule_, + const CharType delimiter = L'>' + ) const ; +public: + struct return_values { + StringType object_name; + StringType contents; + //class_id_type class_id; + int_least16_t class_id; + //object_id_type object_id; + uint_least32_t object_id; + //version_type version; + unsigned int version; + tracking_type tracking_level; + StringType class_name; + return_values() : + version(0), + tracking_level(false) + {} + } rv; + bool parse_start_tag(IStream & is) /*const*/; + bool parse_end_tag(IStream & is) const; + bool parse_string(IStream & is, StringType & s) /*const*/; + void init(IStream & is); + bool windup(IStream & is); + basic_xml_grammar(); +}; + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp new file mode 100644 index 00000000000..625458b9eb5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp @@ -0,0 +1,115 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_iarchive.ipp: + +// (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 +#include // NULL +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of xml_text_archive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_start(const char *name){ + // if there's no name + if(NULL == name) + return; + bool result = this->This()->gimpl->parse_start_tag(this->This()->get_is()); + if(true != result){ + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + } + // don't check start tag at highest level + ++depth; + return; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_end(const char *name){ + // if there's no name + if(NULL == name) + return; + bool result = this->This()->gimpl->parse_end_tag(this->This()->get_is()); + if(true != result){ + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + } + + // don't check start tag at highest level + if(0 == --depth) + return; + + if(0 == (this->get_flags() & no_xml_tag_checking)){ + // double check that the tag matches what is expected - useful for debug + if(0 != name[this->This()->gimpl->rv.object_name.size()] + || ! std::equal( + this->This()->gimpl->rv.object_name.begin(), + this->This()->gimpl->rv.object_name.end(), + name + ) + ){ + boost::serialization::throw_exception( + xml_archive_exception( + xml_archive_exception::xml_archive_tag_mismatch, + name + ) + ); + } + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_override(object_id_type & t){ + t = object_id_type(this->This()->gimpl->rv.object_id); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_override(version_type & t){ + t = version_type(this->This()->gimpl->rv.version); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_override(class_id_type & t){ + t = class_id_type(this->This()->gimpl->rv.class_id); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_override(tracking_type & t){ + t = this->This()->gimpl->rv.tracking_level; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_xml_iarchive::basic_xml_iarchive(unsigned int flags) : + detail::common_iarchive(flags), + depth(0) +{} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_xml_iarchive::~basic_xml_iarchive(){ +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp new file mode 100644 index 00000000000..3184413f382 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp @@ -0,0 +1,272 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_oarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL +#include +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; +} // namespace std +#endif + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +namespace detail { +template +struct XML_name { + void operator()(CharType t) const{ + const unsigned char lookup_table[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -. + 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0-9 + 0,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,0,0,0,0,1, // -Z _ + 0,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,0,0,0,0,0, // -z + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + if((unsigned)t > 127) + return; + if(0 == lookup_table[(unsigned)t]) + boost::serialization::throw_exception( + xml_archive_exception( + xml_archive_exception::xml_archive_tag_name_error + ) + ); + } +}; + +} // namespace detail + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions common to both types of xml output + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::write_attribute( + const char *attribute_name, + int t, + const char *conjunction +){ + this->This()->put(' '); + this->This()->put(attribute_name); + this->This()->put(conjunction); + this->This()->save(t); + this->This()->put('"'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::write_attribute( + const char *attribute_name, + const char *key +){ + this->This()->put(' '); + this->This()->put(attribute_name); + this->This()->put("=\""); + this->This()->save(key); + this->This()->put('"'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::indent(){ + int i; + for(i = depth; i-- > 0;) + this->This()->put('\t'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_start(const char *name) +{ + if(NULL == name) + return; + + // be sure name has no invalid characters + std::for_each(name, name + std::strlen(name), detail::XML_name()); + + end_preamble(); + if(depth > 0){ + this->This()->put('\n'); + indent(); + } + ++depth; + this->This()->put('<'); + this->This()->save(name); + pending_preamble = true; + indent_next = false; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_end(const char *name) +{ + if(NULL == name) + return; + + // be sure name has no invalid characters + std::for_each(name, name + std::strlen(name), detail::XML_name()); + + end_preamble(); + --depth; + if(indent_next){ + this->This()->put('\n'); + indent(); + } + indent_next = true; + this->This()->put("This()->save(name); + this->This()->put('>'); + if(0 == depth) + this->This()->put('\n'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::end_preamble(){ + if(pending_preamble){ + this->This()->put('>'); + pending_preamble = false; + } +} +#if 0 +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const object_id_type & t) +{ + int i = t.t; // extra .t is for borland + write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override( + const object_reference_type & t, + int +){ + int i = t.t; // extra .t is for borland + write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const version_type & t) +{ + int i = t.t; // extra .t is for borland + write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); +} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const object_id_type & t) +{ + // borland doesn't do conversion of STRONG_TYPEDEFs very well + const unsigned int i = t; + write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override( + const object_reference_type & t +){ + const unsigned int i = t; + write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const version_type & t) +{ + const unsigned int i = t; + write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const class_id_type & t) +{ + write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override( + const class_id_reference_type & t +){ + write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override( + const class_id_optional_type & t +){ + write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const class_name_type & t) +{ + const char * key = t; + if(NULL == key) + return; + write_attribute(BOOST_ARCHIVE_XML_CLASS_NAME(), key); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const tracking_type & t) +{ + write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::init(){ + // xml header + this->This()->put("\n"); + this->This()->put("\n"); + // xml document wrapper - outer root + this->This()->put("This()->put(">\n"); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::windup(){ + // xml_trailer + this->This()->put("\n"); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_xml_oarchive::basic_xml_oarchive(unsigned int flags) : + detail::common_oarchive(flags), + depth(0), + pending_preamble(false), + indent_next(false) +{ +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_xml_oarchive::~basic_xml_oarchive(){ +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp new file mode 100644 index 00000000000..ae4e2750ce8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp @@ -0,0 +1,128 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_iarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +////////////////////////////////////////////////////////////////////// +// implementation of basic_text_iprimitive overrides for the combination +// of template parameters used to implement a text_iprimitive + +#include // size_t, NULL +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include // RogueWave + +#include + +namespace boost { +namespace archive { + +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load(char *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // Works on all tested platforms + is.read(s, size); + s[size] = '\0'; +} + +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load(std::string &s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(size); + if(0 < size) + is.read(&(*s.begin()), size); +} + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load(wchar_t *ws) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + is.read((char *)ws, size * sizeof(wchar_t)/sizeof(char)); + ws[size] = L'\0'; +} +#endif // BOOST_NO_INTRINSIC_WCHAR_T + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load(std::wstring &ws) +{ + std::size_t size; + * this->This() >> size; + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(size); + // skip separating space + is.get(); + is.read((char *)ws.data(), size * sizeof(wchar_t)/sizeof(char)); +} + +#endif // BOOST_NO_STD_WSTRING +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load_override(class_name_type & t){ + basic_text_iarchive::load_override(t); +} + +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::init(){ + basic_text_iarchive::init(); +} + +template +BOOST_ARCHIVE_DECL +text_iarchive_impl::text_iarchive_impl( + std::istream & is, + unsigned int flags +) : + basic_text_iprimitive( + is, + 0 != (flags & no_codecvt) + ), + basic_text_iarchive(flags) +{ + if(0 == (flags & no_header)) + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->init(); + #else + this->basic_text_iarchive::init(); + #endif +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp new file mode 100644 index 00000000000..37d8664a98c --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp @@ -0,0 +1,122 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_oarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif +#endif + +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_text_oprimitive overrides for the combination +// of template parameters used to create a text_oprimitive + +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save(const char * s) +{ + const std::size_t len = std::ostream::traits_type::length(s); + *this->This() << len; + this->This()->newtoken(); + os << s; +} + +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save(const std::string &s) +{ + const std::size_t size = s.size(); + *this->This() << size; + this->This()->newtoken(); + os << s; +} + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save(const wchar_t * ws) +{ + const std::size_t l = std::wcslen(ws); + * this->This() << l; + this->This()->newtoken(); + os.write((const char *)ws, l * sizeof(wchar_t)/sizeof(char)); +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save(const std::wstring &ws) +{ + const std::size_t l = ws.size(); + * this->This() << l; + this->This()->newtoken(); + os.write((const char *)(ws.data()), l * sizeof(wchar_t)/sizeof(char)); +} +#endif +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL +text_oarchive_impl::text_oarchive_impl( + std::ostream & os, + unsigned int flags +) : + basic_text_oprimitive( + os, + 0 != (flags & no_codecvt) + ), + basic_text_oarchive(flags) +{ + if(0 == (flags & no_header)) + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->init(); + #else + this->basic_text_oarchive::init(); + #endif +} + +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save_binary(const void *address, std::size_t count){ + put('\n'); + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->delimiter = this->eol; +} + +} // namespace archive +} // namespace boost + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp new file mode 100644 index 00000000000..e85625ac326 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp @@ -0,0 +1,118 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_text_wiarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t, NULL + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include // fixup for RogueWave + +#ifndef BOOST_NO_STD_WSTREAMBUF +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of wiprimtives functions +// +template +BOOST_WARCHIVE_DECL void +text_wiarchive_impl::load(char *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + while(size-- > 0){ + *s++ = is.narrow(is.get(), '\0'); + } + *s = '\0'; +} + +template +BOOST_WARCHIVE_DECL void +text_wiarchive_impl::load(std::string &s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(0); + s.reserve(size); + while(size-- > 0){ + char x = is.narrow(is.get(), '\0'); + s += x; + } +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL void +text_wiarchive_impl::load(wchar_t *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // Works on all tested platforms + is.read(s, size); + s[size] = L'\0'; +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL void +text_wiarchive_impl::load(std::wstring &ws) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // borland complains about resize + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(size); + // note breaking a rule here - is this a problem on some platform + is.read(const_cast(ws.data()), size); +} +#endif + +template +BOOST_WARCHIVE_DECL +text_wiarchive_impl::text_wiarchive_impl( + std::wistream & is, + unsigned int flags +) : + basic_text_iprimitive( + is, + 0 != (flags & no_codecvt) + ), + basic_text_iarchive(flags) +{ + if(0 == (flags & no_header)) + basic_text_iarchive::init(); +} + +} // archive +} // boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp new file mode 100644 index 00000000000..2b6d427cd3a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp @@ -0,0 +1,85 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_woarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include // size_t +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; + using ::size_t; +} // namespace std +#endif + +#include + +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of woarchive functions +// +template +BOOST_WARCHIVE_DECL void +text_woarchive_impl::save(const char *s) +{ + // note: superfluous local variable fixes borland warning + const std::size_t size = std::strlen(s); + * this->This() << size; + this->This()->newtoken(); + while(*s != '\0') + os.put(os.widen(*s++)); +} + +template +BOOST_WARCHIVE_DECL void +text_woarchive_impl::save(const std::string &s) +{ + const std::size_t size = s.size(); + * this->This() << size; + this->This()->newtoken(); + const char * cptr = s.data(); + for(std::size_t i = size; i-- > 0;) + os.put(os.widen(*cptr++)); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL void +text_woarchive_impl::save(const wchar_t *ws) +{ + const std::size_t size = std::wostream::traits_type::length(ws); + * this->This() << size; + this->This()->newtoken(); + os.write(ws, size); +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL void +text_woarchive_impl::save(const std::wstring &ws) +{ + const std::size_t size = ws.length(); + * this->This() << size; + this->This()->newtoken(); + os.write(ws.data(), size); +} +#endif + +} // namespace archive +} // namespace boost + +#endif + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp new file mode 100644 index 00000000000..efc32e01632 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp @@ -0,0 +1,199 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_iarchive_impl.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // memcpy +#include // NULL +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR +#include // mbstate_t and mbrtowc +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::mbstate_t; + using ::mbrtowc; + } // namespace std +#endif +#endif // BOOST_NO_CWCHAR + +#include // RogueWave and Dinkumware +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#include + +#include +#include +#include +#include + +#include "basic_xml_grammar.hpp" + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to char archives + +// wide char stuff used by char archives + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load(std::wstring &ws){ + std::string s; + bool result = gimpl->parse_string(is, s); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(0); + std::mbstate_t mbs = std::mbstate_t(); + const char * start = s.data(); + const char * end = start + s.size(); + while(start < end){ + wchar_t wc; + std::size_t count = std::mbrtowc(&wc, start, end - start, &mbs); + if(count == static_cast(-1)) + boost::serialization::throw_exception( + iterators::dataflow_exception( + iterators::dataflow_exception::invalid_conversion + ) + ); + if(count == static_cast(-2)) + continue; + start += count; + ws += wc; + } +} +#endif // BOOST_NO_STD_WSTRING + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load(wchar_t * ws){ + std::string s; + bool result = gimpl->parse_string(is, s); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception( + xml_archive_exception::xml_archive_parsing_error + ) + ); + + std::mbstate_t mbs = std::mbstate_t(); + const char * start = s.data(); + const char * end = start + s.size(); + while(start < end){ + wchar_t wc; + std::size_t length = std::mbrtowc(&wc, start, end - start, &mbs); + if(static_cast(-1) == length) + boost::serialization::throw_exception( + iterators::dataflow_exception( + iterators::dataflow_exception::invalid_conversion + ) + ); + if(static_cast(-2) == length) + continue; + + start += length; + *ws++ = wc; + } + *ws = L'\0'; +} +#endif // BOOST_NO_INTRINSIC_WCHAR_T + +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load(std::string &s){ + bool result = gimpl->parse_string(is, s); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); +} + +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load(char * s){ + std::string tstring; + bool result = gimpl->parse_string(is, tstring); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + std::memcpy(s, tstring.data(), tstring.size()); + s[tstring.size()] = 0; +} + +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load_override(class_name_type & t){ + const std::string & s = gimpl->rv.class_name; + if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + char * tptr = t; + std::memcpy(tptr, s.data(), s.size()); + tptr[s.size()] = '\0'; +} + +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::init(){ + gimpl->init(is); + this->set_library_version( + library_version_type(gimpl->rv.version) + ); +} + +template +BOOST_ARCHIVE_DECL +xml_iarchive_impl::xml_iarchive_impl( + std::istream &is_, + unsigned int flags +) : + basic_text_iprimitive( + is_, + 0 != (flags & no_codecvt) + ), + basic_xml_iarchive(flags), + gimpl(new xml_grammar()) +{ + if(0 == (flags & no_header)) + init(); +} + +template +BOOST_ARCHIVE_DECL +xml_iarchive_impl::~xml_iarchive_impl(){ + if(std::uncaught_exception()) + return; + if(0 == (this->get_flags() & no_header)){ + gimpl->windup(is); + } +} +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp new file mode 100644 index 00000000000..5ebd454e722 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp @@ -0,0 +1,142 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_oarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include // std::copy +#include +#include + +#include // strlen +#include // msvc 6.0 needs this to suppress warnings +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::strlen; +} // namespace std +#endif + +#include +#include + +#ifndef BOOST_NO_CWCHAR +#include +#include +#endif + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to char archives + +// wide char stuff used by char archives +#ifndef BOOST_NO_CWCHAR +// copy chars to output escaping to xml and translating wide chars to mb chars +template +void save_iterator(std::ostream &os, InputIterator begin, InputIterator end){ + typedef boost::archive::iterators::mb_from_wchar< + boost::archive::iterators::xml_escape + > translator; + std::copy( + translator(begin), + translator(end), + boost::archive::iterators::ostream_iterator(os) + ); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save(const std::wstring & ws){ +// at least one library doesn't typedef value_type for strings +// so rather than using string directly make a pointer iterator out of it +// save_iterator(os, ws.data(), ws.data() + std::wcslen(ws.data())); + save_iterator(os, ws.data(), ws.data() + ws.size()); +} +#endif + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save(const wchar_t * ws){ + save_iterator(os, ws, ws + std::wcslen(ws)); +} +#endif + +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save(const std::string & s){ +// at least one library doesn't typedef value_type for strings +// so rather than using string directly make a pointer iterator out of it + typedef boost::archive::iterators::xml_escape< + const char * + > xml_escape_translator; + std::copy( + xml_escape_translator(s.data()), + xml_escape_translator(s.data()+ s.size()), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save(const char * s){ + typedef boost::archive::iterators::xml_escape< + const char * + > xml_escape_translator; + std::copy( + xml_escape_translator(s), + xml_escape_translator(s + std::strlen(s)), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_ARCHIVE_DECL +xml_oarchive_impl::xml_oarchive_impl( + std::ostream & os_, + unsigned int flags +) : + basic_text_oprimitive( + os_, + 0 != (flags & no_codecvt) + ), + basic_xml_oarchive(flags) +{ + if(0 == (flags & no_header)) + this->init(); +} + +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save_binary(const void *address, std::size_t count){ + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->indent_next = true; +} + +template +BOOST_ARCHIVE_DECL +xml_oarchive_impl::~xml_oarchive_impl(){ + if(std::uncaught_exception()) + return; + if(0 == (this->get_flags() & no_header)) + this->windup(); +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp new file mode 100644 index 00000000000..ee66c1263e6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp @@ -0,0 +1,189 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_wiarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} //std +#endif + +#include // msvc 6.0 needs this to suppress warnings +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include // std::copy +#include // uncaught exception +#include // Dinkumware and RogueWave +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include "basic_xml_grammar.hpp" + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to wide char archives + +namespace { // anonymous + +void copy_to_ptr(char * s, const std::wstring & ws){ + std::copy( + iterators::mb_from_wchar( + ws.begin() + ), + iterators::mb_from_wchar( + ws.end() + ), + s + ); + s[ws.size()] = 0; +} + +} // anonymous + +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load(std::string & s){ + std::wstring ws; + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(0); + s.reserve(ws.size()); + std::copy( + iterators::mb_from_wchar( + ws.begin() + ), + iterators::mb_from_wchar( + ws.end() + ), + std::back_inserter(s) + ); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load(std::wstring & ws){ + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); +} +#endif + +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load(char * s){ + std::wstring ws; + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + copy_to_ptr(s, ws); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load(wchar_t * ws){ + std::wstring twstring; + bool result = gimpl->parse_string(is, twstring); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + std::memcpy(ws, twstring.c_str(), twstring.size()); + ws[twstring.size()] = L'\0'; +} +#endif + +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load_override(class_name_type & t){ + const std::wstring & ws = gimpl->rv.class_name; + if(ws.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + copy_to_ptr(t, ws); +} + +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::init(){ + gimpl->init(is); + this->set_library_version( + library_version_type(gimpl->rv.version) + ); +} + +template +BOOST_WARCHIVE_DECL +xml_wiarchive_impl::xml_wiarchive_impl( + std::wistream &is_, + unsigned int flags +) : + basic_text_iprimitive( + is_, + true // don't change the codecvt - use the one below + ), + basic_xml_iarchive(flags), + gimpl(new xml_wgrammar()) +{ + if(0 == (flags & no_codecvt)){ + std::locale l = std::locale( + is_.getloc(), + new boost::archive::detail::utf8_codecvt_facet + ); + // libstdc++ crashes without this + is_.sync(); + is_.imbue(l); + } + if(0 == (flags & no_header)) + init(); +} + +template +BOOST_WARCHIVE_DECL +xml_wiarchive_impl::~xml_wiarchive_impl(){ + if(std::uncaught_exception()) + return; + if(0 == (this->get_flags() & no_header)){ + gimpl->windup(is); + } +} + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp new file mode 100644 index 00000000000..01b1a052d51 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp @@ -0,0 +1,171 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_woarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include +#include // std::copy +#include +#include + +#include // strlen +#include // mbtowc +#ifndef BOOST_NO_CWCHAR +#include // wcslen +#endif + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::strlen; + #if ! defined(BOOST_NO_INTRINSIC_WCHAR_T) + using ::mbtowc; + using ::wcslen; + #endif +} // namespace std +#endif + +#include +#include + +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to wide char archives + +// copy chars to output escaping to xml and widening characters as we go +template +void save_iterator(std::wostream &os, InputIterator begin, InputIterator end){ + typedef iterators::wchar_from_mb< + iterators::xml_escape + > xmbtows; + std::copy( + xmbtows(begin), + xmbtows(end), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save(const std::string & s){ + // note: we don't use s.begin() and s.end() because dinkumware + // doesn't have string::value_type defined. So use a wrapper + // around these values to implement the definitions. + const char * begin = s.data(); + const char * end = begin + s.size(); + save_iterator(os, begin, end); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save(const std::wstring & ws){ +#if 0 + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(ws.begin()), + xmbtows(ws.end()), + boost::archive::iterators::ostream_iterator(os) + ); +#endif + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(ws.data()), + xmbtows(ws.data() + ws.size()), + boost::archive::iterators::ostream_iterator(os) + ); +} +#endif //BOOST_NO_STD_WSTRING + +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save(const char * s){ + save_iterator(os, s, s + std::strlen(s)); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save(const wchar_t * ws){ + os << ws; + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(ws), + xmbtows(ws + std::wcslen(ws)), + boost::archive::iterators::ostream_iterator(os) + ); +} +#endif + +template +BOOST_WARCHIVE_DECL +xml_woarchive_impl::xml_woarchive_impl( + std::wostream & os_, + unsigned int flags +) : + basic_text_oprimitive( + os_, + true // don't change the codecvt - use the one below + ), + basic_xml_oarchive(flags) +{ + if(0 == (flags & no_codecvt)){ + std::locale l = std::locale( + os_.getloc(), + new boost::archive::detail::utf8_codecvt_facet + ); + os_.flush(); + os_.imbue(l); + } + if(0 == (flags & no_header)) + this->init(); +} + +template +BOOST_WARCHIVE_DECL +xml_woarchive_impl::~xml_woarchive_impl(){ + if(std::uncaught_exception()) + return; + if(0 == (this->get_flags() & no_header)){ + save(L"\n"); + } +} + +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save_binary( + const void *address, + std::size_t count +){ + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->indent_next = true; +} + +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp new file mode 100644 index 00000000000..8f9208b60ea --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// base64_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 +#ifndef BOOST_NO_EXCEPTIONS +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by base64s +// +class base64_exception : public std::exception +{ +public: + typedef enum { + invalid_code, // attempt to encode a value > 6 bits + invalid_character, // decode a value not in base64 char set + other_exception + } exception_code; + exception_code code; + + base64_exception(exception_code c = other_exception) : code(c) + {} + + virtual const char *what( ) const throw( ) + { + const char *msg = "unknown exception code"; + switch(code){ + case invalid_code: + msg = "attempt to encode a value > 6 bits"; + break; + case invalid_character: + msg = "attempt to decode a value not in base64 char set"; + break; + default: + BOOST_ASSERT(false); + break; + } + return msg; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_EXCEPTIONS +#endif //BOOST_ARCHIVE_ITERATORS_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp new file mode 100644 index 00000000000..ee849944397 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp @@ -0,0 +1,109 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP +#define BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// base64_from_binary.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 + +#include // size_t +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert binary integers to base64 characters + +namespace detail { + +template +struct from_6_bit { + typedef CharType result_type; + CharType operator()(CharType t) const{ + static const char * lookup_table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/"; + BOOST_ASSERT(t < 64); + return lookup_table[static_cast(t)]; + } +}; + +} // namespace detail + +// note: what we would like to do is +// template +// typedef transform_iterator< +// from_6_bit, +// transform_width +// > base64_from_binary; +// but C++ won't accept this. Rather than using a "type generator" and +// using a different syntax, make a derivation which should be equivalent. +// +// Another issue addressed here is that the transform_iterator doesn't have +// a templated constructor. This makes it incompatible with the dataflow +// ideal. This is also addressed here. + +//template +template< + class Base, + class CharType = typename boost::iterator_value::type +> +class base64_from_binary : + public transform_iterator< + detail::from_6_bit, + Base + > +{ + friend class boost::iterator_core_access; + typedef transform_iterator< + typename detail::from_6_bit, + Base + > super_t; + +public: + // make composible buy using templated constructor + template + base64_from_binary(T start) : + super_t( + Base(static_cast< T >(start)), + detail::from_6_bit() + ) + {} + // intel 7.1 doesn't like default copy constructor + base64_from_binary(const base64_from_binary & rhs) : + super_t( + Base(rhs.base_reference()), + detail::from_6_bit() + ) + {} +// base64_from_binary(){}; +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp new file mode 100644 index 00000000000..89b8f889da3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp @@ -0,0 +1,118 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP +#define BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_from_base64.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 + +#include +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert base64 characters to binary data + +namespace detail { + +template +struct to_6_bit { + typedef CharType result_type; + CharType operator()(CharType t) const{ + static const signed char lookup_table[] = { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, + 52,53,54,55,56,57,58,59,60,61,-1,-1,-1, 0,-1,-1, // render '=' as 0 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, + 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, + -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 + }; + // metrowerks trips this assertion - how come? + #if ! defined(__MWERKS__) + BOOST_STATIC_ASSERT(128 == sizeof(lookup_table)); + #endif + signed char value = -1; + if((unsigned)t <= 127) + value = lookup_table[(unsigned)t]; + if(-1 == value) + boost::serialization::throw_exception( + dataflow_exception(dataflow_exception::invalid_base64_character) + ); + return value; + } +}; + +} // namespace detail + +// note: what we would like to do is +// template +// typedef transform_iterator< +// from_6_bit, +// transform_width +// > base64_from_binary; +// but C++ won't accept this. Rather than using a "type generator" and +// using a different syntax, make a derivation which should be equivalent. +// +// Another issue addressed here is that the transform_iterator doesn't have +// a templated constructor. This makes it incompatible with the dataflow +// ideal. This is also addressed here. + +template< + class Base, + class CharType = typename boost::iterator_value::type +> +class binary_from_base64 : public + transform_iterator< + detail::to_6_bit, + Base + > +{ + friend class boost::iterator_core_access; + typedef transform_iterator< + detail::to_6_bit, + Base + > super_t; +public: + // make composible buy using templated constructor + template + binary_from_base64(T start) : + super_t( + Base(static_cast< T >(start)), + detail::to_6_bit() + ) + {} + // intel 7.1 doesn't like default copy constructor + binary_from_base64(const binary_from_base64 & rhs) : + super_t( + Base(rhs.base_reference()), + detail::to_6_bit() + ) + {} +// binary_from_base64(){}; +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp new file mode 100644 index 00000000000..07733d5fd62 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp @@ -0,0 +1,102 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP +#define BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dataflow.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 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// poor man's tri-state +struct tri_state { + enum state_enum { + is_false = false, + is_true = true, + is_indeterminant + } m_state; + // convert to bool + operator bool (){ + BOOST_ASSERT(is_indeterminant != m_state); + return is_true == m_state ? true : false; + } + // assign from bool + tri_state & operator=(bool rhs) { + m_state = rhs ? is_true : is_false; + return *this; + } + tri_state(bool rhs) : + m_state(rhs ? is_true : is_false) + {} + tri_state(state_enum state) : + m_state(state) + {} + bool operator==(const tri_state & rhs) const { + return m_state == rhs.m_state; + } + bool operator!=(const tri_state & rhs) const { + return m_state != rhs.m_state; + } +}; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implement functions common to dataflow iterators +template +class dataflow { + bool m_eoi; +protected: + // test for iterator equality + tri_state equal(const Derived & rhs) const { + if(m_eoi && rhs.m_eoi) + return true; + if(m_eoi || rhs.m_eoi) + return false; + return tri_state(tri_state::is_indeterminant); + } + void eoi(bool tf){ + m_eoi = tf; + } + bool eoi() const { + return m_eoi; + } +public: + dataflow(bool tf) : + m_eoi(tf) + {} + dataflow() : // used for iterator end + m_eoi(true) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp new file mode 100644 index 00000000000..e3e18605b38 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dataflow_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 +#ifndef BOOST_NO_EXCEPTIONS +#include +#endif //BOOST_NO_EXCEPTIONS + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by dataflows +// +class dataflow_exception : public std::exception +{ +public: + typedef enum { + invalid_6_bitcode, + invalid_base64_character, + invalid_xml_escape_sequence, + comparison_not_permitted, + invalid_conversion, + other_exception + } exception_code; + exception_code code; + + dataflow_exception(exception_code c = other_exception) : code(c) + {} + + virtual const char *what( ) const throw( ) + { + const char *msg = "unknown exception code"; + switch(code){ + case invalid_6_bitcode: + msg = "attempt to encode a value > 6 bits"; + break; + case invalid_base64_character: + msg = "attempt to decode a value not in base64 char set"; + break; + case invalid_xml_escape_sequence: + msg = "invalid xml escape_sequence"; + break; + case comparison_not_permitted: + msg = "cannot invoke iterator comparison now"; + break; + case invalid_conversion: + msg = "invalid multbyte/wide char conversion"; + break; + default: + BOOST_ASSERT(false); + break; + } + return msg; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp new file mode 100644 index 00000000000..103b31e0fef --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp @@ -0,0 +1,115 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// escape.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 +#include // NULL + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert escapes into text + +template +class escape : + public boost::iterator_adaptor< + Derived, + Base, + typename boost::iterator_value::type, + single_pass_traversal_tag, + typename boost::iterator_value::type + > +{ + typedef typename boost::iterator_value::type base_value_type; + typedef typename boost::iterator_reference::type reference_type; + friend class boost::iterator_core_access; + + typedef typename boost::iterator_adaptor< + Derived, + Base, + base_value_type, + single_pass_traversal_tag, + base_value_type + > super_t; + + typedef escape this_t; + + void dereference_impl() { + m_current_value = static_cast(this)->fill(m_bnext, m_bend); + m_full = true; + } + + //Access the value referred to + reference_type dereference() const { + if(!m_full) + const_cast(this)->dereference_impl(); + return m_current_value; + } + + bool equal(const this_t & rhs) const { + if(m_full){ + if(! rhs.m_full) + const_cast(& rhs)->dereference_impl(); + } + else{ + if(rhs.m_full) + const_cast(this)->dereference_impl(); + } + if(m_bnext != rhs.m_bnext) + return false; + if(this->base_reference() != rhs.base_reference()) + return false; + return true; + } + + void increment(){ + if(++m_bnext < m_bend){ + m_current_value = *m_bnext; + return; + } + ++(this->base_reference()); + m_bnext = NULL; + m_bend = NULL; + m_full = false; + } + + // buffer to handle pending characters + const base_value_type *m_bnext; + const base_value_type *m_bend; + bool m_full; + base_value_type m_current_value; +public: + escape(Base base) : + super_t(base), + m_bnext(NULL), + m_bend(NULL), + m_full(false), + m_current_value(0) + { + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp new file mode 100644 index 00000000000..2504b030db1 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp @@ -0,0 +1,99 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP +#define BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert_linebreaks.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 + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::memcpy; } +#endif + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert line break every N characters +template< + class Base, + int N, + class CharType = typename boost::iterator_value::type +> +class insert_linebreaks : + public iterator_adaptor< + insert_linebreaks, + Base, + CharType, + single_pass_traversal_tag, + CharType + > +{ +private: + friend class boost::iterator_core_access; + typedef iterator_adaptor< + insert_linebreaks, + Base, + CharType, + single_pass_traversal_tag, + CharType + > super_t; + + bool equal(const insert_linebreaks & rhs) const { + return +// m_count == rhs.m_count +// && base_reference() == rhs.base_reference() + this->base_reference() == rhs.base_reference() + ; + } + + void increment() { + if(m_count == N){ + m_count = 0; + return; + } + ++m_count; + ++(this->base_reference()); + } + CharType dereference() const { + if(m_count == N) + return '\n'; + return * (this->base_reference()); + } + unsigned int m_count; +public: + // make composible buy using templated constructor + template + insert_linebreaks(T start) : + super_t(Base(static_cast< T >(start))), + m_count(0) + {} + // intel 7.1 doesn't like default copy constructor + insert_linebreaks(const insert_linebreaks & rhs) : + super_t(rhs.base_reference()), + m_count(rhs.m_count) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp new file mode 100644 index 00000000000..a187f605e69 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp @@ -0,0 +1,92 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP +#define BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// istream_iterator.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. + +// note: this is a custom version of the standard istream_iterator. +// This is necessary as the standard version doesn't work as expected +// for wchar_t based streams on systems for which wchar_t not a true +// type but rather a synonym for some integer type. + +#include // NULL +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// given a type, make an input iterator based on a pointer to that type +template +class istream_iterator : + public boost::iterator_facade< + istream_iterator, + Elem, + std::input_iterator_tag, + Elem + > +{ + friend class boost::iterator_core_access; + typedef istream_iterator this_t ; + typedef typename boost::iterator_facade< + istream_iterator, + Elem, + std::input_iterator_tag, + Elem + > super_t; + typedef typename std::basic_istream istream_type; + + bool equal(const this_t & rhs) const { + // note: only works for comparison against end of stream + return m_istream == rhs.m_istream; + } + + //Access the value referred to + Elem dereference() const { + return static_cast(m_istream->peek()); + } + + void increment(){ + if(NULL != m_istream){ + m_istream->ignore(1); + } + } + + istream_type *m_istream; + Elem m_current_value; +public: + istream_iterator(istream_type & is) : + m_istream(& is) + { + //increment(); + } + + istream_iterator() : + m_istream(NULL), + m_current_value(NULL) + {} + + istream_iterator(const istream_iterator & rhs) : + m_istream(rhs.m_istream), + m_current_value(rhs.m_current_value) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp new file mode 100644 index 00000000000..05df71c258e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp @@ -0,0 +1,139 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP +#define BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// mb_from_wchar.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 +#include // size_t +#ifndef BOOST_NO_CWCHAR +#include // mbstate_t +#endif +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::mbstate_t; +} // namespace std +#endif + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate wide strings and to char +// strings of the currently selected locale +template // the input iterator +class mb_from_wchar + : public boost::iterator_adaptor< + mb_from_wchar, + Base, + wchar_t, + single_pass_traversal_tag, + char + > +{ + friend class boost::iterator_core_access; + + typedef typename boost::iterator_adaptor< + mb_from_wchar, + Base, + wchar_t, + single_pass_traversal_tag, + char + > super_t; + + typedef mb_from_wchar this_t; + + char dereference_impl() { + if(! m_full){ + fill(); + m_full = true; + } + return m_buffer[m_bnext]; + } + + char dereference() const { + return (const_cast(this))->dereference_impl(); + } + // test for iterator equality + bool equal(const mb_from_wchar & rhs) const { + // once the value is filled, the base_reference has been incremented + // so don't permit comparison anymore. + return + 0 == m_bend + && 0 == m_bnext + && this->base_reference() == rhs.base_reference() + ; + } + + void fill(){ + wchar_t value = * this->base_reference(); + const wchar_t *wend; + char *bend; + std::codecvt_base::result r = m_codecvt_facet.out( + m_mbs, + & value, & value + 1, wend, + m_buffer, m_buffer + sizeof(m_buffer), bend + ); + BOOST_ASSERT(std::codecvt_base::ok == r); + m_bnext = 0; + m_bend = bend - m_buffer; + } + + void increment(){ + if(++m_bnext < m_bend) + return; + m_bend = + m_bnext = 0; + ++(this->base_reference()); + m_full = false; + } + + boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; + std::mbstate_t m_mbs; + // buffer to handle pending characters + char m_buffer[9 /* MB_CUR_MAX */]; + std::size_t m_bend; + std::size_t m_bnext; + bool m_full; + +public: + // make composible buy using templated constructor + template + mb_from_wchar(T start) : + super_t(Base(static_cast< T >(start))), + m_mbs(std::mbstate_t()), + m_bend(0), + m_bnext(0), + m_full(false) + {} + // intel 7.1 doesn't like default copy constructor + mb_from_wchar(const mb_from_wchar & rhs) : + super_t(rhs.base_reference()), + m_bend(rhs.m_bend), + m_bnext(rhs.m_bnext), + m_full(rhs.m_full) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp new file mode 100644 index 00000000000..49a9b99034b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp @@ -0,0 +1,83 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP +#define BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// ostream_iterator.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. + +// note: this is a custom version of the standard ostream_iterator. +// This is necessary as the standard version doesn't work as expected +// for wchar_t based streams on systems for which wchar_t not a true +// type but rather a synonym for some integer type. + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// given a type, make an input iterator based on a pointer to that type +template +class ostream_iterator : + public boost::iterator_facade< + ostream_iterator, + Elem, + std::output_iterator_tag, + ostream_iterator & + > +{ + friend class boost::iterator_core_access; + typedef ostream_iterator this_t ; + typedef Elem char_type; + typedef std::basic_ostream ostream_type; + + //emulate the behavior of std::ostream + ostream_iterator & dereference() const { + return const_cast(*this); + } + bool equal(const this_t & rhs) const { + return m_ostream == rhs.m_ostream; + } + void increment(){} +protected: + ostream_type *m_ostream; + void put_val(char_type e){ + if(NULL != m_ostream){ + m_ostream->put(e); + if(! m_ostream->good()) + m_ostream = NULL; + } + } +public: + this_t & operator=(char_type c){ + put_val(c); + return *this; + } + ostream_iterator(ostream_type & os) : + m_ostream (& os) + {} + ostream_iterator() : + m_ostream (NULL) + {} + ostream_iterator(const ostream_iterator & rhs) : + m_ostream (rhs.m_ostream) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp new file mode 100644 index 00000000000..c3580ab258a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP +#define BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// remove_whitespace.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 + +#include +#include +#include + +// here is the default standard implementation of the functor used +// by the filter iterator to remove spaces. Unfortunately usage +// of this implementation in combination with spirit trips a bug +// VC 6.5. The only way I can find to work around it is to +// implement a special non-standard version for this platform + +#ifndef BOOST_NO_CWCTYPE +#include // iswspace +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::iswspace; } +#endif +#endif + +#include // isspace +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::isspace; } +#endif + +#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// this is required for the RW STL on Linux and Tru64. +#undef isspace +#undef iswspace +#endif + +namespace { // anonymous + +template +struct remove_whitespace_predicate; + +template<> +struct remove_whitespace_predicate +{ + bool operator()(unsigned char t){ + return ! std::isspace(t); + } +}; + +#ifndef BOOST_NO_CWCHAR +template<> +struct remove_whitespace_predicate +{ + bool operator()(wchar_t t){ + return ! std::iswspace(t); + } +}; +#endif + +} // namespace anonymous + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert base64 file data (including whitespace and padding) to binary + +namespace boost { +namespace archive { +namespace iterators { + +// custom version of filter iterator which doesn't look ahead further than +// necessary + +template +class filter_iterator + : public boost::iterator_adaptor< + filter_iterator, + Base, + use_default, + single_pass_traversal_tag + > +{ + friend class boost::iterator_core_access; + typedef typename boost::iterator_adaptor< + filter_iterator, + Base, + use_default, + single_pass_traversal_tag + > super_t; + typedef filter_iterator this_t; + typedef typename super_t::reference reference_type; + + reference_type dereference_impl(){ + if(! m_full){ + while(! m_predicate(* this->base_reference())) + ++(this->base_reference()); + m_full = true; + } + return * this->base_reference(); + } + + reference_type dereference() const { + return const_cast(this)->dereference_impl(); + } + + Predicate m_predicate; + bool m_full; +public: + // note: this function is public only because comeau compiler complained + // I don't know if this is because the compiler is wrong or what + void increment(){ + m_full = false; + ++(this->base_reference()); + } + filter_iterator(Base start) : + super_t(start), + m_full(false) + {} + filter_iterator(){} +}; + +template +class remove_whitespace : + public filter_iterator< + remove_whitespace_predicate< + typename boost::iterator_value::type + //typename Base::value_type + >, + Base + > +{ + friend class boost::iterator_core_access; + typedef filter_iterator< + remove_whitespace_predicate< + typename boost::iterator_value::type + //typename Base::value_type + >, + Base + > super_t; +public: +// remove_whitespace(){} // why is this needed? + // make composible buy using templated constructor + template + remove_whitespace(T start) : + super_t(Base(static_cast< T >(start))) + {} + // intel 7.1 doesn't like default copy constructor + remove_whitespace(const remove_whitespace & rhs) : + super_t(rhs.base_reference()) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp new file mode 100644 index 00000000000..09c050a9274 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp @@ -0,0 +1,177 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP +#define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// transform_width.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. + +// iterator which takes elements of x bits and returns elements of y bits. +// used to change streams of 8 bit characters into streams of 6 bit characters. +// and vice-versa for implementing base64 encodeing/decoding. Be very careful +// when using and end iterator. end is only reliable detected when the input +// stream length is some common multiple of x and y. E.G. Base64 6 bit +// character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters +// or 3 8 bit characters + +#include +#include + +#include // std::min + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template< + class Base, + int BitsOut, + int BitsIn, + class CharType = typename boost::iterator_value::type // output character +> +class transform_width : + public boost::iterator_adaptor< + transform_width, + Base, + CharType, + single_pass_traversal_tag, + CharType + > +{ + friend class boost::iterator_core_access; + typedef typename boost::iterator_adaptor< + transform_width, + Base, + CharType, + single_pass_traversal_tag, + CharType + > super_t; + + typedef transform_width this_t; + typedef typename iterator_value::type base_value_type; + + void fill(); + + CharType dereference() const { + if(!m_buffer_out_full) + const_cast(this)->fill(); + return m_buffer_out; + } + + bool equal_impl(const this_t & rhs){ + if(BitsIn < BitsOut) // discard any left over bits + return this->base_reference() == rhs.base_reference(); + else{ + // BitsIn > BitsOut // zero fill + if(this->base_reference() == rhs.base_reference()){ + m_end_of_sequence = true; + return 0 == m_remaining_bits; + } + return false; + } + } + + // standard iterator interface + bool equal(const this_t & rhs) const { + return const_cast(this)->equal_impl(rhs); + } + + void increment(){ + m_buffer_out_full = false; + } + + bool m_buffer_out_full; + CharType m_buffer_out; + + // last read element from input + base_value_type m_buffer_in; + + // number of bits to left in the input buffer. + unsigned int m_remaining_bits; + + // flag to indicate we've reached end of data. + bool m_end_of_sequence; + +public: + // make composible buy using templated constructor + template + transform_width(T start) : + super_t(Base(static_cast< T >(start))), + m_buffer_out_full(false), + m_buffer_out(0), + // To disable GCC warning, but not truly necessary + //(m_buffer_in will be initialized later before being + //used because m_remaining_bits == 0) + m_buffer_in(0), + m_remaining_bits(0), + m_end_of_sequence(false) + {} + // intel 7.1 doesn't like default copy constructor + transform_width(const transform_width & rhs) : + super_t(rhs.base_reference()), + m_buffer_out_full(rhs.m_buffer_out_full), + m_buffer_out(rhs.m_buffer_out), + m_buffer_in(rhs.m_buffer_in), + m_remaining_bits(rhs.m_remaining_bits), + m_end_of_sequence(false) + {} +}; + +template< + class Base, + int BitsOut, + int BitsIn, + class CharType +> +void transform_width::fill() { + unsigned int missing_bits = BitsOut; + m_buffer_out = 0; + do{ + if(0 == m_remaining_bits){ + if(m_end_of_sequence){ + m_buffer_in = 0; + m_remaining_bits = missing_bits; + } + else{ + m_buffer_in = * this->base_reference()++; + m_remaining_bits = BitsIn; + } + } + + // append these bits to the next output + // up to the size of the output + unsigned int i = (std::min)(missing_bits, m_remaining_bits); + // shift interesting bits to least significant position + base_value_type j = m_buffer_in >> (m_remaining_bits - i); + // and mask off the un interesting higher bits + // note presumption of twos complement notation + j &= (1 << i) - 1; + // append then interesting bits to the output value + m_buffer_out <<= i; + m_buffer_out |= j; + + // and update counters + missing_bits -= i; + m_remaining_bits -= i; + }while(0 < missing_bits); + m_buffer_out_full = true; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp new file mode 100644 index 00000000000..abf62406088 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp @@ -0,0 +1,89 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unescape.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 + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template +class unescape + : public boost::iterator_adaptor< + unescape, + Base, + typename pointee::type, + single_pass_traversal_tag, + typename pointee::type + > +{ + friend class boost::iterator_core_access; + typedef typename boost::iterator_adaptor< + unescape, + Base, + typename pointee::type, + single_pass_traversal_tag, + typename pointee::type + > super_t; + + typedef unescape this_t; +public: + typedef typename this_t::value_type value_type; + typedef typename this_t::reference reference; +private: + value_type dereference_impl() { + if(! m_full){ + m_current_value = static_cast(this)->drain(); + m_full = true; + } + return m_current_value; + } + + reference dereference() const { + return const_cast(this)->dereference_impl(); + } + + value_type m_current_value; + bool m_full; + + void increment(){ + ++(this->base_reference()); + dereference_impl(); + m_full = false; + }; + +public: + + unescape(Base base) : + super_t(base), + m_full(false) + {} + +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp new file mode 100644 index 00000000000..2af8f6401f2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp @@ -0,0 +1,194 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP +#define BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// wchar_from_mb.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 +#include +#include // size_t +#ifndef BOOST_NO_CWCHAR +#include // mbstate_t +#endif +#include // copy + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::mbstate_t; +} // namespace std +#endif +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template +class wchar_from_mb + : public boost::iterator_adaptor< + wchar_from_mb, + Base, + wchar_t, + single_pass_traversal_tag, + wchar_t + > +{ + friend class boost::iterator_core_access; + typedef typename boost::iterator_adaptor< + wchar_from_mb, + Base, + wchar_t, + single_pass_traversal_tag, + wchar_t + > super_t; + + typedef wchar_from_mb this_t; + + void drain(); + + wchar_t dereference() const { + if(m_output.m_next == m_output.m_next_available) + return static_cast(0); + return * m_output.m_next; + } + + void increment(){ + if(m_output.m_next == m_output.m_next_available) + return; + if(++m_output.m_next == m_output.m_next_available){ + if(m_input.m_done) + return; + drain(); + } + } + + bool equal(this_t const & rhs) const { + return dereference() == rhs.dereference(); + } + + boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; + std::mbstate_t m_mbs; + + template + struct sliding_buffer { + boost::array m_buffer; + typename boost::array::const_iterator m_next_available; + typename boost::array::iterator m_next; + bool m_done; + // default ctor + sliding_buffer() : + m_next_available(m_buffer.begin()), + m_next(m_buffer.begin()), + m_done(false) + {} + // copy ctor + sliding_buffer(const sliding_buffer & rhs) : + m_next_available( + std::copy( + rhs.m_buffer.begin(), + rhs.m_next_available, + m_buffer.begin() + ) + ), + m_next( + m_buffer.begin() + (rhs.m_next - rhs.m_buffer.begin()) + ), + m_done(rhs.m_done) + {} + }; + + sliding_buffer::type> m_input; + sliding_buffer::type> m_output; + +public: + // make composible buy using templated constructor + template + wchar_from_mb(T start) : + super_t(Base(static_cast< T >(start))), + m_mbs(std::mbstate_t()) + { + BOOST_ASSERT(std::mbsinit(&m_mbs)); + drain(); + } + // default constructor used as an end iterator + wchar_from_mb(){} + + // copy ctor + wchar_from_mb(const wchar_from_mb & rhs) : + super_t(rhs.base_reference()), + m_mbs(rhs.m_mbs), + m_input(rhs.m_input), + m_output(rhs.m_output) + {} +}; + +template +void wchar_from_mb::drain(){ + BOOST_ASSERT(! m_input.m_done); + for(;;){ + typename boost::iterators::iterator_reference::type c = *(this->base_reference()); + // a null character in a multibyte stream is takes as end of string + if(0 == c){ + m_input.m_done = true; + break; + } + ++(this->base_reference()); + * const_cast::type *>( + (m_input.m_next_available++) + ) = c; + // if input buffer is full - we're done for now + if(m_input.m_buffer.end() == m_input.m_next_available) + break; + } + const typename boost::iterators::iterator_value::type * input_new_start; + typename iterator_value::type * next_available; + + std::codecvt_base::result r = m_codecvt_facet.in( + m_mbs, + m_input.m_buffer.begin(), + m_input.m_next_available, + input_new_start, + m_output.m_buffer.begin(), + m_output.m_buffer.end(), + next_available + ); + BOOST_ASSERT(std::codecvt_base::ok == r); + m_output.m_next_available = next_available; + m_output.m_next = m_output.m_buffer.begin(); + + // we're done with some of the input so shift left. + m_input.m_next_available = std::copy( + input_new_start, + m_input.m_next_available, + m_input.m_buffer.begin() + ); + m_input.m_next = m_input.m_buffer.begin(); +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp new file mode 100644 index 00000000000..c838a73b864 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp @@ -0,0 +1,121 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_escape.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 +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert escapes into xml text + +template +class xml_escape + : public escape, Base> +{ + friend class boost::iterator_core_access; + + typedef escape, Base> super_t; + +public: + char fill(const char * & bstart, const char * & bend); + wchar_t fill(const wchar_t * & bstart, const wchar_t * & bend); + + template + xml_escape(T start) : + super_t(Base(static_cast< T >(start))) + {} + // intel 7.1 doesn't like default copy constructor + xml_escape(const xml_escape & rhs) : + super_t(rhs.base_reference()) + {} +}; + +template +char xml_escape::fill( + const char * & bstart, + const char * & bend +){ + char current_value = * this->base_reference(); + switch(current_value){ + case '<': + bstart = "<"; + bend = bstart + 4; + break; + case '>': + bstart = ">"; + bend = bstart + 4; + break; + case '&': + bstart = "&"; + bend = bstart + 5; + break; + case '"': + bstart = """; + bend = bstart + 6; + break; + case '\'': + bstart = "'"; + bend = bstart + 6; + break; + default: + return current_value; + } + return *bstart; +} + +template +wchar_t xml_escape::fill( + const wchar_t * & bstart, + const wchar_t * & bend +){ + wchar_t current_value = * this->base_reference(); + switch(current_value){ + case '<': + bstart = L"<"; + bend = bstart + 4; + break; + case '>': + bstart = L">"; + bend = bstart + 4; + break; + case '&': + bstart = L"&"; + bend = bstart + 5; + break; + case '"': + bstart = L"""; + bend = bstart + 6; + break; + case '\'': + bstart = L"'"; + bend = bstart + 6; + break; + default: + return current_value; + } + return *bstart; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp new file mode 100644 index 00000000000..69977404567 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp @@ -0,0 +1,125 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_unescape.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 + +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// replace &??? xml escape sequences with the corresponding characters +template +class xml_unescape + : public unescape, Base> +{ + friend class boost::iterator_core_access; + typedef xml_unescape this_t; + typedef unescape super_t; + typedef typename boost::iterator_reference reference_type; + + reference_type dereference() const { + return unescape, Base>::dereference(); + } +public: + // workaround msvc 7.1 ICU crash + #if defined(BOOST_MSVC) + typedef int value_type; + #else + typedef typename this_t::value_type value_type; + #endif + + void drain_residue(const char *literal); + value_type drain(); + + template + xml_unescape(T start) : + super_t(Base(static_cast< T >(start))) + {} + // intel 7.1 doesn't like default copy constructor + xml_unescape(const xml_unescape & rhs) : + super_t(rhs.base_reference()) + {} +}; + +template +void xml_unescape::drain_residue(const char * literal){ + do{ + if(* literal != * ++(this->base_reference())) + boost::serialization::throw_exception( + dataflow_exception( + dataflow_exception::invalid_xml_escape_sequence + ) + ); + } + while('\0' != * ++literal); +} + +// note key constraint on this function is that can't "look ahead" any +// more than necessary into base iterator. Doing so would alter the base +// iterator refenence which would make subsequent iterator comparisons +// incorrect and thereby break the composiblity of iterators. +template +typename xml_unescape::value_type +//int +xml_unescape::drain(){ + value_type retval = * this->base_reference(); + if('&' != retval){ + return retval; + } + retval = * ++(this->base_reference()); + switch(retval){ + case 'l': // < + drain_residue("t;"); + retval = '<'; + break; + case 'g': // > + drain_residue("t;"); + retval = '>'; + break; + case 'a': + retval = * ++(this->base_reference()); + switch(retval){ + case 'p': // ' + drain_residue("os;"); + retval = '\''; + break; + case 'm': // & + drain_residue("p;"); + retval = '&'; + break; + } + break; + case 'q': + drain_residue("uot;"); + retval = '"'; + break; + } + return retval; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp new file mode 100644 index 00000000000..71a64378c20 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_unescape_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 +#ifndef BOOST_NO_EXCEPTIONS +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by xml_unescapes +// +class xml_unescape_exception : public std::exception +{ +public: + xml_unescape_exception() + {} + + virtual const char *what( ) const throw( ) + { + return "xml contained un-recognized escape code"; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_EXCEPTIONS +#endif //BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp new file mode 100644 index 00000000000..4a898a8ad16 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_binary_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class polymorphic_binary_iarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_binary_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_binary_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_binary_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp new file mode 100644 index 00000000000..931b243feb8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp @@ -0,0 +1,43 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + binary_oarchive_impl< + binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type + > + > polymorphic_binary_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_binary_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp new file mode 100644 index 00000000000..d3c59a9f0f4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp @@ -0,0 +1,168 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // std::size_t +#include // ULONG_MAX +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include +#include +#include +#include + +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail { + class basic_iarchive; + class basic_iserializer; +} + +class polymorphic_iarchive; + +class BOOST_SYMBOL_VISIBLE polymorphic_iarchive_impl : + public detail::interface_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_iarchive; + friend class load_access; +#endif + // primitive types the only ones permitted by polymorphic archives + virtual void load(bool & t) = 0; + + virtual void load(char & t) = 0; + virtual void load(signed char & t) = 0; + virtual void load(unsigned char & t) = 0; + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void load(wchar_t & t) = 0; + #endif + #endif + virtual void load(short & t) = 0; + virtual void load(unsigned short & t) = 0; + virtual void load(int & t) = 0; + virtual void load(unsigned int & t) = 0; + virtual void load(long & t) = 0; + virtual void load(unsigned long & t) = 0; + + #if defined(BOOST_HAS_LONG_LONG) + virtual void load(boost::long_long_type & t) = 0; + virtual void load(boost::ulong_long_type & t) = 0; + #elif defined(BOOST_HAS_MS_INT64) + virtual void load(__int64 & t) = 0; + virtual void load(unsigned __int64 & t) = 0; + #endif + + virtual void load(float & t) = 0; + virtual void load(double & t) = 0; + + // string types are treated as primitives + virtual void load(std::string & t) = 0; + #ifndef BOOST_NO_STD_WSTRING + virtual void load(std::wstring & t) = 0; + #endif + + // used for xml and other tagged formats + virtual void load_start(const char * name) = 0; + virtual void load_end(const char * name) = 0; + virtual void register_basic_serializer(const detail::basic_iserializer & bis) = 0; + virtual detail::helper_collection & get_helper_collection() = 0; + + // msvc and borland won't automatically pass these to the base class so + // make it explicit here + template + void load_override(T & t) + { + archive::load(* this->This(), t); + } + // special treatment for name-value pairs. + template + void load_override( + const boost::serialization::nvp< T > & t + ){ + load_start(t.name()); + archive::load(* this->This(), t.value()); + load_end(t.name()); + } +protected: + virtual ~polymorphic_iarchive_impl(){}; +public: + // utility function implemented by all legal archives + virtual void set_library_version(library_version_type archive_library_version) = 0; + virtual library_version_type get_library_version() const = 0; + virtual unsigned int get_flags() const = 0; + virtual void delete_created_pointers() = 0; + virtual void reset_object_address( + const void * new_address, + const void * old_address + ) = 0; + + virtual void load_binary(void * t, std::size_t size) = 0; + + // these are used by the serialization library implementation. + virtual void load_object( + void *t, + const detail::basic_iserializer & bis + ) = 0; + virtual const detail::basic_pointer_iserializer * load_pointer( + void * & t, + const detail::basic_pointer_iserializer * bpis_ptr, + const detail::basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type + ) + ) = 0; +}; + +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE polymorphic_iarchive : + public polymorphic_iarchive_impl +{ +public: + virtual ~polymorphic_iarchive(){}; +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_iarchive) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp new file mode 100644 index 00000000000..edac4edb1e8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp @@ -0,0 +1,154 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t +#include // ULONG_MAX +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail { + class basic_oarchive; + class basic_oserializer; +} + +class polymorphic_oarchive; + +class BOOST_SYMBOL_VISIBLE polymorphic_oarchive_impl : + public detail::interface_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_oarchive; + friend class save_access; +#endif + // primitive types the only ones permitted by polymorphic archives + virtual void save(const bool t) = 0; + + virtual void save(const char t) = 0; + virtual void save(const signed char t) = 0; + virtual void save(const unsigned char t) = 0; + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void save(const wchar_t t) = 0; + #endif + #endif + virtual void save(const short t) = 0; + virtual void save(const unsigned short t) = 0; + virtual void save(const int t) = 0; + virtual void save(const unsigned int t) = 0; + virtual void save(const long t) = 0; + virtual void save(const unsigned long t) = 0; + + #if defined(BOOST_HAS_LONG_LONG) + virtual void save(const boost::long_long_type t) = 0; + virtual void save(const boost::ulong_long_type t) = 0; + #elif defined(BOOST_HAS_MS_INT64) + virtual void save(const __int64 t) = 0; + virtual void save(const unsigned __int64 t) = 0; + #endif + + virtual void save(const float t) = 0; + virtual void save(const double t) = 0; + + // string types are treated as primitives + virtual void save(const std::string & t) = 0; + #ifndef BOOST_NO_STD_WSTRING + virtual void save(const std::wstring & t) = 0; + #endif + + virtual void save_null_pointer() = 0; + // used for xml and other tagged formats + virtual void save_start(const char * name) = 0; + virtual void save_end(const char * name) = 0; + virtual void register_basic_serializer(const detail::basic_oserializer & bos) = 0; + virtual detail::helper_collection & get_helper_collection() = 0; + + virtual void end_preamble() = 0; + + // msvc and borland won't automatically pass these to the base class so + // make it explicit here + template + void save_override(T & t) + { + archive::save(* this->This(), t); + } + // special treatment for name-value pairs. + template + void save_override( + const ::boost::serialization::nvp< T > & t + ){ + save_start(t.name()); + archive::save(* this->This(), t.const_value()); + save_end(t.name()); + } +protected: + virtual ~polymorphic_oarchive_impl(){}; +public: + // utility functions implemented by all legal archives + virtual unsigned int get_flags() const = 0; + virtual library_version_type get_library_version() const = 0; + virtual void save_binary(const void * t, std::size_t size) = 0; + + virtual void save_object( + const void *x, + const detail::basic_oserializer & bos + ) = 0; + virtual void save_pointer( + const void * t, + const detail::basic_pointer_oserializer * bpos_ptr + ) = 0; +}; + +// note: preserve naming symmetry +class BOOST_SYMBOL_VISIBLE polymorphic_oarchive : + public polymorphic_oarchive_impl +{ +public: + virtual ~polymorphic_oarchive(){}; +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_oarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp new file mode 100644 index 00000000000..7bef2927865 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class polymorphic_text_iarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_text_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp new file mode 100644 index 00000000000..457aad9fd75 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + text_oarchive_impl +> polymorphic_text_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp new file mode 100644 index 00000000000..8466f05d6a6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class polymorphic_text_wiarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_text_wiarchive(std::wistream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_text_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_wiarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp new file mode 100644 index 00000000000..295625d1bcf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + text_woarchive_impl +> polymorphic_text_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_woarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp new file mode 100644 index 00000000000..4dc3f894b38 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class polymorphic_xml_iarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_xml_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_xml_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp new file mode 100644 index 00000000000..514f9e530a8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + xml_oarchive_impl +> polymorphic_xml_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp new file mode 100644 index 00000000000..d4ab731267f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +class polymorphic_xml_wiarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_xml_wiarchive(std::wistream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_xml_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_wiarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp new file mode 100644 index 00000000000..dd8963fbb14 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + xml_woarchive_impl +> polymorphic_xml_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_woarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp new file mode 100644 index 00000000000..d9d60adf0b8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp @@ -0,0 +1,132 @@ +#ifndef BOOST_ARCHIVE_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE text_iarchive_impl : + public basic_text_iprimitive, + public basic_text_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_iarchive; + friend class load_access; +#endif + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + void load(version_type & t){ + unsigned int v; + load(v); + t = version_type(v); + } + void load(boost::serialization::item_version_type & t){ + unsigned int v; + load(v); + t = boost::serialization::item_version_type(v); + } + BOOST_ARCHIVE_DECL void + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL void + load(wchar_t * t); + #endif + BOOST_ARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL void + load(std::wstring &ws); + #endif + template + void load_override(T & t){ + basic_text_iarchive::load_override(t); + } + BOOST_ARCHIVE_DECL void + load_override(class_name_type & t); + BOOST_ARCHIVE_DECL void + init(); + BOOST_ARCHIVE_DECL + text_iarchive_impl(std::istream & is, unsigned int flags); + // don't import inline definitions! leave this as a reminder. + //BOOST_ARCHIVE_DECL + ~text_iarchive_impl(){}; +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE text_iarchive : + public text_iarchive_impl{ +public: + text_iarchive(std::istream & is_, unsigned int flags = 0) : + // note: added _ to suppress useless gcc warning + text_iarchive_impl(is_, flags) + {} + ~text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_iarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_TEXT_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp new file mode 100644 index 00000000000..9ba0dafffb4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp @@ -0,0 +1,121 @@ +#ifndef BOOST_ARCHIVE_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // std::size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE text_oarchive_impl : + /* protected ? */ public basic_text_oprimitive, + public basic_text_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_oarchive; + friend class basic_text_oarchive; + friend class save_access; +#endif + template + void save(const T & t){ + this->newtoken(); + basic_text_oprimitive::save(t); + } + void save(const version_type & t){ + save(static_cast(t)); + } + void save(const boost::serialization::item_version_type & t){ + save(static_cast(t)); + } + BOOST_ARCHIVE_DECL void + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL void + save(const wchar_t * t); + #endif + BOOST_ARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL void + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_DECL + text_oarchive_impl(std::ostream & os, unsigned int flags); + // don't import inline definitions! leave this as a reminder. + //BOOST_ARCHIVE_DECL + ~text_oarchive_impl(){}; +public: + BOOST_ARCHIVE_DECL void + save_binary(const void *address, std::size_t count); +}; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from text_oarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE text_oarchive : + public text_oarchive_impl +{ +public: + text_oarchive(std::ostream & os_, unsigned int flags = 0) : + // note: added _ to suppress useless gcc warning + text_oarchive_impl(os_, flags) + {} + ~text_oarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_oarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_TEXT_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp new file mode 100644 index 00000000000..3adf068a51a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include + +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE text_wiarchive_impl : + public basic_text_iprimitive, + public basic_text_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; + friend load_access; + #else + friend class detail::interface_iarchive; + friend class load_access; + #endif +#endif + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + void load(version_type & t){ + unsigned int v; + load(v); + t = version_type(v); + } + void load(boost::serialization::item_version_type & t){ + unsigned int v; + load(v); + t = boost::serialization::item_version_type(v); + } + BOOST_WARCHIVE_DECL void + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL void + load(wchar_t * t); + #endif + BOOST_WARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL void + load(std::wstring &ws); + #endif + template + void load_override(T & t){ + basic_text_iarchive::load_override(t); + } + BOOST_WARCHIVE_DECL + text_wiarchive_impl(std::wistream & is, unsigned int flags); + ~text_wiarchive_impl(){}; +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE text_wiarchive : + public text_wiarchive_impl{ +public: + text_wiarchive(std::wistream & is, unsigned int flags = 0) : + text_wiarchive_impl(is, flags) + {} + ~text_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_wiarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp new file mode 100644 index 00000000000..b6b4f8ed59a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp @@ -0,0 +1,155 @@ +#ifndef BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include // size_t + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE text_woarchive_impl : + public basic_text_oprimitive, + public basic_text_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + friend basic_text_oarchive; + friend save_access; + #else + friend class detail::interface_oarchive; + friend class basic_text_oarchive; + friend class save_access; + #endif +#endif + template + void save(const T & t){ + this->newtoken(); + basic_text_oprimitive::save(t); + } + void save(const version_type & t){ + save(static_cast(t)); + } + void save(const boost::serialization::item_version_type & t){ + save(static_cast(t)); + } + BOOST_WARCHIVE_DECL void + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL void + save(const wchar_t * t); + #endif + BOOST_WARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL void + save(const std::wstring &ws); + #endif + text_woarchive_impl(std::wostream & os, unsigned int flags) : + basic_text_oprimitive( + os, + 0 != (flags & no_codecvt) + ), + basic_text_oarchive(flags) + { + if(0 == (flags & no_header)) + basic_text_oarchive::init(); + } +public: + void save_binary(const void *address, std::size_t count){ + put(static_cast('\n')); + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + put(static_cast('\n')); + this->delimiter = this->none; + } + +}; + +// we use the following because we can't use +// typedef text_oarchive_impl > text_oarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from text_oarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE text_woarchive : + public text_woarchive_impl +{ +public: + text_woarchive(std::wostream & os, unsigned int flags = 0) : + text_woarchive_impl(os, flags) + {} + ~text_woarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_woarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp b/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp new file mode 100644 index 00000000000..400d23b9f68 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_ARCHIVE_TMPDIR_HPP +#define BOOST_ARCHIVE_TMPDIR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// tmpdir.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 // getenv +#include // NULL +//#include + +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::getenv; +} +#endif + +namespace boost { +namespace archive { + +inline const char * tmpdir(){ + const char *dirname; + dirname = std::getenv("TMP"); + if(NULL == dirname) + dirname = std::getenv("TMPDIR"); + if(NULL == dirname) + dirname = std::getenv("TEMP"); + if(NULL == dirname){ + //BOOST_ASSERT(false); // no temp directory found + dirname = "."; + } + return dirname; +} + +} // archive +} // boost + +#endif // BOOST_ARCHIVE_TMPDIR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp b/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp new file mode 100644 index 00000000000..0b60004f095 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp @@ -0,0 +1,58 @@ +#ifndef BOOST_ARCHIVE_WCSLEN_HPP +#define BOOST_ARCHIVE_WCSLEN_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// wcslen.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 // size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR + +// a couple of libraries which include wchar_t don't include +// wcslen + +#if defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB < 306 \ +|| defined(__LIBCOMO__) + +namespace std { +inline std::size_t wcslen(const wchar_t * ws) +{ + const wchar_t * eows = ws; + while(* eows != 0) + ++eows; + return eows - ws; +} +} // namespace std + +#else + +#ifndef BOOST_NO_CWCHAR +#include +#endif +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif + +#endif // wcslen + +#endif //BOOST_NO_CWCHAR + +#endif //BOOST_ARCHIVE_WCSLEN_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp new file mode 100644 index 00000000000..82c53ef5d3e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp @@ -0,0 +1,57 @@ +#ifndef BOOST_ARCHIVE_XML_ARCHIVE_EXCEPTION_HPP +#define BOOST_ARCHIVE_XML_ARCHIVE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_archive_exception.hpp: + +// (C) Copyright 2007 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 +#include + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by xml archives +// +class BOOST_SYMBOL_VISIBLE xml_archive_exception : + public virtual boost::archive::archive_exception +{ +public: + typedef enum { + xml_archive_parsing_error, // see save_register + xml_archive_tag_mismatch, + xml_archive_tag_name_error + } exception_code; + BOOST_ARCHIVE_DECL xml_archive_exception( + exception_code c, + const char * e1 = NULL, + const char * e2 = NULL + ); + BOOST_ARCHIVE_DECL xml_archive_exception(xml_archive_exception const &) ; + virtual BOOST_ARCHIVE_DECL ~xml_archive_exception() BOOST_NOEXCEPT_OR_NOTHROW ; +}; + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_XML_ARCHIVE_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp new file mode 100644 index 00000000000..abd2f9fc4e3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp @@ -0,0 +1,142 @@ +#ifndef BOOST_ARCHIVE_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class basic_xml_grammar; +typedef basic_xml_grammar xml_grammar; + +template +class BOOST_SYMBOL_VISIBLE xml_iarchive_impl : + public basic_text_iprimitive, + public basic_xml_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_iarchive; + friend class basic_xml_iarchive; + friend class load_access; +#endif + // use boost:scoped_ptr to implement automatic deletion; + boost::scoped_ptr gimpl; + + std::istream & get_is(){ + return is; + } + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + void + load(version_type & t){ + unsigned int v; + load(v); + t = version_type(v); + } + void + load(boost::serialization::item_version_type & t){ + unsigned int v; + load(v); + t = boost::serialization::item_version_type(v); + } + BOOST_ARCHIVE_DECL void + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL void + load(wchar_t * t); + #endif + BOOST_ARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL void + load(std::wstring &ws); + #endif + template + void load_override(T & t){ + basic_xml_iarchive::load_override(t); + } + BOOST_ARCHIVE_DECL void + load_override(class_name_type & t); + BOOST_ARCHIVE_DECL void + init(); + BOOST_ARCHIVE_DECL + xml_iarchive_impl(std::istream & is, unsigned int flags); + BOOST_ARCHIVE_DECL + ~xml_iarchive_impl(); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE xml_iarchive : + public xml_iarchive_impl{ +public: + xml_iarchive(std::istream & is, unsigned int flags = 0) : + xml_iarchive_impl(is, flags) + {} + ~xml_iarchive(){}; +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_iarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_XML_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp new file mode 100644 index 00000000000..eea12680372 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_ARCHIVE_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE xml_oarchive_impl : + public basic_text_oprimitive, + public basic_xml_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_oarchive; + friend class basic_xml_oarchive; + friend class save_access; +#endif + template + void save(const T & t){ + basic_text_oprimitive::save(t); + } + void + save(const version_type & t){ + save(static_cast(t)); + } + void + save(const boost::serialization::item_version_type & t){ + save(static_cast(t)); + } + BOOST_ARCHIVE_DECL void + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL void + save(const wchar_t * t); + #endif + BOOST_ARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL void + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_DECL + xml_oarchive_impl(std::ostream & os, unsigned int flags); + BOOST_ARCHIVE_DECL + ~xml_oarchive_impl(); +public: + BOOST_ARCHIVE_DECL + void save_binary(const void *address, std::size_t count); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +// we use the following because we can't use +// typedef xml_oarchive_impl > xml_oarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from xml_oarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE xml_oarchive : + public xml_oarchive_impl +{ +public: + xml_oarchive(std::ostream & os, unsigned int flags = 0) : + xml_oarchive_impl(os, flags) + {} + ~xml_oarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_oarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp new file mode 100644 index 00000000000..ac24289ac11 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp @@ -0,0 +1,149 @@ +#ifndef BOOST_ARCHIVE_XML_WIARCHIVE_HPP +#define BOOST_ARCHIVE_XML_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include + +#include +#include +#include +#include +#include +#include +// #include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class basic_xml_grammar; +typedef basic_xml_grammar xml_wgrammar; + +template +class BOOST_SYMBOL_VISIBLE xml_wiarchive_impl : + public basic_text_iprimitive, + public basic_xml_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_iarchive; + friend class basic_xml_iarchive; + friend class load_access; +#endif + boost::scoped_ptr gimpl; + std::wistream & get_is(){ + return is; + } + template + void + load(T & t){ + basic_text_iprimitive::load(t); + } + void + load(version_type & t){ + unsigned int v; + load(v); + t = version_type(v); + } + void + load(boost::serialization::item_version_type & t){ + unsigned int v; + load(v); + t = boost::serialization::item_version_type(v); + } + BOOST_WARCHIVE_DECL void + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL void + load(wchar_t * t); + #endif + BOOST_WARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL void + load(std::wstring &ws); + #endif + template + void load_override(T & t){ + basic_xml_iarchive::load_override(t); + } + BOOST_WARCHIVE_DECL void + load_override(class_name_type & t); + BOOST_WARCHIVE_DECL void + init(); + BOOST_WARCHIVE_DECL + xml_wiarchive_impl(std::wistream & is, unsigned int flags) ; + BOOST_WARCHIVE_DECL + ~xml_wiarchive_impl(); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE xml_wiarchive : + public xml_wiarchive_impl{ +public: + xml_wiarchive(std::wistream & is, unsigned int flags = 0) : + xml_wiarchive_impl(is, flags) + {} + ~xml_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_wiarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_XML_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp new file mode 100644 index 00000000000..cb7ce68cb6f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp @@ -0,0 +1,134 @@ +#ifndef BOOST_ARCHIVE_XML_WOARCHIVE_HPP +#define BOOST_ARCHIVE_XML_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else +#include // size_t +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +//#include +#include +#include +#include +#include +#include +//#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE xml_woarchive_impl : + public basic_text_oprimitive, + public basic_xml_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_oarchive; + friend class basic_xml_oarchive; + friend class save_access; +#endif + //void end_preamble(){ + // basic_xml_oarchive::end_preamble(); + //} + template + void + save(const T & t){ + basic_text_oprimitive::save(t); + } + void + save(const version_type & t){ + save(static_cast(t)); + } + void + save(const boost::serialization::item_version_type & t){ + save(static_cast(t)); + } + BOOST_WARCHIVE_DECL void + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL void + save(const wchar_t * t); + #endif + BOOST_WARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL void + save(const std::wstring &ws); + #endif + BOOST_WARCHIVE_DECL + xml_woarchive_impl(std::wostream & os, unsigned int flags); + BOOST_WARCHIVE_DECL + ~xml_woarchive_impl(); +public: + BOOST_WARCHIVE_DECL void + save_binary(const void *address, std::size_t count); + +}; + +// we use the following because we can't use +// typedef xml_woarchive_impl > xml_woarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from xml_woarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE xml_woarchive : + public xml_woarchive_impl +{ +public: + xml_woarchive(std::wostream & os, unsigned int flags = 0) : + xml_woarchive_impl(os, flags) + {} + ~xml_woarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_woarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp new file mode 100644 index 00000000000..4e0bb370c2f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp @@ -0,0 +1,51 @@ +/////////////////////////////////////////////////////////////////////////////// +// foreach.hpp header file +// +// Copyright 2010 Eric Niebler. +// 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/foreach for documentation +// +// Credits: +// Kazutoshi Satoda: for suggesting the need for a _fwd header for foreach's +// customization points. + +#ifndef BOOST_FOREACH_FWD_HPP +#define BOOST_FOREACH_FWD_HPP + +// This must be at global scope, hence the uglified name +enum boost_foreach_argument_dependent_lookup_hack +{ + boost_foreach_argument_dependent_lookup_hack_value +}; + +namespace boost +{ + +namespace foreach +{ + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::tag + // + typedef boost_foreach_argument_dependent_lookup_hack tag; + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::is_lightweight_proxy + // Specialize this for user-defined collection types if they are inexpensive to copy. + // This tells BOOST_FOREACH it can avoid the rvalue/lvalue detection stuff. + template + struct is_lightweight_proxy; + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::is_noncopyable + // Specialize this for user-defined collection types if they cannot be copied. + // This also tells BOOST_FOREACH to avoid the rvalue/lvalue detection stuff. + template + struct is_noncopyable; + +} // namespace foreach + +} // namespace boost + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp new file mode 100644 index 00000000000..787cdf83195 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp @@ -0,0 +1,1513 @@ +/* Copyright 2003-2015 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_COMPOSITE_KEY_HPP +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) +#include +#endif + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif + +/* A composite key stores n key extractors and "computes" the + * result on a given value as a packed reference to the value and + * the composite key itself. Actual invocations to the component + * key extractors are lazily performed when executing an operation + * on composite_key results (equality, comparison, hashing.) + * As the other key extractors in Boost.MultiIndex, composite_key + * is overloaded to work on chained pointers to T and reference_wrappers + * of T. + */ + +/* This user_definable macro limits the number of elements of a composite + * key; useful for shortening resulting symbol names (MSVC++ 6.0, for + * instance has problems coping with very long symbol names.) + * NB: This cannot exceed the maximum number of arguments of + * boost::tuple. In Boost 1.32, the limit is 10. + */ + +#if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE) +#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10 +#endif + +/* maximum number of key extractors in a composite key */ + +#if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */ +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \ + BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE +#else +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10 +#endif + +/* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ + +#define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \ + BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data) + +/* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ + +#define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \ + BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param) + +/* if n==0 -> text0 + * otherwise -> textn=tuples::null_type + */ + +#define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \ + typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type) + +/* const textn& kn=textn() */ + +#define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \ + const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)() + +/* typename list(0)::type */ + +#define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \ + BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \ + BOOST_PP_LIST_AT(list,1),n \ + >::type + +namespace boost{ + +template class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +namespace detail{ + +/* n-th key extractor of a composite key */ + +template +struct nth_key_from_value +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename mpl::eval_if_c< + N::value, + tuples::element, + mpl::identity + >::type type; +}; + +/* nth_composite_key_##name::type yields + * functor >, or tuples::null_type + * if N exceeds the length of the composite key. + */ + +#define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \ +template \ +struct BOOST_PP_CAT(key_,name) \ +{ \ + typedef functor type; \ +}; \ + \ +template<> \ +struct BOOST_PP_CAT(key_,name) \ +{ \ + typedef tuples::null_type type; \ +}; \ + \ +template \ +struct BOOST_PP_CAT(nth_composite_key_,name) \ +{ \ + typedef typename nth_key_from_value::type key_from_value; \ + typedef typename BOOST_PP_CAT(key_,name)::type type; \ +}; + +/* nth_composite_key_equal_to + * nth_composite_key_less + * nth_composite_key_greater + * nth_composite_key_hash + */ + +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to) +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less) +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater) +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash) + +/* used for defining equality and comparison ops of composite_key_result */ + +#define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text + +struct generic_operator_equal +{ + template + bool operator()(const T& x,const Q& y)const{return x==y;} +}; + +typedef tuple< + BOOST_MULTI_INDEX_CK_ENUM( + BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO, + detail::generic_operator_equal)> generic_operator_equal_tuple; + +struct generic_operator_less +{ + template + bool operator()(const T& x,const Q& y)const{return x generic_operator_less_tuple; + +/* Metaprogramming machinery for implementing equality, comparison and + * hashing operations of composite_key_result. + * + * equal_* checks for equality between composite_key_results and + * between those and tuples, accepting a tuple of basic equality functors. + * compare_* does lexicographical comparison. + * hash_* computes a combination of elementwise hash values. + */ + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename EqualCons +> +struct equal_ckey_ckey; /* fwd decl. */ + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename EqualCons +> +struct equal_ckey_ckey_terminal +{ + static bool compare( + const KeyCons1&,const Value1&, + const KeyCons2&,const Value2&, + const EqualCons&) + { + return true; + } +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename EqualCons +> +struct equal_ckey_ckey_normal +{ + static bool compare( + const KeyCons1& c0,const Value1& v0, + const KeyCons2& c1,const Value2& v1, + const EqualCons& eq) + { + if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false; + return equal_ckey_ckey< + BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, + BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, + BOOST_DEDUCED_TYPENAME EqualCons::tail_type + >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail()); + } +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename EqualCons +> +struct equal_ckey_ckey: + mpl::if_< + mpl::or_< + is_same, + is_same + >, + equal_ckey_ckey_terminal, + equal_ckey_ckey_normal + >::type +{ +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename EqualCons +> +struct equal_ckey_cval; /* fwd decl. */ + +template +< + typename KeyCons,typename Value, + typename ValCons,typename EqualCons +> +struct equal_ckey_cval_terminal +{ + static bool compare( + const KeyCons&,const Value&,const ValCons&,const EqualCons&) + { + return true; + } + + static bool compare( + const ValCons&,const KeyCons&,const Value&,const EqualCons&) + { + return true; + } +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename EqualCons +> +struct equal_ckey_cval_normal +{ + static bool compare( + const KeyCons& c,const Value& v,const ValCons& vc, + const EqualCons& eq) + { + if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false; + return equal_ckey_cval< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME EqualCons::tail_type + >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail()); + } + + static bool compare( + const ValCons& vc,const KeyCons& c,const Value& v, + const EqualCons& eq) + { + if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false; + return equal_ckey_cval< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME EqualCons::tail_type + >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail()); + } +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename EqualCons +> +struct equal_ckey_cval: + mpl::if_< + mpl::or_< + is_same, + is_same + >, + equal_ckey_cval_terminal, + equal_ckey_cval_normal + >::type +{ +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename CompareCons +> +struct compare_ckey_ckey; /* fwd decl. */ + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename CompareCons +> +struct compare_ckey_ckey_terminal +{ + static bool compare( + const KeyCons1&,const Value1&, + const KeyCons2&,const Value2&, + const CompareCons&) + { + return false; + } +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename CompareCons +> +struct compare_ckey_ckey_normal +{ + static bool compare( + const KeyCons1& c0,const Value1& v0, + const KeyCons2& c1,const Value2& v1, + const CompareCons& comp) + { + if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true; + if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false; + return compare_ckey_ckey< + BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, + BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, + BOOST_DEDUCED_TYPENAME CompareCons::tail_type + >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail()); + } +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename CompareCons +> +struct compare_ckey_ckey: + mpl::if_< + mpl::or_< + is_same, + is_same + >, + compare_ckey_ckey_terminal, + compare_ckey_ckey_normal + >::type +{ +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename CompareCons +> +struct compare_ckey_cval; /* fwd decl. */ + +template +< + typename KeyCons,typename Value, + typename ValCons,typename CompareCons +> +struct compare_ckey_cval_terminal +{ + static bool compare( + const KeyCons&,const Value&,const ValCons&,const CompareCons&) + { + return false; + } + + static bool compare( + const ValCons&,const KeyCons&,const Value&,const CompareCons&) + { + return false; + } +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename CompareCons +> +struct compare_ckey_cval_normal +{ + static bool compare( + const KeyCons& c,const Value& v,const ValCons& vc, + const CompareCons& comp) + { + if(comp.get_head()(c.get_head()(v),vc.get_head()))return true; + if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false; + return compare_ckey_cval< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME CompareCons::tail_type + >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail()); + } + + static bool compare( + const ValCons& vc,const KeyCons& c,const Value& v, + const CompareCons& comp) + { + if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true; + if(comp.get_head()(c.get_head()(v),vc.get_head()))return false; + return compare_ckey_cval< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME CompareCons::tail_type + >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail()); + } +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename CompareCons +> +struct compare_ckey_cval: + mpl::if_< + mpl::or_< + is_same, + is_same + >, + compare_ckey_cval_terminal, + compare_ckey_cval_normal + >::type +{ +}; + +template +struct hash_ckey; /* fwd decl. */ + +template +struct hash_ckey_terminal +{ + static std::size_t hash( + const KeyCons&,const Value&,const HashCons&,std::size_t carry) + { + return carry; + } +}; + +template +struct hash_ckey_normal +{ + static std::size_t hash( + const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0) + { + /* same hashing formula as boost::hash_combine */ + + carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2); + return hash_ckey< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME HashCons::tail_type + >::hash(c.get_tail(),v,h.get_tail(),carry); + } +}; + +template +struct hash_ckey: + mpl::if_< + is_same, + hash_ckey_terminal, + hash_ckey_normal + >::type +{ +}; + +template +struct hash_cval; /* fwd decl. */ + +template +struct hash_cval_terminal +{ + static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry) + { + return carry; + } +}; + +template +struct hash_cval_normal +{ + static std::size_t hash( + const ValCons& vc,const HashCons& h,std::size_t carry=0) + { + carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2); + return hash_cval< + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME HashCons::tail_type + >::hash(vc.get_tail(),h.get_tail(),carry); + } +}; + +template +struct hash_cval: + mpl::if_< + is_same, + hash_cval_terminal, + hash_cval_normal + >::type +{ +}; + +} /* namespace multi_index::detail */ + +/* composite_key_result */ + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4512) +#endif + +template +struct composite_key_result +{ + typedef CompositeKey composite_key_type; + typedef typename composite_key_type::value_type value_type; + + composite_key_result( + const composite_key_type& composite_key_,const value_type& value_): + composite_key(composite_key_),value(value_) + {} + + const composite_key_type& composite_key; + const value_type& value; +}; + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +/* composite_key */ + +template< + typename Value, + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue) +> +struct composite_key: + private tuple +{ +private: + typedef tuple super; + +public: + typedef super key_extractor_tuple; + typedef Value value_type; + typedef composite_key_result result_type; + + composite_key( + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)): + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) + {} + + composite_key(const key_extractor_tuple& x):super(x){} + + const key_extractor_tuple& key_extractors()const{return *this;} + key_extractor_tuple& key_extractors(){return *this;} + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,result_type>::type +#else + result_type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + result_type operator()(const value_type& x)const + { + return result_type(*this,x); + } + + result_type operator()(const reference_wrapper& x)const + { + return result_type(*this,x.get()); + } + + result_type operator()(const reference_wrapper& x)const + { + return result_type(*this,x.get()); + } +}; + +/* comparison operators */ + +/* == */ + +template +inline bool operator==( + const composite_key_result& x, + const composite_key_result& y) +{ + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; + typedef typename CompositeKey1::value_type value_type1; + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; + typedef typename CompositeKey2::value_type value_type2; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_ckey< + key_extractor_tuple1,value_type1, + key_extractor_tuple2,value_type2, + detail::generic_operator_equal_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y.composite_key.key_extractors(),y.value, + detail::generic_operator_equal_tuple()); +} + +template< + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) +> +inline bool operator==( + const composite_key_result& x, + const tuple& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,detail::generic_operator_equal_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y,detail::generic_operator_equal_tuple()); +} + +template +< + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey +> +inline bool operator==( + const tuple& x, + const composite_key_result& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,detail::generic_operator_equal_tuple + >::compare( + x,y.composite_key.key_extractors(), + y.value,detail::generic_operator_equal_tuple()); +} + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline bool operator==( + const composite_key_result& x, + const std::tuple& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + static_cast(tuples::length::value)== + std::tuple_size::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,detail::generic_operator_equal_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + detail::make_cons_stdtuple(y),detail::generic_operator_equal_tuple()); +} + +template +inline bool operator==( + const std::tuple& x, + const composite_key_result& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + static_cast(tuples::length::value)== + std::tuple_size::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,detail::generic_operator_equal_tuple + >::compare( + detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), + y.value,detail::generic_operator_equal_tuple()); +} +#endif + +/* < */ + +template +inline bool operator<( + const composite_key_result& x, + const composite_key_result& y) +{ + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; + typedef typename CompositeKey1::value_type value_type1; + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; + typedef typename CompositeKey2::value_type value_type2; + + return detail::compare_ckey_ckey< + key_extractor_tuple1,value_type1, + key_extractor_tuple2,value_type2, + detail::generic_operator_less_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y.composite_key.key_extractors(),y.value, + detail::generic_operator_less_tuple()); +} + +template +< + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) +> +inline bool operator<( + const composite_key_result& x, + const tuple& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,detail::generic_operator_less_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y,detail::generic_operator_less_tuple()); +} + +template +< + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey +> +inline bool operator<( + const tuple& x, + const composite_key_result& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,detail::generic_operator_less_tuple + >::compare( + x,y.composite_key.key_extractors(), + y.value,detail::generic_operator_less_tuple()); +} + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline bool operator<( + const composite_key_result& x, + const std::tuple& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,detail::generic_operator_less_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + detail::make_cons_stdtuple(y),detail::generic_operator_less_tuple()); +} + +template +inline bool operator<( + const std::tuple& x, + const composite_key_result& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,detail::generic_operator_less_tuple + >::compare( + detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), + y.value,detail::generic_operator_less_tuple()); +} +#endif + +/* rest of comparison operators */ + +#define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \ +template inline bool operator!=(const a1& x,const a2& y) \ +{ \ + return !(x==y); \ +} \ + \ +template inline bool operator>(const a1& x,const a2& y) \ +{ \ + return y inline bool operator>=(const a1& x,const a2& y) \ +{ \ + return !(x inline bool operator<=(const a1& x,const a2& y) \ +{ \ + return !(y, + composite_key_result +) + +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + composite_key_result, + tuple +) + +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey, + tuple, + composite_key_result +) + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( + typename CompositeKey, + typename... Values, + composite_key_result, + std::tuple +) + +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( + typename CompositeKey, + typename... Values, + std::tuple, + composite_key_result +) +#endif + +/* composite_key_equal_to */ + +template +< + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred) +> +struct composite_key_equal_to: + private tuple +{ +private: + typedef tuple super; + +public: + typedef super key_eq_tuple; + + composite_key_equal_to( + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)): + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) + {} + + composite_key_equal_to(const key_eq_tuple& x):super(x){} + + const key_eq_tuple& key_eqs()const{return *this;} + key_eq_tuple& key_eqs(){return *this;} + + template + bool operator()( + const composite_key_result & x, + const composite_key_result & y)const + { + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; + typedef typename CompositeKey1::value_type value_type1; + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; + typedef typename CompositeKey2::value_type value_type2; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value&& + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_ckey< + key_extractor_tuple1,value_type1, + key_extractor_tuple2,value_type2, + key_eq_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y.composite_key.key_extractors(),y.value, + key_eqs()); + } + + template + < + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) + > + bool operator()( + const composite_key_result& x, + const tuple& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value&& + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,key_eq_tuple + >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs()); + } + + template + < + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey + > + bool operator()( + const tuple& x, + const composite_key_result& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value&& + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,key_eq_tuple + >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs()); + } + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + bool operator()( + const composite_key_result& x, + const std::tuple& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value&& + static_cast(tuples::length::value)== + std::tuple_size::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,key_eq_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + detail::make_cons_stdtuple(y),key_eqs()); + } + + template + bool operator()( + const std::tuple& x, + const composite_key_result& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + std::tuple_size::value<= + static_cast(tuples::length::value)&& + std::tuple_size::value== + static_cast(tuples::length::value)); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,key_eq_tuple + >::compare( + detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), + y.value,key_eqs()); + } +#endif +}; + +/* composite_key_compare */ + +template +< + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare) +> +struct composite_key_compare: + private tuple +{ +private: + typedef tuple super; + +public: + typedef super key_comp_tuple; + + composite_key_compare( + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)): + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) + {} + + composite_key_compare(const key_comp_tuple& x):super(x){} + + const key_comp_tuple& key_comps()const{return *this;} + key_comp_tuple& key_comps(){return *this;} + + template + bool operator()( + const composite_key_result & x, + const composite_key_result & y)const + { + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; + typedef typename CompositeKey1::value_type value_type1; + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; + typedef typename CompositeKey2::value_type value_type2; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value|| + tuples::length::value<= + tuples::length::value); + + return detail::compare_ckey_ckey< + key_extractor_tuple1,value_type1, + key_extractor_tuple2,value_type2, + key_comp_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y.composite_key.key_extractors(),y.value, + key_comps()); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template + bool operator()( + const composite_key_result& x, + const Value& y)const + { + return operator()(x,boost::make_tuple(boost::cref(y))); + } +#endif + + template + < + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) + > + bool operator()( + const composite_key_result& x, + const tuple& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value|| + tuples::length::value<= + tuples::length::value); + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,key_comp_tuple + >::compare(x.composite_key.key_extractors(),x.value,y,key_comps()); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template + bool operator()( + const Value& x, + const composite_key_result& y)const + { + return operator()(boost::make_tuple(boost::cref(x)),y); + } +#endif + + template + < + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey + > + bool operator()( + const tuple& x, + const composite_key_result& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value|| + tuples::length::value<= + tuples::length::value); + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,key_comp_tuple + >::compare(x,y.composite_key.key_extractors(),y.value,key_comps()); + } + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + bool operator()( + const composite_key_result& x, + const std::tuple& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value|| + std::tuple_size::value<= + static_cast(tuples::length::value)); + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,key_comp_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + detail::make_cons_stdtuple(y),key_comps()); + } + + template + bool operator()( + const std::tuple& x, + const composite_key_result& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + std::tuple_size::value<= + static_cast(tuples::length::value)|| + tuples::length::value<= + tuples::length::value); + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,key_comp_tuple + >::compare( + detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), + y.value,key_comps()); + } +#endif +}; + +/* composite_key_hash */ + +template +< + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash) +> +struct composite_key_hash: + private tuple +{ +private: + typedef tuple super; + +public: + typedef super key_hasher_tuple; + + composite_key_hash( + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)): + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) + {} + + composite_key_hash(const key_hasher_tuple& x):super(x){} + + const key_hasher_tuple& key_hash_functions()const{return *this;} + key_hasher_tuple& key_hash_functions(){return *this;} + + template + std::size_t operator()(const composite_key_result & x)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::hash_ckey< + key_extractor_tuple,value_type, + key_hasher_tuple + >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions()); + } + + template + std::size_t operator()( + const tuple& x)const + { + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::hash_cval< + key_tuple,key_hasher_tuple + >::hash(x,key_hash_functions()); + } + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + std::size_t operator()(const std::tuple& x)const + { + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + std::tuple_size::value== + static_cast(tuples::length::value)); + + return detail::hash_cval< + cons_key_tuple,key_hasher_tuple + >::hash(detail::make_cons_stdtuple(x),key_hash_functions()); + } +#endif +}; + +/* Instantiations of the former functors with "natural" basic components: + * composite_key_result_equal_to uses std::equal_to of the values. + * composite_key_result_less uses std::less. + * composite_key_result_greater uses std::greater. + * composite_key_result_hash uses boost::hash. + */ + +#define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \ +composite_key_equal_to< \ + BOOST_MULTI_INDEX_CK_ENUM( \ + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ + /* the argument is a PP list */ \ + (detail::nth_composite_key_equal_to, \ + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ + BOOST_PP_NIL))) \ + > + +template +struct composite_key_result_equal_to: +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS +BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER +{ +private: + typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super; + +public: + typedef CompositeKeyResult first_argument_type; + typedef first_argument_type second_argument_type; + typedef bool result_type; + + using super::operator(); +}; + +#define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \ +composite_key_compare< \ + BOOST_MULTI_INDEX_CK_ENUM( \ + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ + /* the argument is a PP list */ \ + (detail::nth_composite_key_less, \ + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ + BOOST_PP_NIL))) \ + > + +template +struct composite_key_result_less: +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS +BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER +{ +private: + typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super; + +public: + typedef CompositeKeyResult first_argument_type; + typedef first_argument_type second_argument_type; + typedef bool result_type; + + using super::operator(); +}; + +#define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \ +composite_key_compare< \ + BOOST_MULTI_INDEX_CK_ENUM( \ + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ + /* the argument is a PP list */ \ + (detail::nth_composite_key_greater, \ + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ + BOOST_PP_NIL))) \ + > + +template +struct composite_key_result_greater: +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS +BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER +{ +private: + typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super; + +public: + typedef CompositeKeyResult first_argument_type; + typedef first_argument_type second_argument_type; + typedef bool result_type; + + using super::operator(); +}; + +#define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \ +composite_key_hash< \ + BOOST_MULTI_INDEX_CK_ENUM( \ + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ + /* the argument is a PP list */ \ + (detail::nth_composite_key_hash, \ + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ + BOOST_PP_NIL))) \ + > + +template +struct composite_key_result_hash: +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS +BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER +{ +private: + typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super; + +public: + typedef CompositeKeyResult argument_type; + typedef std::size_t result_type; + + using super::operator(); +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Specializations of std::equal_to, std::less, std::greater and boost::hash + * for composite_key_results enabling interoperation with tuples of values. + */ + +namespace std{ + +template +struct equal_to >: + boost::multi_index::composite_key_result_equal_to< + boost::multi_index::composite_key_result + > +{ +}; + +template +struct less >: + boost::multi_index::composite_key_result_less< + boost::multi_index::composite_key_result + > +{ +}; + +template +struct greater >: + boost::multi_index::composite_key_result_greater< + boost::multi_index::composite_key_result + > +{ +}; + +} /* namespace std */ + +namespace boost{ + +template +struct hash >: + boost::multi_index::composite_key_result_hash< + boost::multi_index::composite_key_result + > +{ +}; + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER +#undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER +#undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER +#undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER +#undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS +#undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO +#undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR +#undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N +#undef BOOST_MULTI_INDEX_CK_CTOR_ARG +#undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM +#undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS +#undef BOOST_MULTI_INDEX_CK_ENUM +#undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp new file mode 100644 index 00000000000..f3346e836d4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp @@ -0,0 +1,54 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include +#include + +/* 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)&&(__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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp new file mode 100644 index 00000000000..02b06442290 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp @@ -0,0 +1,44 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp new file mode 100644 index 00000000000..0a7a26e0d4e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp @@ -0,0 +1,83 @@ +/* Copyright 2003-2016 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* constructs a stack-based object from a serialization archive */ + +template +struct archive_constructed:private noncopyable +{ + template + 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 + 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(); + } + +#include + + T& get(){return *reinterpret_cast(&space);} + +#include + +private: + typename aligned_storage::value>::type space; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp new file mode 100644 index 00000000000..9d78c3a363f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp @@ -0,0 +1,91 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include + +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://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199 + */ + +template > +struct auto_space:private noncopyable +{ + typedef typename boost::detail::allocator::rebind_to< + Allocator,T + >::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 +void swap(auto_space& x,auto_space& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp new file mode 100644 index 00000000000..8c9b62b716a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp @@ -0,0 +1,74 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* MPL machinery to construct a linear hierarchy of indices out of + * a index list. + */ + +struct index_applier +{ + template + struct apply + { + typedef typename IndexSpecifierMeta::type index_specifier; + typedef typename index_specifier:: + BOOST_NESTED_TEMPLATE index_class::type type; + }; +}; + +template +struct nth_layer +{ + BOOST_STATIC_CONSTANT(int,length=mpl::size::value); + + typedef typename mpl::eval_if_c< + N==length, + mpl::identity >, + mpl::apply2< + index_applier, + mpl::at_c, + nth_layer + > + >::type type; +}; + +template +struct multi_index_base_type:nth_layer<0,Value,IndexSpecifierList,Allocator> +{ + BOOST_STATIC_ASSERT(detail::is_index_list::value); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp new file mode 100644 index 00000000000..9be5ec84b43 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp @@ -0,0 +1,114 @@ +/* Copyright 2003-2014 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Iterator class for node-based indices with bidirectional + * iterators (ordered and sequenced indices.) + */ + +template +class bidir_node_iterator: + public bidirectional_iterator_helper< + bidir_node_iterator, + typename Node::value_type, + std::ptrdiff_t, + const typename Node::value_type*, + const typename Node::value_type&> +{ +public: + /* coverity[uninit_ctor]: suppress warning */ + 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 + void save(Archive& ar,const unsigned int)const + { + node_base_type* bnode=node; + ar< + void load(Archive& ar,const unsigned int) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast(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 +bool operator==( + const bidir_node_iterator& x, + const bidir_node_iterator& y) +{ + return x.get_node()==y.get_node(); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp new file mode 100644 index 00000000000..d9fa434d9a9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp @@ -0,0 +1,243 @@ +/* Copyright 2003-2015 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_BUCKET_ARRAY_HPP +#define BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* bucket structure for use by hashed indices */ + +#define BOOST_MULTI_INDEX_BA_SIZES_32BIT \ +(53ul)(97ul)(193ul)(389ul)(769ul) \ +(1543ul)(3079ul)(6151ul)(12289ul)(24593ul) \ +(49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \ +(1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \ +(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \ +(1610612741ul)(3221225473ul) + +#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */ +#define BOOST_MULTI_INDEX_BA_SIZES \ +BOOST_MULTI_INDEX_BA_SIZES_32BIT \ +(4294967291ul) +#else + /* obtained with aid from + * http://javaboutique.internet.com/prime_numb/ + * http://www.rsok.com/~jrm/next_ten_primes.html + * and verified with + * http://www.alpertron.com.ar/ECM.HTM + */ + +#define BOOST_MULTI_INDEX_BA_SIZES \ +BOOST_MULTI_INDEX_BA_SIZES_32BIT \ +(6442450939ul)(12884901893ul)(25769803751ul)(51539607551ul) \ +(103079215111ul)(206158430209ul)(412316860441ul)(824633720831ul) \ +(1649267441651ul)(3298534883309ul)(6597069766657ul)(13194139533299ul) \ +(26388279066623ul)(52776558133303ul)(105553116266489ul)(211106232532969ul) \ +(422212465066001ul)(844424930131963ul)(1688849860263953ul) \ +(3377699720527861ul)(6755399441055731ul)(13510798882111483ul) \ +(27021597764222939ul)(54043195528445957ul)(108086391056891903ul) \ +(216172782113783843ul)(432345564227567621ul)(864691128455135207ul) \ +(1729382256910270481ul)(3458764513820540933ul)(6917529027641081903ul) \ +(13835058055282163729ul)(18446744073709551557ul) +#endif + +template /* templatized to have in-header static var defs */ +class bucket_array_base:private noncopyable +{ +protected: + static const std::size_t sizes[ + BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)]; + + static std::size_t size_index(std::size_t n) + { + const std::size_t *bound=std::lower_bound(sizes,sizes+sizes_length,n); + if(bound==sizes+sizes_length)--bound; + return bound-sizes; + } + +#define BOOST_MULTI_INDEX_BA_POSITION_CASE(z,n,_) \ + case n:return hash%BOOST_PP_SEQ_ELEM(n,BOOST_MULTI_INDEX_BA_SIZES); + + static std::size_t position(std::size_t hash,std::size_t size_index_) + { + /* Accelerate hash%sizes[size_index_] by replacing with a switch on + * hash%Ci expressions, each Ci a compile-time constant, which the + * compiler can implement without using integer division. + */ + + switch(size_index_){ + default: /* never used */ + BOOST_PP_REPEAT( + BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES), + BOOST_MULTI_INDEX_BA_POSITION_CASE,~) + } + } + +private: + static const std::size_t sizes_length; +}; + +template +const std::size_t bucket_array_base<_>::sizes[]={ + BOOST_PP_SEQ_ENUM(BOOST_MULTI_INDEX_BA_SIZES) +}; + +template +const std::size_t bucket_array_base<_>::sizes_length= + sizeof(bucket_array_base<_>::sizes)/ + sizeof(bucket_array_base<_>::sizes[0]); + +#undef BOOST_MULTI_INDEX_BA_POSITION_CASE +#undef BOOST_MULTI_INDEX_BA_SIZES +#undef BOOST_MULTI_INDEX_BA_SIZES_32BIT + +template +class bucket_array:bucket_array_base<> +{ + typedef bucket_array_base<> super; + typedef hashed_index_base_node_impl< + typename boost::detail::allocator::rebind_to< + Allocator, + char + >::type + > base_node_impl_type; + +public: + typedef typename base_node_impl_type::base_pointer base_pointer; + typedef typename base_node_impl_type::pointer pointer; + + bucket_array(const Allocator& al,pointer end_,std::size_t size_): + size_index_(super::size_index(size_)), + spc(al,super::sizes[size_index_]+1) + { + clear(end_); + } + + std::size_t size()const + { + return super::sizes[size_index_]; + } + + std::size_t position(std::size_t hash)const + { + return super::position(hash,size_index_); + } + + base_pointer begin()const{return buckets();} + base_pointer end()const{return buckets()+size();} + base_pointer at(std::size_t n)const{return buckets()+n;} + + void clear(pointer end_) + { + for(base_pointer x=begin(),y=end();x!=y;++x)x->prior()=pointer(0); + end()->prior()=end_->prior()=end_; + end_->next()=end(); + } + + void swap(bucket_array& x) + { + std::swap(size_index_,x.size_index_); + spc.swap(x.spc); + } + +private: + std::size_t size_index_; + auto_space spc; + + base_pointer buckets()const + { + return spc.data(); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + friend class boost::serialization::access; + + /* bucket_arrays do not emit any kind of serialization info. They are + * fed to Boost.Serialization as hashed index iterators need to track + * them during serialization. + */ + + template + void serialize(Archive&,const unsigned int) + { + } +#endif +}; + +template +void swap(bucket_array& x,bucket_array& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +/* bucket_arrays never get constructed directly by Boost.Serialization, + * as archives are always fed pointers to previously existent + * arrays. 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 +inline void load_construct_data( + Archive&,boost::multi_index::detail::bucket_array*, + 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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp new file mode 100644 index 00000000000..855c5e06aa9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp @@ -0,0 +1,93 @@ +/* Copyright 2003-2014 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_CONS_STDTUPLE_HPP +#define BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* std::tuple wrapper providing the cons-based interface of boost::tuple for + * composite_key interoperability. + */ + +template +struct cons_stdtuple; + +struct cons_stdtuple_ctor_terminal +{ + typedef boost::tuples::null_type result_type; + + template + static result_type create(const StdTuple&) + { + return boost::tuples::null_type(); + } +}; + +template +struct cons_stdtuple_ctor_normal +{ + typedef cons_stdtuple result_type; + + static result_type create(const StdTuple& t) + { + return result_type(t); + } +}; + +template +struct cons_stdtuple_ctor: + boost::mpl::if_c< + N::value, + cons_stdtuple_ctor_normal, + cons_stdtuple_ctor_terminal + >::type +{}; + +template +struct cons_stdtuple +{ + typedef typename std::tuple_element::type head_type; + typedef cons_stdtuple_ctor tail_ctor; + typedef typename tail_ctor::result_type tail_type; + + cons_stdtuple(const StdTuple& t_):t(t_){} + + const head_type& get_head()const{return std::get(t);} + tail_type get_tail()const{return tail_ctor::create(t);} + + const StdTuple& t; +}; + +template +typename cons_stdtuple_ctor::result_type +make_cons_stdtuple(const StdTuple& t) +{ + return cons_stdtuple_ctor::create(t); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp new file mode 100644 index 00000000000..3e04a3e8295 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp @@ -0,0 +1,52 @@ +/* Copyright 2003-2013 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) +#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 +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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp new file mode 100644 index 00000000000..9a34b259cf3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp @@ -0,0 +1,142 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include + +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 +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& x)const + { + return std::less()(first,x.first); + } +}; + +template +class copy_map:private noncopyable +{ +public: + typedef const copy_map_entry* 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;isecond->value()); + deallocate((spc.data()+i)->second); + } + } + } + + const_iterator begin()const{return raw_ptr(spc.data());} + const_iterator end()const{return raw_ptr(spc.data()+n);} + + void clone(Node* node) + { + (spc.data()+n)->first=node; + (spc.data()+n)->second=raw_ptr(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( + raw_ptr*>(spc.data()), + raw_ptr*>(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,0))->second; + } + + void release() + { + released=true; + } + +private: + typedef typename boost::detail::allocator::rebind_to< + Allocator,Node + >::type allocator_type; + typedef typename allocator_type::pointer allocator_pointer; + + allocator_type al_; + std::size_t size_; + auto_space,Allocator> spc; + std::size_t n; + Node* header_org_; + Node* header_cpy_; + bool released; + + void deallocate(Node* node) + { + al_.deallocate(static_cast(node),1); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp new file mode 100644 index 00000000000..f0fa7304253 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp @@ -0,0 +1,34 @@ +/* Copyright 2003-2013 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_DO_NOT_COPY_ELEMENTS_TAG_HPP +#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Used to mark a special ctor variant that copies the internal objects of + * a container but not its elements. + */ + +struct do_not_copy_elements_tag{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp new file mode 100644 index 00000000000..cbebf264045 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp @@ -0,0 +1,120 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +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 +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 +bool operator==( + const duplicates_iterator& x, + const duplicates_iterator& y) +{ + return x.get_node()==y.get_node(); +} + +template +bool operator!=( + const duplicates_iterator& x, + const duplicates_iterator& y) +{ + return !(x==y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp new file mode 100644 index 00000000000..217b61143af --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp @@ -0,0 +1,42 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* determines whether an index type has a given tag in its tag list */ + +template +struct has_tag +{ + template + struct apply:mpl::contains + { + }; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp new file mode 100644 index 00000000000..81902f5a4a5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp @@ -0,0 +1,105 @@ +/* Copyright 2003-2013 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_HASH_INDEX_ARGS_HPP +#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Hashed index specifiers can be instantiated in two forms: + * + * (hashed_unique|hashed_non_unique)< + * KeyFromValue, + * Hash=boost::hash, + * Pred=std::equal_to > + * (hashed_unique|hashed_non_unique)< + * TagList, + * KeyFromValue, + * Hash=boost::hash, + * Pred=std::equal_to > + * + * hashed_index_args implements the machinery to accept this + * argument-dependent polymorphism. + */ + +template +struct index_args_default_hash +{ + typedef ::boost::hash type; +}; + +template +struct index_args_default_pred +{ + typedef std::equal_to type; +}; + +template +struct hashed_index_args +{ + typedef is_tag 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_hash_type; + typedef typename mpl::eval_if< + mpl::is_na, + index_args_default_hash, + mpl::identity + >::type hash_type; + typedef typename mpl::if_< + full_form, + Arg4, + Arg3>::type supplied_pred_type; + typedef typename mpl::eval_if< + mpl::is_na, + index_args_default_pred, + mpl::identity + >::type pred_type; + + BOOST_STATIC_ASSERT(is_tag::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp new file mode 100644 index 00000000000..8d063002a1d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp @@ -0,0 +1,166 @@ +/* Copyright 2003-2014 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_HASH_INDEX_ITERATOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Iterator class for hashed indices. + */ + +struct hashed_index_global_iterator_tag{}; +struct hashed_index_local_iterator_tag{}; + +template +class hashed_index_iterator: + public forward_iterator_helper< + hashed_index_iterator, + typename Node::value_type, + std::ptrdiff_t, + const typename Node::value_type*, + const typename Node::value_type&> +{ +public: + /* coverity[uninit_ctor]: suppress warning */ + hashed_index_iterator(){} + hashed_index_iterator(Node* node_):node(node_){} + + const typename Node::value_type& operator*()const + { + return node->value(); + } + + hashed_index_iterator& operator++() + { + this->increment(Category()); + 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 + void save(Archive& ar,const unsigned int)const + { + node_base_type* bnode=node; + ar< + void load(Archive& ar,const unsigned int version) + { + load(ar,version,Category()); + } + + template + void load( + Archive& ar,const unsigned int version,hashed_index_global_iterator_tag) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast(bnode); + if(version<1){ + BucketArray* throw_away; /* consume unused ptr */ + ar>>serialization::make_nvp("pointer",throw_away); + } + } + + template + void load( + Archive& ar,const unsigned int version,hashed_index_local_iterator_tag) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast(bnode); + if(version<1){ + BucketArray* buckets; + ar>>serialization::make_nvp("pointer",buckets); + if(buckets&&node&&node->impl()==buckets->end()->prior()){ + /* end local_iterators used to point to end node, now they are null */ + node=0; + } + } + } +#endif + + /* get_node is not to be used by the user */ + + typedef Node node_type; + + Node* get_node()const{return node;} + +private: + + void increment(hashed_index_global_iterator_tag) + { + Node::increment(node); + } + + void increment(hashed_index_local_iterator_tag) + { + Node::increment_local(node); + } + + Node* node; +}; + +template +bool operator==( + const hashed_index_iterator& x, + const hashed_index_iterator& y) +{ + return x.get_node()==y.get_node(); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +/* class version = 1 : hashed_index_iterator does no longer serialize a bucket + * array pointer. + */ + +namespace serialization { +template +struct version< + boost::multi_index::detail::hashed_index_iterator +> +{ + BOOST_STATIC_CONSTANT(int,value=1); +}; +} /* namespace serialization */ +#endif + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp new file mode 100644 index 00000000000..7788e810ac9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp @@ -0,0 +1,778 @@ +/* Copyright 2003-2015 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_HASH_INDEX_NODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Certain C++ requirements on unordered associative containers (see LWG issue + * #579) imply a data structure where nodes are linked in a single list, which + * in its turn forces implementors to add additional overhed per node to + * associate each with its corresponding bucket. Others resort to storing hash + * values, we use an alternative structure providing unconditional O(1) + * manipulation, even in situations of unfair hash distribution, plus some + * lookup speedups. For unique indices we maintain a doubly linked list of + * nodes except that if N is the first node of a bucket its associated + * bucket node is embedded between N and the preceding node in the following + * manner: + * + * +---+ +---+ +---+ +---+ + * <--+ |<--+ | <--+ |<--+ | + * ... | B0| | B1| ... | B1| | B2| ... + * | |-+ | +--> | |-+ | +--> + * +-+-+ | +---+ +-+-+ | +---+ + * | ^ | ^ + * | | | | + * | +-+ | +-+ + * | | | | + * v | v | + * --+---+---+---+-- --+---+---+---+-- + * ... | | B1| | ... | | B2| | ... + * --+---+---+---+-- --+---+---+---+-- + * + * + * The fist and last nodes of buckets can be checked with + * + * first node of a bucket: Npn != N + * last node of a bucket: Nnp != N + * + * (n and p short for ->next(), ->prior(), bucket nodes have prior pointers + * only). Pure insert and erase (without lookup) can be unconditionally done + * in O(1). + * For non-unique indices we add the following additional complexity: when + * there is a group of 3 or more equivalent elements, they are linked as + * follows: + * + * +-----------------------+ + * | v + * +---+ | +---+ +---+ +---+ + * | | +-+ | | |<--+ | + * | F | | S | ... | P | | L | + * | +-->| | | +-+ | | + * +---+ +---+ +---+ | +---+ + * ^ | + * +-----------------------+ + * + * F, S, P and L are the first, second, penultimate and last node in the + * group, respectively (S and P can coincide if the group has size 3.) This + * arrangement is used to skip equivalent elements in O(1) when doing lookup, + * while preserving O(1) insert/erase. The following invariants identify + * special positions (some of the operations have to be carefully implemented + * as Xnn is not valid if Xn points to a bucket): + * + * first node of a bucket: Npnp == N + * last node of a bucket: Nnpp == N + * first node of a group: Nnp != N && Nnppn == N + * second node of a group: Npn != N && Nppnn == N + * n-1 node of a group: Nnp != N && Nnnpp == N + * last node of a group: Npn != N && Npnnp == N + * + * The memory overhead is one pointer per bucket plus two pointers per node, + * probably unbeatable. The resulting structure is bidirectonally traversable, + * though currently we are just providing forward iteration. + */ + +template +struct hashed_index_node_impl; + +/* half-header (only prior() pointer) to use for the bucket array */ + +template +struct hashed_index_base_node_impl +{ + typedef typename + boost::detail::allocator::rebind_to< + Allocator,hashed_index_base_node_impl + >::type::pointer base_pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator,hashed_index_base_node_impl + >::type::const_pointer const_base_pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + hashed_index_node_impl + >::type::pointer pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + hashed_index_node_impl + >::type::const_pointer const_pointer; + + pointer& prior(){return prior_;} + pointer prior()const{return prior_;} + +private: + pointer prior_; +}; + +/* full header (prior() and next()) for the nodes */ + +template +struct hashed_index_node_impl:hashed_index_base_node_impl +{ +private: + typedef hashed_index_base_node_impl super; + +public: + typedef typename super::base_pointer base_pointer; + typedef typename super::const_base_pointer const_base_pointer; + typedef typename super::pointer pointer; + typedef typename super::const_pointer const_pointer; + + base_pointer& next(){return next_;} + base_pointer next()const{return next_;} + + static pointer pointer_from(base_pointer x) + { + return static_cast( + static_cast( + raw_ptr(x))); + } + + static base_pointer base_pointer_from(pointer x) + { + return static_cast( + raw_ptr(x)); + } + +private: + base_pointer next_; +}; + +/* Boost.MultiIndex requires machinery to reverse unlink operations. A simple + * way to make a pointer-manipulation function undoable is to templatize + * its internal pointer assignments with a functor that, besides doing the + * assignment, keeps track of the original pointer values and can later undo + * the operations in reverse order. + */ + +struct default_assigner +{ + template void operator()(T& x,const T& val){x=val;} +}; + +template +struct unlink_undo_assigner +{ + typedef typename Node::base_pointer base_pointer; + typedef typename Node::pointer pointer; + + unlink_undo_assigner():pointer_track_count(0),base_pointer_track_count(0){} + + void operator()(pointer& x,pointer val) + { + pointer_tracks[pointer_track_count].x=&x; + pointer_tracks[pointer_track_count++].val=x; + x=val; + } + + void operator()(base_pointer& x,base_pointer val) + { + base_pointer_tracks[base_pointer_track_count].x=&x; + base_pointer_tracks[base_pointer_track_count++].val=x; + x=val; + } + + void operator()() /* undo op */ + { + /* in the absence of aliasing, restitution order is immaterial */ + + while(pointer_track_count--){ + *(pointer_tracks[pointer_track_count].x)= + pointer_tracks[pointer_track_count].val; + } + while(base_pointer_track_count--){ + *(base_pointer_tracks[base_pointer_track_count].x)= + base_pointer_tracks[base_pointer_track_count].val; + } + } + + struct pointer_track {pointer* x; pointer val;}; + struct base_pointer_track{base_pointer* x; base_pointer val;}; + + /* We know the maximum number of pointer and base pointer assignments that + * the two unlink versions do, so we can statically reserve the needed + * storage. + */ + + pointer_track pointer_tracks[3]; + int pointer_track_count; + base_pointer_track base_pointer_tracks[2]; + int base_pointer_track_count; +}; + +/* algorithmic stuff for unique and non-unique variants */ + +struct hashed_unique_tag{}; +struct hashed_non_unique_tag{}; + +template +struct hashed_index_node_alg; + +template +struct hashed_index_node_alg +{ + typedef typename Node::base_pointer base_pointer; + typedef typename Node::const_base_pointer const_base_pointer; + typedef typename Node::pointer pointer; + typedef typename Node::const_pointer const_pointer; + + static bool is_first_of_bucket(pointer x) + { + return x->prior()->next()!=base_pointer_from(x); + } + + static pointer after(pointer x) + { + return is_last_of_bucket(x)?x->next()->prior():pointer_from(x->next()); + } + + static pointer after_local(pointer x) + { + return is_last_of_bucket(x)?pointer(0):pointer_from(x->next()); + } + + static pointer next_to_inspect(pointer x) + { + return is_last_of_bucket(x)?pointer(0):pointer_from(x->next()); + } + + static void link(pointer x,base_pointer buc,pointer end) + { + if(buc->prior()==pointer(0)){ /* empty bucket */ + x->prior()=end->prior(); + x->next()=end->prior()->next(); + x->prior()->next()=buc; + buc->prior()=x; + end->prior()=x; + } + else{ + x->prior()=buc->prior()->prior(); + x->next()=base_pointer_from(buc->prior()); + buc->prior()=x; + x->next()->prior()=x; + } + } + + static void unlink(pointer x) + { + default_assigner assign; + unlink(x,assign); + } + + typedef unlink_undo_assigner unlink_undo; + + template + static void unlink(pointer x,Assigner& assign) + { + if(is_first_of_bucket(x)){ + if(is_last_of_bucket(x)){ + assign(x->prior()->next()->prior(),pointer(0)); + assign(x->prior()->next(),x->next()); + assign(x->next()->prior()->prior(),x->prior()); + } + else{ + assign(x->prior()->next()->prior(),pointer_from(x->next())); + assign(x->next()->prior(),x->prior()); + } + } + else if(is_last_of_bucket(x)){ + assign(x->prior()->next(),x->next()); + assign(x->next()->prior()->prior(),x->prior()); + } + else{ + assign(x->prior()->next(),x->next()); + assign(x->next()->prior(),x->prior()); + } + } + + /* used only at rehashing */ + + static void append(pointer x,pointer end) + { + x->prior()=end->prior(); + x->next()=end->prior()->next(); + x->prior()->next()=base_pointer_from(x); + end->prior()=x; + } + + static bool unlink_last(pointer end) + { + /* returns true iff bucket is emptied */ + + pointer x=end->prior(); + if(x->prior()->next()==base_pointer_from(x)){ + x->prior()->next()=x->next(); + end->prior()=x->prior(); + return false; + } + else{ + x->prior()->next()->prior()=pointer(0); + x->prior()->next()=x->next(); + end->prior()=x->prior(); + return true; + } + } + +private: + static pointer pointer_from(base_pointer x) + { + return Node::pointer_from(x); + } + + static base_pointer base_pointer_from(pointer x) + { + return Node::base_pointer_from(x); + } + + static bool is_last_of_bucket(pointer x) + { + return x->next()->prior()!=x; + } +}; + +template +struct hashed_index_node_alg +{ + typedef typename Node::base_pointer base_pointer; + typedef typename Node::const_base_pointer const_base_pointer; + typedef typename Node::pointer pointer; + typedef typename Node::const_pointer const_pointer; + + static bool is_first_of_bucket(pointer x) + { + return x->prior()->next()->prior()==x; + } + + static bool is_first_of_group(pointer x) + { + return + x->next()->prior()!=x&& + x->next()->prior()->prior()->next()==base_pointer_from(x); + } + + static pointer after(pointer x) + { + if(x->next()->prior()==x)return pointer_from(x->next()); + if(x->next()->prior()->prior()==x)return x->next()->prior(); + if(x->next()->prior()->prior()->next()==base_pointer_from(x)) + return pointer_from(x->next()); + return pointer_from(x->next())->next()->prior(); + } + + static pointer after_local(pointer x) + { + if(x->next()->prior()==x)return pointer_from(x->next()); + if(x->next()->prior()->prior()==x)return pointer(0); + if(x->next()->prior()->prior()->next()==base_pointer_from(x)) + return pointer_from(x->next()); + return pointer_from(x->next())->next()->prior(); + } + + static pointer next_to_inspect(pointer x) + { + if(x->next()->prior()==x)return pointer_from(x->next()); + if(x->next()->prior()->prior()==x)return pointer(0); + if(x->next()->prior()->next()->prior()!=x->next()->prior()) + return pointer(0); + return pointer_from(x->next()->prior()->next()); + } + + static void link(pointer x,base_pointer buc,pointer end) + { + if(buc->prior()==pointer(0)){ /* empty bucket */ + x->prior()=end->prior(); + x->next()=end->prior()->next(); + x->prior()->next()=buc; + buc->prior()=x; + end->prior()=x; + } + else{ + x->prior()=buc->prior()->prior(); + x->next()=base_pointer_from(buc->prior()); + buc->prior()=x; + x->next()->prior()=x; + } + }; + + static void link(pointer x,pointer first,pointer last) + { + x->prior()=first->prior(); + x->next()=base_pointer_from(first); + if(is_first_of_bucket(first)){ + x->prior()->next()->prior()=x; + } + else{ + x->prior()->next()=base_pointer_from(x); + } + + if(first==last){ + last->prior()=x; + } + else if(first->next()==base_pointer_from(last)){ + first->prior()=last; + first->next()=base_pointer_from(x); + } + else{ + pointer second=pointer_from(first->next()), + lastbutone=last->prior(); + second->prior()=first; + first->prior()=last; + lastbutone->next()=base_pointer_from(x); + } + } + + static void unlink(pointer x) + { + default_assigner assign; + unlink(x,assign); + } + + typedef unlink_undo_assigner unlink_undo; + + template + static void unlink(pointer x,Assigner& assign) + { + if(x->prior()->next()==base_pointer_from(x)){ + if(x->next()->prior()==x){ + left_unlink(x,assign); + right_unlink(x,assign); + } + else if(x->next()->prior()->prior()==x){ /* last of bucket */ + left_unlink(x,assign); + right_unlink_last_of_bucket(x,assign); + } + else if(x->next()->prior()->prior()->next()== + base_pointer_from(x)){ /* first of group size */ + left_unlink(x,assign); + right_unlink_first_of_group(x,assign); + } + else{ /* n-1 of group */ + unlink_last_but_one_of_group(x,assign); + } + } + else if(x->prior()->next()->prior()==x){ /* first of bucket */ + if(x->next()->prior()==x){ + left_unlink_first_of_bucket(x,assign); + right_unlink(x,assign); + } + else if(x->next()->prior()->prior()==x){ /* last of bucket */ + assign(x->prior()->next()->prior(),pointer(0)); + assign(x->prior()->next(),x->next()); + assign(x->next()->prior()->prior(),x->prior()); + } + else{ /* first of group */ + left_unlink_first_of_bucket(x,assign); + right_unlink_first_of_group(x,assign); + } + } + else if(x->next()->prior()->prior()==x){ /* last of group and bucket */ + left_unlink_last_of_group(x,assign); + right_unlink_last_of_bucket(x,assign); + } + else if(pointer_from(x->prior()->prior()->next()) + ->next()==base_pointer_from(x)){ /* second of group */ + unlink_second_of_group(x,assign); + } + else{ /* last of group, ~(last of bucket) */ + left_unlink_last_of_group(x,assign); + right_unlink(x,assign); + } + } + + /* used only at rehashing */ + + static void link_range( + pointer first,pointer last,base_pointer buc,pointer cend) + { + if(buc->prior()==pointer(0)){ /* empty bucket */ + first->prior()=cend->prior(); + last->next()=cend->prior()->next(); + first->prior()->next()=buc; + buc->prior()=first; + cend->prior()=last; + } + else{ + first->prior()=buc->prior()->prior(); + last->next()=base_pointer_from(buc->prior()); + buc->prior()=first; + last->next()->prior()=last; + } + } + + static void append_range(pointer first,pointer last,pointer cend) + { + first->prior()=cend->prior(); + last->next()=cend->prior()->next(); + first->prior()->next()=base_pointer_from(first); + cend->prior()=last; + } + + static std::pair unlink_last_group(pointer end) + { + /* returns first of group true iff bucket is emptied */ + + pointer x=end->prior(); + if(x->prior()->next()==base_pointer_from(x)){ + x->prior()->next()=x->next(); + end->prior()=x->prior(); + return std::make_pair(x,false); + } + else if(x->prior()->next()->prior()==x){ + x->prior()->next()->prior()=pointer(0); + x->prior()->next()=x->next(); + end->prior()=x->prior(); + return std::make_pair(x,true); + } + else{ + pointer y=pointer_from(x->prior()->next()); + + if(y->prior()->next()==base_pointer_from(y)){ + y->prior()->next()=x->next(); + end->prior()=y->prior(); + return std::make_pair(y,false); + } + else{ + y->prior()->next()->prior()=pointer(0); + y->prior()->next()=x->next(); + end->prior()=y->prior(); + return std::make_pair(y,true); + } + } + } + + static void unlink_range(pointer first,pointer last) + { + if(is_first_of_bucket(first)){ + if(is_last_of_bucket(last)){ + first->prior()->next()->prior()=pointer(0); + first->prior()->next()=last->next(); + last->next()->prior()->prior()=first->prior(); + } + else{ + first->prior()->next()->prior()=pointer_from(last->next()); + last->next()->prior()=first->prior(); + } + } + else if(is_last_of_bucket(last)){ + first->prior()->next()=last->next(); + last->next()->prior()->prior()=first->prior(); + } + else{ + first->prior()->next()=last->next(); + last->next()->prior()=first->prior(); + } + } + +private: + static pointer pointer_from(base_pointer x) + { + return Node::pointer_from(x); + } + + static base_pointer base_pointer_from(pointer x) + { + return Node::base_pointer_from(x); + } + + static bool is_last_of_bucket(pointer x) + { + return x->next()->prior()->prior()==x; + } + + template + static void left_unlink(pointer x,Assigner& assign) + { + assign(x->prior()->next(),x->next()); + } + + template + static void right_unlink(pointer x,Assigner& assign) + { + assign(x->next()->prior(),x->prior()); + } + + template + static void left_unlink_first_of_bucket(pointer x,Assigner& assign) + { + assign(x->prior()->next()->prior(),pointer_from(x->next())); + } + + template + static void right_unlink_last_of_bucket(pointer x,Assigner& assign) + { + assign(x->next()->prior()->prior(),x->prior()); + } + + template + static void right_unlink_first_of_group(pointer x,Assigner& assign) + { + pointer second=pointer_from(x->next()), + last=second->prior(), + lastbutone=last->prior(); + if(second==lastbutone){ + assign(second->next(),base_pointer_from(last)); + assign(second->prior(),x->prior()); + } + else{ + assign(lastbutone->next(),base_pointer_from(second)); + assign(second->next()->prior(),last); + assign(second->prior(),x->prior()); + } + } + + template + static void left_unlink_last_of_group(pointer x,Assigner& assign) + { + pointer lastbutone=x->prior(), + first=pointer_from(lastbutone->next()), + second=pointer_from(first->next()); + if(lastbutone==second){ + assign(lastbutone->prior(),first); + assign(lastbutone->next(),x->next()); + } + else{ + assign(second->prior(),lastbutone); + assign(lastbutone->prior()->next(),base_pointer_from(first)); + assign(lastbutone->next(),x->next()); + } + } + + template + static void unlink_last_but_one_of_group(pointer x,Assigner& assign) + { + pointer first=pointer_from(x->next()), + second=pointer_from(first->next()), + last=second->prior(); + if(second==x){ + assign(last->prior(),first); + assign(first->next(),base_pointer_from(last)); + } + else{ + assign(last->prior(),x->prior()); + assign(x->prior()->next(),base_pointer_from(first)); + } + } + + template + static void unlink_second_of_group(pointer x,Assigner& assign) + { + pointer last=x->prior(), + lastbutone=last->prior(), + first=pointer_from(lastbutone->next()); + if(lastbutone==x){ + assign(first->next(),base_pointer_from(last)); + assign(last->prior(),first); + } + else{ + assign(first->next(),x->next()); + assign(x->next()->prior(),last); + } + } +}; + +template +struct hashed_index_node_trampoline: + hashed_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > +{ + typedef typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type impl_allocator_type; + typedef hashed_index_node_impl impl_type; +}; + +template +struct hashed_index_node: + Super,hashed_index_node_trampoline +{ +private: + typedef hashed_index_node_trampoline trampoline; + +public: + typedef typename trampoline::impl_type impl_type; + typedef hashed_index_node_alg< + impl_type,Category> node_alg; + typedef typename trampoline::base_pointer impl_base_pointer; + typedef typename trampoline::const_base_pointer const_impl_base_pointer; + 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_base_pointer& next(){return trampoline::next();} + impl_base_pointer next()const{return trampoline::next();} + + impl_pointer impl() + { + return static_cast( + static_cast(static_cast(this))); + } + + const_impl_pointer impl()const + { + return static_cast( + static_cast(static_cast(this))); + } + + static hashed_index_node* from_impl(impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + static const hashed_index_node* from_impl(const_impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + /* interoperability with hashed_index_iterator */ + + static void increment(hashed_index_node*& x) + { + x=from_impl(node_alg::after(x->impl())); + } + + static void increment_local(hashed_index_node*& x) + { + x=from_impl(node_alg::after_local(x->impl())); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp new file mode 100644 index 00000000000..ca8a9b2edb1 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +#pragma once +#endif + +#include + +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 +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(this);} +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp new file mode 100644 index 00000000000..ae398456d1f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp @@ -0,0 +1,18 @@ +/* Copyright 2003-2016 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. + */ + +#include + +#if defined(BOOST_GCC)&&(BOOST_GCC>=4*10000+6*100) +#if !defined(BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#else +#pragma GCC diagnostic pop +#endif +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp new file mode 100644 index 00000000000..99000ed4813 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp @@ -0,0 +1,293 @@ +/* Copyright 2003-2014 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#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.) + */ + +struct lvalue_tag{}; +struct rvalue_tag{}; +struct emplaced_tag{}; + +template +class index_base +{ +protected: + typedef index_node_base 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 Value value_type; + +protected: + explicit index_base(const ctor_args_list&,const Allocator&){} + + index_base( + const index_base&, + do_not_copy_elements_tag) + {} + + void copy_( + const index_base&,const copy_map_type&) + {} + + final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag) + { + x=final().allocate_node(); + BOOST_TRY{ + boost::detail::allocator::construct(&x->value(),v); + } + BOOST_CATCH(...){ + final().deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + return x; + } + + final_node_type* insert_(const value_type& v,final_node_type*& x,rvalue_tag) + { + x=final().allocate_node(); + BOOST_TRY{ + /* This shoud have used a modified, T&&-compatible version of + * boost::detail::allocator::construct, but + * is too old and venerable to + * mess with; besides, it is a general internal utility and the imperfect + * perfect forwarding emulation of Boost.Move might break other libs. + */ + + new (&x->value()) value_type(boost::move(const_cast(v))); + } + BOOST_CATCH(...){ + final().deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + return x; + } + + final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag) + { + return x; + } + + final_node_type* insert_( + const value_type& v,node_type*,final_node_type*& x,lvalue_tag) + { + return insert_(v,x,lvalue_tag()); + } + + final_node_type* insert_( + const value_type& v,node_type*,final_node_type*& x,rvalue_tag) + { + return insert_(v,x,rvalue_tag()); + } + + final_node_type* insert_( + const value_type&,node_type*,final_node_type*& x,emplaced_tag) + { + 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&){} + + void swap_elements_(index_base&){} + + bool replace_(const value_type& v,node_type* x,lvalue_tag) + { + x->value()=v; + return true; + } + + bool replace_(const value_type& v,node_type* x,rvalue_tag) + { + x->value()=boost::move(const_cast(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 + void save_(Archive&,const unsigned int,const index_saver_type&)const{} + + template + 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(this);} + const final_type& final()const{return *static_cast(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_insert_(const value_type& x) + {return final().insert_(x);} + std::pair final_insert_rv_(const value_type& x) + {return final().insert_rv_(x);} + template + std::pair final_insert_ref_(const T& t) + {return final().insert_ref_(t);} + template + std::pair final_insert_ref_(T& t) + {return final().insert_ref_(t);} + + template + std::pair final_emplace_( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + std::pair final_insert_( + const value_type& x,final_node_type* position) + {return final().insert_(x,position);} + std::pair final_insert_rv_( + const value_type& x,final_node_type* position) + {return final().insert_rv_(x,position);} + template + std::pair final_insert_ref_( + const T& t,final_node_type* position) + {return final().insert_ref_(t,position);} + template + std::pair final_insert_ref_( + T& t,final_node_type* position) + {return final().insert_ref_(t,position);} + + template + std::pair final_emplace_hint_( + final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return final().emplace_hint_( + position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + 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_( + const value_type& k,final_node_type* x) + {return final().replace_(k,x);} + bool final_replace_rv_( + const value_type& k,final_node_type* x) + {return final().replace_rv_(k,x);} + + template + bool final_modify_(Modifier& mod,final_node_type* x) + {return final().modify_(mod,x);} + + template + 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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp new file mode 100644 index 00000000000..71418a10e19 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp @@ -0,0 +1,139 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include + +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 +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 + void add(Node* node,Archive& ar,const unsigned int) + { + ar>>serialization::make_nvp("position",*node); + entries()[n++]=node; + } + + template + 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 + 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 raw_ptr(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 + FinalNode* unchecked_load_node(Archive& ar)const + { + Node* node=0; + ar>>serialization::make_nvp("pointer",node); + return static_cast(node); + } + + template + FinalNode* load_node(Archive& ar)const + { + Node* node=0; + ar>>serialization::make_nvp("pointer",node); + check_node(node); + return static_cast(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 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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp new file mode 100644 index 00000000000..34d1f9d5a8d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp @@ -0,0 +1,249 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +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()(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 +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 raw_ptr(spc.data());} + + auto_space 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 +class algorithm:private algorithm_base +{ + typedef algorithm_base super; + +public: + algorithm(const Allocator& al,std::size_t size):super(al,size){} + + void add(Node* node) + { + super::add(node); + } + + template + 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 + static Node* get_node(IndexIterator it) + { + return static_cast(it.get_node()); + } +}; + +} /* namespace multi_index::detail::index_matcher */ + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp new file mode 100644 index 00000000000..1a1f0cae4be --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp @@ -0,0 +1,135 @@ +/* Copyright 2003-2016 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#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 +struct pod_value_holder +{ + typename aligned_storage< + sizeof(Value), + alignment_of::value + >::type space; +}; + +template +struct index_node_base:private pod_value_holder +{ + typedef index_node_base base_type; /* used for serialization purposes */ + typedef Value value_type; + typedef Allocator allocator_type; + +#include + + value_type& value() + { + return *reinterpret_cast(&this->space); + } + + const value_type& value()const + { + return *reinterpret_cast(&this->space); + } + +#include + + static index_node_base* from_value(const value_type* p) + { + return static_cast( + reinterpret_cast*>( /* std 9.2.17 */ + const_cast(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 + void serialize(Archive&,const unsigned int) + { + } +#endif +}; + +template +Node* node_from_value(const Value* p) +{ + typedef typename Node::allocator_type allocator_type; + return static_cast( + index_node_base::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 +inline void load_construct_data( + Archive&,boost::multi_index::detail::index_node_base*, + 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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp new file mode 100644 index 00000000000..ae09d4eba4f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp @@ -0,0 +1,135 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include + +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 +class index_saver:private noncopyable +{ +public: + index_saver(const Allocator& al,std::size_t size):alg(al,size){} + + template + void add(Node* node,Archive& ar,const unsigned int) + { + ar< + void add_track(Node* node,Archive& ar,const unsigned int) + { + ar< + 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 + static Node* get_node(IndexIterator it) + { + return it.get_node(); + } + + static Node* null_node(){return 0;} + + template + static void save_node(Node* node,Archive& ar) + { + ar< alg; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp new file mode 100644 index 00000000000..c6c547c7c33 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp @@ -0,0 +1,21 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#if !defined(BOOST_MULTI_INDEX_INVARIANT_ASSERT) +#include +#define BOOST_MULTI_INDEX_INVARIANT_ASSERT BOOST_ASSERT +#endif + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp new file mode 100644 index 00000000000..f6a24218b81 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp @@ -0,0 +1,40 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct is_index_list +{ + BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence::value); + BOOST_STATIC_CONSTANT(bool,non_empty=!mpl::empty::value); + BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp new file mode 100644 index 00000000000..72036d257e2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp @@ -0,0 +1,135 @@ +/* Copyright 2003-2014 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_TRANSPARENT_HPP +#define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Metafunction that checks if f(arg,arg2) executes without argument type + * conversion. By default (i.e. when it cannot be determined) it evaluates to + * true. + */ + +template +struct is_transparent:mpl::true_{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_SFINAE_EXPR)&& \ + !defined(BOOST_NO_CXX11_DECLTYPE)&& \ + (defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL)) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +struct not_is_transparent_result_type{}; + +template +struct is_transparent_class_helper:F +{ + using F::operator(); + template + not_is_transparent_result_type operator()(const T&,const Q&)const; +}; + +template +struct is_transparent_class:mpl::true_{}; + +template +struct is_transparent_class< + F,Arg1,Arg2, + typename enable_if< + is_same< + decltype( + declval >()( + declval(),declval()) + ), + not_is_transparent_result_type + > + >::type +>:mpl::false_{}; + +template +struct is_transparent< + F,Arg1,Arg2, + typename enable_if< + mpl::and_< + is_class, + mpl::not_ > /* is_transparent_class_helper derives from F */ + > + >::type +>:is_transparent_class{}; + +template +struct is_transparent_function:mpl::true_{}; + +template +struct is_transparent_function< + F,Arg1,Arg2, + typename enable_if< + mpl::or_< + mpl::not_::arg1_type,const Arg1&>, + is_same::arg1_type,Arg1> + > >, + mpl::not_::arg2_type,const Arg2&>, + is_same::arg2_type,Arg2> + > > + > + >::type +>:mpl::false_{}; + +template +struct is_transparent< + F,Arg1,Arg2, + typename enable_if< + is_function::type> + >::type +>:is_transparent_function::type,Arg1,Arg2>{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp new file mode 100644 index 00000000000..7a032350b36 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp @@ -0,0 +1,321 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +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 + static typename Class::reference dereference(const Class& x) + { + return x.dereference(); + } + + template + static bool equal(const Class& x,const Class& y) + { + return x.equal(y); + } + + template + static void increment(Class& x) + { + x.increment(); + } + + template + static void decrement(Class& x) + { + x.decrement(); + } + + template + static void advance(Class& x,typename Class::difference_type n) + { + x.advance(n); + } + + template + static typename Class::difference_type distance_to( + const Class& x,const Class& y) + { + return x.distance_to(y); + } +}; + +template +struct iter_adaptor_selector; + +template +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(this);} + const Derived& final()const{return *static_cast(this);} +}; + +template +bool operator==( + const forward_iter_adaptor_base& x, + const forward_iter_adaptor_base& y) +{ + return iter_adaptor_access::equal( + static_cast(x),static_cast(y)); +} + +template<> +struct iter_adaptor_selector +{ + template + struct apply + { + typedef forward_iter_adaptor_base type; + }; +}; + +template +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(this);} + const Derived& final()const{return *static_cast(this);} +}; + +template +bool operator==( + const bidirectional_iter_adaptor_base& x, + const bidirectional_iter_adaptor_base& y) +{ + return iter_adaptor_access::equal( + static_cast(x),static_cast(y)); +} + +template<> +struct iter_adaptor_selector +{ + template + struct apply + { + typedef bidirectional_iter_adaptor_base type; + }; +}; + +template +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(this);} + const Derived& final()const{return *static_cast(this);} +}; + +template +bool operator==( + const random_access_iter_adaptor_base& x, + const random_access_iter_adaptor_base& y) +{ + return iter_adaptor_access::equal( + static_cast(x),static_cast(y)); +} + +template +bool operator<( + const random_access_iter_adaptor_base& x, + const random_access_iter_adaptor_base& y) +{ + return iter_adaptor_access::distance_to( + static_cast(x),static_cast(y))>0; +} + +template +typename random_access_iter_adaptor_base::difference_type +operator-( + const random_access_iter_adaptor_base& x, + const random_access_iter_adaptor_base& y) +{ + return iter_adaptor_access::distance_to( + static_cast(y),static_cast(x)); +} + +template<> +struct iter_adaptor_selector +{ + template + struct apply + { + typedef random_access_iter_adaptor_base type; + }; +}; + +template +struct iter_adaptor_base +{ + typedef iter_adaptor_selector< + typename Base::iterator_category> selector; + typedef typename mpl::apply2< + selector,Derived,Base>::type type; +}; + +template +class iter_adaptor:public iter_adaptor_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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp new file mode 100644 index 00000000000..6df89b18386 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp @@ -0,0 +1,49 @@ +/* Copyright 2003-2013 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) +#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 +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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp new file mode 100644 index 00000000000..ba216ed82cf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp @@ -0,0 +1,97 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +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 + struct apply + { + typedef mpl::s_item< + typename mpl::if_,duplicate_tag_mark,Tag>::type, + MplSet + > type; + }; +}; + +template +struct no_duplicate_tags +{ + typedef typename mpl::fold< + TagList, + mpl::set0<>, + duplicate_tag_marker + >::type aux; + + BOOST_STATIC_CONSTANT( + bool,value=!(mpl::has_key::value)); +}; + +/* Variant for an index list: duplication is checked + * across all the indices. + */ + +struct duplicate_tag_list_marker +{ + template + struct apply:mpl::fold< + BOOST_DEDUCED_TYPENAME Index::tag_list, + MplSet, + duplicate_tag_marker> + { + }; +}; + +template +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::value)); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp new file mode 100644 index 00000000000..7fe85cf968b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp @@ -0,0 +1,66 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* MPL machinery to construct the internal node type associated to an + * index list. + */ + +struct index_node_applier +{ + template + struct apply + { + typedef typename mpl::deref::type index_specifier; + typedef typename index_specifier:: + BOOST_NESTED_TEMPLATE node_class::type type; + }; +}; + +template +struct multi_index_node_type +{ + BOOST_STATIC_ASSERT(detail::is_index_list::value); + + typedef typename mpl::reverse_iter_fold< + IndexSpecifierList, + index_node_base, + mpl::bind2 + >::type type; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp new file mode 100644 index 00000000000..3e2641f2f4d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp @@ -0,0 +1,83 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include + +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 > + * (ordered_unique|ordered_non_unique)< + * TagList,KeyFromValue,Compare=std::less > + * + * index_args implements the machinery to accept this argument-dependent + * polymorphism. + */ + +template +struct index_args_default_compare +{ + typedef std::less type; +}; + +template +struct ordered_index_args +{ + typedef is_tag 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, + index_args_default_compare, + mpl::identity + >::type compare_type; + + BOOST_STATIC_ASSERT(is_tag::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp new file mode 100644 index 00000000000..040cb989630 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp @@ -0,0 +1,1567 @@ +/* Copyright 2003-2015 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_IMPL_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) +#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 and accepts + * an augmenting policy for optional addition of order statistics. + */ + +/* 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,typename AugmentPolicy +> +class ordered_index; + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +class ordered_index_impl: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,public safe_mode::safe_container< + ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> > +#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< + AugmentPolicy,typename super::node_type> node_type; + +protected: /* for the benefit of AugmentPolicy::augmented_interface */ + 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 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) + typedef safe_mode::safe_iterator< + bidir_node_iterator, + ordered_index_impl> iterator; +#else + typedef bidir_node_iterator 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 reverse_iterator; + typedef typename + boost::reverse_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< + KeyFromValue,Compare, + SuperMeta,TagList,Category,AugmentPolicy + > >::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 + +protected: +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_container< + ordered_index_impl> safe_super; +#endif + + typedef typename call_traits< + value_type>::param_type value_param_type; + typedef typename call_traits< + key_type>::param_type key_param_type; + + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_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. + * Assignment operators defined at ordered_index rather than here. + */ + + allocator_type get_allocator()const BOOST_NOEXCEPT + { + return this->final().get_allocator(); + } + + /* iterators */ + + iterator + begin()BOOST_NOEXCEPT{return make_iterator(leftmost());} + const_iterator + begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());} + iterator + end()BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator + end()const BOOST_NOEXCEPT{return make_iterator(header());} + reverse_iterator + rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + const_reverse_iterator + rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + reverse_iterator + rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_reverse_iterator + rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_iterator + cbegin()const BOOST_NOEXCEPT{return begin();} + const_iterator + cend()const BOOST_NOEXCEPT{return end();} + const_reverse_iterator + crbegin()const BOOST_NOEXCEPT{return rbegin();} + const_reverse_iterator + crend()const BOOST_NOEXCEPT{return rend();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value(&x)); + } + + /* capacity */ + + bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} + size_type size()const BOOST_NOEXCEPT{return this->final_size_();} + size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} + + /* modifiers */ + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace,emplace_impl) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + iterator,emplace_hint,emplace_hint_impl,iterator,position) + + std::pair insert(const value_type& x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_(x); + return std::pair(make_iterator(p.first),p.second); + } + + std::pair insert(BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + return std::pair(make_iterator(p.first),p.second); + } + + iterator insert(iterator position,const value_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 p=this->final_insert_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + + iterator insert(iterator position,BOOST_RV_REF(value_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 p=this->final_insert_rv_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + + template + void insert(InputIterator first,InputIterator last) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + node_type* hint=header(); /* end() */ + for(;first!=last;++first){ + hint=this->final_insert_ref_( + *first,static_cast(hint)).first; + node_type::increment(hint); + } + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(std::initializer_list list) + { + insert(list.begin(),list.end()); + } +#endif + + 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(position++.get_node())); + return position; + } + + size_type erase(key_param_type x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair 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,const value_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(position.get_node())); + } + + bool replace(iterator position,BOOST_RV_REF(value_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_rv_( + x,static_cast(position.get_node())); + } + + template + 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(position.get_node())); + } + + template + 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(position.get_node())); + } + + template + 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(mod,key)); + } + + template + 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(mod,key), + modify_key_adaptor(back_,key)); + } + + void swap( + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x); + this->final_swap_(x.final()); + } + + void clear()BOOST_NOEXCEPT + { + 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 + iterator find(const CompatibleKey& x)const + { + return make_iterator(ordered_index_find(root(),header(),key,x,comp_)); + } + + template + iterator find( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator(ordered_index_find(root(),header(),key,x,comp)); + } + + template + size_type count(const CompatibleKey& x)const + { + return count(x,comp_); + } + + template + size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const + { + std::pair p=equal_range(x,comp); + size_type n=std::distance(p.first,p.second); + return n; + } + + template + iterator lower_bound(const CompatibleKey& x)const + { + return make_iterator( + ordered_index_lower_bound(root(),header(),key,x,comp_)); + } + + template + iterator lower_bound( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator( + ordered_index_lower_bound(root(),header(),key,x,comp)); + } + + template + iterator upper_bound(const CompatibleKey& x)const + { + return make_iterator( + ordered_index_upper_bound(root(),header(),key,x,comp_)); + } + + template + iterator upper_bound( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator( + ordered_index_upper_bound(root(),header(),key,x,comp)); + } + + template + std::pair equal_range( + const CompatibleKey& x)const + { + std::pair p= + ordered_index_equal_range(root(),header(),key,x,comp_); + return std::pair( + make_iterator(p.first),make_iterator(p.second)); + } + + template + std::pair equal_range( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + std::pair p= + ordered_index_equal_range(root(),header(),key,x,comp); + return std::pair( + make_iterator(p.first),make_iterator(p.second)); + } + + /* range */ + + template + std::pair + range(LowerBounder lower,UpperBounder upper)const + { + typedef typename mpl::if_< + is_same, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same, + both_unbounded_tag, + lower_unbounded_tag + >::type, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same, + upper_unbounded_tag, + none_unbounded_tag + >::type + >::type dispatch; + + return range(lower,upper,dispatch()); + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + ordered_index_impl(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_impl( + const ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& 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 a subsequent call to copy_(). + */ + } + + ordered_index_impl( + const ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, + do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + comp_(x.comp_) + { + empty_initialize(); + } + + ~ordered_index_impl() + { + /* 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(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_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, + const copy_map_type& map) + { + if(!x.root()){ + empty_initialize(); + } + else{ + header()->color()=x.header()->color(); + AugmentPolicy::copy(x.header()->impl(),header()->impl()); + + node_type* root_cpy=map.find(static_cast(x.root())); + header()->parent()=root_cpy->impl(); + + node_type* leftmost_cpy=map.find( + static_cast(x.leftmost())); + header()->left()=leftmost_cpy->impl(); + + node_type* rightmost_cpy=map.find( + static_cast(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(); + AugmentPolicy::copy(org->impl(),cpy->impl()); + + 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(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); + } + + template + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) + { + link_info inf; + if(!link_point(key(v),inf,Category())){ + return static_cast(node_type::from_impl(inf.pos)); + } + + final_node_type* res=super::insert_(v,x,variant); + if(res==x){ + node_impl_type::link( + static_cast(x)->impl(),inf.side,inf.pos,header()->impl()); + } + return res; + } + + template + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) + { + link_info inf; + if(!hinted_link_point(key(v),position,inf,Category())){ + return static_cast(node_type::from_impl(inf.pos)); + } + + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x){ + node_impl_type::link( + static_cast(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_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& 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); + } + + void swap_elements_( + ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + if(in_place(v,x,Category())){ + return super::replace_(v,x,variant); + } + + 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,variant)){ + 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 + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm)const + { + save_(ar,version,sm,Category()); + } + + template + 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(!AugmentPolicy::invariant(x->impl()))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_impl. + */ + void check_invariant_()const{this->final_check_invariant_();} +#endif + +protected: /* for the benefit of AugmentPolicy::augmented_interface */ + 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());} + +private: + 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 + { + /* coverity[uninit_ctor]: suppress warning */ + 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(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 + std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return std::pair(make_iterator(p.first),p.second); + } + + template + iterator emplace_hint_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_hint_( + static_cast(position.get_node()), + BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return make_iterator(p.first); + } + + template + std::pair + 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( + 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(make_iterator(y),make_iterator(y)); + } + + template + std::pair + range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const + { + return std::pair( + begin(), + make_iterator(upper_range(root(),header(),upper))); + } + + template + std::pair + range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const + { + return std::pair( + make_iterator(lower_range(root(),header(),lower)), + end()); + } + + template + std::pair + range(LowerBounder,UpperBounder,both_unbounded_tag)const + { + return std::pair(begin(),end()); + } + + template + 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 + 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 + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm, + ordered_unique_tag)const + { + super::save_(ar,version,sm); + } + + template + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm, + ordered_unique_tag) + { + super::load_(ar,version,lm); + } + + template + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm, + ordered_non_unique_tag)const + { + typedef duplicates_iterator 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 + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm, + ordered_non_unique_tag) + { + lm.load( + ::boost::bind( + &ordered_index_impl::rearranger,this, + ::boost::arg<1>(),::boost::arg<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 */ + +protected: /* for the benefit of AugmentPolicy::augmented_interface */ + 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 +}; + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +class ordered_index: + public AugmentPolicy::template augmented_interface< + ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy + > + >::type +{ + typedef typename AugmentPolicy::template + augmented_interface< + ordered_index_impl< + KeyFromValue,Compare, + SuperMeta,TagList,Category,AugmentPolicy + > + >::type super; +public: + typedef typename super::ctor_args_list ctor_args_list; + typedef typename super::allocator_type allocator_type; + typedef typename super::iterator iterator; + + /* 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& operator=(const ordered_index& x) + { + this->final()=x.final(); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + ordered_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + +protected: + ordered_index( + const ctor_args_list& args_list,const allocator_type& al): + super(args_list,al){} + + ordered_index(const ordered_index& x):super(x){}; + + ordered_index(const ordered_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()){}; +}; + +/* comparison */ + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator==( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& 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 AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator<( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& 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 AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator!=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return !(x==y); +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator>( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return y +bool operator>=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return !(x +bool operator<=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return !(x>y); +} + +/* specialized algorithms */ + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +void swap( + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Boost.Foreach compatibility */ + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +inline boost::mpl::true_* boost_foreach_is_noncopyable( + boost::multi_index::detail::ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&, + boost_foreach_argument_dependent_lookup_hack) +{ + return 0; +} + +#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp new file mode 100644 index 00000000000..6590ef05fdd --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp @@ -0,0 +1,128 @@ +/* Copyright 2003-2015 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_IMPL_FWD_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +class ordered_index; + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator==( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator<( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator!=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator>( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator>=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator<=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +void swap( + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y); + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp new file mode 100644 index 00000000000..e7af0377fb9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp @@ -0,0 +1,658 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) +#include +#include +#include +#include +#include +#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 +struct ordered_index_node_impl; /* fwd decl. */ + +template +struct ordered_index_node_std_base +{ + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl + >::type::pointer pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl + >::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 +struct ordered_index_node_compressed_base +{ + typedef ordered_index_node_impl< + AugmentPolicy,Allocator>* pointer; + typedef const ordered_index_node_impl< + AugmentPolicy,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_&uintptr_type(1)); + } + + 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 +struct ordered_index_node_impl_base: + +#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) + AugmentPolicy::template augmented_node< + typename mpl::if_c< + !(has_uintptr_type::value)|| + (alignment_of< + ordered_index_node_compressed_base + >::value%2)|| + !(is_same< + typename boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl + >::type::pointer, + ordered_index_node_impl*>::value), + ordered_index_node_std_base, + ordered_index_node_compressed_base + >::type + >::type +#else + AugmentPolicy::template augmented_node< + ordered_index_node_std_base + >::type +#endif + +{}; + +template +struct ordered_index_node_impl: + ordered_index_node_impl_base +{ +private: + typedef ordered_index_node_impl_base 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; + AugmentPolicy::rotate_left(x,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; + AugmentPolicy::rotate_right(x,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); + AugmentPolicy::add(x,pointer(header->parent())); + 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(); + } + } + AugmentPolicy::remove(y,pointer(root)); + if(y!=z){ + AugmentPolicy::copy(z,y); + 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 +struct ordered_index_node_trampoline: + ordered_index_node_impl< + AugmentPolicy, + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > +{ + typedef ordered_index_node_impl< + AugmentPolicy, + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > impl_type; +}; + +template +struct ordered_index_node: + Super,ordered_index_node_trampoline +{ +private: + typedef ordered_index_node_trampoline 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( + static_cast(static_cast(this))); + } + + const_impl_pointer impl()const + { + return static_cast( + static_cast(static_cast(this))); + } + + static ordered_index_node* from_impl(impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + static const ordered_index_node* from_impl(const_impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp new file mode 100644 index 00000000000..84d5cacae19 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp @@ -0,0 +1,266 @@ +/* Copyright 2003-2014 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for index memfuns having templatized and + * non-templatized versions. + * Implementation note: When CompatibleKey is consistently promoted to + * KeyFromValue::result_type for comparison, the promotion is made once in + * advance to increase efficiency. + */ + +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) +{ + typedef typename KeyFromValue::result_type key_type; + + return ordered_index_find( + top,y,key,x,comp, + mpl::and_< + promotes_1st_arg, + promotes_2nd_arg >()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline Node* ordered_index_find( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ordered_index_find(top,y,key,x,comp,mpl::false_()); +} + +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,mpl::false_) +{ + 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) +{ + typedef typename KeyFromValue::result_type key_type; + + return ordered_index_lower_bound( + top,y,key,x,comp, + promotes_2nd_arg()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline Node* ordered_index_lower_bound( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ordered_index_lower_bound(top,y,key,x,comp,mpl::false_()); +} + +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,mpl::false_) +{ + 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) +{ + typedef typename KeyFromValue::result_type key_type; + + return ordered_index_upper_bound( + top,y,key,x,comp, + promotes_1st_arg()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline Node* ordered_index_upper_bound( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ordered_index_upper_bound(top,y,key,x,comp,mpl::false_()); +} + +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,mpl::false_) +{ + 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 ordered_index_equal_range( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ordered_index_equal_range( + top,y,key,x,comp, + mpl::and_< + promotes_1st_arg, + promotes_2nd_arg >()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::pair ordered_index_equal_range( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ordered_index_equal_range(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::pair ordered_index_equal_range( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + 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( + ordered_index_lower_bound( + Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), + ordered_index_upper_bound( + Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); + } + } + + return std::pair(y,y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp new file mode 100644 index 00000000000..7a11b6e9fbe --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp @@ -0,0 +1,83 @@ +/* Copyright 2003-2017 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_PROMOTES_ARG_HPP +#define BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +/* Metafunctions to check if f(arg1,arg2) promotes either arg1 to the type of + * arg2 or viceversa. By default, (i.e. if it cannot be determined), no + * promotion is assumed. + */ + +#if BOOST_WORKAROUND(BOOST_MSVC,<1400) + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct promotes_1st_arg:mpl::false_{}; + +template +struct promotes_2nd_arg:mpl::false_{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#else + +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct promotes_1st_arg: + mpl::and_< + mpl::not_ >, + is_convertible, + is_transparent + > +{}; + +template +struct promotes_2nd_arg: + mpl::and_< + mpl::not_ >, + is_convertible, + is_transparent + > +{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp new file mode 100644 index 00000000000..c32007435c0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp @@ -0,0 +1,52 @@ +/* Copyright 2003-2015 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_RAW_PTR_HPP +#define BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* gets the underlying pointer of a pointer-like value */ + +template +inline RawPointer raw_ptr(RawPointer const& p,mpl::true_) +{ + return p; +} + +template +inline RawPointer raw_ptr(Pointer const& p,mpl::false_) +{ + return p==Pointer(0)?0:&*p; +} + +template +inline RawPointer raw_ptr(Pointer const& p) +{ + return raw_ptr(p,is_same()); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp new file mode 100644 index 00000000000..ee2c799d5a8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp @@ -0,0 +1,11 @@ +/* Copyright 2003-2016 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. + */ + +#define BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING +#include +#undef BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp new file mode 100644 index 00000000000..4b00345a6d9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp @@ -0,0 +1,173 @@ +/* Copyright 2003-2013 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_RND_INDEX_LOADER_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* This class implements a serialization rearranger for random access + * indices. In order to achieve O(n) performance, the following strategy + * is followed: the nodes of the index are handled as if in a bidirectional + * list, where the next pointers are stored in the original + * random_access_index_ptr_array and the prev pointers are stored in + * an auxiliary array. Rearranging of nodes in such a bidirectional list + * is constant time. Once all the arrangements are performed (on destruction + * time) the list is traversed in reverse order and + * pointers are swapped and set accordingly so that they recover its + * original semantics ( *(node->up())==node ) while retaining the + * new order. + */ + +template +class random_access_index_loader_base:private noncopyable +{ +protected: + typedef random_access_index_node_impl< + typename boost::detail::allocator::rebind_to< + Allocator, + char + >::type + > node_impl_type; + typedef typename node_impl_type::pointer node_impl_pointer; + typedef random_access_index_ptr_array ptr_array; + + random_access_index_loader_base(const Allocator& al_,ptr_array& ptrs_): + al(al_), + ptrs(ptrs_), + header(*ptrs.end()), + prev_spc(al,0), + preprocessed(false) + {} + + ~random_access_index_loader_base() + { + if(preprocessed) + { + node_impl_pointer n=header; + next(n)=n; + + for(std::size_t i=ptrs.size();i--;){ + n=prev(n); + std::size_t d=position(n); + if(d!=i){ + node_impl_pointer m=prev(next_at(i)); + std::swap(m->up(),n->up()); + next_at(d)=next_at(i); + std::swap(prev_at(d),prev_at(i)); + } + next(n)=n; + } + } + } + + void rearrange(node_impl_pointer position_,node_impl_pointer x) + { + preprocess(); /* only incur this penalty if rearrange() is ever called */ + if(position_==node_impl_pointer(0))position_=header; + next(prev(x))=next(x); + prev(next(x))=prev(x); + prev(x)=position_; + next(x)=next(position_); + next(prev(x))=prev(next(x))=x; + } + +private: + void preprocess() + { + if(!preprocessed){ + /* get space for the auxiliary prev array */ + auto_space tmp(al,ptrs.size()+1); + prev_spc.swap(tmp); + + /* prev_spc elements point to the prev nodes */ + std::rotate_copy( + &*ptrs.begin(),&*ptrs.end(),&*ptrs.end()+1,&*prev_spc.data()); + + /* ptrs elements point to the next nodes */ + std::rotate(&*ptrs.begin(),&*ptrs.begin()+1,&*ptrs.end()+1); + + preprocessed=true; + } + } + + std::size_t position(node_impl_pointer x)const + { + return (std::size_t)(x->up()-ptrs.begin()); + } + + node_impl_pointer& next_at(std::size_t n)const + { + return *ptrs.at(n); + } + + node_impl_pointer& prev_at(std::size_t n)const + { + return *(prev_spc.data()+n); + } + + node_impl_pointer& next(node_impl_pointer x)const + { + return *(x->up()); + } + + node_impl_pointer& prev(node_impl_pointer x)const + { + return prev_at(position(x)); + } + + Allocator al; + ptr_array& ptrs; + node_impl_pointer header; + auto_space prev_spc; + bool preprocessed; +}; + +template +class random_access_index_loader: + private random_access_index_loader_base +{ + typedef random_access_index_loader_base super; + typedef typename super::node_impl_pointer node_impl_pointer; + typedef typename super::ptr_array ptr_array; + +public: + random_access_index_loader(const Allocator& al_,ptr_array& ptrs_): + super(al_,ptrs_) + {} + + void rearrange(Node* position_,Node *x) + { + super::rearrange( + position_?position_->impl():node_impl_pointer(0),x->impl()); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp new file mode 100644 index 00000000000..ad61ea25dda --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp @@ -0,0 +1,273 @@ +/* Copyright 2003-2015 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_RND_INDEX_NODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct random_access_index_node_impl +{ + typedef typename + boost::detail::allocator::rebind_to< + Allocator,random_access_index_node_impl + >::type::pointer pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator,random_access_index_node_impl + >::type::const_pointer const_pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator,pointer + >::type::pointer ptr_pointer; + + ptr_pointer& up(){return up_;} + ptr_pointer up()const{return up_;} + + /* interoperability with rnd_node_iterator */ + + static void increment(pointer& x) + { + x=*(x->up()+1); + } + + static void decrement(pointer& x) + { + x=*(x->up()-1); + } + + static void advance(pointer& x,std::ptrdiff_t n) + { + x=*(x->up()+n); + } + + static std::ptrdiff_t distance(pointer x,pointer y) + { + return y->up()-x->up(); + } + + /* algorithmic stuff */ + + static void relocate(ptr_pointer pos,ptr_pointer x) + { + pointer n=*x; + if(xup()=pos-1; + } + else{ + while(x!=pos){ + *x=*(x-1); + (*x)->up()=x; + --x; + } + *pos=n; + n->up()=pos; + } + }; + + static void relocate(ptr_pointer pos,ptr_pointer first,ptr_pointer last) + { + ptr_pointer begin,middle,end; + if(posup()=begin+j; + break; + } + else{ + *(begin+j)=*(begin+k); + (*(begin+j))->up()=begin+j; + } + + if(kup()=begin+k; + break; + } + else{ + *(begin+k)=*(begin+j); + (*(begin+k))->up()=begin+k; + } + } + } + }; + + static void extract(ptr_pointer x,ptr_pointer pend) + { + --pend; + while(x!=pend){ + *x=*(x+1); + (*x)->up()=x; + ++x; + } + } + + static void transfer( + ptr_pointer pbegin0,ptr_pointer pend0,ptr_pointer pbegin1) + { + while(pbegin0!=pend0){ + *pbegin1=*pbegin0++; + (*pbegin1)->up()=pbegin1; + ++pbegin1; + } + } + + static void reverse(ptr_pointer pbegin,ptr_pointer pend) + { + std::ptrdiff_t d=(pend-pbegin)/2; + for(std::ptrdiff_t i=0;iup()=pbegin; + (*pend)->up()=pend; + ++pbegin; + } + } + +private: + ptr_pointer up_; +}; + +template +struct random_access_index_node_trampoline: + random_access_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > +{ + typedef random_access_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > impl_type; +}; + +template +struct random_access_index_node: + Super,random_access_index_node_trampoline +{ +private: + typedef random_access_index_node_trampoline trampoline; + +public: + typedef typename trampoline::impl_type impl_type; + typedef typename trampoline::pointer impl_pointer; + typedef typename trampoline::const_pointer const_impl_pointer; + typedef typename trampoline::ptr_pointer impl_ptr_pointer; + + impl_ptr_pointer& up(){return trampoline::up();} + impl_ptr_pointer up()const{return trampoline::up();} + + impl_pointer impl() + { + return static_cast( + static_cast(static_cast(this))); + } + + const_impl_pointer impl()const + { + return static_cast( + static_cast(static_cast(this))); + } + + static random_access_index_node* from_impl(impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + static const random_access_index_node* from_impl(const_impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + /* interoperability with rnd_node_iterator */ + + static void increment(random_access_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::increment(xi); + x=from_impl(xi); + } + + static void decrement(random_access_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::decrement(xi); + x=from_impl(xi); + } + + static void advance(random_access_index_node*& x,std::ptrdiff_t n) + { + impl_pointer xi=x->impl(); + trampoline::advance(xi,n); + x=from_impl(xi); + } + + static std::ptrdiff_t distance( + random_access_index_node* x,random_access_index_node* y) + { + return trampoline::distance(x->impl(),y->impl()); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp new file mode 100644 index 00000000000..f5e76e4441f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp @@ -0,0 +1,203 @@ +/* Copyright 2003-2015 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_RND_INDEX_OPS_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for random_access_index memfuns having templatized and + * non-templatized versions. + */ + +template +Node* random_access_index_remove( + random_access_index_ptr_array& ptrs,Predicate pred) +{ + typedef typename Node::value_type value_type; + typedef typename Node::impl_ptr_pointer impl_ptr_pointer; + + impl_ptr_pointer first=ptrs.begin(), + res=first, + last=ptrs.end(); + for(;first!=last;++first){ + if(!pred( + const_cast(Node::from_impl(*first)->value()))){ + if(first!=res){ + std::swap(*first,*res); + (*first)->up()=first; + (*res)->up()=res; + } + ++res; + } + } + return Node::from_impl(*res); +} + +template +Node* random_access_index_unique( + random_access_index_ptr_array& ptrs,BinaryPredicate binary_pred) +{ + typedef typename Node::value_type value_type; + typedef typename Node::impl_ptr_pointer impl_ptr_pointer; + + impl_ptr_pointer first=ptrs.begin(), + res=first, + last=ptrs.end(); + if(first!=last){ + for(;++first!=last;){ + if(!binary_pred( + const_cast(Node::from_impl(*res)->value()), + const_cast(Node::from_impl(*first)->value()))){ + ++res; + if(first!=res){ + std::swap(*first,*res); + (*first)->up()=first; + (*res)->up()=res; + } + } + } + ++res; + } + return Node::from_impl(*res); +} + +template +void random_access_index_inplace_merge( + const Allocator& al, + random_access_index_ptr_array& ptrs, + BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp) +{ + typedef typename Node::value_type value_type; + typedef typename Node::impl_pointer impl_pointer; + typedef typename Node::impl_ptr_pointer impl_ptr_pointer; + + auto_space spc(al,ptrs.size()); + + impl_ptr_pointer first0=ptrs.begin(), + last0=first1, + last1=ptrs.end(), + out=spc.data(); + while(first0!=last0&&first1!=last1){ + if(comp( + const_cast(Node::from_impl(*first1)->value()), + const_cast(Node::from_impl(*first0)->value()))){ + *out++=*first1++; + } + else{ + *out++=*first0++; + } + } + std::copy(&*first0,&*last0,&*out); + std::copy(&*first1,&*last1,&*out); + + first1=ptrs.begin(); + out=spc.data(); + while(first1!=last1){ + *first1=*out++; + (*first1)->up()=first1; + ++first1; + } +} + +/* sorting */ + +/* auxiliary stuff */ + +template +struct random_access_index_sort_compare +{ + typedef typename Node::impl_pointer first_argument_type; + typedef typename Node::impl_pointer second_argument_type; + typedef bool result_type; + + random_access_index_sort_compare(Compare comp_=Compare()):comp(comp_){} + + bool operator()( + typename Node::impl_pointer x,typename Node::impl_pointer y)const + { + typedef typename Node::value_type value_type; + + return comp( + const_cast(Node::from_impl(x)->value()), + const_cast(Node::from_impl(y)->value())); + } + +private: + Compare comp; +}; + +template +void random_access_index_sort( + const Allocator& al, + random_access_index_ptr_array& ptrs, + Compare comp) +{ + /* The implementation is extremely simple: an auxiliary + * array of pointers is sorted using stdlib facilities and + * then used to rearrange the index. This is suboptimal + * in space and time, but has some advantages over other + * possible approaches: + * - Use std::stable_sort() directly on ptrs using some + * special iterator in charge of maintaining pointers + * and up() pointers in sync: we cannot guarantee + * preservation of the container invariants in the face of + * exceptions, if, for instance, std::stable_sort throws + * when ptrs transitorily contains duplicate elements. + * - Rewrite the internal algorithms of std::stable_sort + * adapted for this case: besides being a fair amount of + * work, making a stable sort compatible with Boost.MultiIndex + * invariants (basically, no duplicates or missing elements + * even if an exception is thrown) is complicated, error-prone + * and possibly won't perform much better than the + * solution adopted. + */ + + if(ptrs.size()<=1)return; + + typedef typename Node::impl_pointer impl_pointer; + typedef typename Node::impl_ptr_pointer impl_ptr_pointer; + typedef random_access_index_sort_compare< + Node,Compare> ptr_compare; + + impl_ptr_pointer first=ptrs.begin(); + impl_ptr_pointer last=ptrs.end(); + auto_space< + impl_pointer, + Allocator> spc(al,ptrs.size()); + impl_ptr_pointer buf=spc.data(); + + std::copy(&*first,&*last,&*buf); + std::stable_sort(&*buf,&*buf+ptrs.size(),ptr_compare(comp)); + + while(first!=last){ + *first=*buf++; + (*first)->up()=first; + ++first; + } +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp new file mode 100644 index 00000000000..bae1c851b8e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp @@ -0,0 +1,144 @@ +/* Copyright 2003-2013 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_RND_INDEX_PTR_ARRAY_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* pointer structure for use by random access indices */ + +template +class random_access_index_ptr_array:private noncopyable +{ + typedef random_access_index_node_impl< + typename boost::detail::allocator::rebind_to< + Allocator, + char + >::type + > node_impl_type; + +public: + typedef typename node_impl_type::pointer value_type; + typedef typename boost::detail::allocator::rebind_to< + Allocator,value_type + >::type::pointer pointer; + + random_access_index_ptr_array( + const Allocator& al,value_type end_,std::size_t sz): + size_(sz), + capacity_(sz), + spc(al,capacity_+1) + { + *end()=end_; + end_->up()=end(); + } + + std::size_t size()const{return size_;} + std::size_t capacity()const{return capacity_;} + + void room_for_one() + { + if(size_==capacity_){ + reserve(capacity_<=10?15:capacity_+capacity_/2); + } + } + + void reserve(std::size_t c) + { + if(c>capacity_)set_capacity(c); + } + + void shrink_to_fit() + { + if(capacity_>size_)set_capacity(size_); + } + + pointer begin()const{return ptrs();} + pointer end()const{return ptrs()+size_;} + pointer at(std::size_t n)const{return ptrs()+n;} + + void push_back(value_type x) + { + *(end()+1)=*end(); + (*(end()+1))->up()=end()+1; + *end()=x; + (*end())->up()=end(); + ++size_; + } + + void erase(value_type x) + { + node_impl_type::extract(x->up(),end()+1); + --size_; + } + + void clear() + { + *begin()=*end(); + (*begin())->up()=begin(); + size_=0; + } + + void swap(random_access_index_ptr_array& x) + { + std::swap(size_,x.size_); + std::swap(capacity_,x.capacity_); + spc.swap(x.spc); + } + +private: + std::size_t size_; + std::size_t capacity_; + auto_space spc; + + pointer ptrs()const + { + return spc.data(); + } + + void set_capacity(std::size_t c) + { + auto_space spc1(spc.get_allocator(),c+1); + node_impl_type::transfer(begin(),end()+1,spc1.data()); + spc.swap(spc1); + capacity_=c; + } +}; + +template +void swap( + random_access_index_ptr_array& x, + random_access_index_ptr_array& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp new file mode 100644 index 00000000000..48026132fb7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp @@ -0,0 +1,140 @@ +/* Copyright 2003-2014 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_RND_NODE_ITERATOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Iterator class for node-based indices with random access iterators. */ + +template +class rnd_node_iterator: + public random_access_iterator_helper< + rnd_node_iterator, + typename Node::value_type, + std::ptrdiff_t, + const typename Node::value_type*, + const typename Node::value_type&> +{ +public: + /* coverity[uninit_ctor]: suppress warning */ + rnd_node_iterator(){} + explicit rnd_node_iterator(Node* node_):node(node_){} + + const typename Node::value_type& operator*()const + { + return node->value(); + } + + rnd_node_iterator& operator++() + { + Node::increment(node); + return *this; + } + + rnd_node_iterator& operator--() + { + Node::decrement(node); + return *this; + } + + rnd_node_iterator& operator+=(std::ptrdiff_t n) + { + Node::advance(node,n); + return *this; + } + + rnd_node_iterator& operator-=(std::ptrdiff_t n) + { + Node::advance(node,-n); + 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 + void save(Archive& ar,const unsigned int)const + { + node_base_type* bnode=node; + ar< + void load(Archive& ar,const unsigned int) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast(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 +bool operator==( + const rnd_node_iterator& x, + const rnd_node_iterator& y) +{ + return x.get_node()==y.get_node(); +} + +template +bool operator<( + const rnd_node_iterator& x, + const rnd_node_iterator& y) +{ + return Node::distance(x.get_node(),y.get_node())>0; +} + +template +std::ptrdiff_t operator-( + const rnd_node_iterator& x, + const rnd_node_iterator& y) +{ + return Node::distance(y.get_node(),x.get_node()); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp new file mode 100644 index 00000000000..fb233cf4973 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp @@ -0,0 +1,300 @@ +/* Copyright 2003-2017 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_RNK_INDEX_OPS_HPP +#define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for ranked_index memfuns having templatized and + * non-templatized versions. + */ + +template +inline std::size_t ranked_node_size(Pointer x) +{ + return x!=Pointer(0)?x->size:0; +} + +template +inline Pointer ranked_index_nth(std::size_t n,Pointer end_) +{ + Pointer top=end_->parent(); + if(top==Pointer(0)||n>=top->size)return end_; + + for(;;){ + std::size_t s=ranked_node_size(top->left()); + if(n==s)return top; + if(nleft(); + else{ + top=top->right(); + n-=s+1; + } + } +} + +template +inline std::size_t ranked_index_rank(Pointer x,Pointer end_) +{ + Pointer top=end_->parent(); + if(top==Pointer(0))return 0; + if(x==end_)return top->size; + + std::size_t s=ranked_node_size(x->left()); + while(x!=top){ + Pointer z=x->parent(); + if(x==z->right()){ + s+=ranked_node_size(z->left())+1; + } + x=z; + } + return s; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_find_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ranked_index_find_rank( + top,y,key,x,comp, + mpl::and_< + promotes_1st_arg, + promotes_2nd_arg >()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::size_t ranked_index_find_rank( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ranked_index_find_rank(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_find_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + if(!top)return 0; + + std::size_t s=top->impl()->size, + s0=s; + Node* y0=y; + + do{ + if(!comp(key(top->value()),x)){ + y=top; + s-=ranked_node_size(y->right())+1; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + }while(top); + + return (y==y0||comp(x,key(y->value())))?s0:s; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_lower_bound_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ranked_index_lower_bound_rank( + top,y,key,x,comp, + promotes_2nd_arg()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::size_t ranked_index_lower_bound_rank( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_lower_bound_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + if(!top)return 0; + + std::size_t s=top->impl()->size; + + do{ + if(!comp(key(top->value()),x)){ + y=top; + s-=ranked_node_size(y->right())+1; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + }while(top); + + return s; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_upper_bound_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ranked_index_upper_bound_rank( + top,y,key,x,comp, + promotes_1st_arg()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::size_t ranked_index_upper_bound_rank( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_upper_bound_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + if(!top)return 0; + + std::size_t s=top->impl()->size; + + do{ + if(comp(x,key(top->value()))){ + y=top; + s-=ranked_node_size(y->right())+1; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + }while(top); + + return s; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::pair ranked_index_equal_range_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ranked_index_equal_range_rank( + top,y,key,x,comp, + mpl::and_< + promotes_1st_arg, + promotes_2nd_arg >()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::pair ranked_index_equal_range_rank( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::pair ranked_index_equal_range_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + if(!top)return std::pair(0,0); + + std::size_t s=top->impl()->size; + + do{ + if(comp(key(top->value()),x)){ + top=Node::from_impl(top->right()); + } + else if(comp(x,key(top->value()))){ + y=top; + s-=ranked_node_size(y->right())+1; + top=Node::from_impl(top->left()); + } + else{ + return std::pair( + s-top->impl()->size+ + ranked_index_lower_bound_rank( + Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), + s-ranked_node_size(top->right())+ + ranked_index_upper_bound_rank( + Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); + } + }while(top); + + return std::pair(s,s); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp new file mode 100644 index 00000000000..905270e9fb3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp @@ -0,0 +1,588 @@ +/* Copyright 2003-2013 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) +#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, 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 +#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 /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#endif + +#if defined(BOOST_HAS_THREADS) +#include +#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 +inline bool check_valid_iterator(const Iterator& it) +{ + return it.valid()||it.unchecked(); +} + +template +inline bool check_dereferenceable_iterator(const Iterator& it) +{ + return (it.valid()&&it!=it.owner()->end())||it.unchecked(); +} + +template +inline bool check_incrementable_iterator(const Iterator& it) +{ + return (it.valid()&&it!=it.owner()->end())||it.unchecked(); +} + +template +inline bool check_decrementable_iterator(const Iterator& it) +{ + return (it.valid()&&it!=it.owner()->begin())||it.unchecked(); +} + +template +inline bool check_is_owner( + const Iterator& it,const typename Iterator::container_type& cont) +{ + return (it.valid()&&it.owner()==&cont)||it.unchecked(); +} + +template +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 +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 +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 +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 +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 +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(&it.cont->header); + (next_=static_cast(prev_->next))!=0;){ + if(next_!=&it&&*next_==it){ + prev_->next=next_->next; + next_->cont=0; + } + else prev_=next_; + } + } + it.detach(); + } +} + +template 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 friend class safe_mode::safe_container; + template 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 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, + * - iterators must be generated via safe_iterator, which adapts a + * preexistent unsafe iterator class. + */ + +template +class safe_container; + +template +class safe_iterator: + public detail::iter_adaptor,Iterator>, + public detail::safe_iterator_base +{ + typedef detail::iter_adaptor 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* cont_): + safe_super(cont_){} + template + safe_iterator(const T0& t0,safe_container* cont_): + super(Iterator(t0)),safe_super(cont_){} + template + safe_iterator( + const T0& t0,const T1& t1,safe_container* 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( + static_cast*>( + 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(); + * 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 + void save(Archive& ar,const unsigned int version)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + this->base_reference().save(ar,version); + } + + template + void load(Archive& ar,const unsigned int version) + { + this->base_reference().load(ar,version); + safe_super::uncheck(); + } +#endif +}; + +template +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(this)->end(); + iterator *prev_,*next_; + for( + prev_=static_cast(&this->header); + (next_=static_cast(prev_->next))!=0;){ + if(*next_!=end_){ + prev_->next=next_->next; + next_->cont=0; + } + else prev_=next_; + } + } + + void swap(safe_container& x) + { + super::swap(x); + } +}; + +} /* namespace multi_index::safe_mode */ + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +namespace serialization{ +template +struct version< + boost::multi_index::safe_mode::safe_iterator +> +{ + BOOST_STATIC_CONSTANT( + int,value=boost::serialization::version::value); +}; +} /* namespace serialization */ +#endif + +} /* namespace boost */ + +#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp new file mode 100644 index 00000000000..116f8f50415 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp @@ -0,0 +1,453 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include +#include + +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: Change the Way You + * Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000, + * http://www.drdobbs.com/184403758 + * with the following modifications: + * - General pretty formatting (pretty to my taste at least.) + * - Naming style changed to standard C++ library requirements. + * - 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. + * + * We also define the following variants of the idiom: + * + * - make_guard_if_c( ... ) + * - make_guard_if( ... ) + * - make_obj_guard_if_c( ... ) + * - make_obj_guard_if( ... ) + * which may be used with a compile-time constant to yield + * a "null_guard" if the boolean compile-time parameter is false, + * or conversely, the guard is only constructed if the constant is true. + * This is useful to avoid extra tagging, because the returned + * null_guard can be optimzed comlpetely away by the compiler. + */ + +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 + static void safe_execute(J& j){ + BOOST_TRY{ + if(!j.dismissed_)j.execute(); + } + BOOST_CATCH(...){} + BOOST_CATCH_END + } + + mutable bool dismissed_; + +private: + scope_guard_impl_base& operator=(const scope_guard_impl_base&); +}; + +typedef const scope_guard_impl_base& scope_guard; + +struct null_guard : public scope_guard_impl_base +{ + template< class T1 > + null_guard( const T1& ) + { } + + template< class T1, class T2 > + null_guard( const T1&, const T2& ) + { } + + template< class T1, class T2, class T3 > + null_guard( const T1&, const T2&, const T3& ) + { } + + template< class T1, class T2, class T3, class T4 > + null_guard( const T1&, const T2&, const T3&, const T4& ) + { } + + template< class T1, class T2, class T3, class T4, class T5 > + null_guard( const T1&, const T2&, const T3&, const T4&, const T5& ) + { } +}; + +template< bool cond, class T > +struct null_guard_return +{ + typedef typename boost::mpl::if_c::type type; +}; + +template +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 +inline scope_guard_impl0 make_guard(F fun) +{ + return scope_guard_impl0(fun); +} + +template +inline typename null_guard_return >::type +make_guard_if_c(F fun) +{ + return typename null_guard_return >::type(fun); +} + +template +inline typename null_guard_return >::type +make_guard_if(F fun) +{ + return make_guard_if(fun); +} + +template +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 +inline scope_guard_impl1 make_guard(F fun,P1 p1) +{ + return scope_guard_impl1(fun,p1); +} + +template +inline typename null_guard_return >::type +make_guard_if_c(F fun,P1 p1) +{ + return typename null_guard_return >::type(fun,p1); +} + +template +inline typename null_guard_return >::type +make_guard_if(F fun,P1 p1) +{ + return make_guard_if_c(fun,p1); +} + +template +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 +inline scope_guard_impl2 make_guard(F fun,P1 p1,P2 p2) +{ + return scope_guard_impl2(fun,p1,p2); +} + +template +inline typename null_guard_return >::type +make_guard_if_c(F fun,P1 p1,P2 p2) +{ + return typename null_guard_return >::type(fun,p1,p2); +} + +template +inline typename null_guard_return >::type +make_guard_if(F fun,P1 p1,P2 p2) +{ + return make_guard_if_c(fun,p1,p2); +} + +template +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 +inline scope_guard_impl3 make_guard(F fun,P1 p1,P2 p2,P3 p3) +{ + return scope_guard_impl3(fun,p1,p2,p3); +} + +template +inline typename null_guard_return >::type +make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3) +{ + return typename null_guard_return >::type(fun,p1,p2,p3); +} + +template +inline typename null_guard_return< C::value,scope_guard_impl3 >::type +make_guard_if(F fun,P1 p1,P2 p2,P3 p3) +{ + return make_guard_if_c(fun,p1,p2,p3); +} + +template +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 +inline scope_guard_impl4 make_guard( + F fun,P1 p1,P2 p2,P3 p3,P4 p4) +{ + return scope_guard_impl4(fun,p1,p2,p3,p4); +} + +template +inline typename null_guard_return >::type +make_guard_if_c( + F fun,P1 p1,P2 p2,P3 p3,P4 p4) +{ + return typename null_guard_return >::type(fun,p1,p2,p3,p4); +} + +template +inline typename null_guard_return >::type +make_guard_if( + F fun,P1 p1,P2 p2,P3 p3,P4 p4) +{ + return make_guard_if_c(fun,p1,p2,p3,p4); +} + +template +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 +inline obj_scope_guard_impl0 make_obj_guard(Obj& obj,MemFun mem_fun) +{ + return obj_scope_guard_impl0(obj,mem_fun); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if_c(Obj& obj,MemFun mem_fun) +{ + return typename null_guard_return >::type(obj,mem_fun); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if(Obj& obj,MemFun mem_fun) +{ + return make_obj_guard_if_c(obj,mem_fun); +} + +template +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 +inline obj_scope_guard_impl1 make_obj_guard( + Obj& obj,MemFun mem_fun,P1 p1) +{ + return obj_scope_guard_impl1(obj,mem_fun,p1); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if_c( Obj& obj,MemFun mem_fun,P1 p1) +{ + return typename null_guard_return >::type(obj,mem_fun,p1); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1) +{ + return make_obj_guard_if_c(obj,mem_fun,p1); +} + +template +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 +inline obj_scope_guard_impl2 +make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) +{ + return obj_scope_guard_impl2(obj,mem_fun,p1,p2); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) +{ + return typename null_guard_return >::type(obj,mem_fun,p1,p2); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) +{ + return make_obj_guard_if_c(obj,mem_fun,p1,p2); +} + +template +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 +inline obj_scope_guard_impl3 +make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) +{ + return obj_scope_guard_impl3(obj,mem_fun,p1,p2,p3); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) +{ + return typename null_guard_return >::type(obj,mem_fun,p1,p2,p3); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) +{ + return make_obj_guard_if_c(obj,mem_fun,p1,p2,p3); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp new file mode 100644 index 00000000000..85b345af938 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp @@ -0,0 +1,217 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* doubly-linked node for use by sequenced_index */ + +template +struct sequenced_index_node_impl +{ + typedef typename + boost::detail::allocator::rebind_to< + Allocator,sequenced_index_node_impl + >::type::pointer pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator,sequenced_index_node_impl + >::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 +struct sequenced_index_node_trampoline: + sequenced_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > +{ + typedef sequenced_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > impl_type; +}; + +template +struct sequenced_index_node:Super,sequenced_index_node_trampoline +{ +private: + typedef sequenced_index_node_trampoline 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( + static_cast(static_cast(this))); + } + + const_impl_pointer impl()const + { + return static_cast( + static_cast(static_cast(this))); + } + + static sequenced_index_node* from_impl(impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + static const sequenced_index_node* from_impl(const_impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp new file mode 100644 index 00000000000..142bdd9dd9a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp @@ -0,0 +1,203 @@ +/* Copyright 2003-2016 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for sequenced_index memfuns having templatized and + * non-templatized versions. + */ + +template +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 +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 +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 +void sequenced_index_collate( + BOOST_DEDUCED_TYPENAME Node::impl_type* x, + BOOST_DEDUCED_TYPENAME Node::impl_type* y, + Compare comp) +{ + 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::digits+1); + +#include + +template +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::value + >::type carry_spc_type; + carry_spc_type carry_spc; + impl_type& carry= + *reinterpret_cast(&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= + reinterpret_cast(&counter_spc); + std::size_t fill=0; + + carry.prior()=carry.next()=static_cast(&carry); + counter[0].prior()=counter[0].next()=static_cast(&counter[0]); + + BOOST_TRY{ + while(header->next()!=header->impl()){ + impl_type::relink(carry.next(),header->next()); + std::size_t i=0; + while(i(&counter[i])){ + sequenced_index_collate(&carry,&counter[i++],comp); + } + impl_type::swap( + static_cast(&carry), + static_cast(&counter[i])); + if(i==fill){ + ++fill; + counter[fill].prior()=counter[fill].next()= + static_cast(&counter[fill]); + } + } + + for(std::size_t i=1;i(&counter[i],&counter[i-1],comp); + } + impl_type::swap( + header->impl(),static_cast(&counter[fill-1])); + } + BOOST_CATCH(...) + { + impl_type::relink( + header->impl(),carry.next(),static_cast(&carry)); + for(std::size_t i=0;i<=fill;++i){ + impl_type::relink( + header->impl(),counter[i].next(), + static_cast(&counter[i])); + } + BOOST_RETHROW; + } + BOOST_CATCH_END +} + +#include + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp new file mode 100644 index 00000000000..ccd8bb4f791 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp @@ -0,0 +1,73 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +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 +struct serialization_version +{ + serialization_version(): + value(boost::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 + void save(Archive&,const unsigned int)const{} + + template + void load(Archive&,const unsigned int version) + { + this->value=version; + } + + unsigned int value; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +namespace serialization { +template +struct version > +{ + BOOST_STATIC_CONSTANT(int,value=version::value); +}; +} /* namespace serialization */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp new file mode 100644 index 00000000000..9c92d01d4de --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp @@ -0,0 +1,76 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +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. + */ + +templatestruct 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::type type; +}; + +typedef mpl::bool_ has_uintptr_type; +typedef uintptr_aux::type uintptr_type; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp new file mode 100644 index 00000000000..dc09be1770d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp @@ -0,0 +1,66 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +/* dummy type and variable for use in ordered_index::range() */ + +/* 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(); +} + +/* 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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp new file mode 100644 index 00000000000..ac42e8779aa --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp @@ -0,0 +1,56 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct value_comparison +{ + typedef Value first_argument_type; + typedef Value second_argument_type; + typedef bool result_type; + + value_comparison( + const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()): + key(key_),comp(comp_) + { + } + + bool operator()( + typename call_traits::param_type x, + typename call_traits::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/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp new file mode 100644 index 00000000000..06ff430f4be --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp @@ -0,0 +1,247 @@ +/* Copyright 2003-2013 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_VARTEMPL_SUPPORT_HPP +#define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +/* Utilities for emulation of variadic template functions. Variadic packs are + * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters: + * + * - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK + * - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK + * - std::forward(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK + * + * Forwarding emulated with Boost.Move. A template functions foo_imp + * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS + * arguments: variable number of arguments is emulated by providing a set of + * overloads foo forwarding to foo_impl with + * + * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg) + * + * which fill the extra args with boost::multi_index::detail::noarg's. + * boost::multi_index::detail::vartempl_placement_new works the opposite + * way: it acceps a full a pointer x to Value and a + * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to + * new(x) Value(args) where args is the argument pack after discarding + * noarg's. + * + * Emulation decays to the real thing when the compiler supports variadic + * templates and move semantics natively. + */ + +#include + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\ + defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS) +#define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5 +#endif + +#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \ +BOOST_PP_ENUM_PARAMS( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T) + +#define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \ +BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n) + +#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \ +BOOST_PP_ENUM( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + BOOST_MULTI_INDEX_VARTEMPL_ARG,~) + +#define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \ +boost::forward(BOOST_PP_CAT(t,n)) + +#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \ +BOOST_PP_ENUM( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) + +namespace boost{namespace multi_index{namespace detail{ +struct noarg{}; +}}} + +/* call vartempl function without args */ + +#define BOOST_MULTI_INDEX_NULL_PARAM_PACK \ +BOOST_PP_ENUM_PARAMS( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) + +#define BOOST_MULTI_INDEX_TEMPLATE_N(n) \ +template + +#define BOOST_MULTI_INDEX_TEMPLATE_0(n) + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \ +BOOST_PP_IF(n, \ + BOOST_MULTI_INDEX_TEMPLATE_N, \ + BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ +BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ +BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ +{ \ + return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_AND( \ + n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ + ); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ + ret,name_from,name_to) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \ + (ret)(name_from)(name_to)) + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \ + z,n,data) \ +BOOST_PP_IF(n, \ + BOOST_MULTI_INDEX_TEMPLATE_N, \ + BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ +BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ +BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ + BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ +{ \ + return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ + BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ + ); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ + ret,name_from,name_to,extra_arg_type,extra_arg_name) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \ + (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name)) + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \ +template< \ + typename Value \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_PARAMS(n,typename T) \ +> \ +Value* name( \ + Value* x \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \ +{ \ + return new(x) Value( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \ +} + +#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \ + name) + +BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new) + +#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX +#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#else + +/* native variadic templates support */ + +#include + +#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args +#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args +#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward(args)... +#define BOOST_MULTI_INDEX_NULL_PARAM_PACK + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ + ret,name_from,name_to) \ +template ret name_from(Args&&... args) \ +{ \ + return name_to(std::forward(args)...); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ + ret,name_from,name_to,extra_arg_type,extra_arg_name) \ +template ret name_from( \ + extra_arg_type extra_arg_name,Args&&... args) \ +{ \ + return name_to(extra_arg_name,std::forward(args)...); \ +} + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +Value* vartempl_placement_new(Value*x,Args&&... args) +{ + return new(x) Value(std::forward(args)...); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp new file mode 100644 index 00000000000..2c13769100c --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp @@ -0,0 +1,185 @@ +/* Copyright 2003-2015 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_GLOBAL_FUN_HPP +#define BOOST_MULTI_INDEX_GLOBAL_FUN_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace boost{ + +template class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +namespace detail{ + +/* global_fun is a read-only key extractor from Value based on a given global + * (or static member) function with signature: + * + * Type f([const] Value [&]); + * + * Additionally, global_fun and const_global_fun are overloaded to support + * referece_wrappers of Value and "chained pointers" to Value'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 unique_ptr.) + */ + +template +struct const_ref_global_fun_base +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(Value x)const + { + return PtrToFunction(x); + } + + Type operator()( + const reference_wrapper< + typename remove_reference::type>& x)const + { + return operator()(x.get()); + } + + Type operator()( + const reference_wrapper< + typename remove_const< + typename remove_reference::type>::type>& x + +#if BOOST_WORKAROUND(BOOST_MSVC,==1310) +/* http://lists.boost.org/Archives/boost/2015/10/226135.php */ + ,int=0 +#endif + + )const + { + return operator()(x.get()); + } +}; + +template +struct non_const_ref_global_fun_base +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(Value x)const + { + return PtrToFunction(x); + } + + Type operator()( + const reference_wrapper< + typename remove_reference::type>& x)const + { + return operator()(x.get()); + } +}; + +template +struct non_ref_global_fun_base +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(const Value& x)const + { + return PtrToFunction(x); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type operator()( + const reference_wrapper::type>& x)const + { + return operator()(x.get()); + } +}; + +} /* namespace multi_index::detail */ + +template +struct global_fun: + mpl::if_c< + is_reference::value, + typename mpl::if_c< + is_const::type>::value, + detail::const_ref_global_fun_base, + detail::non_const_ref_global_fun_base + >::type, + detail::non_ref_global_fun_base + >::type +{ +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp new file mode 100644 index 00000000000..352d0c13f17 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp @@ -0,0 +1,1725 @@ +/* Copyright 2003-2015 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_HASHED_INDEX_HPP +#define BOOST_MULTI_INDEX_HASHED_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&hashed_index::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* hashed_index adds a layer of hashed 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 + * Category tags defined in hash_index_node.hpp. + */ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +class hashed_index: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,public safe_mode::safe_container< + hashed_index > +#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 hashed_index_node< + typename super::node_type,Category> node_type; + +private: + typedef typename node_type::node_alg node_alg; + typedef typename node_type::impl_type node_impl_type; + typedef typename node_impl_type::pointer node_impl_pointer; + typedef typename node_impl_type::base_pointer node_impl_base_pointer; + typedef bucket_array< + typename super::final_allocator_type> bucket_array_type; + +public: + /* types */ + + typedef typename KeyFromValue::result_type key_type; + typedef typename node_type::value_type value_type; + typedef KeyFromValue key_from_value; + typedef Hash hasher; + typedef Pred key_equal; + typedef tuple ctor_args; + typedef typename super::final_allocator_type allocator_type; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_iterator< + hashed_index_iterator< + node_type,bucket_array_type, + hashed_index_global_iterator_tag>, + hashed_index> iterator; +#else + typedef hashed_index_iterator< + node_type,bucket_array_type, + hashed_index_global_iterator_tag> iterator; +#endif + + typedef iterator const_iterator; + + typedef hashed_index_iterator< + node_type,bucket_array_type, + hashed_index_local_iterator_tag> local_iterator; + typedef local_iterator const_local_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, + hashed_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) + typedef safe_mode::safe_container< + hashed_index> safe_super; +#endif + + typedef typename call_traits::param_type value_param_type; + typedef typename call_traits< + key_type>::param_type key_param_type; + + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + +public: + + /* construct/destroy/copy + * Default and copy ctors are in the protected section as indices are + * not supposed to be created on their own. No range ctor either. + */ + + hashed_index& operator=( + const hashed_index& x) + { + this->final()=x.final(); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + hashed_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + + allocator_type get_allocator()const BOOST_NOEXCEPT + { + return this->final().get_allocator(); + } + + /* size and capacity */ + + bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} + size_type size()const BOOST_NOEXCEPT{return this->final_size_();} + size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} + + /* iterators */ + + iterator begin()BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(header()->next()->prior()));} + const_iterator begin()const BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(header()->next()->prior()));} + iterator end()BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator end()const BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator cbegin()const BOOST_NOEXCEPT{return begin();} + const_iterator cend()const BOOST_NOEXCEPT{return end();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value(&x)); + } + + /* modifiers */ + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace,emplace_impl) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + iterator,emplace_hint,emplace_hint_impl,iterator,position) + + std::pair insert(const value_type& x) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_(x); + return std::pair(make_iterator(p.first),p.second); + } + + std::pair insert(BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + return std::pair(make_iterator(p.first),p.second); + } + + iterator insert(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + + iterator insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + + template + void insert(InputIterator first,InputIterator last) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + for(;first!=last;++first)this->final_insert_ref_(*first); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(std::initializer_list list) + { + insert(list.begin(),list.end()); + } +#endif + + 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_HASHED_INDEX_CHECK_INVARIANT; + this->final_erase_(static_cast(position++.get_node())); + return position; + } + + size_type erase(key_param_type k) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + + std::size_t buc=buckets.position(hash_(k)); + for(node_impl_pointer x=buckets.at(buc)->prior(); + x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ + if(eq_(k,key(node_type::from_impl(x)->value()))){ + node_impl_pointer y=end_of_range(x); + size_type s=0; + do{ + node_impl_pointer z=node_alg::after(x); + this->final_erase_( + static_cast(node_type::from_impl(x))); + x=z; + ++s; + }while(x!=y); + return s; + } + } + return 0; + } + + 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_HASHED_INDEX_CHECK_INVARIANT; + while(first!=last){ + first=erase(first); + } + return first; + } + + bool replace(iterator position,const value_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_HASHED_INDEX_CHECK_INVARIANT; + return this->final_replace_( + x,static_cast(position.get_node())); + } + + bool replace(iterator position,BOOST_RV_REF(value_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_HASHED_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + + template + 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_HASHED_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(position.get_node())); + } + + template + 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_HASHED_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(position.get_node())); + } + + template + 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_HASHED_INDEX_CHECK_INVARIANT; + return modify( + position,modify_key_adaptor(mod,key)); + } + + template + 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_HASHED_INDEX_CHECK_INVARIANT; + return modify( + position, + modify_key_adaptor(mod,key), + modify_key_adaptor(back_,key)); + } + + void clear()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + void swap(hashed_index& x) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x); + this->final_swap_(x.final()); + } + + /* observers */ + + key_from_value key_extractor()const{return key;} + hasher hash_function()const{return hash_;} + key_equal key_eq()const{return eq_;} + + /* lookup */ + + /* Internally, these ops rely on const_iterator being the same + * type as iterator. + */ + + /* Implementation note: When CompatibleKey is consistently promoted to + * KeyFromValue::result_type for equality comparison, the promotion is made + * once in advance to increase efficiency. + */ + + template + iterator find(const CompatibleKey& k)const + { + return find(k,hash_,eq_); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + iterator find( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq)const + { + return find( + k,hash,eq,promotes_1st_arg()); + } + + template + size_type count(const CompatibleKey& k)const + { + return count(k,hash_,eq_); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + size_type count( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq)const + { + return count( + k,hash,eq,promotes_1st_arg()); + } + + template + std::pair equal_range(const CompatibleKey& k)const + { + return equal_range(k,hash_,eq_); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + std::pair equal_range( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq)const + { + return equal_range( + k,hash,eq,promotes_1st_arg()); + } + + /* bucket interface */ + + size_type bucket_count()const BOOST_NOEXCEPT{return buckets.size();} + size_type max_bucket_count()const BOOST_NOEXCEPT{return static_cast(-1);} + + size_type bucket_size(size_type n)const + { + size_type res=0; + for(node_impl_pointer x=buckets.at(n)->prior(); + x!=node_impl_pointer(0);x=node_alg::after_local(x)){ + ++res; + } + return res; + } + + size_type bucket(key_param_type k)const + { + return buckets.position(hash_(k)); + } + + local_iterator begin(size_type n) + { + return const_cast(this)->begin(n); + } + + const_local_iterator begin(size_type n)const + { + node_impl_pointer x=buckets.at(n)->prior(); + if(x==node_impl_pointer(0))return end(n); + return make_local_iterator(node_type::from_impl(x)); + } + + local_iterator end(size_type n) + { + return const_cast(this)->end(n); + } + + const_local_iterator end(size_type)const + { + return make_local_iterator(0); + } + + const_local_iterator cbegin(size_type n)const{return begin(n);} + const_local_iterator cend(size_type n)const{return end(n);} + + local_iterator local_iterator_to(const value_type& x) + { + return make_local_iterator(node_from_value(&x)); + } + + const_local_iterator local_iterator_to(const value_type& x)const + { + return make_local_iterator(node_from_value(&x)); + } + + /* hash policy */ + + float load_factor()const BOOST_NOEXCEPT + {return static_cast(size())/bucket_count();} + float max_load_factor()const BOOST_NOEXCEPT{return mlf;} + void max_load_factor(float z){mlf=z;calculate_max_load();} + + void rehash(size_type n) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + if(size()<=max_load&&n<=bucket_count())return; + + size_type bc =(std::numeric_limits::max)(); + float fbc=static_cast(1+size()/mlf); + if(bc>fbc){ + bc=static_cast(fbc); + if(bc(std::ceil(static_cast(n)/mlf))); + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + hashed_index(const ctor_args_list& args_list,const allocator_type& al): + super(args_list.get_tail(),al), + key(tuples::get<1>(args_list.get_head())), + hash_(tuples::get<2>(args_list.get_head())), + eq_(tuples::get<3>(args_list.get_head())), + buckets(al,header()->impl(),tuples::get<0>(args_list.get_head())), + mlf(1.0f) + { + calculate_max_load(); + } + + hashed_index( + const hashed_index& x): + super(x), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + hash_(x.hash_), + eq_(x.eq_), + buckets(x.get_allocator(),header()->impl(),x.buckets.size()), + mlf(x.mlf), + max_load(x.max_load) + { + /* Copy ctor just takes the internal configuration objects from x. The rest + * is done in subsequent call to copy_(). + */ + } + + hashed_index( + const hashed_index& x, + do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + hash_(x.hash_), + eq_(x.eq_), + buckets(x.get_allocator(),header()->impl(),0), + mlf(1.0f) + { + calculate_max_load(); + } + + ~hashed_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(this)); + } +#else + iterator make_iterator(node_type* node) + { + return iterator(node); + } + + const_iterator make_iterator(node_type* node)const + { + return const_iterator(node); + } +#endif + + local_iterator make_local_iterator(node_type* node) + { + return local_iterator(node); + } + + const_local_iterator make_local_iterator(node_type* node)const + { + return const_local_iterator(node); + } + + void copy_( + const hashed_index& x, + const copy_map_type& map) + { + copy_(x,map,Category()); + } + + void copy_( + const hashed_index& x, + const copy_map_type& map,hashed_unique_tag) + { + if(x.size()!=0){ + node_impl_pointer end_org=x.header()->impl(), + org=end_org, + cpy=header()->impl(); + do{ + node_impl_pointer prev_org=org->prior(), + prev_cpy= + static_cast(map.find(static_cast( + node_type::from_impl(prev_org))))->impl(); + cpy->prior()=prev_cpy; + if(node_alg::is_first_of_bucket(org)){ + node_impl_base_pointer buc_org=prev_org->next(), + buc_cpy= + buckets.begin()+(buc_org-x.buckets.begin()); + prev_cpy->next()=buc_cpy; + buc_cpy->prior()=cpy; + } + else{ + prev_cpy->next()=node_impl_type::base_pointer_from(cpy); + } + org=prev_org; + cpy=prev_cpy; + }while(org!=end_org); + } + + super::copy_(x,map); + } + + void copy_( + const hashed_index& x, + const copy_map_type& map,hashed_non_unique_tag) + { + if(x.size()!=0){ + node_impl_pointer end_org=x.header()->impl(), + org=end_org, + cpy=header()->impl(); + do{ + node_impl_pointer next_org=node_alg::after(org), + next_cpy= + static_cast(map.find(static_cast( + node_type::from_impl(next_org))))->impl(); + if(node_alg::is_first_of_bucket(next_org)){ + node_impl_base_pointer buc_org=org->next(), + buc_cpy= + buckets.begin()+(buc_org-x.buckets.begin()); + cpy->next()=buc_cpy; + buc_cpy->prior()=next_cpy; + next_cpy->prior()=cpy; + } + else{ + if(org->next()==node_impl_type::base_pointer_from(next_org)){ + cpy->next()=node_impl_type::base_pointer_from(next_cpy); + } + else{ + cpy->next()= + node_impl_type::base_pointer_from( + static_cast(map.find(static_cast( + node_type::from_impl( + node_impl_type::pointer_from(org->next())))))->impl()); + } + + if(next_org->prior()!=org){ + next_cpy->prior()= + static_cast(map.find(static_cast( + node_type::from_impl(next_org->prior()))))->impl(); + } + else{ + next_cpy->prior()=cpy; + } + } + org=next_org; + cpy=next_cpy; + }while(org!=end_org); + } + + super::copy_(x,map); + } + + template + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) + { + reserve_for_insert(size()+1); + + std::size_t buc=find_bucket(v); + link_info pos(buckets.at(buc)); + if(!link_point(v,pos)){ + return static_cast( + node_type::from_impl(node_impl_type::pointer_from(pos))); + } + + final_node_type* res=super::insert_(v,x,variant); + if(res==x)link(static_cast(x),pos); + return res; + } + + template + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) + { + reserve_for_insert(size()+1); + + std::size_t buc=find_bucket(v); + link_info pos(buckets.at(buc)); + if(!link_point(v,pos)){ + return static_cast( + node_type::from_impl(node_impl_type::pointer_from(pos))); + } + + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x)link(static_cast(x),pos); + 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_() + { + delete_all_nodes_(Category()); + } + + void delete_all_nodes_(hashed_unique_tag) + { + for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ + node_impl_pointer y=x->prior(); + this->final_delete_node_( + static_cast(node_type::from_impl(x))); + x=y; + } + } + + void delete_all_nodes_(hashed_non_unique_tag) + { + for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ + node_impl_pointer y=x->prior(); + if(y->next()!=node_impl_type::base_pointer_from(x)&& + y->next()->prior()!=x){ /* n-1 of group */ + /* Make the second node prior() pointer back-linked so that it won't + * refer to a deleted node when the time for its own destruction comes. + */ + + node_impl_pointer first=node_impl_type::pointer_from(y->next()); + first->next()->prior()=first; + } + this->final_delete_node_( + static_cast(node_type::from_impl(x))); + x=y; + } + } + + void clear_() + { + super::clear_(); + buckets.clear(header()->impl()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::detach_dereferenceable_iterators(); +#endif + } + + void swap_( + hashed_index& x) + { + std::swap(key,x.key); + std::swap(hash_,x.hash_); + std::swap(eq_,x.eq_); + buckets.swap(x.buckets); + std::swap(mlf,x.mlf); + std::swap(max_load,x.max_load); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + void swap_elements_( + hashed_index& x) + { + buckets.swap(x.buckets); + std::swap(mlf,x.mlf); + std::swap(max_load,x.max_load); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + if(eq_(key(v),key(x->value()))){ + return super::replace_(v,x,variant); + } + + unlink_undo undo; + unlink(x,undo); + + BOOST_TRY{ + std::size_t buc=find_bucket(v); + link_info pos(buckets.at(buc)); + if(link_point(v,pos)&&super::replace_(v,x,variant)){ + link(x,pos); + return true; + } + undo(); + return false; + } + BOOST_CATCH(...){ + undo(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_(node_type* x) + { + std::size_t buc; + bool b; + BOOST_TRY{ + buc=find_bucket(x->value()); + b=in_place(x->impl(),key(x->value()),buc); + } + BOOST_CATCH(...){ + erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + if(!b){ + unlink(x); + BOOST_TRY{ + link_info pos(buckets.at(buc)); + if(!link_point(x->value(),pos)){ + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + return false; + } + link(x,pos); + } + 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)){ + 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) + { + std::size_t buc=find_bucket(x->value()); + if(in_place(x->impl(),key(x->value()),buc)){ + return super::modify_rollback_(x); + } + + unlink_undo undo; + unlink(x,undo); + + BOOST_TRY{ + link_info pos(buckets.at(buc)); + if(link_point(x->value(),pos)&&super::modify_rollback_(x)){ + link(x,pos); + return true; + } + undo(); + return false; + } + BOOST_CATCH(...){ + undo(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + /* comparison */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + /* defect macro refers to class, not function, templates, but anyway */ + + template + friend bool operator==( + const hashed_index&,const hashed_index& y); +#endif + + bool equals(const hashed_index& x)const{return equals(x,Category());} + + bool equals(const hashed_index& x,hashed_unique_tag)const + { + if(size()!=x.size())return false; + for(const_iterator it=begin(),it_end=end(),it2_end=x.end(); + it!=it_end;++it){ + const_iterator it2=x.find(key(*it)); + if(it2==it2_end||!(*it==*it2))return false; + } + return true; + } + + bool equals(const hashed_index& x,hashed_non_unique_tag)const + { + if(size()!=x.size())return false; + for(const_iterator it=begin(),it_end=end();it!=it_end;){ + const_iterator it2,it2_last; + boost::tie(it2,it2_last)=x.equal_range(key(*it)); + if(it2==it2_last)return false; + + const_iterator it_last=make_iterator( + node_type::from_impl(end_of_range(it.get_node()->impl()))); + if(std::distance(it,it_last)!=std::distance(it2,it2_last))return false; + + /* From is_permutation code in + * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3068.pdf + */ + + for(;it!=it_last;++it,++it2){ + if(!(*it==*it2))break; + } + if(it!=it_last){ + for(const_iterator scan=it;scan!=it_last;++scan){ + if(std::find(it,scan,*scan)!=scan)continue; + std::ptrdiff_t matches=std::count(it2,it2_last,*scan); + if(matches==0||matches!=std::count(scan,it_last,*scan))return false; + } + it=it_last; + } + } + return true; + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm)const + { + ar< + void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) + { + ar>>serialization::make_nvp("position",buckets); + 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())return false; + } + else{ + size_type s0=0; + for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s0){} + if(s0!=size())return false; + + size_type s1=0; + for(size_type buc=0;bucfinal_check_invariant_();} +#endif + +private: + node_type* header()const{return this->final_header();} + + std::size_t find_bucket(value_param_type v)const + { + return bucket(key(v)); + } + + struct link_info_non_unique + { + link_info_non_unique(node_impl_base_pointer pos): + first(pos),last(node_impl_base_pointer(0)){} + + operator const node_impl_base_pointer&()const{return this->first;} + + node_impl_base_pointer first,last; + }; + + typedef typename mpl::if_< + is_same, + node_impl_base_pointer, + link_info_non_unique + >::type link_info; + + bool link_point(value_param_type v,link_info& pos) + { + return link_point(v,pos,Category()); + } + + bool link_point( + value_param_type v,node_impl_base_pointer& pos,hashed_unique_tag) + { + for(node_impl_pointer x=pos->prior();x!=node_impl_pointer(0); + x=node_alg::after_local(x)){ + if(eq_(key(v),key(node_type::from_impl(x)->value()))){ + pos=node_impl_type::base_pointer_from(x); + return false; + } + } + return true; + } + + bool link_point( + value_param_type v,link_info_non_unique& pos,hashed_non_unique_tag) + { + for(node_impl_pointer x=pos.first->prior();x!=node_impl_pointer(0); + x=node_alg::next_to_inspect(x)){ + if(eq_(key(v),key(node_type::from_impl(x)->value()))){ + pos.first=node_impl_type::base_pointer_from(x); + pos.last=node_impl_type::base_pointer_from(last_of_range(x)); + return true; + } + } + return true; + } + + node_impl_pointer last_of_range(node_impl_pointer x)const + { + return last_of_range(x,Category()); + } + + node_impl_pointer last_of_range(node_impl_pointer x,hashed_unique_tag)const + { + return x; + } + + node_impl_pointer last_of_range( + node_impl_pointer x,hashed_non_unique_tag)const + { + node_impl_base_pointer y=x->next(); + node_impl_pointer z=y->prior(); + if(z==x){ /* range of size 1 or 2 */ + node_impl_pointer yy=node_impl_type::pointer_from(y); + return + eq_( + key(node_type::from_impl(x)->value()), + key(node_type::from_impl(yy)->value()))?yy:x; + } + else if(z->prior()==x) /* last of bucket */ + return x; + else /* group of size>2 */ + return z; + } + + node_impl_pointer end_of_range(node_impl_pointer x)const + { + return end_of_range(x,Category()); + } + + node_impl_pointer end_of_range(node_impl_pointer x,hashed_unique_tag)const + { + return node_alg::after(last_of_range(x)); + } + + node_impl_pointer end_of_range( + node_impl_pointer x,hashed_non_unique_tag)const + { + node_impl_base_pointer y=x->next(); + node_impl_pointer z=y->prior(); + if(z==x){ /* range of size 1 or 2 */ + node_impl_pointer yy=node_impl_type::pointer_from(y); + if(!eq_( + key(node_type::from_impl(x)->value()), + key(node_type::from_impl(yy)->value())))yy=x; + return yy->next()->prior()==yy? + node_impl_type::pointer_from(yy->next()): + yy->next()->prior(); + } + else if(z->prior()==x) /* last of bucket */ + return z; + else /* group of size>2 */ + return z->next()->prior()==z? + node_impl_type::pointer_from(z->next()): + z->next()->prior(); + } + + void link(node_type* x,const link_info& pos) + { + link(x,pos,Category()); + } + + void link(node_type* x,node_impl_base_pointer pos,hashed_unique_tag) + { + node_alg::link(x->impl(),pos,header()->impl()); + } + + void link(node_type* x,const link_info_non_unique& pos,hashed_non_unique_tag) + { + if(pos.last==node_impl_base_pointer(0)){ + node_alg::link(x->impl(),pos.first,header()->impl()); + } + else{ + node_alg::link( + x->impl(), + node_impl_type::pointer_from(pos.first), + node_impl_type::pointer_from(pos.last)); + } + } + + void unlink(node_type* x) + { + node_alg::unlink(x->impl()); + } + + typedef typename node_alg::unlink_undo unlink_undo; + + void unlink(node_type* x,unlink_undo& undo) + { + node_alg::unlink(x->impl(),undo); + } + + void calculate_max_load() + { + float fml=static_cast(mlf*static_cast(bucket_count())); + max_load=(std::numeric_limits::max)(); + if(max_load>fml)max_load=static_cast(fml); + } + + void reserve_for_insert(size_type n) + { + if(n>max_load){ + size_type bc =(std::numeric_limits::max)(); + float fbc=static_cast(1+static_cast(n)/mlf); + if(bc>fbc)bc =static_cast(fbc); + unchecked_rehash(bc); + } + } + + void unchecked_rehash(size_type n){unchecked_rehash(n,Category());} + + void unchecked_rehash(size_type n,hashed_unique_tag) + { + node_impl_type cpy_end_node; + node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), + end_=header()->impl(); + bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); + + if(size()!=0){ + auto_space< + std::size_t,allocator_type> hashes(get_allocator(),size()); + auto_space< + node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); + std::size_t i=0,size_=size(); + bool within_bucket=false; + BOOST_TRY{ + for(;i!=size_;++i){ + node_impl_pointer x=end_->prior(); + + /* only this can possibly throw */ + std::size_t h=hash_(key(node_type::from_impl(x)->value())); + + hashes.data()[i]=h; + node_ptrs.data()[i]=x; + within_bucket=!node_alg::unlink_last(end_); + node_alg::link(x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); + } + } + BOOST_CATCH(...){ + if(i!=0){ + std::size_t prev_buc=buckets.position(hashes.data()[i-1]); + if(!within_bucket)prev_buc=~prev_buc; + + for(std::size_t j=i;j--;){ + std::size_t buc=buckets.position(hashes.data()[j]); + node_impl_pointer x=node_ptrs.data()[j]; + if(buc==prev_buc)node_alg::append(x,end_); + else node_alg::link(x,buckets.at(buc),end_); + prev_buc=buc; + } + } + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; + end_->next()=cpy_end->next(); + end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; + buckets.swap(buckets_cpy); + calculate_max_load(); + } + + void unchecked_rehash(size_type n,hashed_non_unique_tag) + { + node_impl_type cpy_end_node; + node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), + end_=header()->impl(); + bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); + + if(size()!=0){ + auto_space< + std::size_t,allocator_type> hashes(get_allocator(),size()); + auto_space< + node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); + std::size_t i=0; + bool within_bucket=false; + BOOST_TRY{ + for(;;++i){ + node_impl_pointer x=end_->prior(); + if(x==end_)break; + + /* only this can possibly throw */ + std::size_t h=hash_(key(node_type::from_impl(x)->value())); + + hashes.data()[i]=h; + node_ptrs.data()[i]=x; + std::pair p= + node_alg::unlink_last_group(end_); + node_alg::link_range( + p.first,x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); + within_bucket=!(p.second); + } + } + BOOST_CATCH(...){ + if(i!=0){ + std::size_t prev_buc=buckets.position(hashes.data()[i-1]); + if(!within_bucket)prev_buc=~prev_buc; + + for(std::size_t j=i;j--;){ + std::size_t buc=buckets.position(hashes.data()[j]); + node_impl_pointer x=node_ptrs.data()[j], + y= + x->prior()->next()!=node_impl_type::base_pointer_from(x)&& + x->prior()->next()->prior()!=x? + node_impl_type::pointer_from(x->prior()->next()):x; + node_alg::unlink_range(y,x); + if(buc==prev_buc)node_alg::append_range(y,x,end_); + else node_alg::link_range(y,x,buckets.at(buc),end_); + prev_buc=buc; + } + } + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; + end_->next()=cpy_end->next(); + end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; + buckets.swap(buckets_cpy); + calculate_max_load(); + } + + bool in_place(node_impl_pointer x,key_param_type k,std::size_t buc)const + { + return in_place(x,k,buc,Category()); + } + + bool in_place( + node_impl_pointer x,key_param_type k,std::size_t buc, + hashed_unique_tag)const + { + bool found=false; + for(node_impl_pointer y=buckets.at(buc)->prior(); + y!=node_impl_pointer(0);y=node_alg::after_local(y)){ + if(y==x)found=true; + else if(eq_(k,key(node_type::from_impl(y)->value())))return false; + } + return found; + } + + bool in_place( + node_impl_pointer x,key_param_type k,std::size_t buc, + hashed_non_unique_tag)const + { + bool found=false; + int range_size=0; + for(node_impl_pointer y=buckets.at(buc)->prior();y!=node_impl_pointer(0);){ + if(node_alg::is_first_of_group(y)){ /* group of 3 or more */ + if(y==x){ + /* in place <-> equal to some other member of the group */ + return eq_( + k, + key(node_type::from_impl( + node_impl_type::pointer_from(y->next()))->value())); + } + else{ + node_impl_pointer z= + node_alg::after_local(y->next()->prior()); /* end of range */ + if(eq_(k,key(node_type::from_impl(y)->value()))){ + if(found)return false; /* x lies outside */ + do{ + if(y==x)return true; + y=node_alg::after_local(y); + }while(y!=z); + return false; /* x not found */ + } + else{ + if(range_size==1&&!found)return false; + if(range_size==2)return found; + range_size=0; + y=z; /* skip range (and potentially x, too, which is fine) */ + } + } + } + else{ /* group of 1 or 2 */ + if(y==x){ + if(range_size==1)return true; + range_size=1; + found=true; + } + else if(eq_(k,key(node_type::from_impl(y)->value()))){ + if(range_size==0&&found)return false; + if(range_size==1&&!found)return false; + if(range_size==2)return false; + ++range_size; + } + else{ + if(range_size==1&&!found)return false; + if(range_size==2)return found; + range_size=0; + } + y=node_alg::after_local(y); + } + } + return found; + } + +#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 + std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return std::pair(make_iterator(p.first),p.second); + } + + template + iterator emplace_hint_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_hint_( + static_cast(position.get_node()), + BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return make_iterator(p.first); + } + + template< + typename CompatibleHash,typename CompatiblePred + > + iterator find( + const key_type& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const + { + return find(k,hash,eq,mpl::false_()); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + iterator find( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const + { + std::size_t buc=buckets.position(hash(k)); + for(node_impl_pointer x=buckets.at(buc)->prior(); + x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ + if(eq(k,key(node_type::from_impl(x)->value()))){ + return make_iterator(node_type::from_impl(x)); + } + } + return end(); + } + + template< + typename CompatibleHash,typename CompatiblePred + > + size_type count( + const key_type& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const + { + return count(k,hash,eq,mpl::false_()); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + size_type count( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const + { + std::size_t buc=buckets.position(hash(k)); + for(node_impl_pointer x=buckets.at(buc)->prior(); + x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ + if(eq(k,key(node_type::from_impl(x)->value()))){ + size_type res=0; + node_impl_pointer y=end_of_range(x); + do{ + ++res; + x=node_alg::after(x); + }while(x!=y); + return res; + } + } + return 0; + } + + template< + typename CompatibleHash,typename CompatiblePred + > + std::pair equal_range( + const key_type& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const + { + return equal_range(k,hash,eq,mpl::false_()); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + std::pair equal_range( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const + { + std::size_t buc=buckets.position(hash(k)); + for(node_impl_pointer x=buckets.at(buc)->prior(); + x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ + if(eq(k,key(node_type::from_impl(x)->value()))){ + return std::pair( + make_iterator(node_type::from_impl(x)), + make_iterator(node_type::from_impl(end_of_range(x)))); + } + } + return std::pair(end(),end()); + } + + key_from_value key; + hasher hash_; + key_equal eq_; + bucket_array_type buckets; + float mlf; + size_type max_load; + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +/* comparison */ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +bool operator==( + const hashed_index& x, + const hashed_index& y) +{ + return x.equals(y); +} + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +bool operator!=( + const hashed_index& x, + const hashed_index& y) +{ + return !(x==y); +} + +/* specialized algorithms */ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +void swap( + hashed_index& x, + hashed_index& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +/* hashed index specifiers */ + +template +struct hashed_unique +{ + typedef typename detail::hashed_index_args< + Arg1,Arg2,Arg3,Arg4> 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::hash_type hash_type; + typedef typename index_args::pred_type pred_type; + + template + struct node_class + { + typedef detail::hashed_index_node type; + }; + + template + struct index_class + { + typedef detail::hashed_index< + key_from_value_type,hash_type,pred_type, + SuperMeta,tag_list_type,detail::hashed_unique_tag> type; + }; +}; + +template +struct hashed_non_unique +{ + typedef typename detail::hashed_index_args< + Arg1,Arg2,Arg3,Arg4> 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::hash_type hash_type; + typedef typename index_args::pred_type pred_type; + + template + struct node_class + { + typedef detail::hashed_index_node< + Super,detail::hashed_non_unique_tag> type; + }; + + template + struct index_class + { + typedef detail::hashed_index< + key_from_value_type,hash_type,pred_type, + SuperMeta,tag_list_type,detail::hashed_non_unique_tag> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Boost.Foreach compatibility */ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +inline boost::mpl::true_* boost_foreach_is_noncopyable( + boost::multi_index::detail::hashed_index< + KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>*&, + boost_foreach_argument_dependent_lookup_hack) +{ + return 0; +} + +#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp new file mode 100644 index 00000000000..d77e36c321b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp @@ -0,0 +1,74 @@ +/* Copyright 2003-2013 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_HASHED_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +class hashed_index; + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +bool operator==( + const hashed_index& x, + const hashed_index& y); + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +bool operator!=( + const hashed_index& x, + const hashed_index& y); + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +void swap( + hashed_index& x, + hashed_index& y); + +} /* namespace multi_index::detail */ + +/* hashed_index specifiers */ + +template< + typename Arg1,typename Arg2=mpl::na, + typename Arg3=mpl::na,typename Arg4=mpl::na +> +struct hashed_unique; + +template< + typename Arg1,typename Arg2=mpl::na, + typename Arg3=mpl::na,typename Arg4=mpl::na +> +struct hashed_non_unique; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp new file mode 100644 index 00000000000..6c832ce1562 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp @@ -0,0 +1,145 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace boost{ + +template 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 unique_ptr.) + */ + +template +struct const_identity_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if,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& x)const + { + return x.get(); + } + + Type& operator()( + const reference_wrapper::type>& x + +#if BOOST_WORKAROUND(BOOST_MSVC,==1310) +/* http://lists.boost.org/Archives/boost/2015/10/226135.php */ + ,int=0 +#endif + + )const + { + return x.get(); + } +}; + +template +struct non_const_identity_base +{ + typedef Type result_type; + + /* templatized for pointer-like types */ + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Type& x)const + { + return x; + } + + Type& operator()(Type& x)const + { + return x; + } + + const Type& operator()(const reference_wrapper& x)const + { + return x.get(); + } + + Type& operator()(const reference_wrapper& x)const + { + return x.get(); + } +}; + +} /* namespace multi_index::detail */ + +template +struct identity: + mpl::if_c< + is_const::value, + detail::const_identity_base,detail::non_const_identity_base + >::type +{ +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp new file mode 100644 index 00000000000..af6bd55ef5f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp @@ -0,0 +1,26 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +template struct identity; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp new file mode 100644 index 00000000000..d2217e39166 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp @@ -0,0 +1,68 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include + +/* 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) +#define BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE +#endif + +#if BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE +struct indexed_by: + mpl::vector +{ +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_INDEXED_BY_TEMPLATE_PARM +#undef BOOST_MULTI_INDEX_INDEXED_BY_SIZE + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp new file mode 100644 index 00000000000..60179ba2339 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp @@ -0,0 +1,22 @@ +/* Copyright 2003-2013 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_KEY_EXTRACTORS_HPP +#define BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include +#include +#include +#include + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp new file mode 100644 index 00000000000..111c386c5f5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp @@ -0,0 +1,205 @@ +/* Copyright 2003-2015 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_MEM_FUN_HPP +#define BOOST_MULTI_INDEX_MEM_FUN_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace boost{ + +template class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +/* mem_fun implements a read-only key extractor based on a given non-const + * member function of a class. + * const_mem_fun does the same for const member functions. + * Additionally, mem_fun and const_mem_fun are 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 unique_ptr.) + */ + +template +struct const_mem_fun +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(const Class& x)const + { + return (x.*PtrToMemberFunction)(); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +template +struct mem_fun +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(Class& x)const + { + return (x.*PtrToMemberFunction)(); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +/* MSVC++ 6.0 has problems with const member functions as non-type template + * parameters, somehow it takes them as non-const. const_mem_fun_explicit + * workarounds this deficiency by accepting an extra type parameter that + * specifies the signature of the member function. The workaround was found at: + * Daniel, C.:"Re: weird typedef problem in VC", + * news:microsoft.public.vc.language, 21st nov 2002, + * http://groups.google.com/groups? + * hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05 + * + * MSVC++ 6.0 support has been dropped and [const_]mem_fun_explicit is + * deprecated. + */ + +template< + class Class,typename Type, + typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> +struct const_mem_fun_explicit +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(const Class& x)const + { + return (x.*PtrToMemberFunction)(); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +template< + class Class,typename Type, + typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> +struct mem_fun_explicit +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(Class& x)const + { + return (x.*PtrToMemberFunction)(); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +/* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN used to + * resolve to [const_]mem_fun_explicit for MSVC++ 6.0 and to + * [const_]mem_fun otherwise. Support for this compiler having been dropped, + * they are now just wrappers over [const_]mem_fun kept for backwards- + * compatibility reasons. + */ + +#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \ +::boost::multi_index::const_mem_fun< Class,Type,&Class::MemberFunName > +#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \ +::boost::multi_index::mem_fun< Class,Type,&Class::MemberFunName > + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp new file mode 100644 index 00000000000..a8e645074a2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp @@ -0,0 +1,262 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace boost{ + +template 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 unique_ptr.) + */ + +template +struct const_member_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,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& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +template +struct non_const_member_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Class& x)const + { + return x.*PtrToMember; + } + + Type& operator()(Class& x)const + { + return x.*PtrToMember; + } + + const Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +} /* namespace multi_index::detail */ + +template +struct member: + mpl::if_c< + is_const::value, + detail::const_member_base, + detail::non_const_member_base + >::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. + * + * Support for such old compilers is dropped and + * [non_]const_member_offset_base is deprecated. + */ + +template +struct const_member_offset_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type& operator()(const Class& x)const + { + return *static_cast( + static_cast( + static_cast( + static_cast(&x))+OffsetOfMember)); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +template +struct non_const_member_offset_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Class& x)const + { + return *static_cast( + static_cast( + static_cast( + static_cast(&x))+OffsetOfMember)); + } + + Type& operator()(Class& x)const + { + return *static_cast( + static_cast( + static_cast(static_cast(&x))+OffsetOfMember)); + } + + const Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +} /* namespace multi_index::detail */ + +template +struct member_offset: + mpl::if_c< + is_const::value, + detail::const_member_offset_base, + detail::non_const_member_offset_base + >::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/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp new file mode 100644 index 00000000000..5bcd69de8c9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp @@ -0,0 +1,114 @@ +/* Copyright 2003-2015 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_HPP +#define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* no augment policy for plain ordered indices */ + +struct null_augment_policy +{ + template + struct augmented_interface + { + typedef OrderedIndexImpl type; + }; + + template + struct augmented_node + { + typedef OrderedIndexNodeImpl type; + }; + + template static void add(Pointer,Pointer){} + template static void remove(Pointer,Pointer){} + template static void copy(Pointer,Pointer){} + template static void rotate_left(Pointer,Pointer){} + template static void rotate_right(Pointer,Pointer){} + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + template static bool invariant(Pointer){return true;} + +#endif +}; + +} /* namespace multi_index::detail */ + +/* ordered_index specifiers */ + +template +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 + struct node_class + { + typedef detail::ordered_index_node type; + }; + + template + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_unique_tag, + detail::null_augment_policy> type; + }; +}; + +template +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 + struct node_class + { + typedef detail::ordered_index_node type; + }; + + template + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_non_unique_tag, + detail::null_augment_policy> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp new file mode 100644 index 00000000000..fe44aaf860d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp @@ -0,0 +1,35 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include +#include + +namespace boost{ + +namespace multi_index{ + +/* ordered_index specifiers */ + +template +struct ordered_unique; + +template +struct ordered_non_unique; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp new file mode 100644 index 00000000000..fe1884ddd38 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp @@ -0,0 +1,1167 @@ +/* Copyright 2003-2015 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_RANDOM_ACCESS_INDEX_HPP +#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&random_access_index::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* random_access_index adds a layer of random access indexing + * to a given Super + */ + +template +class random_access_index: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,public safe_mode::safe_container< + random_access_index > +#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 random_access_index_node< + typename super::node_type> node_type; + +private: + typedef typename node_type::impl_type node_impl_type; + typedef random_access_index_ptr_array< + typename super::final_allocator_type> ptr_array; + typedef typename ptr_array::pointer node_impl_ptr_pointer; + +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) + typedef safe_mode::safe_iterator< + rnd_node_iterator, + random_access_index> iterator; +#else + typedef rnd_node_iterator 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 reverse_iterator; + typedef typename + boost::reverse_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, + random_access_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) + typedef safe_mode::safe_container< + random_access_index> safe_super; +#endif + + typedef typename call_traits< + value_type>::param_type value_param_type; + + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_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. + */ + + random_access_index& operator=( + const random_access_index& x) + { + this->final()=x.final(); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + random_access_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + + template + void assign(InputIterator first,InputIterator last) + { + assign_iter(first,last,mpl::not_ >()); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void assign(std::initializer_list list) + { + assign(list.begin(),list.end()); + } +#endif + + void assign(size_type n,value_param_type value) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;ifinal().get_allocator(); + } + + /* iterators */ + + iterator begin()BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(*ptrs.begin()));} + const_iterator begin()const BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(*ptrs.begin()));} + iterator + end()BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator + end()const BOOST_NOEXCEPT{return make_iterator(header());} + reverse_iterator + rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + const_reverse_iterator + rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + reverse_iterator + rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_reverse_iterator + rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_iterator + cbegin()const BOOST_NOEXCEPT{return begin();} + const_iterator + cend()const BOOST_NOEXCEPT{return end();} + const_reverse_iterator + crbegin()const BOOST_NOEXCEPT{return rbegin();} + const_reverse_iterator + crend()const BOOST_NOEXCEPT{return rend();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value(&x)); + } + + /* capacity */ + + bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} + size_type size()const BOOST_NOEXCEPT{return this->final_size_();} + size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} + size_type capacity()const BOOST_NOEXCEPT{return ptrs.capacity();} + + void reserve(size_type n) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + ptrs.reserve(n); + } + + void shrink_to_fit() + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + ptrs.shrink_to_fit(); + } + + void resize(size_type n) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + if(n>size()) + for(size_type m=n-size();m--;) + this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); + else if(nsize())for(size_type m=n-size();m--;)this->final_insert_(x); + else if(nvalue(); + } + + const_reference at(size_type n)const + { + if(n>=size())throw_exception(std::out_of_range("random access index")); + return node_type::from_impl(*ptrs.at(n))->value(); + } + + const_reference front()const{return operator[](0);} + const_reference back()const{return operator[](size()-1);} + + /* modifiers */ + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_front,emplace_front_impl) + + std::pair push_front(const value_type& x) + {return insert(begin(),x);} + std::pair push_front(BOOST_RV_REF(value_type) x) + {return insert(begin(),boost::move(x));} + void pop_front(){erase(begin());} + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_back,emplace_back_impl) + + std::pair push_back(const value_type& x) + {return insert(end(),x);} + std::pair push_back(BOOST_RV_REF(value_type) x) + {return insert(end(),boost::move(x));} + void pop_back(){erase(--end());} + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + emplace_return_type,emplace,emplace_impl,iterator,position) + + std::pair insert(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_(x); + if(p.second&&position.get_node()!=header()){ + relocate(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + + std::pair insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + if(p.second&&position.get_node()!=header()){ + relocate(position.get_node(),p.first); + } + return std::pair(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_RND_INDEX_CHECK_INVARIANT; + size_type s=0; + BOOST_TRY{ + while(n--){ + if(push_back(x).second)++s; + } + } + BOOST_CATCH(...){ + relocate(position,end()-s,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-s,end()); + } + + template + void insert(iterator position,InputIterator first,InputIterator last) + { + insert_iter(position,first,last,mpl::not_ >()); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(iterator position,std::initializer_list list) + { + insert(position,list.begin(),list.end()); + } +#endif + + 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_RND_INDEX_CHECK_INVARIANT; + this->final_erase_(static_cast(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_RND_INDEX_CHECK_INVARIANT; + difference_type n=last-first; + relocate(end(),first,last); + while(n--)pop_back(); + return last; + } + + bool replace(iterator position,const value_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_RND_INDEX_CHECK_INVARIANT; + return this->final_replace_( + x,static_cast(position.get_node())); + } + + bool replace(iterator position,BOOST_RV_REF(value_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_RND_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + + template + 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_RND_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(position.get_node())); + } + + template + 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_RND_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(position.get_node())); + } + + void swap(random_access_index& x) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x); + this->final_swap_(x.final()); + } + + void clear()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + /* list operations */ + + void splice(iterator position,random_access_index& 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_RND_INDEX_CHECK_INVARIANT; + iterator first=x.begin(),last=x.end(); + size_type n=0; + BOOST_TRY{ + while(first!=last){ + if(push_back(*first).second){ + first=x.erase(first); + ++n; + } + else ++first; + } + } + BOOST_CATCH(...){ + relocate(position,end()-n,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-n,end()); + } + + void splice( + iterator position,random_access_index& 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_RND_INDEX_CHECK_INVARIANT; + if(&x==this)relocate(position,i); + 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,random_access_index& 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_RND_INDEX_CHECK_INVARIANT; + if(&x==this)relocate(position,first,last); + else{ + size_type n=0; + BOOST_TRY{ + while(first!=last){ + if(push_back(*first).second){ + first=x.erase(first); + ++n; + } + else ++first; + } + } + BOOST_CATCH(...){ + relocate(position,end()-n,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-n,end()); + } + } + + void remove(value_param_type value) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n= + end()-make_iterator( + random_access_index_remove( + ptrs, + ::boost::bind(std::equal_to(),::boost::arg<1>(),value))); + while(n--)pop_back(); + } + + template + void remove_if(Predicate pred) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n= + end()-make_iterator(random_access_index_remove(ptrs,pred)); + while(n--)pop_back(); + } + + void unique() + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n= + end()-make_iterator( + random_access_index_unique( + ptrs,std::equal_to())); + while(n--)pop_back(); + } + + template + void unique(BinaryPredicate binary_pred) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n= + end()-make_iterator( + random_access_index_unique(ptrs,binary_pred)); + while(n--)pop_back(); + } + + void merge(random_access_index& x) + { + if(this!=&x){ + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + size_type s=size(); + splice(end(),x); + random_access_index_inplace_merge( + get_allocator(),ptrs,ptrs.at(s),std::less()); + } + } + + template + void merge(random_access_index& x,Compare comp) + { + if(this!=&x){ + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + size_type s=size(); + splice(end(),x); + random_access_index_inplace_merge( + get_allocator(),ptrs,ptrs.at(s),comp); + } + } + + void sort() + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + random_access_index_sort( + get_allocator(),ptrs,std::less()); + } + + template + void sort(Compare comp) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + random_access_index_sort( + get_allocator(),ptrs,comp); + } + + void reverse()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + node_impl_type::reverse(ptrs.begin(),ptrs.end()); + } + + /* 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_RND_INDEX_CHECK_INVARIANT; + if(position!=i)relocate(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_RND_INDEX_CHECK_INVARIANT; + if(position!=last)relocate( + position.get_node(),first.get_node(),last.get_node()); + } + + template + void rearrange(InputIterator first) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + for(node_impl_ptr_pointer p0=ptrs.begin(),p0_end=ptrs.end(); + p0!=p0_end;++first,++p0){ + const value_type& v1=*first; + node_impl_ptr_pointer p1=node_from_value(&v1)->up(); + + std::swap(*p0,*p1); + (*p0)->up()=p0; + (*p1)->up()=p1; + } + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + random_access_index( + const ctor_args_list& args_list,const allocator_type& al): + super(args_list.get_tail(),al), + ptrs(al,header()->impl(),0) + { + } + + random_access_index(const random_access_index& x): + super(x), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + ptrs(x.get_allocator(),header()->impl(),x.size()) + { + /* The actual copying takes place in subsequent call to copy_(). + */ + } + + random_access_index( + const random_access_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + ptrs(x.get_allocator(),header()->impl(),0) + { + } + + ~random_access_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(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 random_access_index& x,const copy_map_type& map) + { + for(node_impl_ptr_pointer begin_org=x.ptrs.begin(), + begin_cpy=ptrs.begin(), + end_org=x.ptrs.end(); + begin_org!=end_org;++begin_org,++begin_cpy){ + *begin_cpy= + static_cast( + map.find( + static_cast( + node_type::from_impl(*begin_org))))->impl(); + (*begin_cpy)->up()=begin_cpy; + } + + super::copy_(x,map); + } + + template + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) + { + ptrs.room_for_one(); + final_node_type* res=super::insert_(v,x,variant); + if(res==x)ptrs.push_back(static_cast(x)->impl()); + return res; + } + + template + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) + { + ptrs.room_for_one(); + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x)ptrs.push_back(static_cast(x)->impl()); + return res; + } + + void erase_(node_type* x) + { + ptrs.erase(x->impl()); + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + } + + void delete_all_nodes_() + { + for(node_impl_ptr_pointer x=ptrs.begin(),x_end=ptrs.end();x!=x_end;++x){ + this->final_delete_node_( + static_cast(node_type::from_impl(*x))); + } + } + + void clear_() + { + super::clear_(); + ptrs.clear(); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::detach_dereferenceable_iterators(); +#endif + } + + void swap_(random_access_index& x) + { + ptrs.swap(x.ptrs); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + void swap_elements_(random_access_index& x) + { + ptrs.swap(x.ptrs); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + return super::replace_(v,x,variant); + } + + bool modify_(node_type* x) + { + BOOST_TRY{ + if(!super::modify_(x)){ + ptrs.erase(x->impl()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + return false; + } + else return true; + } + BOOST_CATCH(...){ + ptrs.erase(x->impl()); + +#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 + 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 + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm) + { + { + typedef random_access_index_loader loader; + + loader ld(get_allocator(),ptrs); + lm.load( + ::boost::bind( + &loader::rearrange,&ld,::boost::arg<1>(),::boost::arg<2>()), + ar,version); + } /* exit scope so that ld frees its resources */ + super::load_(ar,version,lm); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + if(size()>capacity())return false; + if(size()==0||begin()==end()){ + if(size()!=0||begin()!=end())return false; + } + else{ + size_type s=0; + for(const_iterator it=begin(),it_end=end();;++it,++s){ + if(*(it.get_node()->up())!=it.get_node()->impl())return false; + if(it==it_end)break; + } + if(s!=size())return false; + } + + return super::invariant_(); + } + + /* This forwarding function eases things for the boost::mem_fn construct + * in BOOST_MULTI_INDEX_RND_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();} + + static void relocate(node_type* position,node_type* x) + { + node_impl_type::relocate(position->up(),x->up()); + } + + static void relocate(node_type* position,node_type* first,node_type* last) + { + node_impl_type::relocate( + position->up(),first->up(),last->up()); + } + +#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 + void assign_iter(InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + clear(); + for(;first!=last;++first)this->final_insert_ref_(*first); + } + + void assign_iter(size_type n,value_param_type value,mpl::false_) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;i + void insert_iter( + iterator position,InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + size_type s=0; + BOOST_TRY{ + for(;first!=last;++first){ + if(this->final_insert_ref_(*first).second)++s; + } + } + BOOST_CATCH(...){ + relocate(position,end()-s,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-s,end()); + } + + 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_RND_INDEX_CHECK_INVARIANT; + size_type s=0; + BOOST_TRY{ + while(n--){ + if(push_back(x).second)++s; + } + } + BOOST_CATCH(...){ + relocate(position,end()-s,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-s,end()); + } + + template + std::pair emplace_front_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_back_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + if(p.second&&position.get_node()!=header()){ + relocate(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + + ptr_array ptrs; + +#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 random_access_index& x, + const random_access_index& 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 random_access_index& x, + const random_access_index& 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 random_access_index& x, + const random_access_index& y) +{ + return !(x==y); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const random_access_index& x, + const random_access_index& y) +{ + return y +bool operator>=( + const random_access_index& x, + const random_access_index& y) +{ + return !(x +bool operator<=( + const random_access_index& x, + const random_access_index& y) +{ + return !(x>y); +} + +/* specialized algorithms */ + +template +void swap( + random_access_index& x, + random_access_index& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +/* random access index specifier */ + +template +struct random_access +{ + BOOST_STATIC_ASSERT(detail::is_tag::value); + + template + struct node_class + { + typedef detail::random_access_index_node type; + }; + + template + struct index_class + { + typedef detail::random_access_index< + SuperMeta,typename TagList::type> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Boost.Foreach compatibility */ + +template +inline boost::mpl::true_* boost_foreach_is_noncopyable( + boost::multi_index::detail::random_access_index*&, + boost_foreach_argument_dependent_lookup_hack) +{ + return 0; +} + +#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp new file mode 100644 index 00000000000..2ea19295426 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp @@ -0,0 +1,91 @@ +/* Copyright 2003-2013 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_RANDOM_ACCESS_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +class random_access_index; + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator==( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator!=( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>=( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<=( + const random_access_index& x, + const random_access_index& y); + +template +void swap( + random_access_index& x, + random_access_index& y); + +} /* namespace multi_index::detail */ + +/* index specifiers */ + +template > +struct random_access; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp new file mode 100644 index 00000000000..4b24c4f5937 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp @@ -0,0 +1,382 @@ +/* Copyright 2003-2017 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_RANKED_INDEX_HPP +#define BOOST_MULTI_INDEX_RANKED_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* ranked_index augments a given ordered index to provide rank operations */ + +template +struct ranked_node:OrderedIndexNodeImpl +{ + std::size_t size; +}; + +template +class ranked_index:public OrderedIndexImpl +{ + typedef OrderedIndexImpl super; + +protected: + typedef typename super::node_type node_type; + typedef typename super::node_impl_pointer node_impl_pointer; + +public: + typedef typename super::ctor_args_list ctor_args_list; + typedef typename super::allocator_type allocator_type; + typedef typename super::iterator iterator; + + /* rank operations */ + + iterator nth(std::size_t n)const + { + return this->make_iterator(node_type::from_impl( + ranked_index_nth(n,this->header()->impl()))); + } + + std::size_t rank(iterator position)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + + return ranked_index_rank( + position.get_node()->impl(),this->header()->impl()); + } + + template + std::size_t find_rank(const CompatibleKey& x)const + { + return ranked_index_find_rank( + this->root(),this->header(),this->key,x,this->comp_); + } + + template + std::size_t find_rank( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return ranked_index_find_rank( + this->root(),this->header(),this->key,x,comp); + } + + template + std::size_t lower_bound_rank(const CompatibleKey& x)const + { + return ranked_index_lower_bound_rank( + this->root(),this->header(),this->key,x,this->comp_); + } + + template + std::size_t lower_bound_rank( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return ranked_index_lower_bound_rank( + this->root(),this->header(),this->key,x,comp); + } + + template + std::size_t upper_bound_rank(const CompatibleKey& x)const + { + return ranked_index_upper_bound_rank( + this->root(),this->header(),this->key,x,this->comp_); + } + + template + std::size_t upper_bound_rank( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return ranked_index_upper_bound_rank( + this->root(),this->header(),this->key,x,comp); + } + + template + std::pair equal_range_rank( + const CompatibleKey& x)const + { + return ranked_index_equal_range_rank( + this->root(),this->header(),this->key,x,this->comp_); + } + + template + std::pair equal_range_rank( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return ranked_index_equal_range_rank( + this->root(),this->header(),this->key,x,comp); + } + + template + std::pair + range_rank(LowerBounder lower,UpperBounder upper)const + { + typedef typename mpl::if_< + is_same, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same, + both_unbounded_tag, + lower_unbounded_tag + >::type, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same, + upper_unbounded_tag, + none_unbounded_tag + >::type + >::type dispatch; + + return range_rank(lower,upper,dispatch()); + } + +protected: + ranked_index(const ranked_index& x):super(x){}; + + ranked_index(const ranked_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()){}; + + ranked_index( + const ctor_args_list& args_list,const allocator_type& al): + super(args_list,al){} + +private: + template + std::pair + range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const + { + node_type* y=this->header(); + node_type* z=this->root(); + + if(!z)return std::pair(0,0); + + std::size_t s=z->impl()->size; + + do{ + if(!lower(this->key(z->value()))){ + z=node_type::from_impl(z->right()); + } + else if(!upper(this->key(z->value()))){ + y=z; + s-=ranked_node_size(y->right())+1; + z=node_type::from_impl(z->left()); + } + else{ + return std::pair( + s-z->impl()->size+ + lower_range_rank(node_type::from_impl(z->left()),z,lower), + s-ranked_node_size(z->right())+ + upper_range_rank(node_type::from_impl(z->right()),y,upper)); + } + }while(z); + + return std::pair(s,s); + } + + template + std::pair + range_rank(LowerBounder,UpperBounder upper,lower_unbounded_tag)const + { + return std::pair( + 0, + upper_range_rank(this->root(),this->header(),upper)); + } + + template + std::pair + range_rank(LowerBounder lower,UpperBounder,upper_unbounded_tag)const + { + return std::pair( + lower_range_rank(this->root(),this->header(),lower), + this->size()); + } + + template + std::pair + range_rank(LowerBounder,UpperBounder,both_unbounded_tag)const + { + return std::pair(0,this->size()); + } + + template + std::size_t + lower_range_rank(node_type* top,node_type* y,LowerBounder lower)const + { + if(!top)return 0; + + std::size_t s=top->impl()->size; + + do{ + if(lower(this->key(top->value()))){ + y=top; + s-=ranked_node_size(y->right())+1; + top=node_type::from_impl(top->left()); + } + else top=node_type::from_impl(top->right()); + }while(top); + + return s; + } + + template + std::size_t + upper_range_rank(node_type* top,node_type* y,UpperBounder upper)const + { + if(!top)return 0; + + std::size_t s=top->impl()->size; + + do{ + if(!upper(this->key(top->value()))){ + y=top; + s-=ranked_node_size(y->right())+1; + top=node_type::from_impl(top->left()); + } + else top=node_type::from_impl(top->right()); + }while(top); + + return s; + } +}; + +/* augmenting policy for ordered_index */ + +struct rank_policy +{ + template + struct augmented_node + { + typedef ranked_node type; + }; + + template + struct augmented_interface + { + typedef ranked_index type; + }; + + /* algorithmic stuff */ + + template + static void add(Pointer x,Pointer root) + { + x->size=1; + while(x!=root){ + x=x->parent(); + ++(x->size); + } + } + + template + static void remove(Pointer x,Pointer root) + { + while(x!=root){ + x=x->parent(); + --(x->size); + } + } + + template + static void copy(Pointer x,Pointer y) + { + y->size=x->size; + } + + template + static void rotate_left(Pointer x,Pointer y) /* in: x==y->left() */ + { + y->size=x->size; + x->size=ranked_node_size(x->left())+ranked_node_size(x->right())+1; + } + + template + static void rotate_right(Pointer x,Pointer y) /* in: x==y->right() */ + { + rotate_left(x,y); + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + template + static bool invariant(Pointer x) + { + return x->size==ranked_node_size(x->left())+ranked_node_size(x->right())+1; + } +#endif +}; + +} /* namespace multi_index::detail */ + +/* ranked_index specifiers */ + +template +struct ranked_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 + struct node_class + { + typedef detail::ordered_index_node type; + }; + + template + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_unique_tag, + detail::rank_policy> type; + }; +}; + +template +struct ranked_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 + struct node_class + { + typedef detail::ordered_index_node type; + }; + + template + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_non_unique_tag, + detail::rank_policy> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp new file mode 100644 index 00000000000..380d3480736 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp @@ -0,0 +1,35 @@ +/* Copyright 2003-2015 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_RANKED_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include + +namespace boost{ + +namespace multi_index{ + +/* ranked_index specifiers */ + +template +struct ranked_unique; + +template +struct ranked_non_unique; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp new file mode 100644 index 00000000000..1904706edec --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp @@ -0,0 +1,48 @@ +/* Copyright 2003-2013 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) +#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/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp new file mode 100644 index 00000000000..424eebc376d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp @@ -0,0 +1,1062 @@ +/* Copyright 2003-2015 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&sequenced_index::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) +#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 +class sequenced_index: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,public safe_mode::safe_container< + sequenced_index > +#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) + typedef safe_mode::safe_iterator< + bidir_node_iterator, + sequenced_index> iterator; +#else + typedef bidir_node_iterator 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 reverse_iterator; + typedef typename + boost::reverse_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) + typedef safe_mode::safe_container< + sequenced_index> safe_super; +#endif + + typedef typename call_traits::param_type value_param_type; + + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_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& operator=( + const sequenced_index& x) + { + this->final()=x.final(); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + sequenced_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + + template + void assign(InputIterator first,InputIterator last) + { + assign_iter(first,last,mpl::not_ >()); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void assign(std::initializer_list list) + { + assign(list.begin(),list.end()); + } +#endif + + void assign(size_type n,value_param_type value) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;ifinal().get_allocator(); + } + + /* iterators */ + + iterator begin()BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(header()->next()));} + const_iterator begin()const BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(header()->next()));} + iterator + end()BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator + end()const BOOST_NOEXCEPT{return make_iterator(header());} + reverse_iterator + rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + const_reverse_iterator + rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + reverse_iterator + rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_reverse_iterator + rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_iterator + cbegin()const BOOST_NOEXCEPT{return begin();} + const_iterator + cend()const BOOST_NOEXCEPT{return end();} + const_reverse_iterator + crbegin()const BOOST_NOEXCEPT{return rbegin();} + const_reverse_iterator + crend()const BOOST_NOEXCEPT{return rend();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value(&x)); + } + + /* capacity */ + + bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} + size_type size()const BOOST_NOEXCEPT{return this->final_size_();} + size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} + + void resize(size_type n) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(n>size()){ + for(size_type m=n-size();m--;) + this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); + } + else if(nsize())insert(end(),n-size(),x); + else if(n push_front(const value_type& x) + {return insert(begin(),x);} + std::pair push_front(BOOST_RV_REF(value_type) x) + {return insert(begin(),boost::move(x));} + void pop_front(){erase(begin());} + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_back,emplace_back_impl) + + std::pair push_back(const value_type& x) + {return insert(end(),x);} + std::pair push_back(BOOST_RV_REF(value_type) x) + {return insert(end(),boost::move(x));} + void pop_back(){erase(--end());} + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + emplace_return_type,emplace,emplace_impl,iterator,position) + + std::pair insert(iterator position,const value_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 p=this->final_insert_(x); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + + std::pair insert(iterator position,BOOST_RV_REF(value_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 p=this->final_insert_rv_(x); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair(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 + void insert(iterator position,InputIterator first,InputIterator last) + { + insert_iter(position,first,last,mpl::not_ >()); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(iterator position,std::initializer_list list) + { + insert(position,list.begin(),list.end()); + } +#endif + + 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(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,const value_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(position.get_node())); + } + + bool replace(iterator position,BOOST_RV_REF(value_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_rv_( + x,static_cast(position.get_node())); + } + + template + 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(position.get_node())); + } + + template + 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(position.get_node())); + } + + void swap(sequenced_index& x) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x); + this->final_swap_(x.final()); + } + + void clear()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + /* list operations */ + + void splice(iterator position,sequenced_index& 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& 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& 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, + ::boost::bind(std::equal_to(),::boost::arg<1>(),value)); + } + + template + void remove_if(Predicate pred) + { + sequenced_index_remove(*this,pred); + } + + void unique() + { + sequenced_index_unique(*this,std::equal_to()); + } + + template + void unique(BinaryPredicate binary_pred) + { + sequenced_index_unique(*this,binary_pred); + } + + void merge(sequenced_index& x) + { + sequenced_index_merge(*this,x,std::less()); + } + + template + void merge(sequenced_index& x,Compare comp) + { + sequenced_index_merge(*this,x,comp); + } + + void sort() + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + sequenced_index_sort(header(),std::less()); + } + + template + void sort(Compare comp) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + sequenced_index_sort(header(),comp); + } + + void reverse()BOOST_NOEXCEPT + { + 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 + 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(&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& 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( + const sequenced_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()) + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,safe_super() +#endif + + { + empty_initialize(); + } + + ~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(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& 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(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); + } + + template + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) + { + final_node_type* res=super::insert_(v,x,variant); + if(res==x)link(static_cast(x)); + return res; + } + + template + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) + { + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x)link(static_cast(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(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& x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + void swap_elements_(sequenced_index& x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + return super::replace_(v,x,variant); + } + + 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 + 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 + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm) + { + lm.load( + ::boost::bind( + &sequenced_index::rearranger,this,::boost::arg<1>(),::boost::arg<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 + void assign_iter(InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + clear(); + for(;first!=last;++first)this->final_insert_ref_(*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 + void insert_iter( + iterator position,InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + for(;first!=last;++first){ + std::pair p= + this->final_insert_ref_(*first); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.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 + std::pair emplace_front_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_back_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + +#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& x, + const sequenced_index& 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& x, + const sequenced_index& 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& x, + const sequenced_index& y) +{ + return !(x==y); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const sequenced_index& x, + const sequenced_index& y) +{ + return y +bool operator>=( + const sequenced_index& x, + const sequenced_index& y) +{ + return !(x +bool operator<=( + const sequenced_index& x, + const sequenced_index& y) +{ + return !(x>y); +} + +/* specialized algorithms */ + +template +void swap( + sequenced_index& x, + sequenced_index& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +/* sequenced index specifier */ + +template +struct sequenced +{ + BOOST_STATIC_ASSERT(detail::is_tag::value); + + template + struct node_class + { + typedef detail::sequenced_index_node type; + }; + + template + struct index_class + { + typedef detail::sequenced_index type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Boost.Foreach compatibility */ + +template +inline boost::mpl::true_* boost_foreach_is_noncopyable( + boost::multi_index::detail::sequenced_index*&, + boost_foreach_argument_dependent_lookup_hack) +{ + return 0; +} + +#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp new file mode 100644 index 00000000000..a019f2a6d2f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp @@ -0,0 +1,91 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +class sequenced_index; + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator==( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator!=( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>=( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<=( + const sequenced_index& x, + const sequenced_index& y); + +template +void swap( + sequenced_index& x, + sequenced_index& y); + +} /* namespace multi_index::detail */ + +/* index specifiers */ + +template > +struct sequenced; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp new file mode 100644 index 00000000000..ce51f8241ee --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp @@ -0,0 +1,88 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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) +#define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE +#endif + +#if BOOST_MULTI_INDEX_LIMIT_TAG_SIZE +struct is_tag +{ + BOOST_STATIC_CONSTANT(bool,value=(is_base_and_derived::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, + mpl::identity + >::type type; + + BOOST_STATIC_ASSERT(detail::no_duplicate_tags::value); +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_TAG_SIZE + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp new file mode 100644 index 00000000000..9993a8dfa10 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp @@ -0,0 +1,1362 @@ +/* Multiply indexed container. + * + * Copyright 2003-2014 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#include +#include +#include +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#include +#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&multi_index_container::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) +#define BOOST_MULTI_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) +#pragma warning(push) +#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */ +#endif + +template +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 boost::detail::allocator::rebind_to< + Allocator, + typename detail::multi_index_node_type< + Value,IndexSpecifierList,Allocator>::type + >::type::pointer, + multi_index_container >, + 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: + BOOST_COPYABLE_AND_MOVABLE(multi_index_container) + +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template friend class detail::index_base; + template friend struct detail::header_holder; + template 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 node_allocator::pointer, + multi_index_container> bfm_header; + + +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; + + typedef typename super::index_type_list index_type_list; + + 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::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::type:: + ctor_args_list(), + const allocator_type& al= + typename mpl::identity::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 + 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::type:: + ctor_args_list(), + const allocator_type& al= + typename mpl::identity::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_ref_(*first,hint.get_node()).first); + ++hint; + } + } + BOOST_CATCH(...){ + clear_(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container( + std::initializer_list list, + const ctor_args_list& args_list=ctor_args_list(), + const allocator_type& al=allocator_type()): + bfm_allocator(al), + super(args_list,bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + BOOST_TRY{ + typedef const Value* init_iterator; + + iterator hint=super::end(); + for(init_iterator first=list.begin(),last=list.end(); + first!=last;++first){ + hint=super::make_iterator(insert_(*first,hint.get_node()).first); + ++hint; + } + } + BOOST_CATCH(...){ + clear_(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } +#endif + + multi_index_container( + const multi_index_container& 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(BOOST_RV_REF(multi_index_container) x): + bfm_allocator(x.bfm_allocator::member), + bfm_header(), + super(x,detail::do_not_copy_elements_tag()), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x); + swap_elements_(x); + } + + ~multi_index_container() + { + delete_all_nodes_(); + } + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + /* As per http://www.boost.org/doc/html/move/emulation_limitations.html + * #move.emulation_limitations.assignment_operator + */ + + multi_index_container& operator=( + const multi_index_container& x) + { + multi_index_container y(x); + this->swap(y); + return *this; + } +#endif + + multi_index_container& operator=( + BOOST_COPY_ASSIGN_REF(multi_index_container) x) + { + multi_index_container y(x); + this->swap(y); + return *this; + } + + multi_index_container& operator=( + BOOST_RV_REF(multi_index_container) x) + { + this->swap(x); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container& operator=( + std::initializer_list list) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + typedef const Value* init_iterator; + + multi_index_container x(*this,detail::do_not_copy_elements_tag()); + iterator hint=x.end(); + for(init_iterator first=list.begin(),last=list.end(); + first!=last;++first){ + hint=x.make_iterator(x.insert_(*first,hint.get_node()).first); + ++hint; + } + x.swap_elements_(*this); + return*this; + } +#endif + + allocator_type get_allocator()const BOOST_NOEXCEPT + { + return allocator_type(bfm_allocator::member); + } + + /* retrieval of indices by number */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template + struct nth_index + { + BOOST_STATIC_ASSERT(N>=0&&N::type::value); + typedef typename mpl::at_c::type type; + }; + + template + typename nth_index::type& get()BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT(N>=0&&N::type::value); + return *this; + } + + template + const typename nth_index::type& get()const BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT(N>=0&&N::type::value); + return *this; + } +#endif + + /* retrieval of indices by tag */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template + struct index + { + typedef typename mpl::find_if< + index_type_list, + detail::has_tag + >::type iter; + + BOOST_STATIC_CONSTANT( + bool,index_found=!(is_same::type >::value)); + BOOST_STATIC_ASSERT(index_found); + + typedef typename mpl::deref::type type; + }; + + template + typename index::type& get()BOOST_NOEXCEPT + { + return *this; + } + + template + const typename index::type& get()const BOOST_NOEXCEPT + { + return *this; + } +#endif + + /* projection of iterators by number */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template + struct nth_index_iterator + { + typedef typename nth_index::type::iterator type; + }; + + template + struct nth_index_const_iterator + { + typedef typename nth_index::type::const_iterator type; + }; + + template + typename nth_index_iterator::type project(IteratorType it) + { + typedef typename nth_index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT( + (mpl::contains::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast(*this)); + + return index_type::make_iterator(static_cast(it.get_node())); + } + + template + typename nth_index_const_iterator::type project(IteratorType it)const + { + typedef typename nth_index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains::value|| + mpl::contains::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast(*this)); + return index_type::make_iterator(static_cast(it.get_node())); + } +#endif + + /* projection of iterators by tag */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template + struct index_iterator + { + typedef typename index::type::iterator type; + }; + + template + struct index_const_iterator + { + typedef typename index::type::const_iterator type; + }; + + template + typename index_iterator::type project(IteratorType it) + { + typedef typename index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT( + (mpl::contains::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast(*this)); + return index_type::make_iterator(static_cast(it.get_node())); + } + + template + typename index_const_iterator::type project(IteratorType it)const + { + typedef typename index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains::value|| + mpl::contains::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast(*this)); + return index_type::make_iterator(static_cast(it.get_node())); + } +#endif + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + typedef typename super::copy_map_type copy_map_type; + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container( + const multi_index_container& x, + detail::do_not_copy_elements_tag): + bfm_allocator(x.bfm_allocator::member), + bfm_header(), + super(x,detail::do_not_copy_elements_tag()), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } +#endif + + 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(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(-1); + } + + template + std::pair insert_(const Value& v,Variant variant) + { + node_type* x=0; + node_type* res=super::insert_(v,x,variant); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + return std::pair(res,false); + } + } + + std::pair insert_(const Value& v) + { + return insert_(v,detail::lvalue_tag()); + } + + std::pair insert_rv_(const Value& v) + { + return insert_(v,detail::rvalue_tag()); + } + + template + std::pair insert_ref_(T& t) + { + node_type* x=allocate_node(); + BOOST_TRY{ + new(&x->value()) value_type(t); + BOOST_TRY{ + node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + std::pair insert_ref_(const value_type& x) + { + return insert_(x); + } + + std::pair insert_ref_(value_type& x) + { + return insert_(x); + } + + template + std::pair emplace_( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + node_type* x=allocate_node(); + BOOST_TRY{ + detail::vartempl_placement_new( + &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + BOOST_TRY{ + node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + template + std::pair insert_( + const Value& v,node_type* position,Variant variant) + { + node_type* x=0; + node_type* res=super::insert_(v,position,x,variant); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + return std::pair(res,false); + } + } + + std::pair insert_(const Value& v,node_type* position) + { + return insert_(v,position,detail::lvalue_tag()); + } + + std::pair insert_rv_(const Value& v,node_type* position) + { + return insert_(v,position,detail::rvalue_tag()); + } + + template + std::pair insert_ref_( + T& t,node_type* position) + { + node_type* x=allocate_node(); + BOOST_TRY{ + new(&x->value()) value_type(t); + BOOST_TRY{ + node_type* res=super::insert_( + x->value(),position,x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + std::pair insert_ref_( + const value_type& x,node_type* position) + { + return insert_(x,position); + } + + std::pair insert_ref_( + value_type& x,node_type* position) + { + return insert_(x,position); + } + + template + std::pair emplace_hint_( + node_type* position, + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + node_type* x=allocate_node(); + BOOST_TRY{ + detail::vartempl_placement_new( + &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + BOOST_TRY{ + node_type* res=super::insert_( + x->value(),position,x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + 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& 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); + } + + void swap_elements_( + multi_index_container& x) + { + std::swap(bfm_header::member,x.bfm_header::member); + super::swap_elements_(x); + std::swap(node_count,x.node_count); + } + + bool replace_(const Value& k,node_type* x) + { + return super::replace_(k,x,detail::lvalue_tag()); + } + + bool replace_rv_(const Value& k,node_type* x) + { + return super::replace_(k,x,detail::rvalue_tag()); + } + + template + bool modify_(Modifier& mod,node_type* x) + { + mod(const_cast(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 + bool modify_(Modifier& mod,Rollback& back_,node_type* x) + { + mod(const_cast(x->value())); + + bool b; + BOOST_TRY{ + b=super::modify_rollback_(x); + } + BOOST_CATCH(...){ + BOOST_TRY{ + back_(const_cast(x->value())); + BOOST_RETHROW; + } + BOOST_CATCH(...){ + this->erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH_END + + BOOST_TRY{ + if(!b){ + back_(const_cast(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 + void save(Archive& ar,const unsigned int version)const + { + const serialization::collection_size_type s(size_()); + const detail::serialization_version value_version; + ar< + void load(Archive& ar,const unsigned int version) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + + clear_(); + serialization::collection_size_type s; + detail::serialization_version value_version; + if(version<1){ + std::size_t sz; + ar>>serialization::make_nvp("count",sz); + s=static_cast(sz); + } + else{ + ar>>serialization::make_nvp("count",s); + } + if(version<2){ + value_version=0; + } + else{ + ar>>serialization::make_nvp("value_version",value_version); + } + + index_loader_type lm(bfm_allocator::member,s); + + for(std::size_t n=0;n value("item",ar,value_version); + std::pair 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 +}; + +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) +#pragma warning(pop) /* C4522 */ +#endif + +/* retrieval of indices by number */ + +template +struct nth_index +{ + BOOST_STATIC_CONSTANT( + int, + M=mpl::size::type::value); + BOOST_STATIC_ASSERT(N>=0&&N::type type; +}; + +template +typename nth_index< + multi_index_container,N>::type& +get( + multi_index_container& m)BOOST_NOEXCEPT +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + N + >::type index_type; + + BOOST_STATIC_ASSERT(N>=0&& + N< + mpl::size< + BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list + >::type::value); + + return detail::converter::index(m); +} + +template +const typename nth_index< + multi_index_container,N>::type& +get( + const multi_index_container& m +)BOOST_NOEXCEPT +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + N + >::type index_type; + + BOOST_STATIC_ASSERT(N>=0&& + N< + mpl::size< + BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list + >::type::value); + + return detail::converter::index(m); +} + +/* retrieval of indices by tag */ + +template +struct index +{ + typedef typename MultiIndexContainer::index_type_list index_type_list; + + typedef typename mpl::find_if< + index_type_list, + detail::has_tag + >::type iter; + + BOOST_STATIC_CONSTANT( + bool,index_found=!(is_same::type >::value)); + BOOST_STATIC_ASSERT(index_found); + + typedef typename mpl::deref::type type; +}; + +template< + typename Tag,typename Value,typename IndexSpecifierList,typename Allocator +> +typename ::boost::multi_index::index< + multi_index_container,Tag>::type& +get( + multi_index_container& m)BOOST_NOEXCEPT +{ + 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_type; + + return detail::converter::index(m); +} + +template< + typename Tag,typename Value,typename IndexSpecifierList,typename Allocator +> +const typename ::boost::multi_index::index< + multi_index_container,Tag>::type& +get( + const multi_index_container& m +)BOOST_NOEXCEPT +{ + 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_type; + + return detail::converter::index(m); +} + +/* projection of iterators by number */ + +template +struct nth_index_iterator +{ + typedef typename nth_index::type::iterator type; +}; + +template +struct nth_index_const_iterator +{ + typedef typename nth_index::type::const_iterator type; +}; + +template< + int N,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename nth_index_iterator< + multi_index_container,N>::type +project( + multi_index_container& m, + IteratorType it) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ + 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::iterator( + m,static_cast(it.get_node())); +} + +template< + int N,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename nth_index_const_iterator< + multi_index_container,N>::type +project( + const multi_index_container& m, + IteratorType it) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ + 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::const_iterator( + m,static_cast(it.get_node())); +} + +/* projection of iterators by tag */ + +template +struct index_iterator +{ + typedef typename ::boost::multi_index::index< + MultiIndexContainer,Tag>::type::iterator type; +}; + +template +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,Tag>::type +project( + multi_index_container& m, + IteratorType it) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_type,Tag>::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ + 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::iterator( + m,static_cast(it.get_node())); +} + +template< + typename Tag,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename index_const_iterator< + multi_index_container,Tag>::type +project( + const multi_index_container& m, + IteratorType it) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_type,Tag>::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ + 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::const_iterator( + m,static_cast(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& x, + const multi_index_container& 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& x, + const multi_index_container& y) +{ + return get<0>(x)(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator!=( + const multi_index_container& x, + const multi_index_container& 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& x, + const multi_index_container& 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& x, + const multi_index_container& 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& x, + const multi_index_container& y) +{ + return get<0>(x)<=get<0>(y); +} + +/* specialized algorithms */ + +template +void swap( + multi_index_container& x, + multi_index_container& y) +{ + x.swap(y); +} + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +/* 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 +struct version< + boost::multi_index_container +> +{ + 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 +#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp new file mode 100644 index 00000000000..b35acad407a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp @@ -0,0 +1,121 @@ +/* Copyright 2003-2013 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) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +/* Default value for IndexSpecifierList specifies a container + * equivalent to std::set. + */ + +template< + typename Value, + typename IndexSpecifierList=indexed_by > >, + typename Allocator=std::allocator > +class multi_index_container; + +template +struct nth_index; + +template +struct index; + +template +struct nth_index_iterator; + +template +struct nth_index_const_iterator; + +template +struct index_iterator; + +template +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& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator!=( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>=( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<=( + const multi_index_container& x, + const multi_index_container& y); + +template +void swap( + multi_index_container& x, + multi_index_container& 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/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp new file mode 100644 index 00000000000..f6581accc91 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp @@ -0,0 +1,145 @@ +#ifndef BOOST_SERIALIZATION_ACCESS_HPP +#define BOOST_SERIALIZATION_ACCESS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 + +namespace boost { + +namespace archive { +namespace detail { + template + class iserializer; + template + class oserializer; +} // namespace detail +} // namespace archive + +namespace serialization { + +// forward declarations +template +inline void serialize_adl(Archive &, T &, const unsigned int); +namespace detail { + template + struct member_saver; + template + 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 + friend struct detail::member_saver; + template + friend struct detail::member_loader; + template + friend class archive::detail::iserializer; + template + friend class archive::detail::oserializer; + template + friend inline void serialize( + Archive & ar, + T & t, + const unsigned int file_version + ); + template + friend inline void save_construct_data( + Archive & ar, + const T * t, + const unsigned int file_version + ); + template + friend inline void load_construct_data( + Archive & ar, + T * t, + const unsigned int file_version + ); +#endif + + // pass calls to users's class implementation + template + static void member_save( + Archive & ar, + //const T & t, + T & t, + const unsigned int file_version + ){ + t.save(ar, file_version); + } + template + static void member_load( + Archive & ar, + T & t, + const unsigned int file_version + ){ + t.load(ar, file_version); + } + template + 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 to + // 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 + 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); + } + template + 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 + static T & cast_reference(U & u){ + return static_cast(u); + } + template + static T * cast_pointer(U * u){ + return static_cast(u); + } +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_ACCESS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp new file mode 100644 index 00000000000..ccf806b1813 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP +#define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_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 +// serialization/unordered_map.hpp: +// serialization for stl unordered_map templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// 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 +#include +#include +#include +#include + +namespace boost { +namespace serialization { +namespace stl { + +// map input +template +struct archive_input_unordered_map +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + ar >> boost::serialization::make_nvp("item", t.reference()); + std::pair result = + s.insert(boost::move(t.reference())); + // note: the following presumes that the map::value_type was NOT tracked + // in the archive. This is the usual case, but here there is no way + // to determine that. + if(result.second){ + ar.reset_object_address( + & (result.first->second), + & t.reference().second + ); + } + } +}; + +// multimap input +template +struct archive_input_unordered_multimap +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::const_iterator result = + s.insert(t.reference()); + // note: the following presumes that the map::value_type was NOT tracked + // in the archive. This is the usual case, but here there is no way + // to determine that. + ar.reset_object_address( + & result->second, + & t.reference() + ); + } +}; + +} // stl +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp new file mode 100644 index 00000000000..7f0003cc6a4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp @@ -0,0 +1,72 @@ +#ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP +#define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_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_input_unordered_set.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// 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 +#include +#include +#include + +namespace boost { +namespace serialization { + +namespace stl { + +// unordered_set input +template +struct archive_input_unordered_set +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + std::pair result = + s.insert(boost::move(t.reference())); + if(result.second) + ar.reset_object_address(& (* result.first), & t.reference()); + } +}; + +// unordered_multiset input +template +struct archive_input_unordered_multiset +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::const_iterator result = + s.insert(boost::move(t.reference())); + ar.reset_object_address(& (* result), & t.reference()); + } +}; + +} // stl +} // serialization +} // boost + +#endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp new file mode 100644 index 00000000000..612d1a61985 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_SERIALIZATION_ARRAY_HPP +#define BOOST_SERIALIZATION_ARRAY_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// 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) + +// for serialization of . If not supported by the standard +// library - this file becomes empty. This is to avoid breaking backward +// compatibiliy for applications which used this header to support +// serialization of native arrays. Code to serialize native arrays is +// now always include by default. RR + +#include // msvc 6.0 needs this for warning suppression + +#if defined(BOOST_NO_STDC_NAMESPACE) + +#include +#include // std::size_t +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#ifndef BOOST_NO_CXX11_HDR_ARRAY + +#include +#include + +namespace boost { namespace serialization { + +template +void serialize(Archive& ar, std::array& a, const unsigned int /* version */) +{ + ar & boost::serialization::make_nvp( + "elems", + *static_cast(static_cast(a.data())) + ); + +} +} } // end namespace boost::serialization + +#endif // BOOST_NO_CXX11_HDR_ARRAY + +#endif //BOOST_SERIALIZATION_ARRAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp new file mode 100644 index 00000000000..40dffba871a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP +#define BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// 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 // msvc 6.0 needs this for warning suppression + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include + +namespace boost { namespace serialization { + +template +struct use_array_optimization : boost::mpl::always {}; + +} } // end namespace boost::serialization + +#define BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(Archive) \ +namespace boost { namespace serialization { \ +template <> struct use_array_optimization { \ + template \ + struct apply : boost::mpl::apply1::type \ + >::type {}; \ +}; }} + +#endif //BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp new file mode 100644 index 00000000000..adf436e15b4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp @@ -0,0 +1,121 @@ +#ifndef BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP +#define BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// 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 + +#include // msvc 6.0 needs this for warning suppression + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace serialization { + +template +class array_wrapper : + public wrapper_traits > +{ +private: + array_wrapper & operator=(const array_wrapper & rhs); + // note: I would like to make the copy constructor private but this breaks + // make_array. So I make make_array a friend + template + friend const boost::serialization::array_wrapper make_array(Tx * t, S s); +public: + + array_wrapper(const array_wrapper & rhs) : + m_t(rhs.m_t), + m_element_count(rhs.m_element_count) + {} +public: + array_wrapper(T * t, std::size_t s) : + m_t(t), + m_element_count(s) + {} + + // default implementation + template + void serialize_optimized(Archive &ar, const unsigned int, mpl::false_ ) const + { + // default implemention does the loop + std::size_t c = count(); + T * t = address(); + while(0 < c--) + ar & boost::serialization::make_nvp("item", *t++); + } + + // optimized implementation + template + void serialize_optimized(Archive &ar, const unsigned int version, mpl::true_ ) + { + boost::serialization::split_member(ar, *this, version); + } + + // default implementation + template + void save(Archive &ar, const unsigned int version) const + { + ar.save_array(*this,version); + } + + // default implementation + template + void load(Archive &ar, const unsigned int version) + { + ar.load_array(*this,version); + } + + // default implementation + template + void serialize(Archive &ar, const unsigned int version) + { + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const< T >::type + >::type use_optimized; + serialize_optimized(ar,version,use_optimized()); + } + + T * address() const + { + return m_t; + } + + std::size_t count() const + { + return m_element_count; + } + +private: + T * const m_t; + const std::size_t m_element_count; +}; + +template +inline +const array_wrapper< T > make_array(T* t, S s){ + const array_wrapper< T > a(t, s); + return a; +} + +} } // end namespace boost::serialization + + +#endif //BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp new file mode 100644 index 00000000000..632f9312f5f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp @@ -0,0 +1,60 @@ +#ifndef BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP +#define BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// assume_abstract_class.hpp: + +// (C) Copyright 2008 Robert Ramey +// 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 is useful for compilers which don't support the boost::is_abstract + +#include +#include + +#ifndef BOOST_NO_IS_ABSTRACT + +// if there is an intrinsic is_abstract defined, we don't have to do anything +#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) + +// but forward to the "official" is_abstract +namespace boost { +namespace serialization { + template + struct is_abstract : boost::is_abstract< T > {} ; +} // namespace serialization +} // namespace boost + +#else +// we have to "make" one + +namespace boost { +namespace serialization { + template + struct is_abstract : boost::false_type {}; +} // namespace serialization +} // namespace boost + +// define a macro to make explicit designation of this more transparent +#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct is_abstract< T > : boost::true_type {}; \ +template<> \ +struct is_abstract< const T > : boost::true_type {}; \ +}} \ +/**/ + +#endif // BOOST_NO_IS_ABSTRACT + +#endif //BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp new file mode 100644 index 00000000000..1a82cecd4b5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp @@ -0,0 +1,100 @@ +#ifndef BOOST_SERIALIZATION_BASE_OBJECT_HPP +#define BOOST_SERIALIZATION_BASE_OBJECT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +namespace detail +{ + // get the base type for a given derived type + // preserving the const-ness + template + struct base_cast + { + typedef typename + mpl::if_< + is_const, + const B, + B + >::type type; + BOOST_STATIC_ASSERT(is_const::value == is_const::value); + }; + + // only register void casts if the types are polymorphic + template + 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 typename mpl::eval_if< + is_polymorphic, + mpl::identity, + mpl::identity + >::type type; + return type::invoke(); + } + }; + +} // namespace detail +template +typename detail::base_cast::type & +base_object(Derived &d) +{ + BOOST_STATIC_ASSERT(( is_base_and_derived::value)); + BOOST_STATIC_ASSERT(! is_pointer::value); + typedef typename detail::base_cast::type type; + detail::base_register::invoke(); + return access::cast_reference(d); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp new file mode 100644 index 00000000000..5c9038e5a9f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_SERIALIZATION_BINARY_OBJECT_HPP +#define BOOST_SERIALIZATION_BINARY_OBJECT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 + +#include // std::size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +struct binary_object : + public wrapper_traits > +{ + void const * m_t; + std::size_t m_size; + template + void save(Archive & ar, const unsigned int /* file_version */) const { + ar.save_binary(m_t, m_size); + } + template + void load(Archive & ar, const unsigned int /* file_version */) const { + ar.load_binary(const_cast(m_t), m_size); + } + BOOST_SERIALIZATION_SPLIT_MEMBER() + binary_object & operator=(const binary_object & rhs) { + m_t = rhs.m_t; + m_size = rhs.m_size; + return *this; + } + binary_object(const void * const t, std::size_t size) : + m_t(t), + m_size(size) + {} + binary_object(const binary_object & rhs) : + m_t(rhs.m_t), + m_size(rhs.m_size) + {} +}; + +// just a little helper to support the convention that all serialization +// wrappers follow the naming convention make_xxxxx +inline +const binary_object +make_binary_object(const void * t, std::size_t size){ + return binary_object(t, size); +} + +} // namespace serialization +} // boost + +#endif // BOOST_SERIALIZATION_BINARY_OBJECT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp new file mode 100644 index 00000000000..78f9bd74336 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp @@ -0,0 +1,75 @@ +/*! + * \file bitset.hpp + * \brief Provides Boost.Serialization support for std::bitset + * \author Brian Ravnsgaard Riis + * \author Kenneth Riddile + * \date 16.09.2004, updated 04.03.2009 + * \copyright 2004 Brian Ravnsgaard Riis + * \license Boost Software License 1.0 + */ +#ifndef BOOST_SERIALIZATION_BITSET_HPP +#define BOOST_SERIALIZATION_BITSET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // size_t + +#include +#include +#include +#include + +namespace boost{ +namespace serialization{ + +template +inline void save( + Archive & ar, + std::bitset const & t, + const unsigned int /* version */ +){ + const std::string bits = t.template to_string< + std::string::value_type, + std::string::traits_type, + std::string::allocator_type + >(); + ar << BOOST_SERIALIZATION_NVP( bits ); +} + +template +inline void load( + Archive & ar, + std::bitset & t, + const unsigned int /* version */ +){ + std::string bits; + ar >> BOOST_SERIALIZATION_NVP( bits ); + t = std::bitset(bits); +} + +template +inline void serialize( + Archive & ar, + std::bitset & t, + const unsigned int version +){ + boost::serialization::split_free( ar, t, version ); +} + +// don't track bitsets since that would trigger tracking +// all over the program - which probably would be a surprise. +// also, tracking would be hard to implement since, we're +// serialization a representation of the data rather than +// the data itself. +template +struct tracking_level > + : mpl::int_ {} ; + +} //serialization +} //boost + +#endif // BOOST_SERIALIZATION_BITSET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp new file mode 100644 index 00000000000..d564ff15de0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_SERIALIZATION_ARRAY_HPP +#define BOOST_SERIALIZATION_ARRAY_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// 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 + +#include // msvc 6.0 needs this for warning suppression + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include + +namespace boost { namespace serialization { +// implement serialization for boost::array +template +void serialize(Archive& ar, boost::array& a, const unsigned int /* version */) +{ + ar & boost::serialization::make_nvp("elems", a.elems); +} + +} } // end namespace boost::serialization + + +#endif //BOOST_SERIALIZATION_ARRAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp new file mode 100644 index 00000000000..8913b31f9e6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp @@ -0,0 +1,154 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP +#define BOOST_SERIALIZATION_UNORDERED_MAP_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 +// serialization/unordered_map.hpp: +// serialization for stl unordered_map templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// 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 + +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const boost::unordered_map &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + boost::unordered_map + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + boost::unordered_map &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + boost::unordered_map, + boost::serialization::stl::archive_input_unordered_map< + Archive, + boost::unordered_map + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + boost::unordered_map &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// unordered_multimap +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const boost::unordered_multimap &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + boost::unordered_multimap + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + boost::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + boost::unordered_multimap, + boost::serialization::stl::archive_input_unordered_multimap< + Archive, + boost::unordered_multimap + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + boost::unordered_multimap &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp new file mode 100644 index 00000000000..307c7819cbd --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp @@ -0,0 +1,150 @@ +#ifndef BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP +#define BOOST_SERIALIZATION_BOOST_UNORDERED_SET_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 +// unordered_set.hpp: serialization for boost unordered_set templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// 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 + +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const boost::unordered_set &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + boost::unordered_set + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + boost::unordered_set &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + boost::unordered_set, + boost::serialization::stl::archive_input_unordered_set< + Archive, + boost::unordered_set + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + boost::unordered_set &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// unordered_multiset +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const boost::unordered_multiset &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + boost::unordered_multiset + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + boost::unordered_multiset &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + boost::unordered_multiset, + boost::serialization::stl::archive_input_unordered_multiset< + Archive, + boost::unordered_multiset + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + boost::unordered_multiset &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp new file mode 100644 index 00000000000..2dd8fa72584 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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 // size_t +#include +#include +#include +#include + +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/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp new file mode 100644 index 00000000000..3ec9401eff0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP +#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// collection_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 assigns a level implemenation trait to a collection type +// for all primitives. It is needed so that archives which are meant to be +// portable don't write class information in the archive. Since, not all +// compiles recognize the same set of primitive types, the possibility +// exists for archives to be non-portable if class information for primitive +// types is included. This is addressed by the following macros. +#include +//#include +#include + +#include +#include +#include // ULONG_MAX +#include + +#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(T, C) \ +template<> \ +struct implementation_level< C < T > > { \ + typedef mpl::integral_c_tag tag; \ + typedef mpl::int_ type; \ + BOOST_STATIC_CONSTANT(int, value = object_serializable); \ +}; \ +/**/ + +#if defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_INTRINSIC_WCHAR_T) + #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) +#else + #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(wchar_t, C) \ + /**/ +#endif + +#if defined(BOOST_HAS_LONG_LONG) + #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::long_long_type, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::ulong_long_type, C) \ + /**/ +#else + #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) +#endif + +#define BOOST_SERIALIZATION_COLLECTION_TRAITS(C) \ + namespace boost { namespace serialization { \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(bool, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(char, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed char, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned char, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed int, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned int, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed long, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned long, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(float, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(double, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned short, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed short, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ + } } \ + /**/ + +#endif // BOOST_SERIALIZATION_COLLECTION_TRAITS diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp new file mode 100644 index 00000000000..e042c0c130d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp @@ -0,0 +1,106 @@ +#ifndef BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP +#define BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(_MSC_VER) && (_MSC_VER <= 1020) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// collections_load_imp.hpp: serialization for loading stl collections + +// (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. + +// helper function templates for serialization of collections + +#include +#include // size_t +#include // msvc 6.0 needs this for warning suppression +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// + +template< + class Archive, + class T +> +typename boost::enable_if< + typename detail::is_default_constructible< + typename T::value_type + >, + void +>::type +collection_load_impl( + Archive & ar, + T & t, + collection_size_type count, + item_version_type /*item_version*/ +){ + t.resize(count); + typename T::iterator hint; + hint = t.begin(); + while(count-- > 0){ + ar >> boost::serialization::make_nvp("item", *hint++); + } +} + +template< + class Archive, + class T +> +typename boost::disable_if< + typename detail::is_default_constructible< + typename T::value_type + >, + void +>::type +collection_load_impl( + Archive & ar, + T & t, + collection_size_type count, + item_version_type item_version +){ + t.clear(); + while(count-- > 0){ + detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + t.push_back(boost::move(u.reference())); + ar.reset_object_address(& t.back() , & u.reference()); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp new file mode 100644 index 00000000000..f3cabfcf3f5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp @@ -0,0 +1,82 @@ +#ifndef BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP +#define BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// collections_save_imp.hpp: serialization for stl collections + +// (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. + +// helper function templates for serialization of collections + +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// + +template +inline void save_collection( + Archive & ar, + const Container &s, + collection_size_type count) +{ + ar << BOOST_SERIALIZATION_NVP(count); + // record number of elements + const item_version_type item_version( + version::value + ); + #if 0 + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + if(boost::archive::library_version_type(3) < library_version){ + ar << BOOST_SERIALIZATION_NVP(item_version); + } + #else + ar << BOOST_SERIALIZATION_NVP(item_version); + #endif + + typename Container::const_iterator it = s.begin(); + while(count-- > 0){ + // note borland emits a no-op without the explicit namespace + boost::serialization::save_construct_data_adl( + ar, + &(*it), + item_version + ); + ar << boost::serialization::make_nvp("item", *it++); + } +} + +template +inline void save_collection(Archive & ar, const Container &s) +{ + // record number of elements + collection_size_type count(s.size()); + save_collection(ar, s, count); +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp new file mode 100644 index 00000000000..b4ef44cf973 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp @@ -0,0 +1,81 @@ +#ifndef BOOST_SERIALIZATION_COMPLEX_HPP +#define BOOST_SERIALIZATION_COMPLEX_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/utility.hpp: +// serialization for stl utility templates + +// (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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void serialize( + Archive & ar, + std::complex< T > & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +template +inline void save( + Archive & ar, + std::complex< T > const & t, + const unsigned int /* file_version */ +){ + const T re = t.real(); + const T im = t.imag(); + ar << boost::serialization::make_nvp("real", re); + ar << boost::serialization::make_nvp("imag", im); +} + +template +inline void load( + Archive & ar, + std::complex< T >& t, + const unsigned int /* file_version */ +){ + T re; + T im; + ar >> boost::serialization::make_nvp("real", re); + ar >> boost::serialization::make_nvp("imag", im); + t = std::complex< T >(re,im); +} + +// specialization of serialization traits for complex +template +struct is_bitwise_serializable > + : public is_bitwise_serializable< T > {}; + +template +struct implementation_level > + : mpl::int_ {} ; + +// treat complex just like builtin arithmetic types for tracking +template +struct tracking_level > + : mpl::int_ {} ; + +} // serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_COMPLEX_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp new file mode 100644 index 00000000000..ea8cb9239ed --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp @@ -0,0 +1,74 @@ +#ifndef BOOST_SERIALIZATION_CONFIG_HPP +#define BOOST_SERIALIZATION_CONFIG_HPP + +// config.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 +#include + +// note: this version incorporates the related code into the the +// the same library as BOOST_ARCHIVE. This could change some day in the +// future + +// if BOOST_SERIALIZATION_DECL is defined undefine it now: +#ifdef BOOST_SERIALIZATION_DECL + #undef BOOST_SERIALIZATION_DECL +#endif + +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_SERIALIZATION_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) + #if !defined(BOOST_DYN_LINK) + #define BOOST_DYN_LINK + #endif + // export if this is our own source, otherwise import: + #if defined(BOOST_SERIALIZATION_SOURCE) + #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_EXPORT + #else + #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_IMPORT + #endif // defined(BOOST_SERIALIZATION_SOURCE) +#endif // defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) + +// if BOOST_SERIALIZATION_DECL isn't defined yet define it now: +#ifndef BOOST_SERIALIZATION_DECL + #define BOOST_SERIALIZATION_DECL +#endif + +// enable automatic library variant selection ------------------------------// + +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ +&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ +&& !defined(BOOST_SERIALIZATION_SOURCE) + // + // Set the name of our library, this will get undef'ed by auto_link.hpp + // once it's done with it: + // + #define BOOST_LIB_NAME boost_serialization + // + // If we're importing code from a dll, then tell auto_link.hpp about it: + // + #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) + # define BOOST_DYN_LINK + #endif + // + // And include the header that does the work: + // + #include + +#endif + +#endif // BOOST_SERIALIZATION_CONFIG_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp new file mode 100644 index 00000000000..bba81364ce2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_SERIALIZATION_DEQUE_HPP +#define BOOST_SERIALIZATION_DEQUE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// deque.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 + +#include + +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const std::deque &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, std::deque + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::deque &t, + const unsigned int /* file_version */ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + stl::collection_load_impl(ar, t, count, item_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::deque &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::deque) + +#endif // BOOST_SERIALIZATION_DEQUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp new file mode 100644 index 00000000000..4d20b13bf3e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP +#define BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// is_default_constructible.hpp: serialization for loading stl collections +// +// (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 + +#if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + #include + namespace boost{ + namespace serialization { + namespace detail { + + template + struct is_default_constructible : public std::is_default_constructible {}; + + } // detail + } // serializaition + } // boost +#else + // we don't have standard library support for is_default_constructible + // so we fake it by using boost::has_trivial_construtor. But this is not + // actually correct because it's possible that a default constructor + // to be non trivial. So when using this, make sure you're not using your + // own definition of of T() but are using the actual default one! + #include + namespace boost{ + namespace serialization { + namespace detail { + + template + struct is_default_constructible : public boost::has_trivial_constructor {}; + + } // detail + } // serializaition + } // boost + +#endif + + +#endif // BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp new file mode 100644 index 00000000000..a5872557cf2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp @@ -0,0 +1,551 @@ +#ifndef BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED +#define BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) +# pragma once +#endif + +// +// detail/shared_count.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) +# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. +#endif + +#include +#include +#include + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) +#include +#endif + +#include // std::auto_ptr, std::allocator +#include // std::less +#include // std::exception +#include // std::bad_alloc +#include // std::type_info in get_deleter +#include // std::size_t + +#include // msvc 6.0 needs this for warning suppression +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +namespace boost_132 { + +// Debug hooks + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn); +void sp_array_constructor_hook(void * px); +void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn); +void sp_array_destructor_hook(void * px); + +#endif + + +// The standard library that comes with Borland C++ 5.5.1 +// defines std::exception and its members as having C calling +// convention (-pc). When the definition of bad_weak_ptr +// is compiled with -ps, the compiler issues an error. +// Hence, the temporary #pragma option -pc below. The version +// check is deliberately conservative. + +class bad_weak_ptr: public std::exception +{ +public: + + virtual char const * what() const throw() + { + return "boost::bad_weak_ptr"; + } +}; + +namespace detail{ + +class sp_counted_base +{ +//private: + + typedef boost::detail::lightweight_mutex mutex_type; + +public: + + sp_counted_base(): use_count_(1), weak_count_(1) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destruct() is called when weak_count_ drops to zero. + + virtual void destruct() // nothrow + { + delete this; + } + + virtual void * get_deleter(std::type_info const & ti) = 0; + + void add_ref_copy() + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + ++use_count_; + } + + void add_ref_lock() + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + if(use_count_ == 0) boost::serialization::throw_exception(bad_weak_ptr()); + ++use_count_; + } + + void release() // nothrow + { + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + long new_use_count = --use_count_; + + if(new_use_count != 0) return; + } + + dispose(); + weak_release(); + } + + void weak_add_ref() // nothrow + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + ++weak_count_; + } + + void weak_release() // nothrow + { + long new_weak_count; + + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + new_weak_count = --weak_count_; + } + + if(new_weak_count == 0) + { + destruct(); + } + } + + long use_count() const // nothrow + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + return use_count_; + } + +//private: +public: + sp_counted_base(sp_counted_base const &); + sp_counted_base & operator= (sp_counted_base const &); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +#if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32) + mutable mutex_type mtx_; +#endif +}; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +template void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) +{ + boost::sp_scalar_constructor_hook(px, sizeof(T), pn); +} + +template void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) +{ + boost::sp_array_constructor_hook(px); +} + +template void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long) +{ +} + +template void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) +{ + boost::sp_scalar_destructor_hook(px, sizeof(T), pn); +} + +template void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) +{ + boost::sp_array_destructor_hook(px); +} + +template void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long) +{ +} + +#endif + +// +// Borland's Codeguard trips up over the -Vx- option here: +// +#ifdef __CODEGUARD__ +# pragma option push -Vx- +#endif + +template class sp_counted_base_impl: public sp_counted_base +{ +//private: +public: + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_base_impl(sp_counted_base_impl const &); + sp_counted_base_impl & operator= (sp_counted_base_impl const &); + + typedef sp_counted_base_impl this_type; + +public: + + // pre: initial_use_count <= initial_weak_count, d(p) must not throw + + sp_counted_base_impl(P p, D d): ptr(p), del(d) + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + detail::cbi_call_constructor_hook(this, p, d, 0); +#endif + } + + virtual void dispose() // nothrow + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + detail::cbi_call_destructor_hook(this, ptr, del, 0); +#endif + del(ptr); + } + + virtual void * get_deleter(std::type_info const & ti) + { + return ti == typeid(D)? &del: 0; + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new(std::size_t) + { + return std::allocator().allocate(1, static_cast(0)); + } + + void operator delete(void * p) + { + std::allocator().deallocate(static_cast(p), 1); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new(std::size_t) + { + return boost::detail::quick_allocator::alloc(); + } + + void operator delete(void * p) + { + boost::detail::quick_allocator::dealloc(p); + } + +#endif +}; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +int const shared_count_id = 0x2C35F101; +int const weak_count_id = 0x298C38A4; + +#endif + +class weak_count; + +class shared_count +{ +//private: +public: + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class weak_count; + +public: + + shared_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + } + + template shared_count(P p, D d): pi_(0) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_base_impl(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + +#else + + pi_ = new sp_counted_base_impl(p, d); + + if(pi_ == 0) + { + d(p); // delete p + boost::serialization::throw_exception(std::bad_alloc()); + } + +#endif + } + +#ifndef BOOST_NO_AUTO_PTR + + // auto_ptr is special cased to provide the strong guarantee + + template + explicit shared_count(std::auto_ptr & r): pi_( + new sp_counted_base_impl< + Y *, + boost::checked_deleter + >(r.get(), boost::checked_deleter())) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + r.release(); + } + +#endif + + ~shared_count() // nothrow + { + if(pi_ != 0) pi_->release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if(pi_ != 0) pi_->add_ref_copy(); + } + + explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if(tmp != pi_) + { + if(tmp != 0) tmp->add_ref_copy(); + if(pi_ != 0) pi_->release(); + pi_ = tmp; + } + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less()(a.pi_, b.pi_); + } + + void * get_deleter(std::type_info const & ti) const + { + return pi_? pi_->get_deleter(ti): 0; + } +}; + +#ifdef __CODEGUARD__ +# pragma option pop +#endif + + +class weak_count +{ +private: + + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class shared_count; + +public: + + weak_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + } + + weak_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + weak_count(weak_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + ~weak_count() // nothrow + { + if(pi_ != 0) pi_->weak_release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + weak_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + + return *this; + } + + weak_count & operator= (weak_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + + return *this; + } + + void swap(weak_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + friend inline bool operator==(weak_count const & a, weak_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(weak_count const & a, weak_count const & b) + { + return std::less()(a.pi_, b.pi_); + } +}; + +inline shared_count::shared_count(weak_count const & r): pi_(r.pi_) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif +{ + if(pi_ != 0) + { + pi_->add_ref_lock(); + } + else + { + boost::serialization::throw_exception(bad_weak_ptr()); + } +} + +} // namespace detail + +} // namespace boost + +BOOST_SERIALIZATION_ASSUME_ABSTRACT(boost_132::detail::sp_counted_base) + +#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp new file mode 100644 index 00000000000..ee98b7b9449 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp @@ -0,0 +1,443 @@ +#ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED +#define BOOST_SHARED_PTR_132_HPP_INCLUDED + +// +// shared_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002, 2003 Peter Dimov +// +// 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/smart_ptr/shared_ptr.htm for documentation. +// + +#include // for broken compiler workarounds + +#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +#include +#else + +#include +#include +#include +#include + +#include +#include + +#include // for std::auto_ptr +#include // for std::swap +#include // for std::less +#include // for std::bad_cast +#include // for std::basic_ostream + +#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash +# pragma warning(push) +# pragma warning(disable:4284) // odd return type for operator-> +#endif + +namespace boost_132 { + +template class weak_ptr; +template class enable_shared_from_this; + +namespace detail +{ + +struct static_cast_tag {}; +struct const_cast_tag {}; +struct dynamic_cast_tag {}; +struct polymorphic_cast_tag {}; + +template struct shared_ptr_traits +{ + typedef T & reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +#endif + +// enable_shared_from_this support + +template void sp_enable_shared_from_this( shared_count const & pn, enable_shared_from_this< T > const * pe, Y const * px ) +{ + if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast(px), pn); +} + +inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) +{ +} + +} // namespace detail + + +// +// shared_ptr +// +// An enhanced relative of scoped_ptr with reference counted copy semantics. +// The object pointed to is deleted when the last shared_ptr pointing to it +// is destroyed or reset. +// + +template class shared_ptr +{ +private: + // Borland 5.5.1 specific workaround + typedef shared_ptr< T > this_type; + +public: + + typedef T element_type; + typedef T value_type; + typedef T * pointer; + typedef typename detail::shared_ptr_traits< T >::reference reference; + + shared_ptr(): px(0), pn() // never throws in 1.30+ + { + } + + template + explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter()) // Y must be complete + { + detail::sp_enable_shared_from_this( pn, p, p ); + } + + // + // Requirements: D's copy constructor must not throw + // + // shared_ptr will release p by calling d(p) + // + + template shared_ptr(Y * p, D d): px(p), pn(p, d) + { + detail::sp_enable_shared_from_this( pn, p, p ); + } + +// generated copy constructor, assignment, destructor are fine... + +// except that Borland C++ has a bug, and g++ with -Wsynth warns +#if defined(__GNUC__) + shared_ptr & operator=(shared_ptr const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } +#endif + + template + explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw + { + // it is now safe to copy r.px, as pn(r.pn) did not throw + px = r.px; + } + + template + shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws + { + } + + template + shared_ptr(shared_ptr const & r, detail::static_cast_tag): px(static_cast(r.px)), pn(r.pn) + { + } + + template + shared_ptr(shared_ptr const & r, detail::const_cast_tag): px(const_cast(r.px)), pn(r.pn) + { + } + + template + shared_ptr(shared_ptr const & r, detail::dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) // need to allocate new counter -- the cast failed + { + pn = detail::shared_count(); + } + } + + template + shared_ptr(shared_ptr const & r, detail::polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) + { + boost::serialization::throw_exception(std::bad_cast()); + } + } + +#ifndef BOOST_NO_AUTO_PTR + + template + explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn() + { + Y * tmp = r.get(); + pn = detail::shared_count(r); + detail::sp_enable_shared_from_this( pn, tmp, tmp ); + } + +#endif + +#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) + + template + shared_ptr & operator=(shared_ptr const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } + +#endif + +#ifndef BOOST_NO_AUTO_PTR + + template + shared_ptr & operator=(std::auto_ptr & r) + { + this_type(r).swap(*this); + return *this; + } + +#endif + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + template void reset(Y * p) // Y must be complete + { + BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors + this_type(p).swap(*this); + } + + template void reset(Y * p, D d) + { + this_type(p, d).swap(*this); + } + + reference operator* () const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator-> () const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + // implicit conversion to "bool" + +#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) + + operator bool () const + { + return px != 0; + } + +#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + typedef T * (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::get; + } + +#else + + typedef T * this_type::*unspecified_bool_type; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::px; + } + +#endif + + // operator! is redundant, but some compilers need it + + bool operator! () const // never throws + { + return px == 0; + } + + bool unique() const // never throws + { + return pn.unique(); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + void swap(shared_ptr< T > & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + template bool _internal_less(shared_ptr const & rhs) const + { + return pn < rhs.pn; + } + + void * _internal_get_deleter(std::type_info const & ti) const + { + return pn.get_deleter(ti); + } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + +private: + + template friend class shared_ptr; + template friend class weak_ptr; + + +#endif +public: // for serialization + T * px; // contained pointer + detail::shared_count pn; // reference counter + +}; // shared_ptr + +template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a._internal_less(b); +} + +template inline void swap(shared_ptr< T > & a, shared_ptr< T > & b) +{ + a.swap(b); +} + +template shared_ptr< T > static_pointer_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::static_cast_tag()); +} + +template shared_ptr< T > const_pointer_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::const_cast_tag()); +} + +template shared_ptr< T > dynamic_pointer_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::dynamic_cast_tag()); +} + +// shared_*_cast names are deprecated. Use *_pointer_cast instead. + +template shared_ptr< T > shared_static_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::static_cast_tag()); +} + +template shared_ptr< T > shared_dynamic_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::dynamic_cast_tag()); +} + +template shared_ptr< T > shared_polymorphic_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::polymorphic_cast_tag()); +} + +template shared_ptr< T > shared_polymorphic_downcast(shared_ptr const & r) +{ + BOOST_ASSERT(dynamic_cast(r.get()) == r.get()); + return shared_static_cast< T >(r); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline T * get_pointer(shared_ptr< T > const & p) +{ + return p.get(); +} + +// operator<< + + +template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) +{ + os << p.get(); + return os; +} + +// get_deleter (experimental) + +#if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) + +// g++ 2.9x doesn't allow static_cast(void *) +// apparently EDG 2.38 also doesn't accept it + +template D * get_deleter(shared_ptr< T > const & p) +{ + void const * q = p._internal_get_deleter(typeid(D)); + return const_cast(static_cast(q)); +} + +#else + +template D * get_deleter(shared_ptr< T > const & p) +{ + return static_cast(p._internal_get_deleter(typeid(D))); +} + +#endif + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) + +#endif // #ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp new file mode 100644 index 00000000000..490e7ddd3d0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED +#define BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED + +// +// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// 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/smart_ptr/shared_ptr.htm for documentation. +// + +#include +#include +#include +#include + +#ifndef BOOST_NO_AUTO_PTR +# include // for std::auto_ptr +#endif + +#include // for std::swap +#include // for std::less +#include // for std::bad_alloc + +namespace boost +{ + +template class shared_ptr +{ +private: + + typedef detail::atomic_count count_type; + +public: + + typedef T element_type; + typedef T value_type; + + explicit shared_ptr(T * p = 0): px(p) + { +#ifndef BOOST_NO_EXCEPTIONS + + try // prevent leak if new throws + { + pn = new count_type(1); + } + catch(...) + { + boost::checked_delete(p); + throw; + } + +#else + + pn = new count_type(1); + + if(pn == 0) + { + boost::checked_delete(p); + boost::serialization::throw_exception(std::bad_alloc()); + } + +#endif + } + + ~shared_ptr() + { + if(--*pn == 0) + { + boost::checked_delete(px); + delete pn; + } + } + + shared_ptr(shared_ptr const & r): px(r.px) // never throws + { + pn = r.pn; + ++*pn; + } + + shared_ptr & operator=(shared_ptr const & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#ifndef BOOST_NO_AUTO_PTR + + explicit shared_ptr(std::auto_ptr< T > & r) + { + pn = new count_type(1); // may throw + px = r.release(); // fix: moved here to stop leak if new throws + } + + shared_ptr & operator=(std::auto_ptr< T > & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#endif + + void reset(T * p = 0) + { + BOOST_ASSERT(p == 0 || p != px); + shared_ptr(p).swap(*this); + } + + T & operator*() const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator->() const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + long use_count() const // never throws + { + return *pn; + } + + bool unique() const // never throws + { + return *pn == 1; + } + + void swap(shared_ptr< T > & other) // never throws + { + std::swap(px, other.px); + std::swap(pn, other.pn); + } + +private: + + T * px; // contained pointer + count_type * pn; // ptr to reference counter +}; + +template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_ptr< T > const & a, shared_ptr< T > const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(shared_ptr< T > & a, shared_ptr< T > & b) +{ + a.swap(b); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline T * get_pointer(shared_ptr< T > const & p) +{ + return p.get(); +} + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp new file mode 100644 index 00000000000..ae14832c6db --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp @@ -0,0 +1,66 @@ +#ifndef BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP +#define BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// stack_constructor.hpp: serialization for loading stl collections + +// (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 +#include + +namespace boost{ +namespace serialization { +namespace detail { + +// reserve space on stack for an object of type T without actually +// construction such an object +template +struct stack_allocate +{ + T * address() { + return static_cast(storage_.address()); + } + T & reference() { + return * address(); + } +private: + typedef typename boost::aligned_storage< + sizeof(T), + boost::alignment_of::value + > type; + type storage_; +}; + +// construct element on the stack +template +struct stack_construct : public stack_allocate +{ + stack_construct(Archive & ar, const unsigned int version){ + // note borland emits a no-op without the explicit namespace + boost::serialization::load_construct_data_adl( + ar, + this->address(), + version + ); + } + ~stack_construct(){ + this->address()->~T(); // undo load_construct_data above + } +}; + +} // detail +} // serializaition +} // boost + +#endif // BOOST_SERIALIZATION_DETAIL_STACH_CONSTRUCTOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp new file mode 100644 index 00000000000..3a422c30a35 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp @@ -0,0 +1,72 @@ +#ifndef BOOST_SERIALIZATION_EPHEMERAL_HPP +#define BOOST_SERIALIZATION_EPHEMERAL_HPP + +// MS compatible compilers support +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// ephemeral_object.hpp: interface for serialization system. + +// (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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +struct ephemeral_object : + public wrapper_traits > +{ + explicit ephemeral_object(T& t) : + val(t) + {} + + T & value() const { + return val; + } + + const T & const_value() const { + return val; + } + + template + void serialize(Archive &ar, const unsigned int) const + { + ar & val; + } + +private: + T & val; +}; + +template +inline +const ephemeral_object ephemeral(const char * name, T & t){ + return ephemeral_object(name, t); +} + +} // seralization +} // boost + +#endif // BOOST_SERIALIZATION_EPHEMERAL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp new file mode 100644 index 00000000000..9eef440df42 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp @@ -0,0 +1,225 @@ +#ifndef BOOST_SERIALIZATION_EXPORT_HPP +#define BOOST_SERIALIZATION_EXPORT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// export.hpp: set traits of classes to be serialized + +// (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. + +// (C) Copyright 2006 David Abrahams - http://www.boost.org. +// implementation of class export functionality. This is an alternative to +// "forward declaration" method to provoke instantiation of derived classes +// that are to be serialized through pointers. + +#include +#include // NULL + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include // for guid_defined only +#include +#include +#include +#include + +#include + +#include + +namespace boost { +namespace archive { +namespace detail { + +class basic_pointer_iserializer; +class basic_pointer_oserializer; + +template +class pointer_iserializer; +template +class pointer_oserializer; + +template +struct export_impl +{ + static const basic_pointer_iserializer & + enable_load(mpl::true_){ + return boost::serialization::singleton< + pointer_iserializer + >::get_const_instance(); + } + + static const basic_pointer_oserializer & + enable_save(mpl::true_){ + return boost::serialization::singleton< + pointer_oserializer + >::get_const_instance(); + } + inline static void enable_load(mpl::false_) {} + inline static void enable_save(mpl::false_) {} +}; + +// On many platforms, naming a specialization of this template is +// enough to cause its argument to be instantiated. +template +struct instantiate_function {}; + +template +struct ptr_serialization_support +{ +# if defined(BOOST_MSVC) || defined(__SUNPRO_CC) + virtual BOOST_DLLEXPORT void instantiate() BOOST_USED; +# else + static BOOST_DLLEXPORT void instantiate() BOOST_USED; + typedef instantiate_function< + &ptr_serialization_support::instantiate + > x; +# endif +}; + +template +BOOST_DLLEXPORT void +ptr_serialization_support::instantiate() +{ + export_impl::enable_save( + typename Archive::is_saving() + ); + + export_impl::enable_load( + typename Archive::is_loading() + ); +} + +// Note INTENTIONAL usage of anonymous namespace in header. +// This was made this way so that export.hpp could be included +// in other headers. This is still under study. + +namespace extra_detail { + +template +struct guid_initializer +{ + void export_guid(mpl::false_) const { + // generates the statically-initialized objects whose constructors + // register the information allowing serialization of T objects + // through pointers to their base classes. + instantiate_ptr_serialization((T*)0, 0, adl_tag()); + } + void export_guid(mpl::true_) const { + } + guid_initializer const & export_guid() const { + BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); + // note: exporting an abstract base class will have no effect + // and cannot be used to instantitiate serialization code + // (one might be using this in a DLL to instantiate code) + //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value); + export_guid(boost::serialization::is_abstract< T >()); + return *this; + } +}; + +template +struct init_guid; + +} // anonymous +} // namespace detail +} // namespace archive +} // namespace boost + +#define BOOST_CLASS_EXPORT_IMPLEMENT(T) \ + namespace boost { \ + namespace archive { \ + namespace detail { \ + namespace extra_detail { \ + template<> \ + struct init_guid< T > { \ + static guid_initializer< T > const & g; \ + }; \ + guid_initializer< T > const & init_guid< T >::g = \ + ::boost::serialization::singleton< \ + guid_initializer< T > \ + >::get_mutable_instance().export_guid(); \ + }}}} \ +/**/ + +#define BOOST_CLASS_EXPORT_KEY2(T, K) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct guid_defined< T > : boost::mpl::true_ {}; \ +template<> \ +inline const char * guid< T >(){ \ + return K; \ +} \ +} /* serialization */ \ +} /* boost */ \ +/**/ + +#define BOOST_CLASS_EXPORT_KEY(T) \ + BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T)) \ +/**/ + +#define BOOST_CLASS_EXPORT_GUID(T, K) \ +BOOST_CLASS_EXPORT_KEY2(T, K) \ +BOOST_CLASS_EXPORT_IMPLEMENT(T) \ +/**/ + +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + +// CodeWarrior fails to construct static members of class templates +// when they are instantiated from within templates, so on that +// compiler we ask users to specifically register base/derived class +// relationships for exported classes. On all other compilers, use of +// this macro is entirely optional. +# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \ +namespace { \ + static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \ + (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \ + static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \ + ::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \ + , 3); \ +} + +#else + +# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) + +#endif + +// check for unnecessary export. T isn't polymorphic so there is no +// need to export it. +#define BOOST_CLASS_EXPORT_CHECK(T) \ + BOOST_STATIC_WARNING( \ + boost::is_polymorphic::value \ + ); \ + /**/ + +// the default exportable class identifier is the class name +// the default list of archives types for which code id generated +// are the originally included with this serialization system +#define BOOST_CLASS_EXPORT(T) \ + BOOST_CLASS_EXPORT_GUID( \ + T, \ + BOOST_PP_STRINGIZE(T) \ + ) \ + /**/ + +#endif // BOOST_SERIALIZATION_EXPORT_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp new file mode 100644 index 00000000000..bb2a190d465 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp @@ -0,0 +1,116 @@ +#ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP +#define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// extended_type_info.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. + +// for now, extended type info is part of the serialization libraries +// this could change in the future. +#include +#include +#include // NULL +#include +#include +#include + +#include +#include // must be the last header +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + +#define BOOST_SERIALIZATION_MAX_KEY_SIZE 128 + +namespace boost { +namespace serialization { + +namespace void_cast_detail{ + class void_caster; +} + +class BOOST_SYMBOL_VISIBLE extended_type_info : + private boost::noncopyable +{ +private: + friend class boost::serialization::void_cast_detail::void_caster; + + // used to uniquely identify the type of class derived from this one + // so that different derivations of this class can be simultaneously + // included in implementation of sets and maps. + const unsigned int m_type_info_key; + virtual bool is_less_than(const extended_type_info & /*rhs*/) const = 0; + virtual bool is_equal(const extended_type_info & /*rhs*/) const = 0; + const char * m_key; + +protected: + BOOST_SERIALIZATION_DECL void key_unregister() const; + BOOST_SERIALIZATION_DECL void key_register() const; + // this class can't be used as is. It's just the + // common functionality for all type_info replacement + // systems. Hence, make these protected + BOOST_SERIALIZATION_DECL extended_type_info( + const unsigned int type_info_key, + const char * key + ); + virtual BOOST_SERIALIZATION_DECL ~extended_type_info(); +public: + const char * get_key() const { + return m_key; + } + virtual const char * get_debug_info() const = 0; + BOOST_SERIALIZATION_DECL bool operator<(const extended_type_info &rhs) const; + BOOST_SERIALIZATION_DECL bool operator==(const extended_type_info &rhs) const; + bool operator!=(const extended_type_info &rhs) const { + return !(operator==(rhs)); + } + // note explicit "export" of static function to work around + // gcc 4.5 mingw error + static BOOST_SERIALIZATION_DECL const extended_type_info * + find(const char *key); + // for plugins + virtual void * construct(unsigned int /*count*/ = 0, ...) const = 0; + virtual void destroy(void const * const /*p*/) const = 0; +}; + +template +struct guid_defined : boost::mpl::false_ {}; + +namespace ext { + template + struct guid_impl + { + static inline const char * call() + { + return NULL; + } + }; +} + +template +inline const char * guid(){ + return ext::guid_impl::call(); +} + +} // namespace serialization +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp new file mode 100644 index 00000000000..aaa8b44459b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP +#define BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +// extended_type_info_no_rtti.hpp: implementation for version that depends +// on runtime typing (rtti - typeid) but uses a user specified string +// as the portable class identifier. + +// (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 + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +// hijack serialization access +#include + +#include // must be the last header +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275 4511 4512) +#endif + +namespace boost { +namespace serialization { +/////////////////////////////////////////////////////////////////////// +// define a special type_info that doesn't depend on rtti which is not +// available in all situations. + +namespace no_rtti_system { + +// common base class to share type_info_key. This is used to +// identify the method used to keep track of the extended type +class BOOST_SYMBOL_VISIBLE extended_type_info_no_rtti_0 : + public extended_type_info +{ +protected: + BOOST_SERIALIZATION_DECL extended_type_info_no_rtti_0(const char * key); + BOOST_SERIALIZATION_DECL ~extended_type_info_no_rtti_0(); +public: + virtual BOOST_SERIALIZATION_DECL bool + is_less_than(const boost::serialization::extended_type_info &rhs) const ; + virtual BOOST_SERIALIZATION_DECL bool + is_equal(const boost::serialization::extended_type_info &rhs) const ; +}; + +} // no_rtti_system + +template +class extended_type_info_no_rtti : + public no_rtti_system::extended_type_info_no_rtti_0, + public singleton > +{ + template + struct action { + struct defined { + static const char * invoke(){ + return guid< T >(); + } + }; + struct undefined { + // if your program traps here - you failed to + // export a guid for this type. the no_rtti + // system requires export for types serialized + // as pointers. + BOOST_STATIC_ASSERT(0 == sizeof(T)); + static const char * invoke(); + }; + static const char * invoke(){ + typedef + typename boost::mpl::if_c< + tf, + defined, + undefined + >::type type; + return type::invoke(); + } + }; +public: + extended_type_info_no_rtti() : + no_rtti_system::extended_type_info_no_rtti_0(get_key()) + { + key_register(); + } + ~extended_type_info_no_rtti(){ + key_unregister(); + } + const extended_type_info * + get_derived_extended_type_info(const T & t) const { + // find the type that corresponds to the most derived type. + // this implementation doesn't depend on typeid() but assumes + // that the specified type has a function of the following signature. + // A common implemention of such a function is to define as a virtual + // function. So if the is not a polymporphic type it's likely an error + BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); + const char * derived_key = t.get_key(); + BOOST_ASSERT(NULL != derived_key); + return boost::serialization::extended_type_info::find(derived_key); + } + const char * get_key() const{ + return action::value >::invoke(); + } + virtual const char * get_debug_info() const{ + return action::value >::invoke(); + } + virtual void * construct(unsigned int count, ...) const{ + // count up the arguments + std::va_list ap; + va_start(ap, count); + switch(count){ + case 0: + return factory::type, 0>(ap); + case 1: + return factory::type, 1>(ap); + case 2: + return factory::type, 2>(ap); + case 3: + return factory::type, 3>(ap); + case 4: + return factory::type, 4>(ap); + default: + BOOST_ASSERT(false); // too many arguments + // throw exception here? + return NULL; + } + } + virtual void destroy(void const * const p) const{ + boost::serialization::access::destroy( + static_cast(p) + ); + //delete static_cast(p) ; + } +}; + +} // namespace serialization +} // namespace boost + +/////////////////////////////////////////////////////////////////////////////// +// If no other implementation has been designated as default, +// use this one. To use this implementation as the default, specify it +// before any of the other headers. + +#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + namespace boost { + namespace serialization { + template + struct extended_type_info_impl { + typedef typename + boost::serialization::extended_type_info_no_rtti< T > type; + }; + } // namespace serialization + } // namespace boost +#endif + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp new file mode 100644 index 00000000000..8ee591b3169 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP +#define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +// extended_type_info_typeid.hpp: implementation for version that depends +// on runtime typing (rtti - typeid) but uses a user specified string +// as the portable class identifier. + +// (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 +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +// hijack serialization access +#include + +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275 4511 4512) +#endif + +namespace boost { +namespace serialization { +namespace typeid_system { + +class BOOST_SYMBOL_VISIBLE extended_type_info_typeid_0 : + public extended_type_info +{ + virtual const char * get_debug_info() const { + if(static_cast(0) == m_ti) + return static_cast(0); + return m_ti->name(); + } +protected: + const std::type_info * m_ti; + BOOST_SERIALIZATION_DECL extended_type_info_typeid_0(const char * key); + BOOST_SERIALIZATION_DECL ~extended_type_info_typeid_0(); + BOOST_SERIALIZATION_DECL void type_register(const std::type_info & ti); + BOOST_SERIALIZATION_DECL void type_unregister(); + BOOST_SERIALIZATION_DECL const extended_type_info * + get_extended_type_info(const std::type_info & ti) const; +public: + virtual BOOST_SERIALIZATION_DECL bool + is_less_than(const extended_type_info &rhs) const; + virtual BOOST_SERIALIZATION_DECL bool + is_equal(const extended_type_info &rhs) const; + const std::type_info & get_typeid() const { + return *m_ti; + } +}; + +} // typeid_system + +template +class extended_type_info_typeid : + public typeid_system::extended_type_info_typeid_0, + public singleton > +{ +public: + extended_type_info_typeid() : + typeid_system::extended_type_info_typeid_0( + boost::serialization::guid< T >() + ) + { + type_register(typeid(T)); + key_register(); + } + ~extended_type_info_typeid(){ + key_unregister(); + type_unregister(); + } + // get the eti record for the true type of this record + // relying upon standard type info implemenation (rtti) + const extended_type_info * + get_derived_extended_type_info(const T & t) const { + // note: this implementation - based on usage of typeid (rtti) + // only does something if the class has at least one virtual function. + BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); + return + typeid_system::extended_type_info_typeid_0::get_extended_type_info( + typeid(t) + ); + } + const char * get_key() const { + return boost::serialization::guid< T >(); + } + virtual void * construct(unsigned int count, ...) const{ + // count up the arguments + std::va_list ap; + va_start(ap, count); + switch(count){ + case 0: + return factory::type, 0>(ap); + case 1: + return factory::type, 1>(ap); + case 2: + return factory::type, 2>(ap); + case 3: + return factory::type, 3>(ap); + case 4: + return factory::type, 4>(ap); + default: + BOOST_ASSERT(false); // too many arguments + // throw exception here? + return NULL; + } + } + virtual void destroy(void const * const p) const { + boost::serialization::access::destroy( + static_cast(p) + ); + //delete static_cast(p); + } +}; + +} // namespace serialization +} // namespace boost + +/////////////////////////////////////////////////////////////////////////////// +// If no other implementation has been designated as default, +// use this one. To use this implementation as the default, specify it +// before any of the other headers. +#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + namespace boost { + namespace serialization { + template + struct extended_type_info_impl { + typedef typename + boost::serialization::extended_type_info_typeid< T > type; + }; + } // namespace serialization + } // namespace boost +#endif + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp new file mode 100644 index 00000000000..2db7e7e36c3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp @@ -0,0 +1,102 @@ +#ifndef BOOST_SERIALIZATION_FACTORY_HPP +#define BOOST_SERIALIZATION_FACTORY_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +// factory.hpp: create an instance from an extended_type_info instance. + +// (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 // valist +#include // NULL + +#include +#include +#include + +namespace std{ + #if defined(__LIBCOMO__) + using ::va_list; + #endif +} // namespace std + +namespace boost { +namespace serialization { + +// default implementation does nothing. +template +T * factory(std::va_list){ + BOOST_ASSERT(false); + // throw exception here? + return NULL; +} + +} // namespace serialization +} // namespace boost + +#define BOOST_SERIALIZATION_FACTORY(N, T, A0, A1, A2, A3) \ +namespace boost { \ +namespace serialization { \ + template<> \ + T * factory(std::va_list ap){ \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ + , A0 a0 = va_arg(ap, A0);, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ + , A1 a1 = va_arg(ap, A1);, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ + , A2 a2 = va_arg(ap, A2);, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ + , A3 a3 = va_arg(ap, A3);, BOOST_PP_EMPTY()) \ + return new T( \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ + , a0, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 1)) \ + , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ + , a1, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 2)) \ + , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ + , a2, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 3)) \ + , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ + , a3, BOOST_PP_EMPTY()) \ + ); \ + } \ +} \ +} /**/ + +#define BOOST_SERIALIZATION_FACTORY_4(T, A0, A1, A2, A3) \ + BOOST_SERIALIZATION_FACTORY(4, T, A0, A1, A2, A3) + +#define BOOST_SERIALIZATION_FACTORY_3(T, A0, A1, A2) \ + BOOST_SERIALIZATION_FACTORY(3, T, A0, A1, A2, 0) + +#define BOOST_SERIALIZATION_FACTORY_2(T, A0, A1) \ + BOOST_SERIALIZATION_FACTORY(2, T, A0, A1, 0, 0) + +#define BOOST_SERIALIZATION_FACTORY_1(T, A0) \ + BOOST_SERIALIZATION_FACTORY(1, T, A0, 0, 0, 0) + +#define BOOST_SERIALIZATION_FACTORY_0(T) \ +namespace boost { \ +namespace serialization { \ + template<> \ + T * factory(std::va_list){ \ + return new T(); \ + } \ +} \ +} \ +/**/ + +#endif // BOOST_SERIALIZATION_FACTORY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp new file mode 100644 index 00000000000..55ab79d0d58 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_SERIALIZATION_FORCE_INCLUDE_HPP +#define BOOST_SERIALIZATION_FORCE_INCLUDE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 + +// 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__) +# define BOOST_DLLEXPORT __declspec(dllexport) +#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/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp new file mode 100644 index 00000000000..b8a3c20a6ea --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp @@ -0,0 +1,124 @@ +#ifndef BOOST_SERIALIZATION_FORWARD_LIST_HPP +#define BOOST_SERIALIZATION_FORWARD_LIST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// forward_list.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 + +#include +#include // distance + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const std::forward_list &t, + const unsigned int /*file_version*/ +){ + const collection_size_type count(std::distance(t.cbegin(), t.cend())); + boost::serialization::stl::save_collection< + Archive, + std::forward_list + >(ar, t, count); +} + +namespace stl { + +template< + class Archive, + class T, + class Allocator +> +typename boost::disable_if< + typename detail::is_default_constructible< + typename std::forward_list::value_type + >, + void +>::type +collection_load_impl( + Archive & ar, + std::forward_list &t, + collection_size_type count, + item_version_type item_version +){ + t.clear(); + boost::serialization::detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + t.push_front(boost::move(u.reference())); + typename std::forward_list::iterator last; + last = t.begin(); + ar.reset_object_address(&(*t.begin()) , & u.reference()); + while(--count > 0){ + detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + last = t.insert_after(last, boost::move(u.reference())); + ar.reset_object_address(&(*last) , & u.reference()); + } +} + +} // stl + +template +inline void load( + Archive & ar, + std::forward_list &t, + const unsigned int /*file_version*/ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + stl::collection_load_impl(ar, t, count, item_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::forward_list &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::forward_list) + +#endif // BOOST_SERIALIZATION_FORWARD_LIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp new file mode 100644 index 00000000000..88def8f1aa4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp @@ -0,0 +1,77 @@ +#ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP +#define BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// hash_collections_load_imp.hpp: serialization for loading stl collections + +// (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. + +// helper function templates for serialization of hashed collections +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// +template +inline void load_hash_collection(Archive & ar, Container &s) +{ + collection_size_type count; + collection_size_type bucket_count; + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + if(boost::archive::library_version_type(6) != library_version){ + ar >> BOOST_SERIALIZATION_NVP(count); + ar >> BOOST_SERIALIZATION_NVP(bucket_count); + } + else{ + // note: fixup for error in version 6. collection size was + // changed to size_t BUT for hashed collections it was implemented + // as an unsigned int. This should be a problem only on win64 machines + // but I'll leave it for everyone just in case. + unsigned int c; + unsigned int bc; + ar >> BOOST_SERIALIZATION_NVP(c); + count = c; + ar >> BOOST_SERIALIZATION_NVP(bc); + bucket_count = bc; + } + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + s.clear(); + #if ! defined(__MWERKS__) + s.resize(bucket_count); + #endif + InputFunction ifunc; + while(count-- > 0){ + ifunc(ar, s, item_version); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp new file mode 100644 index 00000000000..65dfe83f16e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp @@ -0,0 +1,97 @@ +#ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP +#define BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// hash_collections_save_imp.hpp: serialization for stl collections + +// (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. + +// helper function templates for serialization of collections + +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// + +template +inline void save_hash_collection(Archive & ar, const Container &s) +{ + collection_size_type count(s.size()); + const collection_size_type bucket_count(s.bucket_count()); + const item_version_type item_version( + version::value + ); + + #if 0 + /* should only be necessary to create archives of previous versions + * which is not currently supported. So for now comment this out + */ + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + if(boost::archive::library_version_type(6) != library_version){ + ar << BOOST_SERIALIZATION_NVP(count); + ar << BOOST_SERIALIZATION_NVP(bucket_count); + } + else{ + // note: fixup for error in version 6. collection size was + // changed to size_t BUT for hashed collections it was implemented + // as an unsigned int. This should be a problem only on win64 machines + // but I'll leave it for everyone just in case. + const unsigned int c = count; + const unsigned int bc = bucket_count; + ar << BOOST_SERIALIZATION_NVP(c); + ar << BOOST_SERIALIZATION_NVP(bc); + } + if(boost::archive::library_version_type(3) < library_version){ + // record number of elements + // make sure the target type is registered so we can retrieve + // the version when we load + ar << BOOST_SERIALIZATION_NVP(item_version); + } + #else + ar << BOOST_SERIALIZATION_NVP(count); + ar << BOOST_SERIALIZATION_NVP(bucket_count); + ar << BOOST_SERIALIZATION_NVP(item_version); + #endif + + typename Container::const_iterator it = s.begin(); + while(count-- > 0){ + // note borland emits a no-op without the explicit namespace + boost::serialization::save_construct_data_adl( + ar, + &(*it), + boost::serialization::version< + typename Container::value_type + >::value + ); + ar << boost::serialization::make_nvp("item", *it++); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp new file mode 100644 index 00000000000..22626db6838 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp @@ -0,0 +1,232 @@ +#ifndef BOOST_SERIALIZATION_HASH_MAP_HPP +#define BOOST_SERIALIZATION_HASH_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/hash_map.hpp: +// serialization for stl hash_map templates + +// (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 +#ifdef BOOST_HAS_HASH +#include BOOST_HASH_MAP_HEADER + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +namespace stl { + +// map input +template +struct archive_input_hash_map +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + std::pair result = + s.insert(boost::move(t.reference())); + // note: the following presumes that the map::value_type was NOT tracked + // in the archive. This is the usual case, but here there is no way + // to determine that. + if(result.second){ + ar.reset_object_address( + & (result.first->second), + & t.reference().second + ); + } + } +}; + +// multimap input +template +struct archive_input_hash_multimap +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::const_iterator result + = s.insert(boost::move(t.reference())); + // note: the following presumes that the map::value_type was NOT tracked + // in the archive. This is the usual case, but here there is no way + // to determine that. + ar.reset_object_address( + & result->second, + & t.reference() + ); + } +}; + +} // stl + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::save_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::load_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_hash_map< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// hash_multimap +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::save_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::load_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_hash_multimap< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_HAS_HASH +#endif // BOOST_SERIALIZATION_HASH_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp new file mode 100644 index 00000000000..0c72c18457e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp @@ -0,0 +1,222 @@ +#ifndef BOOST_SERIALIZATION_HASH_SET_HPP +#define BOOST_SERIALIZATION_HASH_SET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// hash_set.hpp: serialization for stl hash_set templates + +// (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 +#ifdef BOOST_HAS_HASH +#include BOOST_HASH_SET_HEADER + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +namespace stl { + +// hash_set input +template +struct archive_input_hash_set +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + std::pair result = + s.insert(boost::move(t.reference())); + if(result.second) + ar.reset_object_address(& (* result.first), & t.reference()); + } +}; + +// hash_multiset input +template +struct archive_input_hash_multiset +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::const_iterator result + = s.insert(boost::move(t.reference())); + ar.reset_object_address(& (* result), & t.reference()); + } +}; + +} // stl + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::save_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::load_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_hash_set< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// hash_multiset +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::save_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::load_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_hash_multiset< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_set) +BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_multiset) + +#endif // BOOST_HAS_HASH +#endif // BOOST_SERIALIZATION_HASH_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp new file mode 100644 index 00000000000..7e24a2cb6d8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace serialization { + template + 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/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp new file mode 100644 index 00000000000..f3e5adac6f8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP +#define BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP + +// (C) Copyright 2010 Robert Ramey +// 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 // uint_least8_t +#include +#include +#include + +// fixes broken example build on x86_64-linux-gnu-gcc-4.6.0 +#include + +namespace boost { +namespace serialization { + +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4244 4267 ) +#endif + +class item_version_type { +private: + typedef unsigned int base_type; + base_type t; +public: + // should be private - but MPI fails if it's not!!! + item_version_type(): t(0) {}; + explicit item_version_type(const unsigned int t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + item_version_type(const item_version_type & t_) : + t(t_.t) + {} + item_version_type & operator=(item_version_type rhs){ + t = rhs.t; + return *this; + } + // used for text output + operator base_type () const { + return t; + } + // used for text input + operator base_type & () { + return t; + } + bool operator==(const item_version_type & rhs) const { + return t == rhs.t; + } + bool operator<(const item_version_type & rhs) const { + return t < rhs.t; + } +}; + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + +} } // end namespace boost::serialization + +BOOST_IS_BITWISE_SERIALIZABLE(item_version_type) + +BOOST_CLASS_IMPLEMENTATION(item_version_type, primitive_type) + +#endif //BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp new file mode 100644 index 00000000000..f6a84d10422 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp @@ -0,0 +1,116 @@ +#ifndef BOOST_SERIALIZATION_LEVEL_HPP +#define BOOST_SERIALIZATION_LEVEL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default serialization implementation level +template +struct implementation_level_impl { + template + struct traits_class_level { + typedef 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 + typename mpl::eval_if< + is_base_and_derived, + traits_class_level< T >, + //else + typename mpl::eval_if< + is_fundamental< T >, + mpl::int_, + //else + typename mpl::eval_if< + is_class< T >, + mpl::int_, + //else + typename mpl::eval_if< + is_array< T >, + mpl::int_, + //else + typename mpl::eval_if< + is_enum< T >, + mpl::int_, + //else + mpl::int_ + > + > + > + > + >::type type; + // vc 7.1 doesn't like enums here + BOOST_STATIC_CONSTANT(int, value = type::value); +}; + +template +struct implementation_level : + public implementation_level_impl +{ +}; + +template +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/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp new file mode 100644 index 00000000000..baf64e04f31 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +# 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/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp new file mode 100644 index 00000000000..5fdc114d7ed --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_SERIALIZATION_LIST_HPP +#define BOOST_SERIALIZATION_LIST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// list.hpp: serialization for stl list templates + +// (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 + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const std::list &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, + std::list + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::list &t, + const unsigned int /* file_version */ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + stl::collection_load_impl(ar, t, count, item_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::list & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::list) + +#endif // BOOST_SERIALIZATION_LIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp new file mode 100644 index 00000000000..9209864c8cf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp @@ -0,0 +1,139 @@ +#ifndef BOOST_SERIALIZATION_MAP_HPP +#define BOOST_SERIALIZATION_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/map.hpp: +// serialization for stl map templates + +// (C) Copyright 2002-2014 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 + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of serialization for map and mult-map STL containers + +template +inline void load_map_collection(Archive & ar, Container &s) +{ + s.clear(); + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + typename Container::iterator hint; + hint = s.begin(); + while(count-- > 0){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, item_version); + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::iterator result = + s.insert(hint, boost::move(t.reference())); + ar.reset_object_address(& (result->second), & t.reference().second); + hint = result; + ++hint; + } +} + +// map +template +inline void save( + Archive & ar, + const std::map &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, + std::map + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::map &t, + const unsigned int /* file_version */ +){ + load_map_collection(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::map &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// multimap +template +inline void save( + Archive & ar, + const std::multimap &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, + std::multimap + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::multimap &t, + const unsigned int /* file_version */ +){ + load_map_collection(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::multimap &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp new file mode 100644 index 00000000000..4e2297b3cc9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp @@ -0,0 +1,123 @@ +#ifndef BOOST_SERIALIZATION_NVP_HPP +#define BOOST_SERIALIZATION_NVP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +struct nvp : + public std::pair, + public wrapper_traits > +{ +//private: + nvp(const nvp & rhs) : + std::pair(rhs.first, rhs.second) + {} +public: + explicit nvp(const char * name_, T & t) : + // note: added _ to suppress useless gcc warning + std::pair(name_, & t) + {} + + const char * name() const { + return this->first; + } + T & value() const { + return *(this->second); + } + + const T & const_value() const { + return *(this->second); + } + + template + void save( + Archive & ar, + const unsigned int /* file_version */ + ) const { + ar.operator<<(const_value()); + } + template + void load( + Archive & ar, + const unsigned int /* file_version */ + ){ + ar.operator>>(value()); + } + BOOST_SERIALIZATION_SPLIT_MEMBER() +}; + +template +inline +const 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 !!! + +template +struct implementation_level > +{ + typedef mpl::integral_c_tag tag; + typedef mpl::int_ type; + BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value); +}; + +// nvp objects are generally created on the stack and are never tracked +template +struct tracking_level > +{ + typedef mpl::integral_c_tag tag; + typedef mpl::int_ type; + BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); +}; + +} // seralization +} // boost + +#include + +#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(*this) \ + ) +/**/ + +#endif // BOOST_SERIALIZATION_NVP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp new file mode 100644 index 00000000000..d6ff830a8c3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp @@ -0,0 +1,107 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 + +// (C) Copyright 2002-4 Pavel Vozenilek . +// 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) + +// Provides non-intrusive serialization for boost::optional. + +#ifndef BOOST_SERIALIZATION_OPTIONAL_HPP_ +#define BOOST_SERIALIZATION_OPTIONAL_HPP_ + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +namespace boost { +namespace serialization { + +template +void save( + Archive & ar, + const boost::optional< T > & t, + const unsigned int /*version*/ +){ + // It is an inherent limitation to the serialization of optional.hpp + // that the underlying type must be either a pointer or must have a + // default constructor. It's possible that this could change sometime + // in the future, but for now, one will have to work around it. This can + // be done by serialization the optional as optional + #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + BOOST_STATIC_ASSERT( + boost::serialization::detail::is_default_constructible::value + || boost::is_pointer::value + ); + #endif + const bool tflag = t.is_initialized(); + ar << boost::serialization::make_nvp("initialized", tflag); + if (tflag){ + ar << boost::serialization::make_nvp("value", *t); + } +} + +template +void load( + Archive & ar, + boost::optional< T > & t, + const unsigned int version +){ + bool tflag; + ar >> boost::serialization::make_nvp("initialized", tflag); + if(! tflag){ + t.reset(); + return; + } + + if(0 == version){ + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + } + if(! t.is_initialized()) + t = T(); + ar >> boost::serialization::make_nvp("value", *t); +} + +template +void serialize( + Archive & ar, + boost::optional< T > & t, + const unsigned int version +){ + boost::serialization::split_free(ar, t, version); +} + +template +struct version > { + BOOST_STATIC_CONSTANT(int, value = 1); +}; + +} // serialization +} // boost + +#endif // BOOST_SERIALIZATION_OPTIONAL_HPP_ diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp new file mode 100644 index 00000000000..5b08ffd1e82 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP +#define BOOST_SERIALIZATION_PRIORITY_QUEUE_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 +// priority_queue.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 +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { +namespace detail{ + +template +struct priority_queue_save : public STD::priority_queue { + template + void operator()(Archive & ar, const unsigned int file_version) const { + save(ar, STD::priority_queue::c, file_version); + } +}; +template +struct priority_queue_load : public STD::priority_queue { + template + void operator()(Archive & ar, const unsigned int file_version) { + load(ar, STD::priority_queue::c, file_version); + } +}; + +} // detail + +template +inline void serialize( + Archive & ar, + std::priority_queue< T, Container, Compare> & t, + const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + static_cast(t)(ar, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::priority_queue) + +#undef STD + +#endif // BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp new file mode 100644 index 00000000000..b22745215d9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_SERIALIZATION_QUEUE_HPP +#define BOOST_SERIALIZATION_QUEUE_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 +// queue.hpp + +// (C) Copyright 2014 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 +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { +namespace detail { + +template +struct queue_save : public STD::queue { + template + void operator()(Archive & ar, const unsigned int file_version) const { + save(ar, STD::queue::c, file_version); + } +}; +template +struct queue_load : public STD::queue { + template + void operator()(Archive & ar, const unsigned int file_version) { + load(ar, STD::queue::c, file_version); + } +}; + +} // detail + +template +inline void serialize( + Archive & ar, + std::queue< T, C> & t, + const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + static_cast(t)(ar, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::queue) + +#undef STD + +#endif // BOOST_SERIALIZATION_QUEUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp new file mode 100644 index 00000000000..0d11f8436e0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp @@ -0,0 +1,58 @@ +#ifndef BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 +#define BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 + +#if defined(_MSC_VER) +# pragma once +#endif + +// Copyright (c) 2003 Vladimir Prus. +// 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) + +// Provides non-intrusive serialization for boost::scoped_ptr +// Does not allow to serialize scoped_ptr's to builtin types. + +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + + template + void save( + Archive & ar, + const boost::scoped_ptr< T > & t, + const unsigned int /* version */ + ){ + T* r = t.get(); + ar << boost::serialization::make_nvp("scoped_ptr", r); + } + + template + void load( + Archive & ar, + boost::scoped_ptr< T > & t, + const unsigned int /* version */ + ){ + T* r; + ar >> boost::serialization::make_nvp("scoped_ptr", r); + t.reset(r); + } + + template + void serialize( + Archive& ar, + boost::scoped_ptr< T >& t, + const unsigned int version + ){ + boost::serialization::split_free(ar, t, version); + } + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp new file mode 100644 index 00000000000..a4d04723c75 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp @@ -0,0 +1,154 @@ +#ifndef BOOST_SERIALIZATION_SERIALIZATION_HPP +#define BOOST_SERIALIZATION_SERIALIZATION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(_MSC_VER) +# pragma warning (disable : 4675) // suppress ADL warning +#endif + +#include +#include + +/////////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 +// serialize(Archive &ar, const unsigned int file_version){ +// ar & base_object(*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 + +///////////////////////////////////////////////////////////////////////////// +// 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 +inline void serialize( + Archive & ar, T & t, const unsigned int file_version +){ + access::serialize(ar, t, static_cast(file_version)); +} + +// save data required for construction +template +inline void save_construct_data( + Archive & /*ar*/, + const T * /*t*/, + const 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 +inline void load_construct_data( + Archive & /*ar*/, + T * t, + const 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 +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. + const version_type v(file_version); + serialize(ar, t, v); +} + +template +inline void save_construct_data_adl( + Archive & ar, + const T * t, + const unsigned int file_version +){ + // see above + const version_type v(file_version); + save_construct_data(ar, t, v); +} + +template +inline void load_construct_data_adl( + Archive & ar, + T * t, + const unsigned int file_version +){ + // see above comment + const version_type v(file_version); + load_construct_data(ar, t, v); +} + +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_SERIALIZATION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp new file mode 100644 index 00000000000..643906c5aac --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_SERIALIZATION_SET_HPP +#define BOOST_SERIALIZATION_SET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// set.hpp: serialization for stl set templates + +// (C) Copyright 2002-2014 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 + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void load_set_collection(Archive & ar, Container &s) +{ + s.clear(); + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + typename Container::iterator hint; + hint = s.begin(); + while(count-- > 0){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, item_version); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::iterator result = + s.insert(hint, boost::move(t.reference())); + ar.reset_object_address(& (* result), & t.reference()); + hint = result; + } +} + +template +inline void save( + Archive & ar, + const std::set &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, std::set + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::set &t, + const unsigned int /* file_version */ +){ + load_set_collection(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::set & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// multiset +template +inline void save( + Archive & ar, + const std::multiset &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, + std::multiset + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::multiset &t, + const unsigned int /* file_version */ +){ + load_set_collection(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::multiset & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::set) +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::multiset) + +#endif // BOOST_SERIALIZATION_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp new file mode 100644 index 00000000000..0d4c5ae6056 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp @@ -0,0 +1,281 @@ +#ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP +#define BOOST_SERIALIZATION_SHARED_PTR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// shared_ptr.hpp: serialization for boost shared pointer + +// (C) Copyright 2004 Robert Ramey and Martin Ecker +// 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 // NULL +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// boost:: shared_ptr serialization traits +// version 1 to distinguish from boost 1.32 version. Note: we can only do this +// for a template when the compiler supports partial template specialization + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + namespace boost { + namespace serialization{ + template + struct version< ::boost::shared_ptr< T > > { + typedef mpl::integral_c_tag tag; + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) + typedef typename mpl::int_<1> type; + #else + typedef mpl::int_<1> type; + #endif + BOOST_STATIC_CONSTANT(int, value = type::value); + }; + // don't track shared pointers + template + struct tracking_level< ::boost::shared_ptr< T > > { + typedef mpl::integral_c_tag tag; + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) + typedef typename mpl::int_< ::boost::serialization::track_never> type; + #else + typedef mpl::int_< ::boost::serialization::track_never> type; + #endif + BOOST_STATIC_CONSTANT(int, value = type::value); + }; + }} + #define BOOST_SERIALIZATION_SHARED_PTR(T) +#else + // define macro to let users of these compilers do this + #define BOOST_SERIALIZATION_SHARED_PTR(T) \ + BOOST_CLASS_VERSION( \ + ::boost::shared_ptr< T >, \ + 1 \ + ) \ + BOOST_CLASS_TRACKING( \ + ::boost::shared_ptr< T >, \ + ::boost::serialization::track_never \ + ) \ + /**/ +#endif + +namespace boost { +namespace serialization{ + +struct null_deleter { + void operator()(void const *) const {} +}; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization for boost::shared_ptr + +// Using a constant means that all shared pointers are held in the same set. +// Thus we detect handle multiple pointers to the same value instances +// in the archive. +void * const shared_ptr_helper_id = 0; + +template +inline void save( + Archive & ar, + const boost::shared_ptr< T > &t, + const unsigned int /* file_version */ +){ + // The most common cause of trapping here would be serializing + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + const T * t_ptr = t.get(); + ar << boost::serialization::make_nvp("px", t_ptr); +} + +#ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP +template +inline void load( + Archive & ar, + boost::shared_ptr< T > &t, + const unsigned int file_version +){ + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + T* r; + if(file_version < 1){ + ar.register_type(static_cast< + boost_132::detail::sp_counted_base_impl * + >(NULL)); + boost_132::shared_ptr< T > sp; + ar >> boost::serialization::make_nvp("px", sp.px); + ar >> boost::serialization::make_nvp("pn", sp.pn); + // got to keep the sps around so the sp.pns don't disappear + boost::serialization::shared_ptr_helper & h = + ar.template get_helper< shared_ptr_helper >( + shared_ptr_helper_id + ); + h.append(sp); + r = sp.get(); + } + else{ + ar >> boost::serialization::make_nvp("px", r); + } + shared_ptr_helper & h = + ar.template get_helper >( + shared_ptr_helper_id + ); + h.reset(t,r); +} +#else + +template +inline void load( + Archive & ar, + boost::shared_ptr< T > &t, + const unsigned int /*file_version*/ +){ + // The most common cause of trapping here would be serializing + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + T* r; + ar >> boost::serialization::make_nvp("px", r); + + boost::serialization::shared_ptr_helper & h = + ar.template get_helper >( + shared_ptr_helper_id + ); + h.reset(t,r); +} +#endif + +template +inline void serialize( + Archive & ar, + boost::shared_ptr< T > &t, + const unsigned int file_version +){ + // correct shared_ptr serialization depends upon object tracking + // being used. + BOOST_STATIC_ASSERT( + boost::serialization::tracking_level< T >::value + != boost::serialization::track_never + ); + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// std::shared_ptr serialization traits +// version 1 to distinguish from boost 1.32 version. Note: we can only do this +// for a template when the compiler supports partial template specialization + +#ifndef BOOST_NO_CXX11_SMART_PTR +#include + +// note: we presume that any compiler/library which supports C++11 +// std::pointers also supports template partial specialization +// trap here if such presumption were to turn out to wrong!!! +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + BOOST_STATIC_ASSERT(false); +#endif + +namespace boost { +namespace serialization{ + template + struct version< ::std::shared_ptr< T > > { + typedef mpl::integral_c_tag tag; + typedef mpl::int_<1> type; + BOOST_STATIC_CONSTANT(int, value = type::value); + }; + // don't track shared pointers + template + struct tracking_level< ::std::shared_ptr< T > > { + typedef mpl::integral_c_tag tag; + typedef mpl::int_< ::boost::serialization::track_never> type; + BOOST_STATIC_CONSTANT(int, value = type::value); + }; +}} +// the following just keeps older programs from breaking +#define BOOST_SERIALIZATION_SHARED_PTR(T) + +namespace boost { +namespace serialization{ + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization for std::shared_ptr + +template +inline void save( + Archive & ar, + const std::shared_ptr< T > &t, + const unsigned int /* file_version */ +){ + // The most common cause of trapping here would be serializing + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + const T * t_ptr = t.get(); + ar << boost::serialization::make_nvp("px", t_ptr); +} + +template +inline void load( + Archive & ar, + std::shared_ptr< T > &t, + const unsigned int /*file_version*/ +){ + // The most common cause of trapping here would be serializing + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + T* r; + ar >> boost::serialization::make_nvp("px", r); + //void (* const id)(Archive &, std::shared_ptr< T > &, const unsigned int) = & load; + boost::serialization::shared_ptr_helper & h = + ar.template get_helper< + shared_ptr_helper + >( + shared_ptr_helper_id + ); + h.reset(t,r); +} + +template +inline void serialize( + Archive & ar, + std::shared_ptr< T > &t, + const unsigned int file_version +){ + // correct shared_ptr serialization depends upon object tracking + // being used. + BOOST_STATIC_ASSERT( + boost::serialization::tracking_level< T >::value + != boost::serialization::track_never + ); + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_NO_CXX11_SMART_PTR + +#endif // BOOST_SERIALIZATION_SHARED_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp new file mode 100644 index 00000000000..3dfaba4d69a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp @@ -0,0 +1,222 @@ +#ifndef BOOST_SERIALIZATION_SHARED_PTR_132_HPP +#define BOOST_SERIALIZATION_SHARED_PTR_132_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// shared_ptr.hpp: serialization for boost shared pointer + +// (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. + +// note: totally unadvised hack to gain access to private variables +// in shared_ptr and shared_count. Unfortunately its the only way to +// do this without changing shared_ptr and shared_count +// the best we can do is to detect a conflict here +#include + +#include +#include // NULL + +#include +#include +#include +#include +#include + +// mark base class as an (uncreatable) base class +#include + +///////////////////////////////////////////////////////////// +// Maintain a couple of lists of loaded shared pointers of the old previous +// version (1.32) + +namespace boost_132 { +namespace serialization { +namespace detail { + +struct null_deleter { + void operator()(void const *) const {} +}; + +} // namespace detail +} // namespace serialization +} // namespace boost_132 + +///////////////////////////////////////////////////////////// +// sp_counted_base_impl serialization + +namespace boost { +namespace serialization { + +template +inline void serialize( + Archive & /* ar */, + boost_132::detail::sp_counted_base_impl & /* t */, + const unsigned int /*file_version*/ +){ + // register the relationship between each derived class + // its polymorphic base + boost::serialization::void_cast_register< + boost_132::detail::sp_counted_base_impl, + boost_132::detail::sp_counted_base + >( + static_cast *>(NULL), + static_cast(NULL) + ); +} + +template +inline void save_construct_data( + Archive & ar, + const + boost_132::detail::sp_counted_base_impl *t, + const unsigned int /* file_version */ +){ + // variables used for construction + ar << boost::serialization::make_nvp("ptr", t->ptr); +} + +template +inline void load_construct_data( + Archive & ar, + boost_132::detail::sp_counted_base_impl * t, + const unsigned int /* file_version */ +){ + P ptr_; + ar >> boost::serialization::make_nvp("ptr", ptr_); + // ::new(t)boost_132::detail::sp_counted_base_impl(ptr_, D()); + // placement + // note: the original ::new... above is replaced by the one here. This one + // creates all new objects with a null_deleter so that after the archive + // is finished loading and the shared_ptrs are destroyed - the underlying + // raw pointers are NOT deleted. This is necessary as they are used by the + // new system as well. + ::new(t)boost_132::detail::sp_counted_base_impl< + P, + boost_132::serialization::detail::null_deleter + >( + ptr_, boost_132::serialization::detail::null_deleter() + ); // placement new + // compensate for that fact that a new shared count always is + // initialized with one. the add_ref_copy below will increment it + // every time its serialized so without this adjustment + // the use and weak counts will be off by one. + t->use_count_ = 0; +} + +} // serialization +} // namespace boost + +///////////////////////////////////////////////////////////// +// shared_count serialization + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const boost_132::detail::shared_count &t, + const unsigned int /* file_version */ +){ + ar << boost::serialization::make_nvp("pi", t.pi_); +} + +template +inline void load( + Archive & ar, + boost_132::detail::shared_count &t, + const unsigned int /* file_version */ +){ + ar >> boost::serialization::make_nvp("pi", t.pi_); + if(NULL != t.pi_) + t.pi_->add_ref_copy(); +} + +} // serialization +} // namespace boost + +BOOST_SERIALIZATION_SPLIT_FREE(boost_132::detail::shared_count) + +///////////////////////////////////////////////////////////// +// implement serialization for shared_ptr< T > + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const boost_132::shared_ptr< T > &t, + const unsigned int /* file_version */ +){ + // only the raw pointer has to be saved + // the ref count is maintained automatically as shared pointers are loaded + ar.register_type(static_cast< + boost_132::detail::sp_counted_base_impl > * + >(NULL)); + ar << boost::serialization::make_nvp("px", t.px); + ar << boost::serialization::make_nvp("pn", t.pn); +} + +template +inline void load( + Archive & ar, + boost_132::shared_ptr< T > &t, + const unsigned int /* file_version */ +){ + // only the raw pointer has to be saved + // the ref count is maintained automatically as shared pointers are loaded + ar.register_type(static_cast< + boost_132::detail::sp_counted_base_impl > * + >(NULL)); + ar >> boost::serialization::make_nvp("px", t.px); + ar >> boost::serialization::make_nvp("pn", t.pn); +} + +template +inline void serialize( + Archive & ar, + boost_132::shared_ptr< T > &t, + const unsigned int file_version +){ + // correct shared_ptr serialization depends upon object tracking + // being used. + BOOST_STATIC_ASSERT( + boost::serialization::tracking_level< T >::value + != boost::serialization::track_never + ); + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +// note: change below uses null_deleter +// This macro is used to export GUIDS for shared pointers to allow +// the serialization system to export them properly. David Tonge +#define BOOST_SHARED_POINTER_EXPORT_GUID(T, K) \ + typedef boost_132::detail::sp_counted_base_impl< \ + T *, \ + boost::checked_deleter< T > \ + > __shared_ptr_ ## T; \ + BOOST_CLASS_EXPORT_GUID(__shared_ptr_ ## T, "__shared_ptr_" K) \ + BOOST_CLASS_EXPORT_GUID(T, K) \ + /**/ + +#define BOOST_SHARED_POINTER_EXPORT(T) \ + BOOST_SHARED_POINTER_EXPORT_GUID( \ + T, \ + BOOST_PP_STRINGIZE(T) \ + ) \ + /**/ + +#endif // BOOST_SERIALIZATION_SHARED_PTR_132_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp new file mode 100644 index 00000000000..37c34d6b2c4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp @@ -0,0 +1,209 @@ +#ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP +#define BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// shared_ptr_helper.hpp: serialization for boost shared pointern + +// (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo +// 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 +#include +#include +#include // NULL + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost_132 { + template class shared_ptr; +} +namespace boost { +namespace serialization { + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +template class SPT > +void load( + Archive & ar, + SPT< class U > &t, + const unsigned int file_version +); +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// a common class for holding various types of shared pointers + +template class SPT> +class shared_ptr_helper { + typedef std::map< + const void *, // address of object + SPT // address shared ptr to single instance + > object_shared_pointer_map; + + // list of shared_pointers create accessable by raw pointer. This + // is used to "match up" shared pointers loaded at different + // points in the archive. Note, we delay construction until + // it is actually used since this is by default included as + // a "mix-in" even if shared_ptr isn't used. + object_shared_pointer_map * m_o_sp; + + struct null_deleter { + void operator()(void const *) const {} + }; + +#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ +|| defined(BOOST_MSVC) \ +|| defined(__SUNPRO_CC) +public: +#else + template + friend void boost::serialization::load( + Archive & ar, + SPT< U > &t, + const unsigned int file_version + ); +#endif + + #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP + // list of loaded pointers. This is used to be sure that the pointers + // stay around long enough to be "matched" with other pointers loaded + // by the same archive. These are created with a "null_deleter" so that + // when this list is destroyed - the underlaying raw pointers are not + // destroyed. This has to be done because the pointers are also held by + // new system which is disjoint from this set. This is implemented + // by a change in load_construct_data below. It makes this file suitable + // only for loading pointers into a 1.33 or later boost system. + std::list > * m_pointers_132; + void + append(const boost_132::shared_ptr & t){ + if(NULL == m_pointers_132) + m_pointers_132 = new std::list >; + m_pointers_132->push_back(t); + } + #endif + + struct non_polymorphic { + template + static const boost::serialization::extended_type_info * + get_object_type(U & ){ + return & boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< U >::type + >::get_const_instance(); + } + }; + struct polymorphic { + template + static const boost::serialization::extended_type_info * + get_object_type(U & u){ + return boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< U >::type + >::get_const_instance().get_derived_extended_type_info(u); + } + }; + +public: + template + void reset(SPT< T > & s, T * t){ + if(NULL == t){ + s.reset(); + return; + } + const boost::serialization::extended_type_info * this_type + = & boost::serialization::type_info_implementation< T >::type + ::get_const_instance(); + + // get pointer to the most derived object's eti. This is effectively + // the object type identifer + typedef typename mpl::if_< + is_polymorphic< T >, + polymorphic, + non_polymorphic + >::type type; + + const boost::serialization::extended_type_info * true_type + = type::get_object_type(*t); + + // note:if this exception is thrown, be sure that derived pointern + // is either registered or exported. + if(NULL == true_type) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::unregistered_class, + this_type->get_debug_info() + ) + ); + // get void pointer to the most derived type + // this uniquely identifies the object referred to + // oid = "object identifier" + const void * oid = void_downcast( + *true_type, + *this_type, + t + ); + if(NULL == oid) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::unregistered_cast, + true_type->get_debug_info(), + this_type->get_debug_info() + ) + ); + + // make tracking array if necessary + if(NULL == m_o_sp) + m_o_sp = new object_shared_pointer_map; + + typename object_shared_pointer_map::iterator i = m_o_sp->find(oid); + + // if it's a new object + if(i == m_o_sp->end()){ + s.reset(t); + std::pair result; + result = m_o_sp->insert(std::make_pair(oid, s)); + BOOST_ASSERT(result.second); + } + // if the object has already been seen + else{ + s = SPT(i->second, t); + } + } + + shared_ptr_helper() : + m_o_sp(NULL) + #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP + , m_pointers_132(NULL) + #endif + {} + virtual ~shared_ptr_helper(){ + if(NULL != m_o_sp) + delete m_o_sp; + #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP + if(NULL != m_pointers_132) + delete m_pointers_132; + #endif + } +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp new file mode 100644 index 00000000000..b50afedbb92 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp @@ -0,0 +1,166 @@ +#ifndef BOOST_SERIALIZATION_SINGLETON_HPP +#define BOOST_SERIALIZATION_SINGLETON_HPP + +/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 +// singleton.hpp +// +// Copyright David Abrahams 2006. Original version +// +// Copyright Robert Ramey 2007. Changes made to permit +// application throughout the serialization library. +// +// 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) +// +// The intention here is to define a template which will convert +// any class into a singleton with the following features: +// +// a) initialized before first use. +// b) thread-safe for const access to the class +// c) non-locking +// +// In order to do this, +// a) Initialize dynamically when used. +// b) Require that all singletons be initialized before main +// is called or any entry point into the shared library is invoked. +// This guarentees no race condition for initialization. +// In debug mode, we assert that no non-const functions are called +// after main is invoked. +// + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include + +#include +#include +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + +////////////////////////////////////////////////////////////////////// +// Provides a dynamically-initialized (singleton) instance of T in a +// way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or +// http://lists.boost.org/Archives/boost/2006/05/105286.php for +// details. +// + +// singletons created by this code are guarenteed to be unique +// within the executable or shared library which creates them. +// This is sufficient and in fact ideal for the serialization library. +// The singleton is created when the module is loaded and destroyed +// when the module is unloaded. + +// This base class has two functions. + +// First it provides a module handle for each singleton indicating +// the executable or shared library in which it was created. This +// turns out to be necessary and sufficient to implement the tables +// used by serialization library. + +// Second, it provides a mechanism to detect when a non-const function +// is called after initialization. + +// make a singleton to lock/unlock all singletons for alteration. +// The intent is that all singletons created/used by this code +// are to be initialized before main is called. A test program +// can lock all the singletons when main is entereed. This any +// attempt to retieve a mutable instances while locked will +// generate a assertion if compiled for debug. + +// note usage of BOOST_DLLEXPORT. These functions are in danger of +// being eliminated by the optimizer when building an application in +// release mode. Usage of the macro is meant to signal the compiler/linker +// to avoid dropping these functions which seem to be unreferenced. +// This usage is not related to autolinking. + +class BOOST_SYMBOL_VISIBLE singleton_module : + public boost::noncopyable +{ +private: + BOOST_SERIALIZATION_DECL BOOST_DLLEXPORT static bool & get_lock() BOOST_USED; +public: + BOOST_DLLEXPORT static void lock(){ + get_lock() = true; + } + BOOST_DLLEXPORT static void unlock(){ + get_lock() = false; + } + BOOST_DLLEXPORT static bool is_locked(){ + return get_lock(); + } +}; + +template +class singleton : public singleton_module +{ +private: + static T & m_instance; + // include this to provoke instantiation at pre-execution time + static void use(T const *) {} + static T & get_instance() { + // use a wrapper so that types T with protected constructors + // can be used + class singleton_wrapper : public T {}; + static singleton_wrapper t; + // refer to instance, causing it to be instantiated (and + // initialized at startup on working compilers) + BOOST_ASSERT(! is_destroyed()); + // note that the following is absolutely essential. + // commenting out this statement will cause compilers to fail to + // construct the instance at pre-execution time. This would prevent + // our usage/implementation of "locking" and introduce uncertainty into + // the sequence of object initializaition. + use(& m_instance); + return static_cast(t); + } + static bool & get_is_destroyed(){ + static bool is_destroyed; + return is_destroyed; + } + +public: + BOOST_DLLEXPORT static T & get_mutable_instance(){ + BOOST_ASSERT(! is_locked()); + return get_instance(); + } + BOOST_DLLEXPORT static const T & get_const_instance(){ + return get_instance(); + } + BOOST_DLLEXPORT static bool is_destroyed(){ + return get_is_destroyed(); + } + BOOST_DLLEXPORT singleton(){ + get_is_destroyed() = false; + } + BOOST_DLLEXPORT ~singleton() { + get_is_destroyed() = true; + } +}; + +template +T & singleton< T >::m_instance = singleton< T >::get_instance(); + +} // namespace serialization +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_SERIALIZATION_SINGLETON_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp new file mode 100644 index 00000000000..d9b971bc4f1 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp @@ -0,0 +1,145 @@ +#ifndef BOOST_SERIALIZATION_SLIST_HPP +#define BOOST_SERIALIZATION_SLIST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// slist.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 +#ifdef BOOST_HAS_SLIST +#include BOOST_SLIST_HEADER + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::slist &t, + const unsigned int file_version +){ + boost::serialization::stl::save_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::slist + >(ar, t); +} + +namespace stl { + +template< + class Archive, + class T, + class Allocator +> +typename boost::disable_if< + typename detail::is_default_constructible< + typename BOOST_STD_EXTENSION_NAMESPACE::slist::value_type + >, + void +>::type +collection_load_impl( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::slist &t, + collection_size_type count, + item_version_type item_version +){ + t.clear(); + boost::serialization::detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + t.push_front(boost::move(u.reference())); + typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; + last = t.begin(); + ar.reset_object_address(&(*t.begin()) , & u.reference()); + while(--count > 0){ + detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + last = t.insert_after(last, boost::move(u.reference())); + ar.reset_object_address(&(*last) , & u.reference()); + } +} + +} // stl + +template +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::slist &t, + const unsigned int file_version +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if(detail::is_default_constructible()){ + t.resize(count); + typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator hint; + hint = t.begin(); + while(count-- > 0){ + ar >> boost::serialization::make_nvp("item", *hint++); + } + } + else{ + t.clear(); + boost::serialization::detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + t.push_front(boost::move(u.reference())); + typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; + last = t.begin(); + ar.reset_object_address(&(*t.begin()) , & u.reference()); + while(--count > 0){ + detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + last = t.insert_after(last, boost::move(u.reference())); + ar.reset_object_address(&(*last) , & u.reference()); + } + } +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::slist &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::slist) + +#endif // BOOST_HAS_SLIST +#endif // BOOST_SERIALIZATION_SLIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp new file mode 100644 index 00000000000..563f36aa20b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp @@ -0,0 +1,275 @@ +#ifndef BOOST_SERIALIZATION_SMART_CAST_HPP +#define BOOST_SERIALIZATION_SMART_CAST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// smart_cast.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. + +// casting of pointers and references. + +// In casting between different C++ classes, there are a number of +// rules that have to be kept in mind in deciding whether to use +// static_cast or dynamic_cast. + +// a) dynamic casting can only be applied when one of the types is polymorphic +// Otherwise static_cast must be used. +// b) only dynamic casting can do runtime error checking +// use of static_cast is generally un checked even when compiled for debug +// c) static_cast would be considered faster than dynamic_cast. + +// If casting is applied to a template parameter, there is no apriori way +// to know which of the two casting methods will be permitted or convenient. + +// smart_cast uses C++ type_traits, and program debug mode to select the +// most convenient cast to use. + +#include +#include +#include // NULL + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace serialization { +namespace smart_cast_impl { + + template + struct reference { + + struct polymorphic { + + struct linear { + template + static T cast(U & u){ + return static_cast< T >(u); + } + }; + + struct cross { + template + static T cast(U & u){ + return dynamic_cast< T >(u); + } + }; + + template + static T cast(U & u){ + // if we're in debug mode + #if ! defined(NDEBUG) \ + || defined(__MWERKS__) + // do a checked dynamic cast + return cross::cast(u); + #else + // borland 5.51 chokes here so we can't use it + // note: if remove_reference isn't function for these types + // cross casting will be selected this will work but will + // not be the most efficient method. This will conflict with + // the original smart_cast motivation. + typedef typename mpl::eval_if< + typename mpl::and_< + mpl::not_::type, + U + > >, + mpl::not_::type + > > + >, + // borland chokes w/o full qualification here + mpl::identity, + mpl::identity + >::type typex; + // typex works around gcc 2.95 issue + return typex::cast(u); + #endif + } + }; + + struct non_polymorphic { + template + static T cast(U & u){ + return static_cast< T >(u); + } + }; + template + static T cast(U & u){ + typedef typename mpl::eval_if< + boost::is_polymorphic, + mpl::identity, + mpl::identity + >::type typex; + return typex::cast(u); + } + }; + + template + struct pointer { + + struct polymorphic { + // unfortunately, this below fails to work for virtual base + // classes. need has_virtual_base to do this. + // Subject for further study + #if 0 + struct linear { + template + static T cast(U * u){ + return static_cast< T >(u); + } + }; + + struct cross { + template + static T cast(U * u){ + T tmp = dynamic_cast< T >(u); + #ifndef NDEBUG + if ( tmp == 0 ) throw_exception(std::bad_cast()); + #endif + return tmp; + } + }; + + template + static T cast(U * u){ + typedef + typename mpl::eval_if< + typename mpl::and_< + mpl::not_::type, + U + > >, + mpl::not_::type + > > + >, + // borland chokes w/o full qualification here + mpl::identity, + mpl::identity + >::type typex; + return typex::cast(u); + } + #else + template + static T cast(U * u){ + T tmp = dynamic_cast< T >(u); + #ifndef NDEBUG + if ( tmp == 0 ) throw_exception(std::bad_cast()); + #endif + return tmp; + } + #endif + }; + + struct non_polymorphic { + template + static T cast(U * u){ + return static_cast< T >(u); + } + }; + + template + static T cast(U * u){ + typedef typename mpl::eval_if< + boost::is_polymorphic, + mpl::identity, + mpl::identity + >::type typex; + return typex::cast(u); + } + + }; + + template + struct void_pointer { + template + static TPtr cast(UPtr uptr){ + return static_cast(uptr); + } + }; + + template + struct error { + // if we get here, its because we are using one argument in the + // cast on a system which doesn't support partial template + // specialization + template + static T cast(U){ + BOOST_STATIC_ASSERT(sizeof(T)==0); + return * static_cast(NULL); + } + }; + +} // smart_cast_impl + +// this implements: +// smart_cast(Source * s) +// smart_cast(s) +// note that it will fail with +// smart_cast(s) +template +T smart_cast(U u) { + typedef + typename mpl::eval_if< + typename mpl::or_< + boost::is_same, + boost::is_same, + boost::is_same, + boost::is_same + >, + mpl::identity >, + // else + typename mpl::eval_if, + mpl::identity >, + // else + typename mpl::eval_if, + mpl::identity >, + // else + mpl::identity + > + > + > + >::type typex; + return typex::cast(u); +} + +// this implements: +// smart_cast_reference(Source & s) +template +T smart_cast_reference(U & u) { + return smart_cast_impl::reference< T >::cast(u); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_SMART_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp new file mode 100644 index 00000000000..85e2f590fe4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +# 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 +#include +#include +#include + +namespace boost { +namespace archive { + namespace detail { + template class interface_oarchive; + template class interface_iarchive; + } // namespace detail +} // namespace archive + +namespace serialization { + +//namespace detail { +template +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 +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 +inline void split_free( + Archive & ar, + T & t, + const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + typex::invoke(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#define BOOST_SERIALIZATION_SPLIT_FREE(T) \ +namespace boost { namespace serialization { \ +template \ +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/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp new file mode 100644 index 00000000000..5f32520559e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +# 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 +#include +#include + +#include + +namespace boost { +namespace archive { + namespace detail { + template class interface_oarchive; + template class interface_iarchive; + } // namespace detail +} // namespace archive + +namespace serialization { +namespace detail { + + template + struct member_saver { + static void invoke( + Archive & ar, + const T & t, + const unsigned int file_version + ){ + access::member_save(ar, t, file_version); + } + }; + + template + struct member_loader { + static void invoke( + Archive & ar, + T & t, + const unsigned int file_version + ){ + access::member_load(ar, t, file_version); + } + }; + +} // detail + +template +inline void split_member( + Archive & ar, T & t, const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::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 \ +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/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp new file mode 100644 index 00000000000..96f90fe8767 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_SERIALIZATION_STACK_HPP +#define BOOST_SERIALIZATION_STACK_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 +// stack.hpp + +// (C) Copyright 2014 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 +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { +namespace detail{ + +template +struct stack_save : public STD::stack { + template + void operator()(Archive & ar, const unsigned int file_version) const { + save(ar, STD::stack::c, file_version); + } +}; +template +struct stack_load : public STD::stack { + template + void operator()(Archive & ar, const unsigned int file_version) { + load(ar, STD::stack::c, file_version); + } +}; + +} // detail + +template +inline void serialize( + Archive & ar, + std::stack< T, C> & t, + const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + static_cast(t)(ar, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::stack) + +#undef STD + +#endif // BOOST_SERIALIZATION_DEQUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp new file mode 100644 index 00000000000..248b8d91556 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp @@ -0,0 +1,96 @@ +#ifndef BOOST_SERIALIZATION_STATE_SAVER_HPP +#define BOOST_SERIALIZATION_STATE_SAVER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// state_saver.hpp: + +// (C) Copyright 2003-4 Pavel Vozenilek and 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. + +// Inspired by Daryle Walker's iostate_saver concept. This saves the original +// value of a variable when a state_saver is constructed and restores +// upon destruction. Useful for being sure that state is restored to +// variables upon exit from scope. + + +#include +#ifndef BOOST_NO_EXCEPTIONS + #include +#endif + +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace serialization { + +template +// T requirements: +// - POD or object semantic (cannot be reference, function, ...) +// - copy constructor +// - operator = (no-throw one preferred) +class state_saver : private boost::noncopyable +{ +private: + const T previous_value; + T & previous_ref; + + struct restore { + static void invoke(T & previous_ref, const T & previous_value){ + previous_ref = previous_value; // won't throw + } + }; + + struct restore_with_exception { + static void invoke(T & previous_ref, const T & previous_value){ + BOOST_TRY{ + previous_ref = previous_value; + } + BOOST_CATCH(::std::exception &) { + // we must ignore it - we are in destructor + } + BOOST_CATCH_END + } + }; + +public: + state_saver( + T & object + ) : + previous_value(object), + previous_ref(object) + {} + + ~state_saver() { + #ifndef BOOST_NO_EXCEPTIONS + typedef typename mpl::eval_if< + has_nothrow_copy< T >, + mpl::identity, + mpl::identity + >::type typex; + typex::invoke(previous_ref, previous_value); + #else + previous_ref = previous_value; + #endif + } + +}; // state_saver<> + +} // serialization +} // boost + +#endif //BOOST_SERIALIZATION_STATE_SAVER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp new file mode 100644 index 00000000000..1d9238fc4d9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp @@ -0,0 +1,103 @@ +#ifndef BOOST_SERIALIZATION_STATIC_WARNING_HPP +#define BOOST_SERIALIZATION_STATIC_WARNING_HPP + +// (C) Copyright Robert Ramey 2003. Jonathan Turkanis 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 +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/static_assert for documentation. + +/* + Revision history: + 15 June 2003 - Initial version. + 31 March 2004 - improved diagnostic messages and portability + (Jonathan Turkanis) + 03 April 2004 - works on VC6 at class and namespace scope + - ported to DigitalMars + - static warnings disabled by default; when enabled, + uses pragmas to enable required compiler warnings + on MSVC, Intel, Metrowerks and Borland 5.x. + (Jonathan Turkanis) + 30 May 2004 - tweaked for msvc 7.1 and gcc 3.3 + - static warnings ENabled by default; when enabled, + (Robert Ramey) +*/ + +#include + +// +// Implementation +// Makes use of the following warnings: +// 1. GCC prior to 3.3: division by zero. +// 2. BCC 6.0 preview: unreferenced local variable. +// 3. DigitalMars: returning address of local automatic variable. +// 4. VC6: class previously seen as struct (as in 'boost/mpl/print.hpp') +// 5. All others: deletion of pointer to incomplete type. +// +// The trick is to find code which produces warnings containing the name of +// a structure or variable. Details, with same numbering as above: +// 1. static_warning_impl::value is zero iff B is false, so diving an int +// by this value generates a warning iff B is false. +// 2. static_warning_impl::type has a constructor iff B is true, so an +// unreferenced variable of this type generates a warning iff B is false. +// 3. static_warning_impl::type overloads operator& to return a dynamically +// allocated int pointer only is B is true, so returning the address of an +// automatic variable of this type generates a warning iff B is fasle. +// 4. static_warning_impl::STATIC_WARNING is decalred as a struct iff B is +// false. +// 5. static_warning_impl::type is incomplete iff B is false, so deleting a +// pointer to this type generates a warning iff B is false. +// + +//------------------Enable selected warnings----------------------------------// + +// Enable the warnings relied on by BOOST_STATIC_WARNING, where possible. + +// 6. replaced implementation with one which depends solely on +// mpl::print<>. The previous one was found to fail for functions +// under recent versions of gcc and intel compilers - Robert Ramey + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +struct BOOST_SERIALIZATION_STATIC_WARNING_LINE{}; + +template +struct static_warning_test{ + typename boost::mpl::eval_if_c< + B, + boost::mpl::true_, + typename boost::mpl::identity< + boost::mpl::print< + BOOST_SERIALIZATION_STATIC_WARNING_LINE + > + > + >::type type; +}; + +template +struct BOOST_SERIALIZATION_SS {}; + +} // serialization +} // boost + +#define BOOST_SERIALIZATION_BSW(B, L) \ + typedef boost::serialization::BOOST_SERIALIZATION_SS< \ + sizeof( boost::serialization::static_warning_test< B, L > ) \ + > BOOST_JOIN(STATIC_WARNING_LINE, L) BOOST_ATTRIBUTE_UNUSED; +#define BOOST_STATIC_WARNING(B) BOOST_SERIALIZATION_BSW(B, __LINE__) + +#endif // BOOST_SERIALIZATION_STATIC_WARNING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp new file mode 100644 index 00000000000..76e695d4f3c --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_SERIALIZATION_STRING_HPP +#define BOOST_SERIALIZATION_STRING_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/string.hpp: +// serialization for stl string templates + +// (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 + +#include +#include + +BOOST_CLASS_IMPLEMENTATION(std::string, boost::serialization::primitive_type) +#ifndef BOOST_NO_STD_WSTRING +BOOST_CLASS_IMPLEMENTATION(std::wstring, boost::serialization::primitive_type) +#endif + +#endif // BOOST_SERIALIZATION_STRING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp new file mode 100644 index 00000000000..fdd1b24c9cb --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP +#define BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// strong_typedef.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2016 Ashish Sadanandan +// 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 +#include +#include +#include +#include + +#define BOOST_STRONG_TYPEDEF(T, D) \ +struct D \ + : boost::totally_ordered1< D \ + , boost::totally_ordered2< D, T \ + > > \ +{ \ + T t; \ + explicit D(const T& t_) BOOST_NOEXCEPT_IF(boost::has_nothrow_copy_constructor::value) : t(t_) {} \ + D() BOOST_NOEXCEPT_IF(boost::has_nothrow_default_constructor::value) : t() {} \ + D(const D & t_) BOOST_NOEXCEPT_IF(boost::has_nothrow_copy_constructor::value) : t(t_.t) {} \ + D& operator=(const D& rhs) BOOST_NOEXCEPT_IF(boost::has_nothrow_assign::value) {t = rhs.t; return *this;} \ + D& operator=(const T& rhs) BOOST_NOEXCEPT_IF(boost::has_nothrow_assign::value) {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 // BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp new file mode 100644 index 00000000000..b67618adc92 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED +#define BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) +# pragma once +#endif + +// boost/throw_exception.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#ifndef BOOST_NO_EXCEPTIONS +#include +#endif + +namespace boost { +namespace serialization { + +#ifdef BOOST_NO_EXCEPTIONS + +inline void throw_exception(std::exception const & e) { + ::boost::throw_exception(e); +} + +#else + +template inline void throw_exception(E const & e){ + throw e; +} + +#endif + +} // namespace serialization +} // namespace boost + +#endif // #ifndef BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp new file mode 100644 index 00000000000..d5c79b8409d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +# 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default tracking level +template +struct tracking_level_impl { + template + struct traits_class_tracking { + typedef 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 + typename mpl::eval_if< + is_base_and_derived, + traits_class_tracking< T >, + //else + typename mpl::eval_if< + is_pointer< T >, + // pointers are not tracked by default + mpl::int_, + //else + typename mpl::eval_if< + // for primitives + typename mpl::equal_to< + implementation_level< T >, + mpl::int_ + >, + // is never + mpl::int_, + // otherwise its selective + mpl::int_ + > > >::type type; + BOOST_STATIC_CONSTANT(int, value = type::value); +}; + +template +struct tracking_level : + public tracking_level_impl +{ +}; + +template +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_ \ + >::value \ + )); \ +}; \ +}} + +#endif // BOOST_SERIALIZATION_TRACKING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp new file mode 100644 index 00000000000..278051e1baf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +# 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/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp new file mode 100644 index 00000000000..9e114fdd3df --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +# 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 +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +// common base class used to detect appended traits class +struct basic_traits {}; + +template +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 typename mpl::int_ level; + typedef typename mpl::int_ tracking; + typedef typename mpl::int_ version; + typedef ETII type_info_implementation; + typedef Wrapper is_wrapper; +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_TRAITS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp new file mode 100644 index 00000000000..24637a8dbb3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp @@ -0,0 +1,73 @@ +#ifndef BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP +#define BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 +#include + +#include +#include +#include +#include +#include + +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 +struct type_info_implementation { + template + struct traits_class_typeinfo_implementation { + typedef typename U::type_info_implementation::type type; + }; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + typename mpl::eval_if< + is_base_and_derived, + traits_class_typeinfo_implementation< T >, + //else + mpl::identity< + 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. +#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 /// BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp new file mode 100644 index 00000000000..8d8703ef4f7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_SERIALIZATION_UNIQUE_PTR_HPP +#define BOOST_SERIALIZATION_UNIQUE_PTR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unique_ptr.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 +#include +#include + +namespace boost { +namespace serialization { + +///////////////////////////////////////////////////////////// +// implement serialization for unique_ptr< T > +// note: this must be added to the boost namespace in order to +// be called by the library +template +inline void save( + Archive & ar, + const std::unique_ptr< T > &t, + const unsigned int /*file_version*/ +){ + // only the raw pointer has to be saved + // the ref count is rebuilt automatically on load + const T * const tx = t.get(); + ar << BOOST_SERIALIZATION_NVP(tx); +} + +template +inline void load( + Archive & ar, + std::unique_ptr< T > &t, + const unsigned int /*file_version*/ +){ + T *tx; + ar >> BOOST_SERIALIZATION_NVP(tx); + // note that the reset automagically maintains the reference count + t.reset(tx); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::unique_ptr< T > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + + +#endif // BOOST_SERIALIZATION_UNIQUE_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp new file mode 100644 index 00000000000..d56a423d180 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp @@ -0,0 +1,73 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP +#define BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unordered_collections_load_imp.hpp: serialization for loading stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// 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. + +// helper function templates for serialization of collections + +#include +#include // size_t +#include // msvc 6.0 needs this for warning suppression +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif +#include + +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// +template +inline void load_unordered_collection(Archive & ar, Container &s) +{ + collection_size_type count; + collection_size_type bucket_count; + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + ar >> BOOST_SERIALIZATION_NVP(count); + ar >> BOOST_SERIALIZATION_NVP(bucket_count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + s.clear(); + s.rehash(bucket_count); + InputFunction ifunc; + while(count-- > 0){ + ifunc(ar, s, item_version); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp new file mode 100644 index 00000000000..56746ebeaa3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP +#define BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_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 +// hash_collections_save_imp.hpp: serialization for stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// 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. + +// helper function templates for serialization of collections + +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// + +template +inline void save_unordered_collection(Archive & ar, const Container &s) +{ + collection_size_type count(s.size()); + const collection_size_type bucket_count(s.bucket_count()); + const item_version_type item_version( + version::value + ); + + #if 0 + /* should only be necessary to create archives of previous versions + * which is not currently supported. So for now comment this out + */ + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + ar << BOOST_SERIALIZATION_NVP(count); + ar << BOOST_SERIALIZATION_NVP(bucket_count); + if(boost::archive::library_version_type(3) < library_version){ + // record number of elements + // make sure the target type is registered so we can retrieve + // the version when we load + ar << BOOST_SERIALIZATION_NVP(item_version); + } + #else + ar << BOOST_SERIALIZATION_NVP(count); + ar << BOOST_SERIALIZATION_NVP(bucket_count); + ar << BOOST_SERIALIZATION_NVP(item_version); + #endif + + typename Container::const_iterator it = s.begin(); + while(count-- > 0){ + // note borland emits a no-op without the explicit namespace + boost::serialization::save_construct_data_adl( + ar, + &(*it), + boost::serialization::version< + typename Container::value_type + >::value + ); + ar << boost::serialization::make_nvp("item", *it++); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp new file mode 100644 index 00000000000..4fdbddd7b65 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp @@ -0,0 +1,160 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP +#define BOOST_SERIALIZATION_UNORDERED_MAP_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 +// serialization/unordered_map.hpp: +// serialization for stl unordered_map templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// 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 + +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const std::unordered_map &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + std::unordered_map + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + std::unordered_map &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + std::unordered_map, + boost::serialization::stl::archive_input_unordered_map< + Archive, + std::unordered_map + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + std::unordered_map &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// unordered_multimap +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const std::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + std::unordered_multimap + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + std::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + std::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_unordered_multimap< + Archive, + std::unordered_multimap + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + std::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp new file mode 100644 index 00000000000..adfee609cbe --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp @@ -0,0 +1,162 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_SET_HPP +#define BOOST_SERIALIZATION_UNORDERED_SET_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 +// unordered_set.hpp: serialization for stl unordered_set templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// 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 + +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const std::unordered_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + std::unordered_set + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + std::unordered_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + std::unordered_set, + stl::archive_input_unordered_set< + Archive, + std::unordered_set< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + std::unordered_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + split_free(ar, t, file_version); +} + +// unordered_multiset +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const std::unordered_multiset< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + stl::save_unordered_collection< + Archive, + std::unordered_multiset + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + std::unordered_multiset< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + std::unordered_multiset, + boost::serialization::stl::archive_input_unordered_multiset< + Archive, + std::unordered_multiset + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + std::unordered_multiset &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp new file mode 100644 index 00000000000..4867a4a12d2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_SERIALIZATION_UTILITY_HPP +#define BOOST_SERIALIZATION_UTILITY_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/utility.hpp: +// serialization for stl utility templates + +// (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 +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +// pair +template +inline void serialize( + Archive & ar, + std::pair & p, + const unsigned int /* file_version */ +){ + // note: we remove any const-ness on the first argument. The reason is that + // for stl maps, the type saved is pair::type typef; + ar & boost::serialization::make_nvp("first", const_cast(p.first)); + ar & boost::serialization::make_nvp("second", p.second); +} + +/// specialization of is_bitwise_serializable for pairs +template +struct is_bitwise_serializable > + : public mpl::and_,is_bitwise_serializable > +{ +}; + +} // serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_UTILITY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp new file mode 100644 index 00000000000..9eece5c1737 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_SERIALIZATION_VALARAY_HPP +#define BOOST_SERIALIZATION_VALARAY_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// valarray.hpp: serialization for stl vector templates + +// (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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// valarray< T > + +template +void save( Archive & ar, const STD::valarray &t, const unsigned int /*file_version*/ ) +{ + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (t.size()){ + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array( + static_cast(&t[0]), + count + ); + } +} + +template +void load( Archive & ar, STD::valarray &t, const unsigned int /*file_version*/ ) +{ + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + if (t.size()){ + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array( + static_cast(&t[0]), + count + ); + } +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( Archive & ar, STD::valarray & t, const unsigned int file_version) +{ + boost::serialization::split_free(ar, t, file_version); +} + +} } // end namespace boost::serialization + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::valarray) +#undef STD + +#endif // BOOST_SERIALIZATION_VALARAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp new file mode 100644 index 00000000000..dce6f3d49e7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp @@ -0,0 +1,158 @@ +#ifndef BOOST_SERIALIZATION_VARIANT_HPP +#define BOOST_SERIALIZATION_VARIANT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// variant.hpp - non-intrusive serialization of variant types +// +// copyright (c) 2005 +// troy d. straszheim +// http://www.resophonic.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. +// +// thanks to Robert Ramey, Peter Dimov, and Richard Crossley. +// + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + +template +struct variant_save_visitor : + boost::static_visitor<> +{ + variant_save_visitor(Archive& ar) : + m_ar(ar) + {} + template + void operator()(T const & value) const + { + m_ar << BOOST_SERIALIZATION_NVP(value); + } +private: + Archive & m_ar; +}; + +template +void save( + Archive & ar, + boost::variant const & v, + unsigned int /*version*/ +){ + int which = v.which(); + ar << BOOST_SERIALIZATION_NVP(which); + variant_save_visitor visitor(ar); + v.apply_visitor(visitor); +} + +template +struct variant_impl { + + struct load_null { + template + static void invoke( + Archive & /*ar*/, + int /*which*/, + V & /*v*/, + const unsigned int /*version*/ + ){} + }; + + struct load_impl { + template + static void invoke( + Archive & ar, + int which, + V & v, + const unsigned int version + ){ + if(which == 0){ + // note: A non-intrusive implementation (such as this one) + // necessary has to copy the value. This wouldn't be necessary + // with an implementation that de-serialized to the address of the + // aligned storage included in the variant. + typedef typename mpl::front::type head_type; + head_type value; + ar >> BOOST_SERIALIZATION_NVP(value); + v = value; + ar.reset_object_address(& boost::get(v), & value); + return; + } + typedef typename mpl::pop_front::type type; + variant_impl::load(ar, which - 1, v, version); + } + }; + + template + static void load( + Archive & ar, + int which, + V & v, + const unsigned int version + ){ + typedef typename mpl::eval_if, + mpl::identity, + mpl::identity + >::type typex; + typex::invoke(ar, which, v, version); + } + +}; + +template +void load( + Archive & ar, + boost::variant& v, + const unsigned int version +){ + int which; + typedef typename boost::variant::types types; + ar >> BOOST_SERIALIZATION_NVP(which); + if(which >= mpl::size::value) + // this might happen if a type was removed from the list of variant types + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::unsupported_version + ) + ); + variant_impl::load(ar, which, v, version); +} + +template +inline void serialize( + Archive & ar, + boost::variant & v, + const unsigned int file_version +){ + split_free(ar,v,file_version); +} + +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_VARIANT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp new file mode 100644 index 00000000000..9a114c00e20 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp @@ -0,0 +1,233 @@ +#ifndef BOOST_SERIALIZATION_VECTOR_HPP +#define BOOST_SERIALIZATION_VECTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector.hpp: serialization for stl vector templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// fast array serialization (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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// default is being compatible with version 1.34.1 files, not 1.35 files +#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) +#endif + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector< T > + +// the default versions + +template +inline void save( + Archive & ar, + const std::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + boost::serialization::stl::save_collection >( + ar, t + ); +} + +template +inline void load( + Archive & ar, + std::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + t.reserve(count); + stl::collection_load_impl(ar, t, count, item_version); +} + +// the optimized versions + +template +inline void save( + Archive & ar, + const std::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array( + static_cast(&t[0]), + count + ); +} + +template +inline void load( + Archive & ar, + std::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + collection_size_type count(t.size()); + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + unsigned int item_version=0; + if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array( + static_cast(&t[0]), + count + ); + } + +// dispatch to either default or optimized versions + +template +inline void save( + Archive & ar, + const std::vector &t, + const unsigned int file_version +){ + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + save(ar,t,file_version, use_optimized()); +} + +template +inline void load( + Archive & ar, + std::vector &t, + const unsigned int file_version +){ +#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP + if (ar.get_library_version()==boost::archive::library_version_type(5)) + { + load(ar,t,file_version, boost::is_arithmetic()); + return; + } +#endif + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + load(ar,t,file_version, use_optimized()); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector +template +inline void save( + Archive & ar, + const std::vector &t, + const unsigned int /* file_version */ +){ + // record number of elements + collection_size_type count (t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + std::vector::const_iterator it = t.begin(); + while(count-- > 0){ + bool tb = *it++; + ar << boost::serialization::make_nvp("item", tb); + } +} + +template +inline void load( + Archive & ar, + std::vector &t, + const unsigned int /* file_version */ +){ + // retrieve number of elements + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + for(collection_size_type i = collection_size_type(0); i < count; ++i){ + bool b; + ar >> boost::serialization::make_nvp("item", b); + t[i] = b; + } +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::vector) +#undef STD + +#endif // BOOST_SERIALIZATION_VECTOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp new file mode 100644 index 00000000000..fd1a7393d1b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp @@ -0,0 +1,26 @@ +////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector_135.hpp: serialization for stl vector templates for compatibility +// with release 1.35, which had a bug + +// (C) Copyright 2008 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) + +// See http://www.boost.org for updates, documentation, and revision history. + + +#ifndef BOOST_SERIALIZATION_VECTOR_135_HPP +#define BOOST_SERIALIZATION_VECTOR_135_HPP + +#ifdef BOOST_SERIALIZATION_VECTOR_VERSIONED +#if BOOST_SERIALIZATION_VECTOR_VERSION != 4 +#error "Boost.Serialization cannot be compatible with both 1.35 and 1.36-1.40 files" +#endif +#else +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V>4) +#endif + +#include + +#endif // BOOST_SERIALIZATION_VECTOR_135_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp new file mode 100644 index 00000000000..21a74d73daa --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp @@ -0,0 +1,107 @@ +#ifndef BOOST_SERIALIZATION_VERSION_HPP +#define BOOST_SERIALIZATION_VERSION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# 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 +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default version number is 0. Override with higher version +// when class definition changes. +template +struct version +{ + template + struct traits_class_version { + typedef 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 + typename mpl::eval_if< + is_base_and_derived, + traits_class_version< T >, + mpl::int_<0> + >::type type; + BOOST_STATIC_CONSTANT(int, value = version::type::value); +}; + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +template +const int version::value; +#endif + +} // 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 +//#include + +#include +#include + +// 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 \ +{ \ + typedef mpl::int_ type; \ + typedef mpl::integral_c_tag tag; \ + BOOST_STATIC_CONSTANT(int, value = version::type::value); \ + BOOST_MPL_ASSERT(( \ + boost::mpl::less< \ + boost::mpl::int_, \ + boost::mpl::int_<256> \ + > \ + )); \ + /* \ + BOOST_MPL_ASSERT(( \ + mpl::equal_to< \ + :implementation_level, \ + mpl::int_ \ + >::value \ + )); \ + */ \ +}; \ +} \ +} + +#endif // BOOST_SERIALIZATION_VERSION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp new file mode 100644 index 00000000000..f1b38286115 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp @@ -0,0 +1,298 @@ +#ifndef BOOST_SERIALIZATION_VOID_CAST_HPP +#define BOOST_SERIALIZATION_VOID_CAST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// void_cast.hpp: interface for run-time casting of void pointers. + +// (C) Copyright 2002-2009 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 // for ptrdiff_t +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + +namespace boost { +namespace serialization { + +class extended_type_info; + +// Given a void *, assume that it really points to an instance of one type +// and alter it so that it would point to an instance of a related type. +// Return the altered pointer. If there exists no sequence of casts that +// can transform from_type to to_type, return a NULL. + +BOOST_SERIALIZATION_DECL void const * +void_upcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const t +); + +inline void * +void_upcast( + extended_type_info const & derived, + extended_type_info const & base, + void * const t +){ + return const_cast(void_upcast( + derived, + base, + const_cast(t) + )); +} + +BOOST_SERIALIZATION_DECL void const * +void_downcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const t +); + +inline void * +void_downcast( + extended_type_info const & derived, + extended_type_info const & base, + void * const t +){ + return const_cast(void_downcast( + derived, + base, + const_cast(t) + )); +} + +namespace void_cast_detail { + +class BOOST_SYMBOL_VISIBLE void_caster : + private boost::noncopyable +{ + friend + BOOST_SERIALIZATION_DECL void const * + boost::serialization::void_upcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const + ); + friend + BOOST_SERIALIZATION_DECL void const * + boost::serialization::void_downcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const + ); +protected: + BOOST_SERIALIZATION_DECL void recursive_register(bool includes_virtual_base = false) const; + BOOST_SERIALIZATION_DECL void recursive_unregister() const; + virtual bool has_virtual_base() const = 0; +public: + // Data members + const extended_type_info * m_derived; + const extended_type_info * m_base; + /*const*/ std::ptrdiff_t m_difference; + void_caster const * const m_parent; + + // note that void_casters are keyed on value of + // member extended type info records - NOT their + // addresses. This is necessary in order for the + // void cast operations to work across dll and exe + // module boundries. + bool operator<(const void_caster & rhs) const; + + const void_caster & operator*(){ + return *this; + } + // each derived class must re-implement these; + virtual void const * upcast(void const * const t) const = 0; + virtual void const * downcast(void const * const t) const = 0; + // Constructor + void_caster( + extended_type_info const * derived, + extended_type_info const * base, + std::ptrdiff_t difference = 0, + void_caster const * const parent = 0 + ) : + m_derived(derived), + m_base(base), + m_difference(difference), + m_parent(parent) + {} + virtual ~void_caster(){} +}; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275 4511 4512) +#endif + +template +class BOOST_SYMBOL_VISIBLE void_caster_primitive : + public void_caster +{ + virtual void const * downcast(void const * const t) const { + const Derived * d = + boost::serialization::smart_cast( + static_cast(t) + ); + return d; + } + virtual void const * upcast(void const * const t) const { + const Base * b = + boost::serialization::smart_cast( + static_cast(t) + ); + return b; + } + virtual bool has_virtual_base() const { + return false; + } +public: + void_caster_primitive(); + virtual ~void_caster_primitive(); +}; + +template +void_caster_primitive::void_caster_primitive() : + void_caster( + & type_info_implementation::type::get_const_instance(), + & type_info_implementation::type::get_const_instance(), + // note:I wanted to displace from 0 here, but at least one compiler + // treated 0 by not shifting it at all. + reinterpret_cast( + static_cast( + reinterpret_cast(8) + ) + ) - 8 + ) +{ + recursive_register(); +} + +template +void_caster_primitive::~void_caster_primitive(){ + recursive_unregister(); +} + +template +class BOOST_SYMBOL_VISIBLE void_caster_virtual_base : + public void_caster +{ + virtual bool has_virtual_base() const { + return true; + } +public: + virtual void const * downcast(void const * const t) const { + const Derived * d = + dynamic_cast( + static_cast(t) + ); + return d; + } + virtual void const * upcast(void const * const t) const { + const Base * b = + dynamic_cast( + static_cast(t) + ); + return b; + } + void_caster_virtual_base(); + virtual ~void_caster_virtual_base(); +}; + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +template +void_caster_virtual_base::void_caster_virtual_base() : + void_caster( + & (type_info_implementation::type::get_const_instance()), + & (type_info_implementation::type::get_const_instance()) + ) +{ + recursive_register(true); +} + +template +void_caster_virtual_base::~void_caster_virtual_base(){ + recursive_unregister(); +} + +template +struct BOOST_SYMBOL_VISIBLE void_caster_base : + public void_caster +{ + typedef + typename mpl::eval_if, + mpl::identity< + void_cast_detail::void_caster_virtual_base + > + ,// else + mpl::identity< + void_cast_detail::void_caster_primitive + > + >::type type; +}; + +} // void_cast_detail + +template +BOOST_DLLEXPORT +inline const void_cast_detail::void_caster & void_cast_register( + Derived const * /* dnull = NULL */, + Base const * /* bnull = NULL */ +){ + typedef + typename mpl::eval_if, + mpl::identity< + void_cast_detail::void_caster_virtual_base + > + ,// else + mpl::identity< + void_cast_detail::void_caster_primitive + > + >::type typex; + return singleton::get_const_instance(); +} + +template +class BOOST_SYMBOL_VISIBLE void_caster : + public void_cast_detail::void_caster_base::type +{ +}; + +} // namespace serialization +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_VOID_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp new file mode 100644 index 00000000000..def61d52bb7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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) +# 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 // NULL +#include + +namespace boost { +namespace serialization { +namespace void_cast_detail{ +class void_caster; +} // namespace void_cast_detail +template +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/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp new file mode 100644 index 00000000000..6952d24cb37 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp @@ -0,0 +1,99 @@ +#ifndef BOOST_SERIALIZATION_WEAK_PTR_HPP +#define BOOST_SERIALIZATION_WEAK_PTR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// weak_ptr.hpp: serialization for boost weak pointer + +// (C) Copyright 2004 Robert Ramey and Martin Ecker +// 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 +#include + +namespace boost { +namespace serialization{ + +template +inline void save( + Archive & ar, + const boost::weak_ptr< T > &t, + const unsigned int /* file_version */ +){ + const boost::shared_ptr< T > sp = t.lock(); + ar << boost::serialization::make_nvp("weak_ptr", sp); +} + +template +inline void load( + Archive & ar, + boost::weak_ptr< T > &t, + const unsigned int /* file_version */ +){ + boost::shared_ptr< T > sp; + ar >> boost::serialization::make_nvp("weak_ptr", sp); + t = sp; +} + +template +inline void serialize( + Archive & ar, + boost::weak_ptr< T > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#ifndef BOOST_NO_CXX11_SMART_PTR +#include + +namespace boost { +namespace serialization{ + +template +inline void save( + Archive & ar, + const std::weak_ptr< T > &t, + const unsigned int /* file_version */ +){ + const std::shared_ptr< T > sp = t.lock(); + ar << boost::serialization::make_nvp("weak_ptr", sp); +} + +template +inline void load( + Archive & ar, + std::weak_ptr< T > &t, + const unsigned int /* file_version */ +){ + std::shared_ptr< T > sp; + ar >> boost::serialization::make_nvp("weak_ptr", sp); + t = sp; +} + +template +inline void serialize( + Archive & ar, + std::weak_ptr< T > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_NO_CXX11_SMART_PTR + +#endif // BOOST_SERIALIZATION_WEAK_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp new file mode 100644 index 00000000000..60d7910b17a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/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 +#include +#include +#include + +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 +{}; + +template +struct is_wrapper_impl : + boost::mpl::eval_if< + boost::is_base_and_derived, + boost::mpl::true_, + boost::mpl::false_ + >::type +{}; + +template +struct is_wrapper { + typedef typename is_wrapper_impl::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 : boost::mpl::true_ {}; \ +} \ +} \ +/**/ + +#endif //BOOST_SERIALIZATION_WRAPPER_HPP diff --git a/dbms/cmake/version.cmake b/dbms/cmake/version.cmake index 6b358857b8c..ec19869e32a 100644 --- a/dbms/cmake/version.cmake +++ b/dbms/cmake/version.cmake @@ -1,6 +1,6 @@ # This strings autochanged from release_lib.sh: -set(VERSION_DESCRIBE v1.1.54314-testing) -set(VERSION_REVISION 54314) +set(VERSION_DESCRIBE v1.1.54319-testing) +set(VERSION_REVISION 54319) # end of autochange set (VERSION_MAJOR 1) diff --git a/dbms/src/Columns/ColumnString.cpp b/dbms/src/Columns/ColumnString.cpp index 858fdbaa9ed..9807afed77b 100644 --- a/dbms/src/Columns/ColumnString.cpp +++ b/dbms/src/Columns/ColumnString.cpp @@ -5,6 +5,9 @@ #include #include +/// Used in the `reserve` method, when the number of rows is known, but sizes of elements are not. +#define APPROX_STRING_SIZE 64 + namespace DB { @@ -257,7 +260,7 @@ void ColumnString::gather(ColumnGathererStream & gatherer) void ColumnString::reserve(size_t n) { offsets.reserve(n); - chars.reserve(n * DBMS_APPROX_STRING_SIZE); + chars.reserve(n * APPROX_STRING_SIZE); } diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index e8600e0a8ed..560d94f9866 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -361,6 +361,7 @@ namespace ErrorCodes extern const int HTTP_LENGTH_REQUIRED = 381; extern const int CANNOT_LOAD_CATBOOST_MODEL = 382; extern const int CANNOT_APPLY_CATBOOST_MODEL = 383; + extern const int MULTIPLE_STREAMS_REQUIRED = 384; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Core/Defines.h b/dbms/src/Core/Defines.h index e3577e4b039..1fc82d49d6f 100644 --- a/dbms/src/Core/Defines.h +++ b/dbms/src/Core/Defines.h @@ -55,11 +55,10 @@ #define DEFAULT_QUERIES_QUEUE_WAIT_TIME_MS 5000 /// Maximum waiting time in the request queue. #define DBMS_DEFAULT_BACKGROUND_POOL_SIZE 16 -/// Used in the `reserve` method, when the number of rows is known, but their dimensions are unknown. -#define DBMS_APPROX_STRING_SIZE 64 - /// Name suffix for the column containing the array offsets. #define ARRAY_SIZES_COLUMN_NAME_SUFFIX ".size" +/// And NULL map. +#define NULL_MAP_COLUMN_NAME_SUFFIX ".null" #define DBMS_MIN_REVISION_WITH_CLIENT_INFO 54032 #define DBMS_MIN_REVISION_WITH_SERVER_TIMEZONE 54058 diff --git a/dbms/src/DataStreams/NativeBlockInputStream.cpp b/dbms/src/DataStreams/NativeBlockInputStream.cpp index a65cd6719e5..68102a70a31 100644 --- a/dbms/src/DataStreams/NativeBlockInputStream.cpp +++ b/dbms/src/DataStreams/NativeBlockInputStream.cpp @@ -48,40 +48,8 @@ NativeBlockInputStream::NativeBlockInputStream( void NativeBlockInputStream::readData(const IDataType & type, IColumn & column, ReadBuffer & istr, size_t rows, double avg_value_size_hint) { - if (type.isNullable()) - { - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); - - ColumnNullable & nullable_col = static_cast(column); - IColumn & nested_col = *nullable_col.getNestedColumn(); - - IColumn & null_map = nullable_col.getNullMapConcreteColumn(); - DataTypeUInt8{}.deserializeBinaryBulk(null_map, istr, rows, avg_value_size_hint); - - readData(nested_type, nested_col, istr, rows, avg_value_size_hint); - - return; - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /** For arrays, we deserialize the offsets first, and then the values. - */ - IColumn & offsets_column = *typeid_cast(column).getOffsetsColumn(); - type_arr->getOffsetsType()->deserializeBinaryBulk(offsets_column, istr, rows, 0); - - if (offsets_column.size() != rows) - throw Exception("Cannot read all data in NativeBlockInputStream.", ErrorCodes::CANNOT_READ_ALL_DATA); - - if (rows) - readData( - *type_arr->getNestedType(), - typeid_cast(column).getData(), - istr, - typeid_cast(column).getOffsets()[rows - 1], 0); - } - else - type.deserializeBinaryBulk(column, istr, rows, avg_value_size_hint); + IDataType::InputStreamGetter input_stream_getter = [&] (const IDataType::SubstreamPath & path) { return &istr; }; + type.deserializeBinaryBulkWithMultipleStreams(column, input_stream_getter, rows, avg_value_size_hint, false, {}); if (column.size() != rows) throw Exception("Cannot read all data in NativeBlockInputStream.", ErrorCodes::CANNOT_READ_ALL_DATA); diff --git a/dbms/src/DataStreams/NativeBlockOutputStream.cpp b/dbms/src/DataStreams/NativeBlockOutputStream.cpp index 2d766454721..c2bf0aa1c44 100644 --- a/dbms/src/DataStreams/NativeBlockOutputStream.cpp +++ b/dbms/src/DataStreams/NativeBlockOutputStream.cpp @@ -60,56 +60,8 @@ void NativeBlockOutputStream::writeData(const IDataType & type, const ColumnPtr else full_column = column; - if (type.isNullable()) - { - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); - - const ColumnNullable & nullable_col = static_cast(*full_column.get()); - const ColumnPtr & nested_col = nullable_col.getNestedColumn(); - - const IColumn & null_map = nullable_col.getNullMapConcreteColumn(); - DataTypeUInt8{}.serializeBinaryBulk(null_map, ostr, offset, limit); - - writeData(nested_type, nested_col, ostr, offset, limit); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /** For arrays, we serialize the offsets first, and then the values. - */ - const ColumnArray & column_array = typeid_cast(*full_column); - type_arr->getOffsetsType()->serializeBinaryBulk(*column_array.getOffsetsColumn(), ostr, offset, limit); - - if (!column_array.getData().empty()) - { - const ColumnArray::Offsets_t & offsets = column_array.getOffsets(); - - if (offset > offsets.size()) - return; - - /** offset - from which array to write. - * limit - how many arrays should be written, or 0, if you write everything that is. - * end - up to which array written part finishes. - * - * nested_offset - from which nested element to write. - * nested_limit - how many nested elements to write, or 0, if you write everything that is. - */ - - size_t end = std::min(offset + limit, offsets.size()); - - size_t nested_offset = offset ? offsets[offset - 1] : 0; - size_t nested_limit = limit - ? offsets[end - 1] - nested_offset - : 0; - - const DataTypePtr & nested_type = type_arr->getNestedType(); - - if (limit == 0 || nested_limit) - writeData(*nested_type, column_array.getDataPtr(), ostr, nested_offset, nested_limit); - } - } - else - type.serializeBinaryBulk(*full_column, ostr, offset, limit); + IDataType::OutputStreamGetter output_stream_getter = [&] (const IDataType::SubstreamPath & path) { return &ostr; }; + type.serializeBinaryBulkWithMultipleStreams(*full_column, output_stream_getter, offset, limit, false, {}); } diff --git a/dbms/src/DataTypes/DataTypeArray.cpp b/dbms/src/DataTypes/DataTypeArray.cpp index f855699f537..c9ba02d1e44 100644 --- a/dbms/src/DataTypes/DataTypeArray.cpp +++ b/dbms/src/DataTypes/DataTypeArray.cpp @@ -107,12 +107,87 @@ void DataTypeArray::deserializeBinary(IColumn & column, ReadBuffer & istr) const } -void DataTypeArray::serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const +namespace +{ + void serializeArraySizesPositionIndependent(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) + { + const ColumnArray & column_array = typeid_cast(column); + const ColumnArray::Offsets_t & offset_values = column_array.getOffsets(); + size_t size = offset_values.size(); + + if (!size) + return; + + size_t end = limit && (offset + limit < size) + ? offset + limit + : size; + + ColumnArray::Offset_t prev_offset = offset == 0 ? 0 : offset_values[offset - 1]; + for (size_t i = offset; i < end; ++i) + { + ColumnArray::Offset_t current_offset = offset_values[i]; + writeIntBinary(current_offset - prev_offset, ostr); + prev_offset = current_offset; + } + } + + void deserializeArraySizesPositionIndependent(IColumn & column, ReadBuffer & istr, size_t limit) + { + ColumnArray & column_array = typeid_cast(column); + ColumnArray::Offsets_t & offset_values = column_array.getOffsets(); + size_t initial_size = offset_values.size(); + offset_values.resize(initial_size + limit); + + size_t i = initial_size; + ColumnArray::Offset_t current_offset = initial_size ? offset_values[initial_size - 1] : 0; + while (i < initial_size + limit && !istr.eof()) + { + ColumnArray::Offset_t current_size = 0; + readIntBinary(current_size, istr); + current_offset += current_size; + offset_values[i] = current_offset; + ++i; + } + + offset_values.resize(i); + } +} + + +void DataTypeArray::enumerateStreams(StreamCallback callback, SubstreamPath path) const +{ + path.push_back(Substream::ArraySizes); + callback(path); + path.back() = Substream::ArrayElements; + nested->enumerateStreams(callback, path); +} + + +void DataTypeArray::serializeBinaryBulkWithMultipleStreams( + const IColumn & column, + OutputStreamGetter getter, + size_t offset, + size_t limit, + bool position_independent_encoding, + SubstreamPath path) const { const ColumnArray & column_array = typeid_cast(column); - const ColumnArray::Offsets_t & offsets = column_array.getOffsets(); - if (offset > offsets.size()) + /// First serialize array sizes. + path.push_back(Substream::ArraySizes); + if (auto stream = getter(path)) + { + if (position_independent_encoding) + serializeArraySizesPositionIndependent(column, *stream, offset, limit); + else + offsets->serializeBinaryBulk(*column_array.getOffsetsColumn(), *stream, offset, limit); + } + + /// Then serialize contents of arrays. + path.back() = Substream::ArrayElements; + const ColumnArray::Offsets_t & offset_values = column_array.getOffsets(); + + if (offset > offset_values.size()) return; /** offset - from which array to write. @@ -123,82 +198,56 @@ void DataTypeArray::serializeBinaryBulk(const IColumn & column, WriteBuffer & os * nested_limit - how many elements of the innards to write, or 0, if you write everything that is. */ - size_t end = std::min(offset + limit, offsets.size()); + size_t end = std::min(offset + limit, offset_values.size()); - size_t nested_offset = offset ? offsets[offset - 1] : 0; + size_t nested_offset = offset ? offset_values[offset - 1] : 0; size_t nested_limit = limit - ? offsets[end - 1] - nested_offset + ? offset_values[end - 1] - nested_offset : 0; if (limit == 0 || nested_limit) - nested->serializeBinaryBulk(column_array.getData(), ostr, nested_offset, nested_limit); + nested->serializeBinaryBulkWithMultipleStreams(column_array.getData(), getter, nested_offset, nested_limit, position_independent_encoding, path); } -void DataTypeArray::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double) const +void DataTypeArray::deserializeBinaryBulkWithMultipleStreams( + IColumn & column, + InputStreamGetter getter, + size_t limit, + double avg_value_size_hint, + bool position_independent_encoding, + SubstreamPath path) const { ColumnArray & column_array = typeid_cast(column); - ColumnArray::Offsets_t & offsets = column_array.getOffsets(); + + path.push_back(Substream::ArraySizes); + if (auto stream = getter(path)) + { + if (position_independent_encoding) + deserializeArraySizesPositionIndependent(column, *stream, limit); + else + offsets->deserializeBinaryBulk(*column_array.getOffsetsColumn(), *stream, limit, 0); + } + + path.back() = Substream::ArrayElements; + + ColumnArray::Offsets_t & offset_values = column_array.getOffsets(); IColumn & nested_column = column_array.getData(); - /// Number of values corresponding with `offsets` must be read. - size_t last_offset = (offsets.empty() ? 0 : offsets.back()); + /// Number of values corresponding with `offset_values` must be read. + size_t last_offset = (offset_values.empty() ? 0 : offset_values.back()); if (last_offset < nested_column.size()) throw Exception("Nested column is longer than last offset", ErrorCodes::LOGICAL_ERROR); size_t nested_limit = last_offset - nested_column.size(); - nested->deserializeBinaryBulk(nested_column, istr, nested_limit, 0); + nested->deserializeBinaryBulkWithMultipleStreams(nested_column, getter, nested_limit, 0, position_independent_encoding, path); - if (column_array.getData().size() != last_offset) + /// Check consistency between offsets and elements subcolumns. + /// But if elements column is empty - it's ok for columns of Nested types that was added by ALTER. + if (!nested_column.empty() && nested_column.size() != last_offset) throw Exception("Cannot read all array values", ErrorCodes::CANNOT_READ_ALL_DATA); } -void DataTypeArray::serializeOffsets(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const -{ - const ColumnArray & column_array = typeid_cast(column); - const ColumnArray::Offsets_t & offsets = column_array.getOffsets(); - size_t size = offsets.size(); - - if (!size) - return; - - size_t end = limit && (offset + limit < size) - ? offset + limit - : size; - - if (offset == 0) - { - writeIntBinary(offsets[0], ostr); - ++offset; - } - - for (size_t i = offset; i < end; ++i) - writeIntBinary(offsets[i] - offsets[i - 1], ostr); -} - - -void DataTypeArray::deserializeOffsets(IColumn & column, ReadBuffer & istr, size_t limit) const -{ - ColumnArray & column_array = typeid_cast(column); - ColumnArray::Offsets_t & offsets = column_array.getOffsets(); - size_t initial_size = offsets.size(); - offsets.resize(initial_size + limit); - - size_t i = initial_size; - ColumnArray::Offset_t current_offset = initial_size ? offsets[initial_size - 1] : 0; - while (i < initial_size + limit && !istr.eof()) - { - ColumnArray::Offset_t current_size = 0; - readIntBinary(current_size, istr); - current_offset += current_size; - offsets[i] = current_offset; - ++i; - } - - offsets.resize(i); -} - - template static void serializeTextImpl(const IColumn & column, size_t row_num, WriteBuffer & ostr, Writer && write_nested) { diff --git a/dbms/src/DataTypes/DataTypeArray.h b/dbms/src/DataTypes/DataTypeArray.h index a063380f1c5..f66c175e159 100644 --- a/dbms/src/DataTypes/DataTypeArray.h +++ b/dbms/src/DataTypes/DataTypeArray.h @@ -68,24 +68,27 @@ public: /** Streaming serialization of arrays is arranged in a special way: * - elements placed in a row are written/read without array sizes; - * - the sizes are written/read in a separate column, - * and the caller must take care of writing/reading the sizes. + * - the sizes are written/read in a separate stream, * This is necessary, because when implementing nested structures, several arrays can have common sizes. */ - /** Write only values, without dimensions. The caller also needs to record the offsets somewhere. */ - void serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const override; + void enumerateStreams(StreamCallback callback, SubstreamPath path) const override; - /** Read only values, without dimensions. - * In this case, all the sizes must already be read in the column beforehand. - */ - void deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const override; + void serializeBinaryBulkWithMultipleStreams( + const IColumn & column, + OutputStreamGetter getter, + size_t offset, + size_t limit, + bool position_independent_encoding, + SubstreamPath path) const override; - /** Write the dimensions. */ - void serializeOffsets(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const; - - /** Read the dimensions. Call this method before reading the values. */ - void deserializeOffsets(IColumn & column, ReadBuffer & istr, size_t limit) const; + void deserializeBinaryBulkWithMultipleStreams( + IColumn & column, + InputStreamGetter getter, + size_t limit, + double avg_value_size_hint, + bool position_independent_encoding, + SubstreamPath path) const override; ColumnPtr createColumn() const override; diff --git a/dbms/src/DataTypes/DataTypeNullable.cpp b/dbms/src/DataTypes/DataTypeNullable.cpp index 40fb3ba77c7..6c40728f05c 100644 --- a/dbms/src/DataTypes/DataTypeNullable.cpp +++ b/dbms/src/DataTypes/DataTypeNullable.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -28,17 +29,54 @@ DataTypeNullable::DataTypeNullable(const DataTypePtr & nested_data_type_) throw Exception("Nested type " + nested_data_type->getName() + " cannot be inside Nullable type", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); } -void DataTypeNullable::serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const + +void DataTypeNullable::enumerateStreams(StreamCallback callback, SubstreamPath path) const +{ + path.push_back(Substream::NullMap); + callback(path); + path.back() = Substream::NullableElements; + nested_data_type->enumerateStreams(callback, path); +} + + +void DataTypeNullable::serializeBinaryBulkWithMultipleStreams( + const IColumn & column, + OutputStreamGetter getter, + size_t offset, + size_t limit, + bool position_independent_encoding, + SubstreamPath path) const { const ColumnNullable & col = static_cast(column); col.checkConsistency(); - nested_data_type->serializeBinaryBulk(*col.getNestedColumn(), ostr, offset, limit); + + /// First serialize null map. + path.push_back(Substream::NullMap); + if (auto stream = getter(path)) + DataTypeUInt8().serializeBinaryBulk(col.getNullMapConcreteColumn(), *stream, offset, limit); + + /// Then serialize contents of arrays. + path.back() = Substream::NullableElements; + nested_data_type->serializeBinaryBulkWithMultipleStreams(*col.getNestedColumn(), getter, offset, limit, position_independent_encoding, path); } -void DataTypeNullable::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const + +void DataTypeNullable::deserializeBinaryBulkWithMultipleStreams( + IColumn & column, + InputStreamGetter getter, + size_t limit, + double avg_value_size_hint, + bool position_independent_encoding, + SubstreamPath path) const { ColumnNullable & col = static_cast(column); - nested_data_type->deserializeBinaryBulk(*col.getNestedColumn(), istr, limit, avg_value_size_hint); + + path.push_back(Substream::NullMap); + if (auto stream = getter(path)) + DataTypeUInt8().deserializeBinaryBulk(col.getNullMapConcreteColumn(), *stream, limit, 0); + + path.back() = Substream::NullableElements; + nested_data_type->deserializeBinaryBulkWithMultipleStreams(*col.getNestedColumn(), getter, limit, avg_value_size_hint, position_independent_encoding, path); } diff --git a/dbms/src/DataTypes/DataTypeNullable.h b/dbms/src/DataTypes/DataTypeNullable.h index 0ffb2fd3634..6b57f99dae4 100644 --- a/dbms/src/DataTypes/DataTypeNullable.h +++ b/dbms/src/DataTypes/DataTypeNullable.h @@ -25,9 +25,23 @@ public: DataTypePtr clone() const override { return std::make_shared(nested_data_type->clone()); } - /// Bulk serialization and deserialization is processing only nested columns. You should process null byte map separately. - void serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const override; - void deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const override; + void enumerateStreams(StreamCallback callback, SubstreamPath path) const override; + + void serializeBinaryBulkWithMultipleStreams( + const IColumn & column, + OutputStreamGetter getter, + size_t offset, + size_t limit, + bool position_independent_encoding, + SubstreamPath path) const override; + + void deserializeBinaryBulkWithMultipleStreams( + IColumn & column, + InputStreamGetter getter, + size_t limit, + double avg_value_size_hint, + bool position_independent_encoding, + SubstreamPath path) const override; void serializeBinary(const Field & field, WriteBuffer & ostr) const override { nested_data_type->serializeBinary(field, ostr); } void deserializeBinary(Field & field, ReadBuffer & istr) const override { nested_data_type->deserializeBinary(field, istr); } diff --git a/dbms/src/DataTypes/IDataType.cpp b/dbms/src/DataTypes/IDataType.cpp index 2074424581d..3b9bec4e16a 100644 --- a/dbms/src/DataTypes/IDataType.cpp +++ b/dbms/src/DataTypes/IDataType.cpp @@ -1,12 +1,26 @@ #include #include +#include +#include + +#include + +#include + #include +#include namespace DB { +namespace ErrorCodes +{ + extern const int MULTIPLE_STREAMS_REQUIRED; +} + + void IDataType::updateAvgValueSizeHint(const IColumn & column, double & avg_value_size_hint) { /// Update the average value size hint if amount of read rows isn't too small @@ -30,6 +44,39 @@ ColumnPtr IDataType::createConstColumn(size_t size, const Field & field) const return std::make_shared(column, size); } + +void IDataType::serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const +{ + throw Exception("Data type " + getName() + " must be serialized with multiple streams", ErrorCodes::MULTIPLE_STREAMS_REQUIRED); +} + +void IDataType::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const +{ + throw Exception("Data type " + getName() + " must be deserialized with multiple streams", ErrorCodes::MULTIPLE_STREAMS_REQUIRED); +} + + +String IDataType::getFileNameForStream(const String & column_name, const IDataType::SubstreamPath & path) +{ + String nested_table_name = DataTypeNested::extractNestedTableName(column_name); + bool is_sizes_of_nested_type = !path.empty() && path.back().type == IDataType::Substream::ArraySizes + && nested_table_name != column_name; + + size_t array_level = 0; + String stream_name = escapeForFileName(is_sizes_of_nested_type ? nested_table_name : column_name); + for (const IDataType::Substream & elem : path) + { + if (elem.type == IDataType::Substream::NullMap) + stream_name += NULL_MAP_COLUMN_NAME_SUFFIX; + else if (elem.type == IDataType::Substream::ArraySizes) + stream_name = DataTypeNested::extractNestedTableName(stream_name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(array_level); + else if (elem.type == IDataType::Substream::ArrayElements) + ++array_level; + } + return stream_name; +} + + void IDataType::insertDefaultInto(IColumn & column) const { column.insertDefault(); diff --git a/dbms/src/DataTypes/IDataType.h b/dbms/src/DataTypes/IDataType.h index 4fa57cad654..95e0a28ccb9 100644 --- a/dbms/src/DataTypes/IDataType.h +++ b/dbms/src/DataTypes/IDataType.h @@ -66,18 +66,91 @@ public: virtual DataTypePtr clone() const = 0; /** Binary serialization for range of values in column - for writing to disk/network, etc. - * 'offset' and 'limit' are used to specify range. + * + * Some data types are represented in multiple streams while being serialized. + * Example: + * - Arrays are represented as stream of all elements and stream of array sizes. + * - Nullable types are represented as stream of values (with unspecified values in place of NULLs) and stream of NULL flags. + * + * Different streams are identified by "path". + * If the data type require single stream (it's true for most of data types), the stream will have empty path. + * Otherwise, the path can have components like "array elements", "array sizes", etc. + * + * For multidimensional arrays, path can have arbiraty length. + * As an example, for 2-dimensional arrays of numbers we have at least three streams: + * - array sizes; (sizes of top level arrays) + * - array elements / array sizes; (sizes of second level (nested) arrays) + * - array elements / array elements; (the most deep elements, placed contiguously) + * + * Descendants must override either serializeBinaryBulk, deserializeBinaryBulk methods (for simple cases with single stream) + * or serializeBinaryBulkWithMultipleStreams, deserializeBinaryBulkWithMultipleStreams, enumerateStreams methods (for cases with multiple streams). + * + * Default implementations of ...WithMultipleStreams methods will call serializeBinaryBulk, deserializeBinaryBulk for single stream. + */ + + struct Substream + { + enum Type + { + ArrayElements, + ArraySizes, + + NullableElements, + NullMap, + }; + Type type; + + Substream(Type type) : type(type) {} + }; + + using SubstreamPath = std::vector; + + using StreamCallback = std::function; + virtual void enumerateStreams(StreamCallback callback, SubstreamPath path) const + { + callback(path); + } + + using OutputStreamGetter = std::function; + using InputStreamGetter = std::function; + + /** 'offset' and 'limit' are used to specify range. * limit = 0 - means no limit. * offset must be not greater than size of column. * offset + limit could be greater than size of column - * - in that case, column is serialized to the end. + * - in that case, column is serialized till the end. */ - virtual void serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const = 0; + virtual void serializeBinaryBulkWithMultipleStreams( + const IColumn & column, + OutputStreamGetter getter, + size_t offset, + size_t limit, + bool position_independent_encoding, + SubstreamPath path) const + { + if (WriteBuffer * stream = getter(path)) + serializeBinaryBulk(column, *stream, offset, limit); + } /** Read no more than limit values and append them into column. * avg_value_size_hint - if not zero, may be used to avoid reallocations while reading column of String type. */ - virtual void deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const = 0; + virtual void deserializeBinaryBulkWithMultipleStreams( + IColumn & column, + InputStreamGetter getter, + size_t limit, + double avg_value_size_hint, + bool position_independent_encoding, + SubstreamPath path) const + { + if (ReadBuffer * stream = getter(path)) + deserializeBinaryBulk(column, *stream, limit, avg_value_size_hint); + } + + /** Override these methods for data types that require just single stream (most of data types). + */ + virtual void serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const; + virtual void deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const; /** Serialization/deserialization of individual values. * @@ -176,6 +249,8 @@ public: /// Updates avg_value_size_hint for newly read column. Uses to optimize deserialization. Zero expected for first column. static void updateAvgValueSizeHint(const IColumn & column, double & avg_value_size_hint); + + static String getFileNameForStream(const String & column_name, const SubstreamPath & path); }; diff --git a/dbms/src/DataTypes/tests/data_type_string.cpp b/dbms/src/DataTypes/tests/data_type_string.cpp index d5e6624a958..1c46d640b19 100644 --- a/dbms/src/DataTypes/tests/data_type_string.cpp +++ b/dbms/src/DataTypes/tests/data_type_string.cpp @@ -38,7 +38,7 @@ try WriteBufferFromFile out_buf("test"); stopwatch.restart(); - data_type.serializeBinaryBulk(*column, out_buf, 0, 0); + data_type.serializeBinaryBulkWithMultipleStreams(*column, [&](const IDataType::SubstreamPath &){ return &out_buf; }, 0, 0, true, {}); stopwatch.stop(); std::cout << "Writing, elapsed: " << stopwatch.elapsedSeconds() << std::endl; @@ -50,7 +50,7 @@ try ReadBufferFromFile in_buf("test"); stopwatch.restart(); - data_type.deserializeBinaryBulk(*column, in_buf, n, 0); + data_type.deserializeBinaryBulkWithMultipleStreams(*column, [&](const IDataType::SubstreamPath &){ return &in_buf; }, n, 0, true, {}); stopwatch.stop(); std::cout << "Reading, elapsed: " << stopwatch.elapsedSeconds() << std::endl; diff --git a/dbms/src/DataTypes/tests/data_types_number_fixed.cpp b/dbms/src/DataTypes/tests/data_types_number_fixed.cpp index 820405af630..b2bdc6a3eb5 100644 --- a/dbms/src/DataTypes/tests/data_types_number_fixed.cpp +++ b/dbms/src/DataTypes/tests/data_types_number_fixed.cpp @@ -27,7 +27,7 @@ int main(int argc, char ** argv) WriteBufferFromOStream out_buf(ostr); stopwatch.restart(); - data_type.serializeBinaryBulk(*column, out_buf, 0, 0); + data_type.serializeBinaryBulkWithMultipleStreams(*column, [&](const IDataType::SubstreamPath &){ return &out_buf; }, 0, 0, true, {}); stopwatch.stop(); std::cout << "Elapsed: " << stopwatch.elapsedSeconds() << std::endl; diff --git a/dbms/src/IO/BufferBase.h b/dbms/src/IO/BufferBase.h index a1a04e26a67..b3d1b8deb97 100644 --- a/dbms/src/IO/BufferBase.h +++ b/dbms/src/IO/BufferBase.h @@ -9,7 +9,7 @@ namespace DB /** Base class for ReadBuffer and WriteBuffer. - * Contains mutual types, variables, and functions. + * Contains common types, variables, and functions. * * ReadBuffer and WriteBuffer are similar to istream and ostream, respectively. * They have to be used, because using iostreams it is impossible to effectively implement some operations. diff --git a/dbms/src/IO/ZlibDeflatingWriteBuffer.cpp b/dbms/src/IO/ZlibDeflatingWriteBuffer.cpp index c2165c382a9..61450e19db4 100644 --- a/dbms/src/IO/ZlibDeflatingWriteBuffer.cpp +++ b/dbms/src/IO/ZlibDeflatingWriteBuffer.cpp @@ -34,7 +34,7 @@ ZlibDeflatingWriteBuffer::ZlibDeflatingWriteBuffer( #pragma GCC diagnostic pop if (rc != Z_OK) - throw Exception(std::string("deflateInit2 failed: ") + zError(rc), ErrorCodes::ZLIB_DEFLATE_FAILED); + throw Exception(std::string("deflateInit2 failed: ") + zError(rc) + "; zlib version: " + ZLIB_VERSION, ErrorCodes::ZLIB_DEFLATE_FAILED); } ZlibDeflatingWriteBuffer::~ZlibDeflatingWriteBuffer() diff --git a/dbms/src/IO/ZlibInflatingReadBuffer.cpp b/dbms/src/IO/ZlibInflatingReadBuffer.cpp index 869108515d3..8100cf88de7 100644 --- a/dbms/src/IO/ZlibInflatingReadBuffer.cpp +++ b/dbms/src/IO/ZlibInflatingReadBuffer.cpp @@ -34,7 +34,7 @@ ZlibInflatingReadBuffer::ZlibInflatingReadBuffer( #pragma GCC diagnostic pop if (rc != Z_OK) - throw Exception(std::string("inflateInit2 failed: ") + zError(rc), ErrorCodes::ZLIB_INFLATE_FAILED); + throw Exception(std::string("inflateInit2 failed: ") + zError(rc) + "; zlib version: " + ZLIB_VERSION, ErrorCodes::ZLIB_INFLATE_FAILED); } ZlibInflatingReadBuffer::~ZlibInflatingReadBuffer() diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 94bd495a5a6..40762b28c12 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -1120,7 +1120,13 @@ ExternalDictionaries & Context::getExternalDictionariesImpl(const bool throw_on_ { if (!this->global_context) throw Exception("Logical error: there is no global context", ErrorCodes::LOGICAL_ERROR); - shared->external_dictionaries = std::make_shared(*this->global_context, throw_on_error); + + auto config_repository = runtime_components_factory->createExternalDictionariesConfigRepository(); + + shared->external_dictionaries = std::make_shared( + std::move(config_repository), + *this->global_context, + throw_on_error); } return *shared->external_dictionaries; @@ -1134,7 +1140,13 @@ ExternalModels & Context::getExternalModelsImpl(bool throw_on_error) const { if (!this->global_context) throw Exception("Logical error: there is no global context", ErrorCodes::LOGICAL_ERROR); - shared->external_models = std::make_shared(*this->global_context, throw_on_error); + + auto config_repository = runtime_components_factory->createExternalModelsConfigRepository(); + + shared->external_models = std::make_shared( + std::move(config_repository), + *this->global_context, + throw_on_error); } return *shared->external_models; diff --git a/dbms/src/Interpreters/ExternalDictionaries.cpp b/dbms/src/Interpreters/ExternalDictionaries.cpp index 9131e8acca6..e12a74c2987 100644 --- a/dbms/src/Interpreters/ExternalDictionaries.cpp +++ b/dbms/src/Interpreters/ExternalDictionaries.cpp @@ -26,10 +26,14 @@ namespace } -ExternalDictionaries::ExternalDictionaries(Context & context, bool throw_on_error) +ExternalDictionaries::ExternalDictionaries( + std::unique_ptr config_repository, + Context & context, + bool throw_on_error) : ExternalLoader(context.getConfigRef(), externalDictionariesUpdateSettings, getExternalDictionariesConfigSettings(), + std::move(config_repository), &Logger::get("ExternalDictionaries"), "external dictionary"), context(context) diff --git a/dbms/src/Interpreters/ExternalDictionaries.h b/dbms/src/Interpreters/ExternalDictionaries.h index 9ed41f89d50..cc03c9b9389 100644 --- a/dbms/src/Interpreters/ExternalDictionaries.h +++ b/dbms/src/Interpreters/ExternalDictionaries.h @@ -18,7 +18,10 @@ public: using DictPtr = std::shared_ptr; /// Dictionaries will be loaded immediately and then will be updated in separate thread, each 'reload_period' seconds. - ExternalDictionaries(Context & context, bool throw_on_error); + ExternalDictionaries( + std::unique_ptr config_repository, + Context & context, + bool throw_on_error); /// Forcibly reloads specified dictionary. void reloadDictionary(const std::string & name) { reload(name); } diff --git a/dbms/src/Interpreters/ExternalLoader.cpp b/dbms/src/Interpreters/ExternalLoader.cpp index 78c91174a4d..5601e12ba38 100644 --- a/dbms/src/Interpreters/ExternalLoader.cpp +++ b/dbms/src/Interpreters/ExternalLoader.cpp @@ -2,15 +2,10 @@ #include #include #include -#include #include #include #include -#include -#include #include -#include -#include namespace DB { @@ -49,9 +44,14 @@ void ExternalLoader::reloadPeriodically() ExternalLoader::ExternalLoader(const Poco::Util::AbstractConfiguration & config, const ExternalLoaderUpdateSettings & update_settings, const ExternalLoaderConfigSettings & config_settings, + std::unique_ptr config_repository, Logger * log, const std::string & loadable_object_name) - : config(config), update_settings(update_settings), config_settings(config_settings), - log(log), object_name(loadable_object_name) + : config(config) + , update_settings(update_settings) + , config_settings(config_settings) + , config_repository(std::move(config_repository)) + , log(log) + , object_name(loadable_object_name) { } @@ -80,34 +80,6 @@ ExternalLoader::~ExternalLoader() reloading_thread.join(); } -namespace -{ -std::set getConfigPaths(const Poco::Util::AbstractConfiguration & config, - const std::string & external_config_paths_setting) -{ - std::set files; - auto patterns = getMultipleValuesFromConfig(config, "", external_config_paths_setting); - for (auto & pattern : patterns) - { - if (pattern.empty()) - continue; - - if (pattern[0] != '/') - { - const auto app_config_path = config.getString("config-file", "config.xml"); - const auto config_dir = Poco::Path{app_config_path}.parent().toString(); - const auto absolute_path = config_dir + pattern; - Poco::Glob::glob(absolute_path, files, 0); - if (!files.empty()) - continue; - } - - Poco::Glob::glob(pattern, files, 0); - } - - return files; -} -} void ExternalLoader::reloadAndUpdate(bool throw_on_error) { @@ -239,7 +211,7 @@ void ExternalLoader::reloadAndUpdate(bool throw_on_error) void ExternalLoader::reloadFromConfigFiles(const bool throw_on_error, const bool force_reload, const std::string & only_dictionary) { - const auto config_paths = getConfigPaths(config, config_settings.path_setting_name); + const auto config_paths = config_repository->list(config, config_settings.path_setting_name); for (const auto & config_path : config_paths) { @@ -260,9 +232,7 @@ void ExternalLoader::reloadFromConfigFiles(const bool throw_on_error, const bool void ExternalLoader::reloadFromConfigFile(const std::string & config_path, const bool throw_on_error, const bool force_reload, const std::string & loadable_name) { - const Poco::File config_file{config_path}; - - if (config_path.empty() || !config_file.exists()) + if (config_path.empty() || !config_repository->exists(config_path)) { LOG_WARNING(log, "config file '" + config_path + "' does not exist"); } @@ -275,14 +245,10 @@ void ExternalLoader::reloadFromConfigFile(const std::string & config_path, const modification_time_it = last_modification_times.emplace(config_path, Poco::Timestamp{0}).first; auto & config_last_modified = modification_time_it->second; - const auto last_modified = config_file.getLastModified(); + const auto last_modified = config_repository->getLastModificationTime(config_path); if (force_reload || last_modified > config_last_modified) { - ConfigProcessor config_processor = ConfigProcessor(config_path); - ConfigProcessor::LoadedConfig cfg = config_processor.loadConfig(); - config_processor.savePreprocessedConfig(cfg); - - Poco::AutoPtr config = cfg.configuration; + auto config = config_repository->load(config_path); /// Definitions of loadable objects may have changed, recreate all of them diff --git a/dbms/src/Interpreters/ExternalLoader.h b/dbms/src/Interpreters/ExternalLoader.h index 526a2457ea1..c0ba5fa7712 100644 --- a/dbms/src/Interpreters/ExternalLoader.h +++ b/dbms/src/Interpreters/ExternalLoader.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,7 @@ public: ExternalLoader(const Configuration & config, const ExternalLoaderUpdateSettings & update_settings, const ExternalLoaderConfigSettings & config_settings, + std::unique_ptr config_repository, Logger * log, const std::string & loadable_object_name); virtual ~ExternalLoader(); @@ -149,6 +151,8 @@ private: const ExternalLoaderUpdateSettings & update_settings; const ExternalLoaderConfigSettings & config_settings; + std::unique_ptr config_repository; + std::thread reloading_thread; Poco::Event destroy; diff --git a/dbms/src/Interpreters/ExternalLoaderConfigRepository.cpp b/dbms/src/Interpreters/ExternalLoaderConfigRepository.cpp new file mode 100644 index 00000000000..7b803e2655d --- /dev/null +++ b/dbms/src/Interpreters/ExternalLoaderConfigRepository.cpp @@ -0,0 +1,62 @@ +#include + +#include +#include + +#include +#include +#include + +namespace DB +{ + +ExternalLoaderConfigRepository::Files ExternalLoaderConfigRepository::list( + const Poco::Util::AbstractConfiguration & config, + const std::string & path_key) const +{ + Files files; + + auto patterns = getMultipleValuesFromConfig(config, "", path_key); + + for (auto & pattern : patterns) + { + if (pattern.empty()) + continue; + + if (pattern[0] != '/') + { + const auto app_config_path = config.getString("config-file", "config.xml"); + const auto config_dir = Poco::Path{app_config_path}.parent().toString(); + const auto absolute_path = config_dir + pattern; + Poco::Glob::glob(absolute_path, files, 0); + if (!files.empty()) + continue; + } + + Poco::Glob::glob(pattern, files, 0); + } + + return files; +} + +bool ExternalLoaderConfigRepository::exists(const std::string & config_file) const +{ + return Poco::File(config_file).exists(); +} + +Poco::Timestamp ExternalLoaderConfigRepository::getLastModificationTime( + const std::string & config_file) const +{ + return Poco::File(config_file).getLastModified(); +} + +Poco::AutoPtr ExternalLoaderConfigRepository::load( + const std::string & config_file) const +{ + ConfigProcessor config_processor{config_file}; + ConfigProcessor::LoadedConfig preprocessed = config_processor.loadConfig(); + config_processor.savePreprocessedConfig(preprocessed); + return preprocessed.configuration; +} + +} diff --git a/dbms/src/Interpreters/ExternalLoaderConfigRepository.h b/dbms/src/Interpreters/ExternalLoaderConfigRepository.h new file mode 100644 index 00000000000..dd5c53329b5 --- /dev/null +++ b/dbms/src/Interpreters/ExternalLoaderConfigRepository.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace DB +{ + +/** Default implementation of config repository used by native server application. + * Represents files in local filesystem. + */ +class ExternalLoaderConfigRepository : public IExternalLoaderConfigRepository +{ +public: + Files list( + const Poco::Util::AbstractConfiguration & config, + const std::string & path_key) const override; + + bool exists(const std::string & config_file) const override; + + Poco::Timestamp getLastModificationTime(const std::string & config_file) const override; + + Poco::AutoPtr load(const std::string & config_file) const override; +}; + +} diff --git a/dbms/src/Interpreters/ExternalModels.cpp b/dbms/src/Interpreters/ExternalModels.cpp index 31c3ae46d8b..e0c417169a6 100644 --- a/dbms/src/Interpreters/ExternalModels.cpp +++ b/dbms/src/Interpreters/ExternalModels.cpp @@ -31,10 +31,14 @@ namespace } -ExternalModels::ExternalModels(Context & context, bool throw_on_error) +ExternalModels::ExternalModels( + std::unique_ptr config_repository, + Context & context, + bool throw_on_error) : ExternalLoader(context.getConfigRef(), externalModelsUpdateSettings, getExternalModelsConfigSettings(), + std::move(config_repository), &Logger::get("ExternalModels"), "external model"), context(context) diff --git a/dbms/src/Interpreters/ExternalModels.h b/dbms/src/Interpreters/ExternalModels.h index bbe23ad28b3..1720a0e7371 100644 --- a/dbms/src/Interpreters/ExternalModels.h +++ b/dbms/src/Interpreters/ExternalModels.h @@ -18,7 +18,10 @@ public: using ModelPtr = std::shared_ptr; /// Models will be loaded immediately and then will be updated in separate thread, each 'reload_period' seconds. - ExternalModels(Context & context, bool throw_on_error); + ExternalModels( + std::unique_ptr config_repository, + Context & context, + bool throw_on_error); /// Forcibly reloads specified model. void reloadModel(const std::string & name) { reload(name); } diff --git a/dbms/src/Interpreters/IExternalLoaderConfigRepository.h b/dbms/src/Interpreters/IExternalLoaderConfigRepository.h new file mode 100644 index 00000000000..93159eb4ba6 --- /dev/null +++ b/dbms/src/Interpreters/IExternalLoaderConfigRepository.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace DB +{ + +/** Repository with configurations of user-defined objects (dictionaries, models). + * Used by ExternalLoader. + */ +class IExternalLoaderConfigRepository +{ +public: + using Files = std::set; + virtual Files list(const Poco::Util::AbstractConfiguration & config, const std::string & path_key) const = 0; + + virtual bool exists(const std::string & config_file) const = 0; + + virtual Poco::Timestamp getLastModificationTime(const std::string & config_file) const = 0; + + virtual Poco::AutoPtr load(const std::string & config_file) const = 0; + + virtual ~IExternalLoaderConfigRepository() {} +}; + +} diff --git a/dbms/src/Interpreters/IRuntimeComponentsFactory.h b/dbms/src/Interpreters/IRuntimeComponentsFactory.h index 226fd26d427..9764fc7195a 100644 --- a/dbms/src/Interpreters/IRuntimeComponentsFactory.h +++ b/dbms/src/Interpreters/IRuntimeComponentsFactory.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -19,6 +20,11 @@ public: virtual std::unique_ptr createGeoDictionariesLoader() = 0; + // Repositories with configurations of user-defined objects (dictionaries, models) + virtual std::unique_ptr createExternalDictionariesConfigRepository() = 0; + + virtual std::unique_ptr createExternalModelsConfigRepository() = 0; + virtual ~IRuntimeComponentsFactory() {} }; diff --git a/dbms/src/Interpreters/Limits.h b/dbms/src/Interpreters/Limits.h index 0ae83f01dcf..cd6fc409508 100644 --- a/dbms/src/Interpreters/Limits.h +++ b/dbms/src/Interpreters/Limits.h @@ -26,82 +26,82 @@ struct Limits * That is, only in the deepest subquery. \ * When reading from a remote server, it is only checked on a remote server. \ */ \ - M(SettingUInt64, max_rows_to_read, 0) \ - M(SettingUInt64, max_bytes_to_read, 0) \ - M(SettingOverflowMode, read_overflow_mode, OverflowMode::THROW) \ + M(SettingUInt64, max_rows_to_read, 0, "") \ + M(SettingUInt64, max_bytes_to_read, 0, "") \ + M(SettingOverflowMode, read_overflow_mode, OverflowMode::THROW, "") \ \ - M(SettingUInt64, max_rows_to_group_by, 0) \ - M(SettingOverflowMode, group_by_overflow_mode, OverflowMode::THROW) \ - M(SettingUInt64, max_bytes_before_external_group_by, 0) \ + M(SettingUInt64, max_rows_to_group_by, 0, "") \ + M(SettingOverflowMode, group_by_overflow_mode, OverflowMode::THROW, "") \ + M(SettingUInt64, max_bytes_before_external_group_by, 0, "") \ \ - M(SettingUInt64, max_rows_to_sort, 0) \ - M(SettingUInt64, max_bytes_to_sort, 0) \ - M(SettingOverflowMode, sort_overflow_mode, OverflowMode::THROW) \ - M(SettingUInt64, max_bytes_before_external_sort, 0) \ + M(SettingUInt64, max_rows_to_sort, 0, "") \ + M(SettingUInt64, max_bytes_to_sort, 0, "") \ + M(SettingOverflowMode, sort_overflow_mode, OverflowMode::THROW, "") \ + M(SettingUInt64, max_bytes_before_external_sort, 0, "") \ \ /** Limits on result size. \ * Are also checked for subqueries and on remote servers. \ */ \ - M(SettingUInt64, max_result_rows, 0) \ - M(SettingUInt64, max_result_bytes, 0) \ - M(SettingOverflowMode, result_overflow_mode, OverflowMode::THROW) \ + M(SettingUInt64, max_result_rows, 0, "") \ + M(SettingUInt64, max_result_bytes, 0, "") \ + M(SettingOverflowMode, result_overflow_mode, OverflowMode::THROW, "") \ \ /* TODO: Check also when merging and finalizing aggregate functions. */ \ - M(SettingSeconds, max_execution_time, 0) \ - M(SettingOverflowMode, timeout_overflow_mode, OverflowMode::THROW) \ + M(SettingSeconds, max_execution_time, 0, "") \ + M(SettingOverflowMode, timeout_overflow_mode, OverflowMode::THROW, "") \ \ /** In rows per second. */ \ - M(SettingUInt64, min_execution_speed, 0) \ + M(SettingUInt64, min_execution_speed, 0, "") \ /** Check that the speed is not too low after the specified time has elapsed. */ \ - M(SettingSeconds, timeout_before_checking_execution_speed, 0) \ + M(SettingSeconds, timeout_before_checking_execution_speed, 0, "") \ \ - M(SettingUInt64, max_columns_to_read, 0) \ - M(SettingUInt64, max_temporary_columns, 0) \ - M(SettingUInt64, max_temporary_non_const_columns, 0) \ + M(SettingUInt64, max_columns_to_read, 0, "") \ + M(SettingUInt64, max_temporary_columns, 0, "") \ + M(SettingUInt64, max_temporary_non_const_columns, 0, "") \ \ - M(SettingUInt64, max_subquery_depth, 100) \ - M(SettingUInt64, max_pipeline_depth, 1000) \ - M(SettingUInt64, max_ast_depth, 1000) /** Checked not during parsing, */ \ - M(SettingUInt64, max_ast_elements, 50000) /** but after parsing the request. */ \ + M(SettingUInt64, max_subquery_depth, 100, "") \ + M(SettingUInt64, max_pipeline_depth, 1000, "") \ + M(SettingUInt64, max_ast_depth, 1000, "") /** Checked not during parsing, */ \ + M(SettingUInt64, max_ast_elements, 50000, "") /** but after parsing the request. */ \ \ /** 0 - everything is allowed. 1 - only read requests. 2 - only read requests, as well as changing settings, except for the readonly setting. */ \ - M(SettingUInt64, readonly, 0) \ + M(SettingUInt64, readonly, 0, "") \ \ /** Limits for the maximum size of the set resulting from the execution of the IN section. */ \ - M(SettingUInt64, max_rows_in_set, 0) \ - M(SettingUInt64, max_bytes_in_set, 0) \ - M(SettingOverflowMode, set_overflow_mode, OverflowMode::THROW) \ + M(SettingUInt64, max_rows_in_set, 0, "") \ + M(SettingUInt64, max_bytes_in_set, 0, "") \ + M(SettingOverflowMode, set_overflow_mode, OverflowMode::THROW, "") \ \ /** Limits for the maximum size of the set obtained by executing the IN section. */ \ - M(SettingUInt64, max_rows_in_join, 0) \ - M(SettingUInt64, max_bytes_in_join, 0) \ - M(SettingOverflowMode, join_overflow_mode, OverflowMode::THROW) \ + M(SettingUInt64, max_rows_in_join, 0, "") \ + M(SettingUInt64, max_bytes_in_join, 0, "") \ + M(SettingOverflowMode, join_overflow_mode, OverflowMode::THROW, "") \ \ /** Limits for the maximum size of the transmitted external table obtained when the GLOBAL IN/JOIN section is executed. */ \ - M(SettingUInt64, max_rows_to_transfer, 0) \ - M(SettingUInt64, max_bytes_to_transfer, 0) \ - M(SettingOverflowMode, transfer_overflow_mode, OverflowMode::THROW) \ + M(SettingUInt64, max_rows_to_transfer, 0, "") \ + M(SettingUInt64, max_bytes_to_transfer, 0, "") \ + M(SettingOverflowMode, transfer_overflow_mode, OverflowMode::THROW, "") \ \ /** Limits for the maximum size of the stored state when executing DISTINCT. */ \ - M(SettingUInt64, max_rows_in_distinct, 0) \ - M(SettingUInt64, max_bytes_in_distinct, 0) \ - M(SettingOverflowMode, distinct_overflow_mode, OverflowMode::THROW) \ + M(SettingUInt64, max_rows_in_distinct, 0, "") \ + M(SettingUInt64, max_bytes_in_distinct, 0, "") \ + M(SettingOverflowMode, distinct_overflow_mode, OverflowMode::THROW, "") \ \ /** Maximum memory usage when processing a request. 0 - not bounded. */ \ - M(SettingUInt64, max_memory_usage, 0) /* For one query */ \ + M(SettingUInt64, max_memory_usage, 0, "") /* For one query */ \ /* Totally for concurrently running queries of one user */ \ - M(SettingUInt64, max_memory_usage_for_user, 0) \ + M(SettingUInt64, max_memory_usage_for_user, 0, "") \ /* Totally for all concurrent queries */ \ - M(SettingUInt64, max_memory_usage_for_all_queries, 0) \ + M(SettingUInt64, max_memory_usage_for_all_queries, 0, "") \ \ /** The maximum speed of data exchange over the network in bytes per second. 0 - not bounded. */ \ - M(SettingUInt64, max_network_bandwidth, 0) \ + M(SettingUInt64, max_network_bandwidth, 0, "") \ /** The maximum number of bytes to receive or transmit over the network, as part of the query. */ \ - M(SettingUInt64, max_network_bytes, 0) \ + M(SettingUInt64, max_network_bytes, 0, "") \ /** The maximum speed of data exchange over the network for the user in bytes per second. 0 - not bounded. */ \ - M(SettingUInt64, max_network_bandwidth_for_user, 0) + M(SettingUInt64, max_network_bandwidth_for_user, 0, "") -#define DECLARE(TYPE, NAME, DEFAULT) \ +#define DECLARE(TYPE, NAME, DEFAULT, DESCRIPTION) \ TYPE NAME {DEFAULT}; APPLY_FOR_LIMITS(DECLARE) @@ -111,7 +111,7 @@ struct Limits /// Set setting by name. bool trySet(const String & name, const Field & value) { - #define TRY_SET(TYPE, NAME, DEFAULT) \ + #define TRY_SET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) NAME.set(value); if (false) {} @@ -127,7 +127,7 @@ struct Limits /// Set the setting by name. Read the binary serialized value from the buffer (for server-to-server interaction). bool trySet(const String & name, ReadBuffer & buf) { - #define TRY_SET(TYPE, NAME, DEFAULT) \ + #define TRY_SET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) NAME.set(buf); if (false) {} @@ -143,7 +143,7 @@ struct Limits /// Skip the binary-serialized value from the buffer. bool tryIgnore(const String & name, ReadBuffer & buf) { - #define TRY_IGNORE(TYPE, NAME, DEFAULT) \ + #define TRY_IGNORE(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) decltype(NAME)(DEFAULT).set(buf); if (false) {} @@ -160,7 +160,7 @@ struct Limits */ bool trySet(const String & name, const String & value) { - #define TRY_SET(TYPE, NAME, DEFAULT) \ + #define TRY_SET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) NAME.set(value); if (false) {} @@ -175,7 +175,7 @@ struct Limits bool tryGet(const String & name, String & value) const { - #define TRY_GET(TYPE, NAME, DEFAULT) \ + #define TRY_GET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) { value = NAME.toString(); return true; } if (false) {} @@ -192,7 +192,7 @@ private: /// Write all the settings to the buffer. (Unlike the corresponding method in Settings, the empty line on the end is not written). void serialize(WriteBuffer & buf) const { - #define WRITE(TYPE, NAME, DEFAULT) \ + #define WRITE(TYPE, NAME, DEFAULT, DESCRIPTION) \ if (NAME.changed) \ { \ writeStringBinary(#NAME, buf); \ diff --git a/dbms/src/Interpreters/RuntimeComponentsFactory.h b/dbms/src/Interpreters/RuntimeComponentsFactory.h index 6072c9ace94..bbadbf68e8b 100644 --- a/dbms/src/Interpreters/RuntimeComponentsFactory.h +++ b/dbms/src/Interpreters/RuntimeComponentsFactory.h @@ -2,6 +2,7 @@ #include #include +#include #include namespace DB @@ -22,6 +23,16 @@ public: { return std::make_unique(); } + + std::unique_ptr createExternalDictionariesConfigRepository() override + { + return std::make_unique(); + } + + std::unique_ptr createExternalModelsConfigRepository() override + { + return std::make_unique(); + } }; } diff --git a/dbms/src/Interpreters/Settings.cpp b/dbms/src/Interpreters/Settings.cpp index 8d59adea717..c501120413f 100644 --- a/dbms/src/Interpreters/Settings.cpp +++ b/dbms/src/Interpreters/Settings.cpp @@ -15,7 +15,7 @@ namespace ErrorCodes /// Set the configuration by name. void Settings::set(const String & name, const Field & value) { -#define TRY_SET(TYPE, NAME, DEFAULT) \ +#define TRY_SET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) NAME.set(value); if (false) {} @@ -29,7 +29,7 @@ void Settings::set(const String & name, const Field & value) /// Set the configuration by name. Read the binary serialized value from the buffer (for interserver interaction). void Settings::set(const String & name, ReadBuffer & buf) { -#define TRY_SET(TYPE, NAME, DEFAULT) \ +#define TRY_SET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) NAME.set(buf); if (false) {} @@ -43,7 +43,7 @@ void Settings::set(const String & name, ReadBuffer & buf) /// Skip the binary-serialized value from the buffer. void Settings::ignore(const String & name, ReadBuffer & buf) { -#define TRY_IGNORE(TYPE, NAME, DEFAULT) \ +#define TRY_IGNORE(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) decltype(NAME)(DEFAULT).set(buf); if (false) {} @@ -58,7 +58,7 @@ void Settings::ignore(const String & name, ReadBuffer & buf) */ void Settings::set(const String & name, const String & value) { -#define TRY_SET(TYPE, NAME, DEFAULT) \ +#define TRY_SET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) NAME.set(value); if (false) {} @@ -71,7 +71,7 @@ void Settings::set(const String & name, const String & value) String Settings::get(const String & name) const { -#define GET(TYPE, NAME, DEFAULT) \ +#define GET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) return NAME.toString(); if (false) {} @@ -89,7 +89,7 @@ String Settings::get(const String & name) const bool Settings::tryGet(const String & name, String & value) const { -#define TRY_GET(TYPE, NAME, DEFAULT) \ +#define TRY_GET(TYPE, NAME, DEFAULT, DESCRIPTION) \ else if (name == #NAME) { value = NAME.toString(); return true; } if (false) {} @@ -162,7 +162,7 @@ void Settings::deserialize(ReadBuffer & buf) /// Record the changed settings to the buffer. (For example, to send to a remote server.) void Settings::serialize(WriteBuffer & buf) const { -#define WRITE(TYPE, NAME, DEFAULT) \ +#define WRITE(TYPE, NAME, DEFAULT, DESCRIPTION) \ if (NAME.changed) \ { \ writeStringBinary(#NAME, buf); \ diff --git a/dbms/src/Interpreters/Settings.h b/dbms/src/Interpreters/Settings.h index bcd5ac8230d..9af4c89fbb2 100644 --- a/dbms/src/Interpreters/Settings.h +++ b/dbms/src/Interpreters/Settings.h @@ -33,289 +33,289 @@ struct Settings /** As a result, for small columns (around 1-8 bytes), with index_granularity = 8192, the block size will be 64 KB. */ \ /** And for large columns (Title - string ~100 bytes), the block size will be ~819 KB. */ \ /** Due to this, the compression ratio almost does not get worse. */ \ - M(SettingUInt64, min_compress_block_size, DEFAULT_MIN_COMPRESS_BLOCK_SIZE) \ - M(SettingUInt64, max_compress_block_size, DEFAULT_MAX_COMPRESS_BLOCK_SIZE) \ + M(SettingUInt64, min_compress_block_size, DEFAULT_MIN_COMPRESS_BLOCK_SIZE, "The actual size of the block, if the uncompressed data less than max_compress_block_size is no less than this value and no less than the volume of data for one mark.") \ + M(SettingUInt64, max_compress_block_size, DEFAULT_MAX_COMPRESS_BLOCK_SIZE, "The maximum size of blocks of uncompressed data before compressing for writing to a table.") \ /** Maximum block size for reading */ \ - M(SettingUInt64, max_block_size, DEFAULT_BLOCK_SIZE) \ + M(SettingUInt64, max_block_size, DEFAULT_BLOCK_SIZE, "Maximum block size for reading") \ /** The maximum block size for insertion, if we control the creation of blocks for insertion. */ \ - M(SettingUInt64, max_insert_block_size, DEFAULT_INSERT_BLOCK_SIZE) \ + M(SettingUInt64, max_insert_block_size, DEFAULT_INSERT_BLOCK_SIZE, "The maximum block size for insertion, if we control the creation of blocks for insertion.") \ /** Squash blocks passed to INSERT query to specified size in rows, if blocks are not big enough. */ \ - M(SettingUInt64, min_insert_block_size_rows, DEFAULT_INSERT_BLOCK_SIZE) \ + M(SettingUInt64, min_insert_block_size_rows, DEFAULT_INSERT_BLOCK_SIZE, "Squash blocks passed to INSERT query to specified size in rows, if blocks are not big enough.") \ /** Squash blocks passed to INSERT query to specified size in bytes, if blocks are not big enough. */ \ - M(SettingUInt64, min_insert_block_size_bytes, (DEFAULT_INSERT_BLOCK_SIZE * 256)) \ + M(SettingUInt64, min_insert_block_size_bytes, (DEFAULT_INSERT_BLOCK_SIZE * 256), "Squash blocks passed to INSERT query to specified size in bytes, if blocks are not big enough.") \ /** The maximum number of threads to execute the request. By default, it is determined automatically. */ \ - M(SettingMaxThreads, max_threads, 0) \ + M(SettingMaxThreads, max_threads, 0, "The maximum number of threads to execute the request. By default, it is determined automatically.") \ /** The maximum size of the buffer to read from the filesystem. */ \ - M(SettingUInt64, max_read_buffer_size, DBMS_DEFAULT_BUFFER_SIZE) \ + M(SettingUInt64, max_read_buffer_size, DBMS_DEFAULT_BUFFER_SIZE, "The maximum size of the buffer to read from the filesystem.") \ /** The maximum number of connections for distributed processing of one query (should be greater than max_threads). */ \ - M(SettingUInt64, max_distributed_connections, DEFAULT_MAX_DISTRIBUTED_CONNECTIONS) \ + M(SettingUInt64, max_distributed_connections, DEFAULT_MAX_DISTRIBUTED_CONNECTIONS, "The maximum number of connections for distributed processing of one query (should be greater than max_threads).") \ /** Which part of the query can be read into RAM for parsing (the remaining data for INSERT, if any, is read later) */ \ - M(SettingUInt64, max_query_size, DEFAULT_MAX_QUERY_SIZE) \ + M(SettingUInt64, max_query_size, DEFAULT_MAX_QUERY_SIZE, "Which part of the query can be read into RAM for parsing (the remaining data for INSERT, if any, is read later)") \ /** The interval in microseconds to check if the request is cancelled, and to send progress info. */ \ - M(SettingUInt64, interactive_delay, DEFAULT_INTERACTIVE_DELAY) \ - M(SettingSeconds, connect_timeout, DBMS_DEFAULT_CONNECT_TIMEOUT_SEC) \ + M(SettingUInt64, interactive_delay, DEFAULT_INTERACTIVE_DELAY, "The interval in microseconds to check if the request is cancelled, and to send progress info.") \ + M(SettingSeconds, connect_timeout, DBMS_DEFAULT_CONNECT_TIMEOUT_SEC, "") \ /** If you should select one of the working replicas. */ \ - M(SettingMilliseconds, connect_timeout_with_failover_ms, DBMS_DEFAULT_CONNECT_TIMEOUT_WITH_FAILOVER_MS) \ - M(SettingSeconds, receive_timeout, DBMS_DEFAULT_RECEIVE_TIMEOUT_SEC) \ - M(SettingSeconds, send_timeout, DBMS_DEFAULT_SEND_TIMEOUT_SEC) \ + M(SettingMilliseconds, connect_timeout_with_failover_ms, DBMS_DEFAULT_CONNECT_TIMEOUT_WITH_FAILOVER_MS, "") \ + M(SettingSeconds, receive_timeout, DBMS_DEFAULT_RECEIVE_TIMEOUT_SEC, "") \ + M(SettingSeconds, send_timeout, DBMS_DEFAULT_SEND_TIMEOUT_SEC, "") \ /** The wait time in the request queue, if the number of concurrent requests exceeds the maximum. */ \ - M(SettingMilliseconds, queue_max_wait_ms, DEFAULT_QUERIES_QUEUE_WAIT_TIME_MS) \ + M(SettingMilliseconds, queue_max_wait_ms, DEFAULT_QUERIES_QUEUE_WAIT_TIME_MS, "The wait time in the request queue, if the number of concurrent requests exceeds the maximum.") \ /** Block at the query wait cycle on the server for the specified number of seconds. */ \ - M(SettingUInt64, poll_interval, DBMS_DEFAULT_POLL_INTERVAL) \ + M(SettingUInt64, poll_interval, DBMS_DEFAULT_POLL_INTERVAL, "Block at the query wait cycle on the server for the specified number of seconds.") \ /** Maximum number of connections with one remote server in the pool. */ \ - M(SettingUInt64, distributed_connections_pool_size, DBMS_DEFAULT_DISTRIBUTED_CONNECTIONS_POOL_SIZE) \ + M(SettingUInt64, distributed_connections_pool_size, DBMS_DEFAULT_DISTRIBUTED_CONNECTIONS_POOL_SIZE, "Maximum number of connections with one remote server in the pool.") \ /** The maximum number of attempts to connect to replicas. */ \ - M(SettingUInt64, connections_with_failover_max_tries, DBMS_CONNECTION_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES) \ + M(SettingUInt64, connections_with_failover_max_tries, DBMS_CONNECTION_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES, "The maximum number of attempts to connect to replicas.") \ /** Calculate minimums and maximums of the result columns. They can be output in JSON-formats. */ \ - M(SettingBool, extremes, false) \ + M(SettingBool, extremes, false, "Calculate minimums and maximums of the result columns. They can be output in JSON-formats.") \ /** Whether to use the cache of uncompressed blocks. */ \ - M(SettingBool, use_uncompressed_cache, true) \ + M(SettingBool, use_uncompressed_cache, true, "Whether to use the cache of uncompressed blocks.") \ /** Whether the running request should be canceled with the same id as the new one. */ \ - M(SettingBool, replace_running_query, false) \ + M(SettingBool, replace_running_query, false, "Whether the running request should be canceled with the same id as the new one.") \ /** Number of threads performing background work for tables (for example, merging in merge tree). \ * TODO: Now only applies when the server is started. You can make it dynamically variable. */ \ - M(SettingUInt64, background_pool_size, DBMS_DEFAULT_BACKGROUND_POOL_SIZE) \ + M(SettingUInt64, background_pool_size, DBMS_DEFAULT_BACKGROUND_POOL_SIZE, "Number of threads performing background work for tables (for example, merging in merge tree).") \ /** Number of threads performing background tasks for replicated tables. \ * TODO: Now only applies when the server is started. You can make it dynamically variable. */ \ - M(SettingUInt64, background_schedule_pool_size, DBMS_DEFAULT_BACKGROUND_POOL_SIZE) \ + M(SettingUInt64, background_schedule_pool_size, DBMS_DEFAULT_BACKGROUND_POOL_SIZE, "Number of threads performing background tasks for replicated tables.") \ \ /** Sleep time for StorageDistributed DirectoryMonitors in case there is no work or exception has been thrown */ \ - M(SettingMilliseconds, distributed_directory_monitor_sleep_time_ms, DBMS_DISTRIBUTED_DIRECTORY_MONITOR_SLEEP_TIME_MS) \ + M(SettingMilliseconds, distributed_directory_monitor_sleep_time_ms, DBMS_DISTRIBUTED_DIRECTORY_MONITOR_SLEEP_TIME_MS, "Sleep time for StorageDistributed DirectoryMonitors in case there is no work or exception has been thrown.") \ \ /** Should StorageDistributed DirectoryMonitors try to batch individual inserts into bigger ones. */ \ - M(SettingBool, distributed_directory_monitor_batch_inserts, false) \ + M(SettingBool, distributed_directory_monitor_batch_inserts, false, "Should StorageDistributed DirectoryMonitors try to batch individual inserts into bigger ones.") \ \ /** Allows disabling WHERE to PREWHERE optimization in SELECT queries from MergeTree */ \ - M(SettingBool, optimize_move_to_prewhere, true) \ + M(SettingBool, optimize_move_to_prewhere, true, "Allows disabling WHERE to PREWHERE optimization in SELECT queries from MergeTree.") \ \ /** Wait for actions to manipulate the partitions. 0 - do not wait, 1 - wait for execution only of itself, 2 - wait for everyone. */ \ - M(SettingUInt64, replication_alter_partitions_sync, 1) \ + M(SettingUInt64, replication_alter_partitions_sync, 1, "Wait for actions to manipulate the partitions. 0 - do not wait, 1 - wait for execution only of itself, 2 - wait for everyone.") \ /** Wait for actions to change the table structure within the specified number of seconds. 0 - wait unlimited time. */ \ - M(SettingUInt64, replication_alter_columns_timeout, 60) \ + M(SettingUInt64, replication_alter_columns_timeout, 60, "Wait for actions to change the table structure within the specified number of seconds. 0 - wait unlimited time.") \ \ - M(SettingLoadBalancing, load_balancing, LoadBalancing::RANDOM) \ + M(SettingLoadBalancing, load_balancing, LoadBalancing::RANDOM, "Which replicas (among healthy replicas) to preferably send a query to (on the first attempt) for distributed processing.") \ \ - M(SettingTotalsMode, totals_mode, TotalsMode::AFTER_HAVING_EXCLUSIVE) \ - M(SettingFloat, totals_auto_threshold, 0.5) \ + M(SettingTotalsMode, totals_mode, TotalsMode::AFTER_HAVING_EXCLUSIVE, "How to calculate TOTALS when HAVING is present, as well as when max_rows_to_group_by and group_by_overflow_mode = ‘any’ are present.") \ + M(SettingFloat, totals_auto_threshold, 0.5, "The threshold for totals_mode = 'auto'.") \ \ /** Whether query compilation is enabled. */ \ - M(SettingBool, compile, false) \ + M(SettingBool, compile, false, "Whether query compilation is enabled.") \ /** The number of structurally identical queries before they are compiled. */ \ - M(SettingUInt64, min_count_to_compile, 3) \ + M(SettingUInt64, min_count_to_compile, 3, "The number of structurally identical queries before they are compiled.") \ /** From what number of keys, a two-level aggregation starts. 0 - the threshold is not set. */ \ - M(SettingUInt64, group_by_two_level_threshold, 100000) \ + M(SettingUInt64, group_by_two_level_threshold, 100000, "From what number of keys, a two-level aggregation starts. 0 - the threshold is not set.") \ /** From what size of the aggregation state in bytes, a two-level aggregation begins to be used. 0 - the threshold is not set. \ * Two-level aggregation is used when at least one of the thresholds is triggered. */ \ - M(SettingUInt64, group_by_two_level_threshold_bytes, 100000000) \ + M(SettingUInt64, group_by_two_level_threshold_bytes, 100000000, "From what size of the aggregation state in bytes, a two-level aggregation begins to be used. 0 - the threshold is not set.") \ /** Is the memory-saving mode of distributed aggregation enabled. */ \ - M(SettingBool, distributed_aggregation_memory_efficient, false) \ + M(SettingBool, distributed_aggregation_memory_efficient, false, "Is the memory-saving mode of distributed aggregation enabled.") \ /** Number of threads to use for merge intermediate aggregation results in memory efficient mode. When bigger, then more memory is consumed. \ * 0 means - same as 'max_threads'. */ \ - M(SettingUInt64, aggregation_memory_efficient_merge_threads, 0) \ + M(SettingUInt64, aggregation_memory_efficient_merge_threads, 0, "Number of threads to use for merge intermediate aggregation results in memory efficient mode. When bigger, then more memory is consumed. 0 means - same as 'max_threads'.") \ \ /** The maximum number of replicas of each shard used when executing the query */ \ - M(SettingUInt64, max_parallel_replicas, 1) \ - M(SettingUInt64, parallel_replicas_count, 0) \ - M(SettingUInt64, parallel_replica_offset, 0) \ + M(SettingUInt64, max_parallel_replicas, 1, "The maximum number of replicas of each shard used when the query is executed. For consistency (to get different parts of the same partition), this option only works for the specified sampling key. The lag of the replicas is not controlled.") \ + M(SettingUInt64, parallel_replicas_count, 0, "") \ + M(SettingUInt64, parallel_replica_offset, 0, "") \ \ /** Silently skip unavailable shards. */ \ - M(SettingBool, skip_unavailable_shards, false) \ + M(SettingBool, skip_unavailable_shards, false, "Silently skip unavailable shards.") \ \ /** Do not merge aggregation states from different servers for distributed query processing \ * - in case it is for certain that there are different keys on different shards. \ */ \ - M(SettingBool, distributed_group_by_no_merge, false) \ + M(SettingBool, distributed_group_by_no_merge, false, "Do not merge aggregation states from different servers for distributed query processing - in case it is for certain that there are different keys on different shards.") \ \ /** Advanced settings for reading from MergeTree */ \ \ /** If at least as many lines are read from one file, the reading can be parallelized. */ \ - M(SettingUInt64, merge_tree_min_rows_for_concurrent_read, (20 * 8192)) \ + M(SettingUInt64, merge_tree_min_rows_for_concurrent_read, (20 * 8192), "If at least as many lines are read from one file, the reading can be parallelized.") \ /** You can skip reading more than that number of rows at the price of one seek per file. */ \ - M(SettingUInt64, merge_tree_min_rows_for_seek, 0) \ + M(SettingUInt64, merge_tree_min_rows_for_seek, 0, "You can skip reading more than that number of rows at the price of one seek per file.") \ /** If the index segment can contain the required keys, divide it into as many parts and recursively check them. */ \ - M(SettingUInt64, merge_tree_coarse_index_granularity, 8) \ + M(SettingUInt64, merge_tree_coarse_index_granularity, 8, "If the index segment can contain the required keys, divide it into as many parts and recursively check them. ") \ /** The maximum number of rows per request, to use the cache of uncompressed data. If the request is large, the cache is not used. \ * (For large queries not to flush out the cache.) */ \ - M(SettingUInt64, merge_tree_max_rows_to_use_cache, (1024 * 1024)) \ + M(SettingUInt64, merge_tree_max_rows_to_use_cache, (1024 * 1024), "The maximum number of rows per request, to use the cache of uncompressed data. If the request is large, the cache is not used.") \ \ /** Distribute read from MergeTree over threads evenly, ensuring stable average execution time of each thread within one read operation. */ \ - M(SettingBool, merge_tree_uniform_read_distribution, true) \ + M(SettingBool, merge_tree_uniform_read_distribution, true, "Distribute read from MergeTree over threads evenly, ensuring stable average execution time of each thread within one read operation.") \ \ /** The minimum length of the expression `expr = x1 OR ... expr = xN` for optimization */ \ - M(SettingUInt64, optimize_min_equality_disjunction_chain_length, 3) \ + M(SettingUInt64, optimize_min_equality_disjunction_chain_length, 3, "The minimum length of the expression `expr = x1 OR ... expr = xN` for optimization ") \ \ /** The minimum number of bytes for input/output operations is bypassing the page cache. 0 - disabled. */ \ - M(SettingUInt64, min_bytes_to_use_direct_io, 0) \ + M(SettingUInt64, min_bytes_to_use_direct_io, 0, "The minimum number of bytes for input/output operations is bypassing the page cache. 0 - disabled.") \ \ /** Throw an exception if there is an index, and it is not used. */ \ - M(SettingBool, force_index_by_date, 0) \ - M(SettingBool, force_primary_key, 0) \ + M(SettingBool, force_index_by_date, 0, "") \ + M(SettingBool, force_primary_key, 0, "") \ \ /** In the INSERT query with specified columns, fill in the default values only for columns with explicit DEFAULTs. */ \ - M(SettingBool, strict_insert_defaults, 0) \ + M(SettingBool, strict_insert_defaults, 0, "In the INSERT query with specified columns, fill in the default values only for columns with explicit DEFAULTs.") \ \ /** If the maximum size of mark_cache is exceeded, delete only records older than mark_cache_min_lifetime seconds. */ \ - M(SettingUInt64, mark_cache_min_lifetime, 10000) \ + M(SettingUInt64, mark_cache_min_lifetime, 10000, "If the maximum size of mark_cache is exceeded, delete only records older than mark_cache_min_lifetime seconds.") \ \ /** Allows you to use more sources than the number of threads - to more evenly distribute work across threads. \ * It is assumed that this is a temporary solution, since it will be possible in the future to make the number of sources equal to the number of threads, \ * but for each source to dynamically select available work for itself. \ */ \ - M(SettingFloat, max_streams_to_max_threads_ratio, 1) \ + M(SettingFloat, max_streams_to_max_threads_ratio, 1, "") \ \ /** Allows you to select the method of data compression when writing */ \ - M(SettingCompressionMethod, network_compression_method, CompressionMethod::LZ4) \ + M(SettingCompressionMethod, network_compression_method, CompressionMethod::LZ4, "Allows you to select the method of data compression when writing.") \ \ /** Allows you to select the level of ZSTD compression */ \ - M(SettingInt64, network_zstd_compression_level, 1) \ + M(SettingInt64, network_zstd_compression_level, 1, "Allows you to select the level of ZSTD compression.") \ \ /** Priority of the query. 1 - the highest, higher value - lower priority; 0 - do not use priorities. */ \ - M(SettingUInt64, priority, 0) \ + M(SettingUInt64, priority, 0, "Priority of the query. 1 - the highest, higher value - lower priority; 0 - do not use priorities.") \ \ /** Log requests and write the log to the system table. */ \ - M(SettingBool, log_queries, 0) \ + M(SettingBool, log_queries, 0, "Log requests and write the log to the system table.") \ \ /** If query length is greater than specified threshold (in bytes), then cut query when writing to query log. \ * Also limit length of printed query in ordinary text log. \ */ \ - M(SettingUInt64, log_queries_cut_to_length, 100000) \ + M(SettingUInt64, log_queries_cut_to_length, 100000, "If query length is greater than specified threshold (in bytes), then cut query when writing to query log. Also limit length of printed query in ordinary text log.") \ \ /** How are distributed subqueries performed inside IN or JOIN sections? */ \ - M(SettingDistributedProductMode, distributed_product_mode, DistributedProductMode::DENY) \ + M(SettingDistributedProductMode, distributed_product_mode, DistributedProductMode::DENY, "How are distributed subqueries performed inside IN or JOIN sections?") \ \ /** The scheme for executing GLOBAL subqueries. */ \ - M(SettingGlobalSubqueriesMethod, global_subqueries_method, GlobalSubqueriesMethod::PUSH) \ + M(SettingGlobalSubqueriesMethod, global_subqueries_method, GlobalSubqueriesMethod::PUSH, "The scheme for executing GLOBAL subqueries.") \ \ /** The maximum number of concurrent requests per user. */ \ - M(SettingUInt64, max_concurrent_queries_for_user, 0) \ + M(SettingUInt64, max_concurrent_queries_for_user, 0, "The maximum number of concurrent requests per user.") \ \ /** For INSERT queries in the replicated table, specifies that deduplication of insertings blocks should be preformed */ \ - M(SettingBool, insert_deduplicate, true) \ + M(SettingBool, insert_deduplicate, true, "For INSERT queries in the replicated table, specifies that deduplication of insertings blocks should be preformed") \ \ /** For INSERT queries in the replicated table, wait writing for the specified number of replicas and linearize the addition of the data. 0 - disabled. */ \ - M(SettingUInt64, insert_quorum, 0) \ - M(SettingMilliseconds, insert_quorum_timeout, 600000) \ + M(SettingUInt64, insert_quorum, 0, "For INSERT queries in the replicated table, wait writing for the specified number of replicas and linearize the addition of the data. 0 - disabled.") \ + M(SettingMilliseconds, insert_quorum_timeout, 600000, "") \ /** For SELECT queries from the replicated table, throw an exception if the replica does not have a chunk written with the quorum; \ * do not read the parts that have not yet been written with the quorum. */ \ - M(SettingUInt64, select_sequential_consistency, 0) \ + M(SettingUInt64, select_sequential_consistency, 0, "For SELECT queries from the replicated table, throw an exception if the replica does not have a chunk written with the quorum.") \ /** The maximum number of different shards and the maximum number of replicas of one shard in the `remote` function. */ \ - M(SettingUInt64, table_function_remote_max_addresses, 1000) \ + M(SettingUInt64, table_function_remote_max_addresses, 1000, "The maximum number of different shards and the maximum number of replicas of one shard in the `remote` function.") \ /** Settings to reduce the number of threads in case of slow reads. */ \ /** Pay attention only to readings that took at least that much time. */ \ - M(SettingMilliseconds, read_backoff_min_latency_ms, 1000) \ + M(SettingMilliseconds, read_backoff_min_latency_ms, 1000, "Pay attention only to readings that took at least that much time.") \ /** Count events when the bandwidth is less than that many bytes per second. */ \ - M(SettingUInt64, read_backoff_max_throughput, 1048576) \ + M(SettingUInt64, read_backoff_max_throughput, 1048576, "Count events when the bandwidth is less than that many bytes per second.") \ /** Do not pay attention to the event, if the previous one has passed less than a certain amount of time. */ \ - M(SettingMilliseconds, read_backoff_min_interval_between_events_ms, 1000) \ + M(SettingMilliseconds, read_backoff_min_interval_between_events_ms, 1000, "Do not pay attention to the event, if the previous one has passed less than a certain amount of time.") \ /** The number of events after which the number of threads will be reduced. */ \ - M(SettingUInt64, read_backoff_min_events, 2) \ + M(SettingUInt64, read_backoff_min_events, 2, "The number of events after which the number of threads will be reduced.") \ \ /** For testing of `exception safety` - throw an exception every time you allocate memory with the specified probability. */ \ - M(SettingFloat, memory_tracker_fault_probability, 0.) \ + M(SettingFloat, memory_tracker_fault_probability, 0., "For testing of `exception safety` - throw an exception every time you allocate memory with the specified probability.") \ \ /** Compress the result if the client over HTTP said that it understands data compressed by gzip or deflate */ \ - M(SettingBool, enable_http_compression, 0) \ + M(SettingBool, enable_http_compression, 0, "Compress the result if the client over HTTP said that it understands data compressed by gzip or deflate.") \ /** Compression level - used if the client on HTTP said that it understands data compressed by gzip or deflate */ \ - M(SettingInt64, http_zlib_compression_level, 3) \ + M(SettingInt64, http_zlib_compression_level, 3, "Compression level - used if the client on HTTP said that it understands data compressed by gzip or deflate.") \ \ /** If you uncompress the POST data from the client compressed by the native format, do not check the checksum */ \ - M(SettingBool, http_native_compression_disable_checksumming_on_decompress, 0) \ + M(SettingBool, http_native_compression_disable_checksumming_on_decompress, 0, "If you uncompress the POST data from the client compressed by the native format, do not check the checksum.") \ \ /** What aggregate function to use for implementation of count(DISTINCT ...) */ \ - M(SettingString, count_distinct_implementation, "uniqExact") \ + M(SettingString, count_distinct_implementation, "uniqExact", "What aggregate function to use for implementation of count(DISTINCT ...)") \ \ /** Write statistics about read rows, bytes, time elapsed in suitable output formats */ \ - M(SettingBool, output_format_write_statistics, true) \ + M(SettingBool, output_format_write_statistics, true, "Write statistics about read rows, bytes, time elapsed in suitable output formats.") \ \ /** Write add http CORS header */ \ - M(SettingBool, add_http_cors_header, false) \ + M(SettingBool, add_http_cors_header, false, "Write add http CORS header.") \ \ /** Skip columns with unknown names from input data (it works for JSONEachRow and TSKV formats). */ \ - M(SettingBool, input_format_skip_unknown_fields, false) \ + M(SettingBool, input_format_skip_unknown_fields, false, "Skip columns with unknown names from input data (it works for JSONEachRow and TSKV formats).") \ \ /** For Values format: if field could not be parsed by streaming parser, run SQL parser and try to interpret it as SQL expression. */ \ - M(SettingBool, input_format_values_interpret_expressions, true) \ + M(SettingBool, input_format_values_interpret_expressions, true, "For Values format: if field could not be parsed by streaming parser, run SQL parser and try to interpret it as SQL expression.") \ \ /** Controls quoting of 64-bit integers in JSON output format. */ \ - M(SettingBool, output_format_json_quote_64bit_integers, true) \ + M(SettingBool, output_format_json_quote_64bit_integers, true, "Controls quoting of 64-bit integers in JSON output format.") \ \ /** Enables "+nan", "-nan", "+inf", "-inf" outputs in JSON output format. */ \ - M(SettingBool, output_format_json_quote_denormals, false) \ + M(SettingBool, output_format_json_quote_denormals, false, "Enables \"+nan\", \"-nan\", \"+inf\", \"-inf\" outputs in JSON output format.") \ \ /** Rows limit for Pretty formats. */ \ - M(SettingUInt64, output_format_pretty_max_rows, 10000) \ + M(SettingUInt64, output_format_pretty_max_rows, 10000, "Rows limit for Pretty formats.") \ \ /** Use client timezone for interpreting DateTime string values, instead of adopting server timezone. */ \ - M(SettingBool, use_client_time_zone, false) \ + M(SettingBool, use_client_time_zone, false, "Use client timezone for interpreting DateTime string values, instead of adopting server timezone.") \ \ /** Send progress notifications using X-ClickHouse-Progress headers. \ * Some clients do not support high amount of HTTP headers (Python requests in particular), so it is disabled by default. \ */ \ - M(SettingBool, send_progress_in_http_headers, false) \ + M(SettingBool, send_progress_in_http_headers, false, "Send progress notifications using X-ClickHouse-Progress headers.") \ \ /** Do not send HTTP headers X-ClickHouse-Progress more frequently than at each specified interval. */ \ - M(SettingUInt64, http_headers_progress_interval_ms, 100) \ + M(SettingUInt64, http_headers_progress_interval_ms, 100, "Do not send HTTP headers X-ClickHouse-Progress more frequently than at each specified interval.") \ \ /** Do fsync after changing metadata for tables and databases (.sql files). \ * Could be disabled in case of poor latency on server with high load of DDL queries and high load of disk subsystem. \ */ \ - M(SettingBool, fsync_metadata, 1) \ + M(SettingBool, fsync_metadata, 1, "Do fsync after changing metadata for tables and databases (.sql files).") \ \ /** Maximum amount of errors while reading text formats (like CSV, TSV). \ * In case of error, if both values are non-zero, \ * and at least absolute or relative amount of errors is lower than corresponding value, \ * will skip until next line and continue. \ */ \ - M(SettingUInt64, input_format_allow_errors_num, 0) \ - M(SettingFloat, input_format_allow_errors_ratio, 0) \ + M(SettingUInt64, input_format_allow_errors_num, 0, "Maximum absolute amount of errors while reading text formats (like CSV, TSV).") \ + M(SettingFloat, input_format_allow_errors_ratio, 0, "Maximum relative amount of errors while reading text formats (like CSV, TSV).") \ \ /** Use NULLs for non-joined rows of outer JOINs. \ * If false, use default value of corresponding columns data type. \ */ \ - M(SettingBool, join_use_nulls, 0) \ + M(SettingBool, join_use_nulls, 0, "Use NULLs for non-joined rows of outer JOINs. If false, use default value of corresponding columns data type.") \ /* */ \ - M(SettingUInt64, preferred_block_size_bytes, 1000000) \ + M(SettingUInt64, preferred_block_size_bytes, 1000000, "") \ /** If set, distributed queries of Replicated tables will choose servers \ * with replication delay in seconds less than the specified value (not inclusive). \ * Zero means do not take delay into account. \ */ \ \ - M(SettingUInt64, max_replica_delay_for_distributed_queries, 300) \ + M(SettingUInt64, max_replica_delay_for_distributed_queries, 300, "If set, distributed queries of Replicated tables will choose servers with replication delay in seconds less than the specified value (not inclusive).") \ /** Suppose max_replica_delay_for_distributed_queries is set and all replicas for the queried table are stale. \ * If this setting is enabled, the query will be performed anyway, otherwise the error will be reported. \ */ \ - M(SettingBool, fallback_to_stale_replicas_for_distributed_queries, 1) \ + M(SettingBool, fallback_to_stale_replicas_for_distributed_queries, 1, "") \ /** For development and testing purposes only still */ \ - M(SettingBool, distributed_ddl_allow_replicated_alter, 0) \ + M(SettingBool, distributed_ddl_allow_replicated_alter, 0, "For development and testing purposes only still.") \ /** Limit on max column size in block while reading. Helps to decrease cache misses count. \ * Should be close to L2 cache size. */ \ - M(SettingUInt64, preferred_max_column_in_block_size_bytes, 0) \ + M(SettingUInt64, preferred_max_column_in_block_size_bytes, 0, "Limit on max column size in block while reading. Helps to decrease cache misses count. Should be close to L2 cache size.") \ \ /** If setting is enabled, insert query into distributed waits until data will be sent to all nodes in cluster. \ */ \ - M(SettingBool, insert_distributed_sync, false) \ + M(SettingBool, insert_distributed_sync, false, "If setting is enabled, insert query into distributed waits until data will be sent to all nodes in cluster.") \ /** Timeout for insert query into distributed. Setting is used only with insert_distributed_sync enabled. \ * Zero value means no timeout. \ */ \ - M(SettingUInt64, insert_distributed_timeout, 0) \ + M(SettingUInt64, insert_distributed_timeout, 0, "Timeout for insert query into distributed. Setting is used only with insert_distributed_sync enabled.") \ /* Timeout for DDL query responses from all hosts in cluster. Negative value means infinite. */ \ - M(SettingInt64, distributed_ddl_task_timeout, 120) \ + M(SettingInt64, distributed_ddl_task_timeout, 120, "Timeout for DDL query responses from all hosts in cluster. Negative value means infinite.") \ \ /** If true, allow parameters of storage engines such as partitioning expression, primary key, etc. \ * to be set not in the engine parameters but as separate clauses (PARTITION BY, ORDER BY...) \ * Enable this setting to allow custom MergeTree partitions. \ */ \ - M(SettingBool, experimental_allow_extended_storage_definition_syntax, false) \ + M(SettingBool, experimental_allow_extended_storage_definition_syntax, false, "If true, allow parameters of storage engines such as partitioning expression, primary key, etc.") \ /* Timeout for flushing data from streaming storages. */ \ - M(SettingMilliseconds, stream_flush_interval_ms, DEFAULT_QUERY_LOG_FLUSH_INTERVAL_MILLISECONDS) \ + M(SettingMilliseconds, stream_flush_interval_ms, DEFAULT_QUERY_LOG_FLUSH_INTERVAL_MILLISECONDS, "Timeout for flushing data from streaming storages.") \ /* Schema identifier (used by schema-based formats) */ \ - M(SettingString, format_schema, "") + M(SettingString, format_schema, "", "Schema identifier (used by schema-based formats)") /// Possible limits for query execution. Limits limits; -#define DECLARE(TYPE, NAME, DEFAULT) \ +#define DECLARE(TYPE, NAME, DEFAULT, DESCRIPTION) \ TYPE NAME {DEFAULT}; APPLY_FOR_SETTINGS(DECLARE) diff --git a/dbms/src/Server/Benchmark.cpp b/dbms/src/Server/Benchmark.cpp index 8d7f1057a2f..f78ee521d8a 100644 --- a/dbms/src/Server/Benchmark.cpp +++ b/dbms/src/Server/Benchmark.cpp @@ -439,8 +439,8 @@ int mainEntryClickHouseBenchmark(int argc, char ** argv) ("database", value()->default_value("default"), "") ("stacktrace", "print stack traces of exceptions") - #define DECLARE_SETTING(TYPE, NAME, DEFAULT) (#NAME, boost::program_options::value (), "Settings.h") - #define DECLARE_LIMIT(TYPE, NAME, DEFAULT) (#NAME, boost::program_options::value (), "Limits.h") + #define DECLARE_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) (#NAME, boost::program_options::value (), "Settings.h") + #define DECLARE_LIMIT(TYPE, NAME, DEFAULT, DESCRIPTION) (#NAME, boost::program_options::value (), "Limits.h") APPLY_FOR_SETTINGS(DECLARE_SETTING) APPLY_FOR_LIMITS(DECLARE_LIMIT) #undef DECLARE_SETTING @@ -462,7 +462,7 @@ int mainEntryClickHouseBenchmark(int argc, char ** argv) /// Extract `settings` and `limits` from received `options` Settings settings; - #define EXTRACT_SETTING(TYPE, NAME, DEFAULT) \ + #define EXTRACT_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) \ if (options.count(#NAME)) \ settings.set(#NAME, options[#NAME].as()); APPLY_FOR_SETTINGS(EXTRACT_SETTING) diff --git a/dbms/src/Server/Client.cpp b/dbms/src/Server/Client.cpp index fbbcf265ec1..47d54dca00f 100644 --- a/dbms/src/Server/Client.cpp +++ b/dbms/src/Server/Client.cpp @@ -181,13 +181,13 @@ private: context.setApplicationType(Context::ApplicationType::CLIENT); /// settings and limits could be specified in config file, but passed settings has higher priority -#define EXTRACT_SETTING(TYPE, NAME, DEFAULT) \ +#define EXTRACT_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) \ if (config().has(#NAME) && !context.getSettingsRef().NAME.changed) \ context.setSetting(#NAME, config().getString(#NAME)); APPLY_FOR_SETTINGS(EXTRACT_SETTING) #undef EXTRACT_SETTING -#define EXTRACT_LIMIT(TYPE, NAME, DEFAULT) \ +#define EXTRACT_LIMIT(TYPE, NAME, DEFAULT, DESCRIPTION) \ if (config().has(#NAME) && !context.getSettingsRef().limits.NAME.changed) \ context.setSetting(#NAME, config().getString(#NAME)); APPLY_FOR_LIMITS(EXTRACT_LIMIT) @@ -1241,8 +1241,8 @@ public: } } -#define DECLARE_SETTING(TYPE, NAME, DEFAULT) (#NAME, boost::program_options::value (), "Settings.h") -#define DECLARE_LIMIT(TYPE, NAME, DEFAULT) (#NAME, boost::program_options::value (), "Limits.h") +#define DECLARE_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) (#NAME, boost::program_options::value (), "Settings.h") +#define DECLARE_LIMIT(TYPE, NAME, DEFAULT, DESCRIPTION) (#NAME, boost::program_options::value (), "Limits.h") /// Main commandline options related to client functionality and all parameters from Settings. boost::program_options::options_description main_description("Main options"); @@ -1331,7 +1331,7 @@ public: } /// Extract settings and limits from the options. -#define EXTRACT_SETTING(TYPE, NAME, DEFAULT) \ +#define EXTRACT_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) \ if (options.count(#NAME)) \ context.setSetting(#NAME, options[#NAME].as()); APPLY_FOR_SETTINGS(EXTRACT_SETTING) diff --git a/dbms/src/Server/LocalServer.cpp b/dbms/src/Server/LocalServer.cpp index 08202f28e3e..f4d11239f17 100644 --- a/dbms/src/Server/LocalServer.cpp +++ b/dbms/src/Server/LocalServer.cpp @@ -140,13 +140,13 @@ void LocalServer::defineOptions(Poco::Util::OptionSet& _options) /// These arrays prevent "variable tracking size limit exceeded" compiler notice. static const char * settings_names[] = { -#define DECLARE_SETTING(TYPE, NAME, DEFAULT) #NAME, +#define DECLARE_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) #NAME, APPLY_FOR_SETTINGS(DECLARE_SETTING) #undef DECLARE_SETTING nullptr}; static const char * limits_names[] = { -#define DECLARE_SETTING(TYPE, NAME, DEFAULT) #NAME, +#define DECLARE_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) #NAME, APPLY_FOR_LIMITS(DECLARE_SETTING) #undef DECLARE_SETTING nullptr}; @@ -166,13 +166,13 @@ void LocalServer::applyOptions() context->setDefaultFormat(config().getString("output-format", config().getString("format", "TSV"))); /// settings and limits could be specified in config file, but passed settings has higher priority -#define EXTRACT_SETTING(TYPE, NAME, DEFAULT) \ +#define EXTRACT_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) \ if (config().has(#NAME) && !context->getSettingsRef().NAME.changed) \ context->setSetting(#NAME, config().getString(#NAME)); APPLY_FOR_SETTINGS(EXTRACT_SETTING) #undef EXTRACT_SETTING -#define EXTRACT_LIMIT(TYPE, NAME, DEFAULT) \ +#define EXTRACT_LIMIT(TYPE, NAME, DEFAULT, DESCRIPTION) \ if (config().has(#NAME) && !context->getSettingsRef().limits.NAME.changed) \ context->setSetting(#NAME, config().getString(#NAME)); APPLY_FOR_LIMITS(EXTRACT_LIMIT) diff --git a/dbms/src/Server/PerformanceTest.cpp b/dbms/src/Server/PerformanceTest.cpp index a808c77ca0f..c12f30eead4 100644 --- a/dbms/src/Server/PerformanceTest.cpp +++ b/dbms/src/Server/PerformanceTest.cpp @@ -838,7 +838,7 @@ private: /// and, if found any settings in test's xml configuration /// with the same name, sets its value to settings std::map::iterator it; -#define EXTRACT_SETTING(TYPE, NAME, DEFAULT) \ +#define EXTRACT_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) \ it = settings_to_apply.find(#NAME); \ if (it != settings_to_apply.end()) \ settings.set(#NAME, settings_to_apply[#NAME]); diff --git a/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.cpp index a1290184789..897e5135a20 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.cpp @@ -108,12 +108,12 @@ Block MergeTreeBaseBlockInputStream::readFromPart() rows_to_read = std::min(rows_to_read, rows_to_read_for_max_size_column_with_filtration); } - size_t unread_rows_in_current_granule = reader.unreadRowsInCurrentGranule(); + size_t unread_rows_in_current_granule = reader.numPendingRowsInCurrentGranule(); if (unread_rows_in_current_granule >= rows_to_read) return rows_to_read; - size_t granule_to_read = (rows_to_read + reader.readRowsInCurrentGranule() + index_granularity / 2) / index_granularity; - return index_granularity * granule_to_read - reader.readRowsInCurrentGranule(); + size_t granule_to_read = (rows_to_read + reader.numReadRowsInCurrentGranule() + index_granularity / 2) / index_granularity; + return index_granularity * granule_to_read - reader.numReadRowsInCurrentGranule(); }; // read rows from reader and clear columns @@ -196,7 +196,7 @@ Block MergeTreeBaseBlockInputStream::readFromPart() if (!pre_range_reader) processNextRange(*task, *pre_reader); - size_t rows_to_read = std::min(pre_range_reader->unreadRows(), space_left); + size_t rows_to_read = std::min(pre_range_reader->numPendingRows(), space_left); size_t read_rows = pre_range_reader->read(res, rows_to_read); rows_was_read_in_last_range += read_rows; if (pre_range_reader->isReadingFinished()) @@ -263,7 +263,7 @@ Block MergeTreeBaseBlockInputStream::readFromPart() if (task->number_of_rows_to_skip) skipRows(res, *task->current_range_reader, *task, task->number_of_rows_to_skip); size_t rows_to_read = ranges_to_read.empty() - ? rows_was_read_in_last_range : task->current_range_reader->unreadRows(); + ? rows_was_read_in_last_range : task->current_range_reader->numPendingRows(); task->current_range_reader->read(res, rows_to_read); } @@ -272,7 +272,7 @@ Block MergeTreeBaseBlockInputStream::readFromPart() const auto & range = ranges_to_read[range_idx]; task->current_range_reader = reader->readRange(range.begin, range.end); size_t rows_to_read = range_idx + 1 == ranges_to_read.size() - ? rows_was_read_in_last_range : task->current_range_reader->unreadRows(); + ? rows_was_read_in_last_range : task->current_range_reader->numPendingRows(); task->current_range_reader->read(res, rows_to_read); } @@ -310,7 +310,7 @@ Block MergeTreeBaseBlockInputStream::readFromPart() /// Now we need to read the same number of rows as in prewhere. size_t rows_to_read = next_range_idx == ranges_to_read.size() - ? rows_was_read_in_last_range : (task->current_range_reader->unreadRows() - number_of_rows_to_skip); + ? rows_was_read_in_last_range : (task->current_range_reader->numPendingRows() - number_of_rows_to_skip); auto readRows = [&]() { @@ -338,7 +338,7 @@ Block MergeTreeBaseBlockInputStream::readFromPart() { auto rows_should_be_copied = pre_filter_pos - pre_filter_begin_pos; auto range_reader_with_skipped_rows = range_reader.getFutureState(number_of_rows_to_skip + rows_should_be_copied); - auto unread_rows_in_current_granule = range_reader_with_skipped_rows.unreadRowsInCurrentGranule(); + auto unread_rows_in_current_granule = range_reader_with_skipped_rows.numPendingRowsInCurrentGranule(); const size_t limit = std::min(pre_filter.size(), pre_filter_pos + unread_rows_in_current_granule); bool will_read_until_mark = unread_rows_in_current_granule == limit - pre_filter_pos; @@ -424,8 +424,7 @@ Block MergeTreeBaseBlockInputStream::readFromPart() else throw Exception{ "Illegal type " + column->getName() + " of column for filter. Must be ColumnUInt8 or ColumnConstUInt8.", - ErrorCodes::ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER - }; + ErrorCodes::ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER}; if (res) { diff --git a/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.h b/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.h index 455c0d97435..0797ecd818b 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.h +++ b/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.h @@ -1,4 +1,5 @@ #pragma once + #include #include #include diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 4415254b3c8..6ed4d39f91b 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -546,7 +546,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::read( column_names_to_read.erase(std::unique(column_names_to_read.begin(), column_names_to_read.end()), column_names_to_read.end()); res = spreadMarkRangesAmongStreamsFinal( - parts_with_ranges, + std::move(parts_with_ranges), column_names_to_read, max_block_size, settings.use_uncompressed_cache, @@ -559,7 +559,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::read( else { res = spreadMarkRangesAmongStreams( - parts_with_ranges, + std::move(parts_with_ranges), num_streams, column_names_to_read, max_block_size, @@ -585,7 +585,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::read( BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( - RangesInDataParts parts, + RangesInDataParts && parts, size_t num_streams, const Names & column_names, size_t max_block_size, @@ -605,7 +605,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( size_t sum_marks = 0; for (size_t i = 0; i < parts.size(); ++i) { - /// Let the segments be listed from right to left so that the leftmost segment can be dropped using `pop_back()`. + /// Let the ranges be listed from right to left so that the leftmost range can be dropped using `pop_back()`. std::reverse(parts[i].ranges.begin(), parts[i].ranges.end()); for (const auto & range : parts[i].ranges) @@ -655,10 +655,12 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( { size_t need_marks = min_marks_per_stream; - /// Loop parts. + /// Loop over parts. + /// We will iteratively take part or some subrange of a part from the back + /// and assign a stream to read from it. while (need_marks > 0 && !parts.empty()) { - RangesInDataPart & part = parts.back(); + RangesInDataPart part = parts.back(); size_t & marks_in_part = sum_marks_in_parts.back(); /// We will not take too few rows from a part. @@ -687,7 +689,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( } else { - /// Cycle through segments of a part. + /// Loop through ranges in part. Take enough ranges to cover "need_marks". while (need_marks > 0) { if (part.ranges.empty()) @@ -725,7 +727,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( } BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsFinal( - RangesInDataParts parts, + RangesInDataParts && parts, const Names & column_names, size_t max_block_size, bool use_uncompressed_cache, diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h index 1e1c48223df..7143e92fec3 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h @@ -36,7 +36,7 @@ private: Logger * log; BlockInputStreams spreadMarkRangesAmongStreams( - RangesInDataParts parts, + RangesInDataParts && parts, size_t num_streams, const Names & column_names, size_t max_block_size, @@ -47,7 +47,7 @@ private: const Settings & settings) const; BlockInputStreams spreadMarkRangesAmongStreamsFinal( - RangesInDataParts parts, + RangesInDataParts && parts, const Names & column_names, size_t max_block_size, bool use_uncompressed_cache, diff --git a/dbms/src/Storages/MergeTree/MergeTreePartChecker.cpp b/dbms/src/Storages/MergeTree/MergeTreePartChecker.cpp index 6ce836828e8..2d039189cb6 100644 --- a/dbms/src/Storages/MergeTree/MergeTreePartChecker.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreePartChecker.cpp @@ -74,7 +74,6 @@ public: size_t read(size_t rows) { ColumnPtr column = type->createColumn(); - type->deserializeBinaryBulk(*column, uncompressed_hashing_buf, rows, 0); return column->size(); } diff --git a/dbms/src/Storages/MergeTree/MergeTreeRangeReader.cpp b/dbms/src/Storages/MergeTree/MergeTreeRangeReader.cpp index 93dcd0ef370..3e6e4927829 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeRangeReader.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeRangeReader.cpp @@ -6,13 +6,13 @@ namespace DB MergeTreeRangeReader::MergeTreeRangeReader( MergeTreeReader & merge_tree_reader, size_t from_mark, size_t to_mark, size_t index_granularity) : merge_tree_reader(merge_tree_reader), current_mark(from_mark), last_mark(to_mark) - , read_rows_after_current_mark(0), index_granularity(index_granularity), continue_reading(false), is_reading_finished(false) + , index_granularity(index_granularity) { } size_t MergeTreeRangeReader::skipToNextMark() { - auto unread_rows_in_current_part = unreadRowsInCurrentGranule(); + auto unread_rows_in_current_part = numPendingRowsInCurrentGranule(); continue_reading = false; ++current_mark; if (current_mark == last_mark) @@ -33,10 +33,10 @@ MergeTreeRangeReader MergeTreeRangeReader::getFutureState(size_t rows_to_read) c size_t MergeTreeRangeReader::read(Block & res, size_t max_rows_to_read) { - size_t rows_to_read = unreadRows(); + size_t rows_to_read = numPendingRows(); rows_to_read = std::min(rows_to_read, max_rows_to_read); if (rows_to_read == 0) - return 0; + throw Exception("Logical error: 0 rows to read.", ErrorCodes::LOGICAL_ERROR); auto read_rows = merge_tree_reader.get().readRows(current_mark, continue_reading, rows_to_read, res); diff --git a/dbms/src/Storages/MergeTree/MergeTreeRangeReader.h b/dbms/src/Storages/MergeTree/MergeTreeRangeReader.h index d05f704fd89..0d8b5357c28 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeRangeReader.h +++ b/dbms/src/Storages/MergeTree/MergeTreeRangeReader.h @@ -13,10 +13,10 @@ class MergeTreeReader; class MergeTreeRangeReader { public: - size_t unreadRows() const { return (last_mark - current_mark) * index_granularity - read_rows_after_current_mark; } - size_t unreadRowsInCurrentGranule() const { return index_granularity - read_rows_after_current_mark; } + size_t numPendingRows() const { return (last_mark - current_mark) * index_granularity - read_rows_after_current_mark; } + size_t numPendingRowsInCurrentGranule() const { return index_granularity - read_rows_after_current_mark; } - size_t readRowsInCurrentGranule() const { return read_rows_after_current_mark; } + size_t numReadRowsInCurrentGranule() const { return read_rows_after_current_mark; } /// Seek to next mark before next reading. size_t skipToNextMark(); @@ -41,10 +41,10 @@ private: std::reference_wrapper merge_tree_reader; size_t current_mark; size_t last_mark; - size_t read_rows_after_current_mark; + size_t read_rows_after_current_mark = 0; size_t index_granularity; - bool continue_reading; - bool is_reading_finished; + bool continue_reading = false; + bool is_reading_finished = false; friend class MergeTreeReader; }; diff --git a/dbms/src/Storages/MergeTree/MergeTreeReader.cpp b/dbms/src/Storages/MergeTree/MergeTreeReader.cpp index 425bdeeabdc..b4407ca4028 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReader.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeReader.cpp @@ -22,12 +22,6 @@ namespace using OffsetColumns = std::map; constexpr auto DATA_FILE_EXTENSION = ".bin"; - constexpr auto NULL_MAP_EXTENSION = ".null.bin"; - - bool isNullStream(const std::string & extension) - { - return extension == NULL_MAP_EXTENSION; - } } namespace ErrorCodes @@ -58,7 +52,7 @@ MergeTreeReader::MergeTreeReader(const String & path, throw Exception("Part " + path + " is missing", ErrorCodes::NOT_FOUND_EXPECTED_DATA_PART); for (const NameAndTypePair & column : columns) - addStream(column.name, *column.type, all_mark_ranges, profile_callback, clock_type); + addStreams(column.name, *column.type, all_mark_ranges, profile_callback, clock_type); } catch (...) { @@ -93,9 +87,6 @@ size_t MergeTreeReader::readRows(size_t from_mark, bool continue_reading, size_t for (const NameAndTypePair & it : columns) { - if (streams.end() == streams.find(it.name)) - continue; - /// The column is already present in the block so we will append the values to the end. bool append = res.has(it.name); @@ -145,8 +136,13 @@ size_t MergeTreeReader::readRows(size_t from_mark, bool continue_reading, size_t try { size_t column_size_before_reading = column.column->size(); - readData(column.name, *column.type, *column.column, from_mark, continue_reading, max_rows_to_read, 0, read_offsets); - read_rows = std::max(read_rows, column.column->size() - column_size_before_reading); + + readData(column.name, *column.type, *column.column, from_mark, continue_reading, max_rows_to_read, read_offsets); + + /// For elements of Nested, column_size_before_reading may be greater than column size + /// if offsets are not empty and were already read, but elements are empty. + if (column.column->size()) + read_rows = std::max(read_rows, column.column->size() - column_size_before_reading); } catch (Exception & e) { @@ -272,12 +268,6 @@ MergeTreeReader::Stream::Stream( } } -std::unique_ptr MergeTreeReader::Stream::createEmptyPtr() -{ - std::unique_ptr res(new Stream); - res->is_empty = true; - return res; -} const MarkInCompressedFile & MergeTreeReader::Stream::getMark(size_t index) { @@ -286,14 +276,10 @@ const MarkInCompressedFile & MergeTreeReader::Stream::getMark(size_t index) return (*marks)[index]; } + void MergeTreeReader::Stream::loadMarks() { - std::string path; - - if (isNullStream(extension)) - path = path_prefix + ".null.mrk"; - else - path = path_prefix + ".mrk"; + std::string path = path_prefix + ".mrk"; auto load = [&]() -> MarkCache::MappedPtr { @@ -304,8 +290,8 @@ void MergeTreeReader::Stream::loadMarks() size_t expected_file_size = sizeof(MarkInCompressedFile) * marks_count; if (expected_file_size != file_size) throw Exception( - "bad size of marks file `" + path + "':" + std::to_string(file_size) + ", must be: " + std::to_string(expected_file_size), - ErrorCodes::CORRUPTED_DATA); + "bad size of marks file `" + path + "':" + std::to_string(file_size) + ", must be: " + std::to_string(expected_file_size), + ErrorCodes::CORRUPTED_DATA); auto res = std::make_shared(marks_count); @@ -365,167 +351,94 @@ void MergeTreeReader::Stream::seekToMark(size_t index) } -void MergeTreeReader::addStream(const String & name, const IDataType & type, const MarkRanges & all_mark_ranges, - const ReadBufferFromFileBase::ProfileCallback & profile_callback, clockid_t clock_type, - size_t level) +void MergeTreeReader::addStreams(const String & name, const IDataType & type, const MarkRanges & all_mark_ranges, + const ReadBufferFromFileBase::ProfileCallback & profile_callback, clockid_t clock_type) { - String escaped_column_name = escapeForFileName(name); - - const DataTypeArray * type_arr = typeid_cast(&type); - bool data_file_exists = Poco::File(path + escaped_column_name + DATA_FILE_EXTENSION).exists(); - bool is_column_of_nested_type = type_arr && level == 0 && DataTypeNested::extractNestedTableName(name) != name; - - /** If data file is missing then we will not try to open it. - * It is necessary since it allows to add new column to structure of the table without creating new files for old parts. - * But we should try to load offset data for array columns of Nested subtable (their data will be filled by default value). - */ - if (!data_file_exists && !is_column_of_nested_type) - return; - - if (type.isNullable()) + IDataType::StreamCallback callback = [&] (const IDataType::SubstreamPath & substream_path) { - /// First create the stream that handles the null map of the given column. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); + String stream_name = IDataType::getFileNameForStream(name, substream_path); - std::string filename = name + NULL_MAP_EXTENSION; - - streams.emplace(filename, std::make_unique( - path + escaped_column_name, NULL_MAP_EXTENSION, data_part->marks_count, - all_mark_ranges, mark_cache, save_marks_in_cache, - uncompressed_cache, aio_threshold, max_read_buffer_size, profile_callback, clock_type)); - - /// Then create the stream that handles the data of the given column. - addStream(name, nested_type, all_mark_ranges, profile_callback, clock_type, level); - } - /// For arrays separate streams for sizes are used. - else if (type_arr) - { - String size_name = DataTypeNested::extractNestedTableName(name) - + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - String escaped_size_name = escapeForFileName(DataTypeNested::extractNestedTableName(name)) - + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - String size_path = path + escaped_size_name + DATA_FILE_EXTENSION; - - /// We have neither offsets nor data -> skipping, default values will be filled after - if (!data_file_exists && !Poco::File(size_path).exists()) + if (streams.count(stream_name)) return; - if (!streams.count(size_name)) - streams.emplace(size_name, std::make_unique( - path + escaped_size_name, DATA_FILE_EXTENSION, data_part->marks_count, - all_mark_ranges, mark_cache, save_marks_in_cache, - uncompressed_cache, aio_threshold, max_read_buffer_size, profile_callback, clock_type)); + bool data_file_exists = Poco::File(path + stream_name + DATA_FILE_EXTENSION).exists(); - if (data_file_exists) - addStream(name, *type_arr->getNestedType(), all_mark_ranges, profile_callback, clock_type, level + 1); - else - streams.emplace(name, Stream::createEmptyPtr()); - } - else - streams.emplace(name, std::make_unique( - path + escaped_column_name, DATA_FILE_EXTENSION, data_part->marks_count, + /** If data file is missing then we will not try to open it. + * It is necessary since it allows to add new column to structure of the table without creating new files for old parts. + */ + if (!data_file_exists) + return; + + streams.emplace(stream_name, std::make_unique( + path + stream_name, DATA_FILE_EXTENSION, data_part->marks_count, all_mark_ranges, mark_cache, save_marks_in_cache, uncompressed_cache, aio_threshold, max_read_buffer_size, profile_callback, clock_type)); + }; + + type.enumerateStreams(callback, {}); } void MergeTreeReader::readData( const String & name, const IDataType & type, IColumn & column, size_t from_mark, bool continue_reading, size_t max_rows_to_read, - size_t level, bool read_offsets) + bool with_offsets) { - if (type.isNullable()) + IDataType::InputStreamGetter stream_getter = [&] (const IDataType::SubstreamPath & path) -> ReadBuffer * { - /// First read from the null map. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); + /// If offsets for arrays have already been read. + if (!with_offsets && !path.empty() && path.back().type == IDataType::Substream::ArraySizes) + return nullptr; - ColumnNullable & nullable_col = static_cast(column); - IColumn & nested_col = *nullable_col.getNestedColumn(); + String stream_name = IDataType::getFileNameForStream(name, path); - std::string filename = name + NULL_MAP_EXTENSION; + auto it = streams.find(stream_name); + if (it == streams.end()) + return nullptr; + + Stream & stream = *it->second; - Stream & stream = *(streams.at(filename)); if (!continue_reading) stream.seekToMark(from_mark); - IColumn & col8 = nullable_col.getNullMapConcreteColumn(); - DataTypeUInt8{}.deserializeBinaryBulk(col8, *stream.data_buffer, max_rows_to_read, 0); - /// Then read data. - readData(name, nested_type, nested_col, from_mark, continue_reading, max_rows_to_read, level, read_offsets); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /// For arrays the sizes must be deserialized first, then the values. - if (read_offsets) - { - Stream & stream = *streams[DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level)]; - if (!continue_reading) - stream.seekToMark(from_mark); - type_arr->deserializeOffsets( - column, - *stream.data_buffer, - max_rows_to_read); - } + return stream.data_buffer; + }; - ColumnArray & array = typeid_cast(column); - const size_t required_internal_size = array.getOffsets().size() ? array.getOffsets()[array.getOffsets().size() - 1] : 0; + double & avg_value_size_hint = avg_value_size_hints[name]; + type.deserializeBinaryBulkWithMultipleStreams(column, stream_getter, max_rows_to_read, avg_value_size_hint, true, {}); + IDataType::updateAvgValueSizeHint(column, avg_value_size_hint); +} - readData( - name, - *type_arr->getNestedType(), - array.getData(), - from_mark, continue_reading, required_internal_size - array.getData().size(), - level + 1); - size_t read_internal_size = array.getData().size(); +static bool arrayHasNoElementsRead(const IColumn & column) +{ + const ColumnArray * column_array = typeid_cast(&column); - /// Fix for erroneously written empty files with array data. - /// This can happen after ALTER that adds new columns to nested data structures. - if (required_internal_size != read_internal_size) - { - if (read_internal_size != 0) - LOG_ERROR(&Logger::get("MergeTreeReader"), - "Internal size of array " + name + " doesn't match offsets: corrupted data, filling with default values."); + if (!column_array) + return false; - array.getDataPtr() = type_arr->getNestedType()->createConstColumn( - required_internal_size, - type_arr->getNestedType()->getDefault())->convertToFullColumnIfConst(); + size_t size = column_array->size(); + if (!size) + return false; - /// NOTE: we could zero this column so that it won't get added to the block - /// and later be recreated with more correct default values (from the table definition). - } - } - else - { - Stream & stream = *streams[name]; + size_t data_size = column_array->getData().size(); + if (data_size) + return false; - /// It means that data column of array column will be empty, and it will be replaced by const data column - if (stream.isEmpty()) - return; - - double & avg_value_size_hint = avg_value_size_hints[name]; - if (!continue_reading) - stream.seekToMark(from_mark); - type.deserializeBinaryBulk(column, *stream.data_buffer, max_rows_to_read, avg_value_size_hint); - - IDataType::updateAvgValueSizeHint(column, avg_value_size_hint); - } + size_t last_offset = column_array->getOffsets()[size - 1]; + return last_offset != 0; } void MergeTreeReader::fillMissingColumns(Block & res, const Names & ordered_names, bool always_reorder) { if (!res) - throw Exception("Empty block passed to fillMissingColumnsImpl", ErrorCodes::LOGICAL_ERROR); + throw Exception("Empty block passed to fillMissingColumns", ErrorCodes::LOGICAL_ERROR); try { /// For a missing column of a nested data structure we must create not a column of empty /// arrays, but a column of arrays of correct length. - /// TODO: If for some nested data structure only missing columns were selected, the arrays in these columns will be empty, - /// even if the offsets for this nested structure are present in the current part. This can be fixed. /// NOTE: Similar, but slightly different code is present in Block::addDefaults. /// First, collect offset columns for all arrays in the block. @@ -534,23 +447,9 @@ void MergeTreeReader::fillMissingColumns(Block & res, const Names & ordered_name { const ColumnWithTypeAndName & column = res.safeGetByPosition(i); - IColumn * observed_column; - std::string column_name; - if (column.column->isNullable()) + if (const ColumnArray * array = typeid_cast(column.column.get())) { - ColumnNullable & nullable_col = static_cast(*(column.column)); - observed_column = nullable_col.getNestedColumn().get(); - column_name = observed_column->getName(); - } - else - { - observed_column = column.column.get(); - column_name = column.name; - } - - if (const ColumnArray * array = typeid_cast(observed_column)) - { - String offsets_name = DataTypeNested::extractNestedTableName(column_name); + String offsets_name = DataTypeNested::extractNestedTableName(column.name); auto & offsets_column = offset_columns[offsets_name]; /// If for some reason multiple offsets columns are present for the same nested data structure, @@ -560,13 +459,26 @@ void MergeTreeReader::fillMissingColumns(Block & res, const Names & ordered_name } } - auto should_evaluate_defaults = false; - auto should_sort = always_reorder; + bool should_evaluate_defaults = false; + bool should_sort = always_reorder; + size_t rows = res.rows(); + + /// insert default values only for columns without default expressions for (const auto & requested_column : columns) { - /// insert default values only for columns without default expressions - if (!res.has(requested_column.name)) + bool has_column = res.has(requested_column.name); + if (has_column) + { + const auto & col = *res.getByName(requested_column.name).column; + if (arrayHasNoElementsRead(col)) + { + res.erase(requested_column.name); + has_column = false; + } + } + + if (!has_column) { should_sort = true; if (storage.column_defaults.count(requested_column.name) != 0) @@ -597,7 +509,7 @@ void MergeTreeReader::fillMissingColumns(Block & res, const Names & ordered_name /// We must turn a constant column into a full column because the interpreter could infer that it is constant everywhere /// but in some blocks (from other parts) it can be a full column. column_to_add.column = column_to_add.type->createConstColumn( - res.rows(), column_to_add.type->getDefault())->convertToFullColumnIfConst(); + rows, column_to_add.type->getDefault())->convertToFullColumnIfConst(); } res.insert(std::move(column_to_add)); diff --git a/dbms/src/Storages/MergeTree/MergeTreeReader.h b/dbms/src/Storages/MergeTree/MergeTreeReader.h index 208804639e3..6f4c1f60dc2 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReader.h +++ b/dbms/src/Storages/MergeTree/MergeTreeReader.h @@ -58,12 +58,8 @@ private: size_t aio_threshold, size_t max_read_buffer_size, const ReadBufferFromFileBase::ProfileCallback & profile_callback, clockid_t clock_type); - static std::unique_ptr createEmptyPtr(); - void seekToMark(size_t index); - bool isEmpty() const { return is_empty; } - ReadBuffer * data_buffer; private: @@ -85,8 +81,6 @@ private: std::unique_ptr cached_buffer; std::unique_ptr non_cached_buffer; - - bool is_empty = false; }; using FileStreams = std::map>; @@ -111,14 +105,13 @@ private: size_t aio_threshold; size_t max_read_buffer_size; - void addStream(const String & name, const IDataType & type, const MarkRanges & all_mark_ranges, - const ReadBufferFromFileBase::ProfileCallback & profile_callback, clockid_t clock_type, - size_t level = 0); + void addStreams(const String & name, const IDataType & type, const MarkRanges & all_mark_ranges, + const ReadBufferFromFileBase::ProfileCallback & profile_callback, clockid_t clock_type); void readData( const String & name, const IDataType & type, IColumn & column, size_t from_mark, bool continue_reading, size_t max_rows_to_read, - size_t level = 0, bool read_offsets = true); + bool read_offsets = true); /// Return the number of rows has been read or zero if there is no columns to read. /// If continue_reading is true, continue reading from last state, otherwise seek to from_mark diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp index 7e086cfe6b2..fcff0213d7f 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp @@ -20,8 +20,6 @@ namespace constexpr auto DATA_FILE_EXTENSION = ".bin"; constexpr auto MARKS_FILE_EXTENSION = ".mrk"; -constexpr auto NULL_MAP_EXTENSION = ".null.bin"; -constexpr auto NULL_MARKS_FILE_EXTENSION = ".null.mrk"; } @@ -42,189 +40,46 @@ IMergedBlockOutputStream::IMergedBlockOutputStream( } -void IMergedBlockOutputStream::addStream( +void IMergedBlockOutputStream::addStreams( const String & path, const String & name, const IDataType & type, size_t estimated_size, - size_t level, - const String & filename, bool skip_offsets) { - String escaped_column_name; - if (filename.size()) - escaped_column_name = escapeForFileName(filename); - else - escaped_column_name = escapeForFileName(name); - - if (type.isNullable()) + IDataType::StreamCallback callback = [&] (const IDataType::SubstreamPath & substream_path) { - /// First create the stream that handles the null map of the given column. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); + if (skip_offsets && !substream_path.empty() && substream_path.back().type == IDataType::Substream::ArraySizes) + return; - std::string null_map_name = name + NULL_MAP_EXTENSION; - column_streams[null_map_name] = std::make_unique( - escaped_column_name, - path + escaped_column_name, NULL_MAP_EXTENSION, - path + escaped_column_name, NULL_MARKS_FILE_EXTENSION, + String stream_name = IDataType::getFileNameForStream(name, substream_path); + + /// Shared offsets for Nested type. + if (column_streams.count(stream_name)) + return; + + column_streams[stream_name] = std::make_unique( + stream_name, + path + stream_name, DATA_FILE_EXTENSION, + path + stream_name, MARKS_FILE_EXTENSION, max_compress_block_size, compression_settings, estimated_size, aio_threshold); + }; - /// Then create the stream that handles the data of the given column. - addStream(path, name, nested_type, estimated_size, level, filename, false); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - if (!skip_offsets) - { - /// For arrays, separate files are used for sizes. - String size_name = DataTypeNested::extractNestedTableName(name) - + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - String escaped_size_name = escapeForFileName(DataTypeNested::extractNestedTableName(name)) - + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - - column_streams[size_name] = std::make_unique( - escaped_size_name, - path + escaped_size_name, DATA_FILE_EXTENSION, - path + escaped_size_name, MARKS_FILE_EXTENSION, - max_compress_block_size, - compression_settings, - estimated_size, - aio_threshold); - } - - addStream(path, name, *type_arr->getNestedType(), estimated_size, level + 1, "", false); - } - else - { - column_streams[name] = std::make_unique( - escaped_column_name, - path + escaped_column_name, DATA_FILE_EXTENSION, - path + escaped_column_name, MARKS_FILE_EXTENSION, - max_compress_block_size, - compression_settings, - estimated_size, - aio_threshold); - } + type.enumerateStreams(callback, {}); } void IMergedBlockOutputStream::writeData( const String & name, - const DataTypePtr & type, - const ColumnPtr & column, + const IDataType & type, + const IColumn & column, OffsetColumns & offset_columns, - size_t level, bool skip_offsets) { - writeDataImpl(name, type, column, nullptr, offset_columns, level, skip_offsets); -} - - -void IMergedBlockOutputStream::writeDataImpl( - const String & name, - const DataTypePtr & type, - const ColumnPtr & column, - const ColumnPtr & offsets, - OffsetColumns & offset_columns, - size_t level, - bool skip_offsets) -{ - /// NOTE: the parameter write_array_data indicates whether we call this method - /// to write the contents of an array. This is to cope with the fact that - /// serialization of arrays for the MergeTree engine slightly differs from - /// what the other engines do. - - if (type->isNullable()) - { - /// First write to the null map. - const auto & nullable_type = static_cast(*type); - const auto & nested_type = nullable_type.getNestedType(); - - const auto & nullable_col = static_cast(*column); - const auto & nested_col = nullable_col.getNestedColumn(); - - std::string filename = name + NULL_MAP_EXTENSION; - ColumnStream & stream = *column_streams[filename]; - auto null_map_type = std::make_shared(); - - writeColumn(nullable_col.getNullMapColumn(), null_map_type, stream, offsets); - - /// Then write data. - writeDataImpl(name, nested_type, nested_col, offsets, offset_columns, level, skip_offsets); - } - else if (auto type_arr = typeid_cast(type.get())) - { - /// For arrays, you first need to serialize dimensions, and then values. - String size_name = DataTypeNested::extractNestedTableName(name) - + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - - const auto & column_array = typeid_cast(*column); - - ColumnPtr next_level_offsets; - ColumnPtr lengths_column; - - auto offsets_data_type = std::make_shared>(); - - if (offsets) - { - /// Have offsets from prev level. Calculate offsets for next level. - next_level_offsets = offsets->clone(); - const auto & array_offsets = column_array.getOffsets(); - auto & next_level_offsets_column = typeid_cast(*next_level_offsets); - auto & next_level_offsets_data = next_level_offsets_column.getData(); - for (auto & offset : next_level_offsets_data) - offset = offset ? array_offsets[offset - 1] : 0; - - /// Calculate lengths of arrays and write them as a new array. - lengths_column = column_array.getLengthsColumn(); - } - - if (!skip_offsets && offset_columns.count(size_name) == 0) - { - offset_columns.insert(size_name); - - ColumnStream & stream = *column_streams[size_name]; - if (offsets) - writeColumn(lengths_column, offsets_data_type, stream, offsets); - else - writeColumn(column, type, stream, nullptr); - } - - writeDataImpl(name, type_arr->getNestedType(), column_array.getDataPtr(), - offsets ? next_level_offsets : column_array.getOffsetsColumn(), - offset_columns, level + 1, skip_offsets); - } - else - { - ColumnStream & stream = *column_streams[name]; - writeColumn(column, type, stream, offsets); - } -} - -void IMergedBlockOutputStream::writeColumn( - const ColumnPtr & column, - const DataTypePtr & type, - IMergedBlockOutputStream::ColumnStream & stream, - ColumnPtr offsets) -{ - std::shared_ptr array_type_holder; - DataTypeArray * array_type; - ColumnPtr array_column; - - if (offsets) - { - array_type_holder = std::make_shared(type); - array_type = array_type_holder.get(); - array_column = std::make_shared(column, offsets); - } - else - array_type = typeid_cast(type.get()); - - size_t size = offsets ? offsets->size() : column->size(); + size_t size = column.size(); size_t prev_mark = 0; while (prev_mark < size) { @@ -237,26 +92,76 @@ void IMergedBlockOutputStream::writeColumn( { limit = storage.index_granularity; - /// There could already be enough data to compress into the new block. - if (stream.compressed.offset() >= min_compress_block_size) - stream.compressed.next(); + /// Write marks. + type.enumerateStreams([&] (const IDataType::SubstreamPath & substream_path) + { + bool is_offsets = !substream_path.empty() && substream_path.back().type == IDataType::Substream::ArraySizes; + if (is_offsets && skip_offsets) + return; - writeIntBinary(stream.plain_hashing.count(), stream.marks); - writeIntBinary(stream.compressed.offset(), stream.marks); + String stream_name = IDataType::getFileNameForStream(name, substream_path); + + /// Don't write offsets more than one time for Nested type. + if (is_offsets && offset_columns.count(stream_name)) + return; + + ColumnStream & stream = *column_streams[stream_name]; + + /// There could already be enough data to compress into the new block. + if (stream.compressed.offset() >= min_compress_block_size) + stream.compressed.next(); + + writeIntBinary(stream.plain_hashing.count(), stream.marks); + writeIntBinary(stream.compressed.offset(), stream.marks); + }, {}); } - if (offsets) - array_type->serializeBinaryBulk(*array_column, stream.compressed, prev_mark, limit); - else if (array_type) - array_type->serializeOffsets(*column, stream.compressed, prev_mark, limit); - else - type->serializeBinaryBulk(*column, stream.compressed, prev_mark, limit); + IDataType::OutputStreamGetter stream_getter = [&] (const IDataType::SubstreamPath & substream_path) -> WriteBuffer * + { + bool is_offsets = !substream_path.empty() && substream_path.back().type == IDataType::Substream::ArraySizes; + if (is_offsets && skip_offsets) + return nullptr; + + String stream_name = IDataType::getFileNameForStream(name, substream_path); + + /// Don't write offsets more than one time for Nested type. + if (is_offsets && offset_columns.count(stream_name)) + return nullptr; + + return &column_streams[stream_name]->compressed; + }; + + type.serializeBinaryBulkWithMultipleStreams(column, stream_getter, prev_mark, limit, true, {}); /// So that instead of the marks pointing to the end of the compressed block, there were marks pointing to the beginning of the next one. - stream.compressed.nextIfAtEnd(); + type.enumerateStreams([&] (const IDataType::SubstreamPath & substream_path) + { + bool is_offsets = !substream_path.empty() && substream_path.back().type == IDataType::Substream::ArraySizes; + if (is_offsets && skip_offsets) + return; + + String stream_name = IDataType::getFileNameForStream(name, substream_path); + + /// Don't write offsets more than one time for Nested type. + if (is_offsets && offset_columns.count(stream_name)) + return; + + column_streams[stream_name]->compressed.nextIfAtEnd(); + }, {}); prev_mark += limit; } + + /// Memoize offsets for Nested types, that are already written. They will not be written again for next columns of Nested structure. + type.enumerateStreams([&] (const IDataType::SubstreamPath & substream_path) + { + bool is_offsets = !substream_path.empty() && substream_path.back().type == IDataType::Substream::ArraySizes; + if (is_offsets) + { + String stream_name = IDataType::getFileNameForStream(name, substream_path); + offset_columns.insert(stream_name); + } + }, {}); } @@ -324,7 +229,7 @@ MergedBlockOutputStream::MergedBlockOutputStream( { init(); for (const auto & it : columns_list) - addStream(part_path, it.name, *it.type, 0, 0, "", false); + addStreams(part_path, it.name, *it.type, 0, false); } MergedBlockOutputStream::MergedBlockOutputStream( @@ -350,7 +255,7 @@ MergedBlockOutputStream::MergedBlockOutputStream( if (it2 != merged_column_to_size_.end()) estimated_size = it2->second; } - addStream(part_path, it.name, *it.type, estimated_size, 0, "", false); + addStreams(part_path, it.name, *it.type, estimated_size, false); } } @@ -467,7 +372,7 @@ void MergedBlockOutputStream::writeImpl(const Block & block, const IColumn::Perm block.checkNumberOfRows(); size_t rows = block.rows(); - /// The set of written offset columns so that you do not write mutual to nested structures columns several times + /// The set of written offset columns so that you do not write shared offsets of nested structures columns several times OffsetColumns offset_columns; auto sort_description = storage.getSortDescription(); @@ -513,18 +418,18 @@ void MergedBlockOutputStream::writeImpl(const Block & block, const IColumn::Perm auto primary_column_it = primary_columns_name_to_position.find(it.name); if (primary_columns_name_to_position.end() != primary_column_it) { - writeData(column.name, column.type, primary_columns[primary_column_it->second].column, offset_columns, 0, false); + writeData(column.name, *column.type, *primary_columns[primary_column_it->second].column, offset_columns, false); } else { /// We rearrange the columns that are not included in the primary key here; Then the result is released - to save RAM. ColumnPtr permutted_column = column.column->permute(*permutation, 0); - writeData(column.name, column.type, permutted_column, offset_columns, 0, false); + writeData(column.name, *column.type, *permutted_column, offset_columns, false); } } else { - writeData(column.name, column.type, column.column, offset_columns, 0, false); + writeData(column.name, *column.type, *column.column, offset_columns, false); } } @@ -580,8 +485,8 @@ void MergedColumnOnlyOutputStream::write(const Block & block) column_streams.clear(); for (size_t i = 0; i < block.columns(); ++i) { - addStream(part_path, block.safeGetByPosition(i).name, - *block.safeGetByPosition(i).type, 0, 0, block.safeGetByPosition(i).name, skip_offsets); + addStreams(part_path, block.safeGetByPosition(i).name, + *block.safeGetByPosition(i).type, 0, skip_offsets); } initialized = true; } @@ -592,7 +497,7 @@ void MergedColumnOnlyOutputStream::write(const Block & block) for (size_t i = 0; i < block.columns(); ++i) { const ColumnWithTypeAndName & column = block.safeGetByPosition(i); - writeData(column.name, column.type, column.column, offset_columns, 0, skip_offsets); + writeData(column.name, *column.type, *column.column, offset_columns, skip_offsets); } size_t written_for_last_mark = (storage.index_granularity - index_offset + rows) % storage.index_granularity; diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h index c28d368b00e..ddaf53b4677 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h @@ -62,12 +62,10 @@ protected: using ColumnStreams = std::map>; - void addStream(const String & path, const String & name, const IDataType & type, size_t estimated_size, - size_t level, const String & filename, bool skip_offsets); + void addStreams(const String & path, const String & name, const IDataType & type, size_t estimated_size, bool skip_offsets); /// Write data of one column. - void writeData(const String & name, const DataTypePtr & type, const ColumnPtr & column, - OffsetColumns & offset_columns, size_t level, bool skip_offsets); + void writeData(const String & name, const IDataType & type, const IColumn & column, OffsetColumns & offset_columns, bool skip_offsets); MergeTreeData & storage; @@ -82,21 +80,13 @@ protected: size_t aio_threshold; CompressionSettings compression_settings; - -private: - /// Internal version of writeData. - void writeDataImpl(const String & name, const DataTypePtr & type, const ColumnPtr & column, - const ColumnPtr & offsets, OffsetColumns & offset_columns, size_t level, bool skip_offsets); - /// Writes column data into stream. - /// If type is Array, writes offsets only. To write array data, unpack array column and use offsets argument. - void writeColumn(const ColumnPtr & column, const DataTypePtr & type, ColumnStream & stream, ColumnPtr offsets); }; /** To write one part. * The data refers to one partition, and is written in one part. */ -class MergedBlockOutputStream : public IMergedBlockOutputStream +class MergedBlockOutputStream final : public IMergedBlockOutputStream { public: MergedBlockOutputStream( @@ -118,7 +108,7 @@ public: /// If the data is pre-sorted. void write(const Block & block) override; - /** If the data is not sorted, but we have previously calculated the permutation, after which they will be sorted. + /** If the data is not sorted, but we have previously calculated the permutation, that will sort it. * This method is used to save RAM, since you do not need to keep two blocks at once - the original one and the sorted one. */ void writeWithPermutation(const Block & block, const IColumn::Permutation * permutation); @@ -155,7 +145,7 @@ private: /// Writes only those columns that are in `block` -class MergedColumnOnlyOutputStream : public IMergedBlockOutputStream +class MergedColumnOnlyOutputStream final : public IMergedBlockOutputStream { public: MergedColumnOnlyOutputStream( diff --git a/dbms/src/Storages/StorageLog.cpp b/dbms/src/Storages/StorageLog.cpp index 93af0b9a8c4..40bafa176d6 100644 --- a/dbms/src/Storages/StorageLog.cpp +++ b/dbms/src/Storages/StorageLog.cpp @@ -20,7 +20,6 @@ #include #include -#include #include @@ -31,10 +30,7 @@ #define DBMS_STORAGE_LOG_DATA_FILE_EXTENSION ".bin" -#define DBMS_STORAGE_LOG_MARKS_FILE_EXTENSION ".mrk" #define DBMS_STORAGE_LOG_MARKS_FILE_NAME "__marks.mrk" -#define DBMS_STORAGE_LOG_NULL_MARKS_FILE_NAME "__null_marks.mrk" -#define DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION ".null.bin" namespace DB @@ -44,6 +40,7 @@ namespace ErrorCodes { extern const int LOGICAL_ERROR; extern const int EMPTY_LIST_OF_COLUMNS_PASSED; + extern const int NO_SUCH_COLUMN_IN_TABLE; extern const int DUPLICATE_COLUMN; extern const int SIZES_OF_MARKS_FILES_ARE_INCONSISTENT; } @@ -60,21 +57,6 @@ public: column_types(column_names.size()), storage(storage_), mark_number(mark_number_), - null_mark_number(0), - rows_limit(rows_limit_), - max_read_buffer_size(max_read_buffer_size_) - { - } - - LogBlockInputStream( - size_t block_size_, const Names & column_names_, StorageLog & storage_, - size_t mark_number_, size_t null_mark_number_, size_t rows_limit_, size_t max_read_buffer_size_) - : block_size(block_size_), - column_names(column_names_), - column_types(column_names.size()), - storage(storage_), - mark_number(mark_number_), - null_mark_number(null_mark_number_), rows_limit(rows_limit_), max_read_buffer_size(max_read_buffer_size_) { @@ -103,7 +85,6 @@ private: DataTypes column_types; StorageLog & storage; size_t mark_number; /// from what mark to read data - size_t null_mark_number; size_t rows_limit; /// The maximum number of rows that can be read size_t rows_read = 0; size_t max_read_buffer_size; @@ -122,11 +103,10 @@ private: CompressedReadBuffer compressed; }; - using FileStreams = std::map>; + using FileStreams = std::map; FileStreams streams; - void addStream(const String & name, const IDataType & type, size_t level = 0); - void readData(const String & name, const IDataType & type, IColumn & column, size_t max_rows_to_read, size_t level = 0, bool read_offsets = true); + void readData(const String & name, const IDataType & type, IColumn & column, size_t max_rows_to_read, bool read_offsets = true); }; @@ -136,12 +116,8 @@ public: explicit LogBlockOutputStream(StorageLog & storage_) : storage(storage_), lock(storage.rwlock), - marks_stream(storage.marks_file.path(), 4096, O_APPEND | O_CREAT | O_WRONLY), - null_marks_stream(storage.has_nullable_columns ? - std::make_unique(storage.null_marks_file.path(), 4096, O_APPEND | O_CREAT | O_WRONLY) : nullptr) + marks_stream(storage.marks_file.path(), 4096, O_APPEND | O_CREAT | O_WRONLY) { - for (const auto & column : storage.getColumnsList()) - addStream(column.name, *column.type); } ~LogBlockOutputStream() override @@ -185,22 +161,21 @@ private: } }; + using Mark = StorageLog::Mark; using MarksForColumns = std::vector>; - using FileStreams = std::map>; + using FileStreams = std::map; FileStreams streams; - using OffsetColumns = std::set; + using WrittenStreams = std::set; WriteBufferFromFile marks_stream; /// Declared below `lock` to make the file open when rwlock is captured. - std::unique_ptr null_marks_stream; - void addStream(const String & name, const IDataType & type, size_t level = 0); - void addNullStream(const String & name); void writeData(const String & name, const IDataType & type, const IColumn & column, - MarksForColumns & out_marks, MarksForColumns & out_null_marks, - OffsetColumns & offset_columns, size_t level = 0); - void writeMarks(MarksForColumns marks, bool write_null_marks); + MarksForColumns & out_marks, + WrittenStreams & written_streams); + + void writeMarks(MarksForColumns && marks); }; @@ -218,20 +193,17 @@ Block LogBlockInputStream::readImpl() /// If the files are not open, then open them. if (streams.empty()) { - std::shared_lock lock(storage.rwlock); - for (size_t i = 0, size = column_names.size(); i < size; ++i) { const auto & name = column_names[i]; column_types[i] = storage.getDataTypeByName(name); - addStream(name, *column_types[i]); } } /// How many rows to read for the next block. size_t max_rows_to_read = std::min(block_size, rows_limit - rows_read); - /// Pointers to offset columns, mutual for columns from nested data structures + /// Pointers to offset columns, shared for columns from nested data structures using OffsetColumns = std::map; OffsetColumns offset_columns; @@ -245,23 +217,8 @@ Block LogBlockInputStream::readImpl() bool read_offsets = true; - const IDataType * observed_type; - bool is_nullable; - - if (column.type->isNullable()) - { - const DataTypeNullable & nullable_type = static_cast(*column.type); - observed_type = nullable_type.getNestedType().get(); - is_nullable = true; - } - else - { - observed_type = column.type.get(); - is_nullable = false; - } - /// For nested structures, remember pointers to columns with offsets - if (const DataTypeArray * type_arr = typeid_cast(observed_type)) + if (const DataTypeArray * type_arr = typeid_cast(column.type.get())) { String name = DataTypeNested::extractNestedTableName(column.name); @@ -271,15 +228,13 @@ Block LogBlockInputStream::readImpl() read_offsets = false; /// on previous iterations the offsets were already read by `readData` column.column = std::make_shared(type_arr->getNestedType()->createColumn(), offset_columns[name]); - if (is_nullable) - column.column = std::make_shared(column.column, std::make_shared()); } else column.column = column.type->createColumn(); try { - readData(name, *column.type, *column.column, max_rows_to_read, 0, read_offsets); + readData(name, *column.type, *column.column, max_rows_to_read, read_offsets); } catch (Exception & e) { @@ -307,88 +262,30 @@ Block LogBlockInputStream::readImpl() } -void LogBlockInputStream::addStream(const String & name, const IDataType & type, size_t level) +void LogBlockInputStream::readData(const String & name, const IDataType & type, IColumn & column, size_t max_rows_to_read, bool with_offsets) { - if (type.isNullable()) + IDataType::InputStreamGetter stream_getter = [&] (const IDataType::SubstreamPath & path) -> ReadBuffer * { - /// First create the stream that handles the null map of the given column. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); + if (!with_offsets && !path.empty() && path.back().type == IDataType::Substream::ArraySizes) + return nullptr; - std::string filename = name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION; + String stream_name = IDataType::getFileNameForStream(name, path); - streams.emplace(filename, std::make_unique( - storage.files[filename].data_file.path(), - null_mark_number - ? storage.files[filename].marks[null_mark_number].offset - : 0, - max_read_buffer_size)); + const auto & file_it = storage.files.find(stream_name); + if (storage.files.end() == file_it) + throw Exception("Logical error: no information about file " + stream_name + " in StorageLog", ErrorCodes::LOGICAL_ERROR); - /// Then create the stream that handles the data of the given column. - addStream(name, nested_type, level); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /// For arrays, separate files are used for sizes. - String size_name = DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - if (!streams.count(size_name)) - streams.emplace(size_name, std::unique_ptr(new Stream( - storage.files[size_name].data_file.path(), - mark_number - ? storage.files[size_name].marks[mark_number].offset - : 0, - max_read_buffer_size))); - - addStream(name, *type_arr->getNestedType(), level + 1); - } - else - streams[name] = std::make_unique( - storage.files[name].data_file.path(), + auto it = streams.try_emplace(stream_name, + file_it->second.data_file.path(), mark_number - ? storage.files[name].marks[mark_number].offset + ? file_it->second.marks[mark_number].offset : 0, - max_read_buffer_size); -} + max_read_buffer_size).first; + return &it->second.compressed; + }; -void LogBlockInputStream::readData(const String & name, const IDataType & type, IColumn & column, size_t max_rows_to_read, - size_t level, bool read_offsets) -{ - if (type.isNullable()) - { - /// First read from the null map. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); - - ColumnNullable & nullable_col = static_cast(column); - IColumn & nested_col = *nullable_col.getNestedColumn(); - - DataTypeUInt8{}.deserializeBinaryBulk(nullable_col.getNullMapConcreteColumn(), - streams[name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION]->compressed, max_rows_to_read, 0); - /// Then read data. - readData(name, nested_type, nested_col, max_rows_to_read, level, read_offsets); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /// For arrays, you first need to deserialize the dimensions, and then the values. - if (read_offsets) - { - type_arr->deserializeOffsets( - column, - streams[DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level)]->compressed, - max_rows_to_read); - } - - if (column.size()) - readData( - name, - *type_arr->getNestedType(), - typeid_cast(column).getData(), - typeid_cast(column).getOffsets()[column.size() - 1], - level + 1); - } - else - type.deserializeBinaryBulk(column, streams[name]->compressed, max_rows_to_read, 0); /// TODO Use avg_value_size_hint. + type.deserializeBinaryBulkWithMultipleStreams(column, stream_getter, max_rows_to_read, 0, true, {}); /// TODO Use avg_value_size_hint. } @@ -396,25 +293,19 @@ void LogBlockOutputStream::write(const Block & block) { storage.check(block, true); - /// The set of written offset columns so that you do not write mutual columns for nested structures multiple times - OffsetColumns offset_columns; + /// The set of written offset columns so that you do not write shared offsets of columns for nested structures multiple times + WrittenStreams written_streams; MarksForColumns marks; marks.reserve(storage.file_count); - MarksForColumns null_marks; - if (null_marks_stream) - null_marks.reserve(storage.null_file_count); - for (size_t i = 0; i < block.columns(); ++i) { const ColumnWithTypeAndName & column = block.safeGetByPosition(i); - writeData(column.name, *column.type, *column.column, marks, null_marks, offset_columns); + writeData(column.name, *column.type, *column.column, marks, written_streams); } - writeMarks(marks, false); - if (null_marks_stream) - writeMarks(null_marks, true); + writeMarks(std::move(marks)); } @@ -426,15 +317,13 @@ void LogBlockOutputStream::writeSuffix() /// Finish write. marks_stream.next(); - if (null_marks_stream) - null_marks_stream->next(); - for (FileStreams::iterator it = streams.begin(); it != streams.end(); ++it) - it->second->finalize(); + for (auto & name_stream : streams) + name_stream.second.finalize(); std::vector column_files; - for (auto & pair : streams) - column_files.push_back(storage.files[pair.first].data_file); + for (const auto & name_stream : streams) + column_files.push_back(storage.files[name_stream.first].data_file); column_files.push_back(storage.marks_file); storage.file_checker.update(column_files.begin(), column_files.end()); @@ -443,123 +332,68 @@ void LogBlockOutputStream::writeSuffix() } -void LogBlockOutputStream::addStream(const String & name, const IDataType & type, size_t level) -{ - if (type.isNullable()) - { - /// First create the stream that handles the null map of the given column. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); - - std::string filename = name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION; - streams.emplace(filename, std::make_unique(storage.files[filename].data_file.path(), - storage.max_compress_block_size)); - - /// Then create the stream that handles the data of the given column. - addStream(name, nested_type, level); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /// For arrays separate files are used for sizes. - String size_name = DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - if (!streams.count(size_name)) - streams.emplace(size_name, std::unique_ptr(new Stream( - storage.files[size_name].data_file.path(), storage.max_compress_block_size))); - - addStream(name, *type_arr->getNestedType(), level + 1); - } - else - streams[name] = std::make_unique(storage.files[name].data_file.path(), storage.max_compress_block_size); -} - - void LogBlockOutputStream::writeData(const String & name, const IDataType & type, const IColumn & column, - MarksForColumns & out_marks, MarksForColumns & out_null_marks, - OffsetColumns & offset_columns, size_t level) + MarksForColumns & out_marks, + WrittenStreams & written_streams) { - if (type.isNullable()) + type.enumerateStreams([&] (const IDataType::SubstreamPath & path) { - /// First write to the null map. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); + String stream_name = IDataType::getFileNameForStream(name, path); + if (written_streams.count(stream_name)) + return; - const ColumnNullable & nullable_col = static_cast(column); - const IColumn & nested_col = *nullable_col.getNestedColumn(); - - std::string filename = name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION; + const auto & file = storage.files[stream_name]; + const auto stream_it = streams.try_emplace(stream_name, storage.files[stream_name].data_file.path(), storage.max_compress_block_size).first; Mark mark; - mark.rows = (storage.files[filename].marks.empty() ? 0 : storage.files[filename].marks.back().rows) + column.size(); - mark.offset = streams[filename]->plain_offset + streams[filename]->plain.count(); + mark.rows = (file.marks.empty() ? 0 : file.marks.back().rows) + column.size(); + mark.offset = stream_it->second.plain_offset + stream_it->second.plain.count(); - out_null_marks.emplace_back(storage.files[filename].column_index, mark); + out_marks.emplace_back(file.column_index, mark); + }, {}); - DataTypeUInt8{}.serializeBinaryBulk(nullable_col.getNullMapConcreteColumn(), streams[filename]->compressed, 0, 0); - streams[filename]->compressed.next(); - - /// Then write data. - writeData(name, nested_type, nested_col, out_marks, out_null_marks, offset_columns, level); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) + IDataType::OutputStreamGetter stream_getter = [&] (const IDataType::SubstreamPath & path) -> WriteBuffer * { - /// For arrays, you first need to serialize the dimensions, and then the values. - String size_name = DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); + String stream_name = IDataType::getFileNameForStream(name, path); + if (written_streams.count(stream_name)) + return nullptr; - if (offset_columns.count(size_name) == 0) - { - offset_columns.insert(size_name); + auto it = streams.find(stream_name); + if (streams.end() == it) + throw Exception("Logical error: stream was not created when writing data in LogBlockOutputStream", ErrorCodes::LOGICAL_ERROR); + return &it->second.compressed; + }; - Mark mark; - mark.rows = (storage.files[size_name].marks.empty() ? 0 : storage.files[size_name].marks.back().rows) + column.size(); - mark.offset = streams[size_name]->plain_offset + streams[size_name]->plain.count(); + type.serializeBinaryBulkWithMultipleStreams(column, stream_getter, 0, 0, true, {}); - out_marks.push_back(std::make_pair(storage.files[size_name].column_index, mark)); - - type_arr->serializeOffsets(column, streams[size_name]->compressed, 0, 0); - streams[size_name]->compressed.next(); - } - - writeData(name, *type_arr->getNestedType(), typeid_cast(column).getData(), - out_marks, out_null_marks, offset_columns, level + 1); - } - else + type.enumerateStreams([&] (const IDataType::SubstreamPath & path) { - Mark mark; - mark.rows = (storage.files[name].marks.empty() ? 0 : storage.files[name].marks.back().rows) + column.size(); - mark.offset = streams[name]->plain_offset + streams[name]->plain.count(); + String stream_name = IDataType::getFileNameForStream(name, path); + if (!written_streams.emplace(stream_name).second) + return; - out_marks.push_back(std::make_pair(storage.files[name].column_index, mark)); - - type.serializeBinaryBulk(column, streams[name]->compressed, 0, 0); - streams[name]->compressed.next(); - } + auto it = streams.find(stream_name); + if (streams.end() == it) + throw Exception("Logical error: stream was not created when writing data in LogBlockOutputStream", ErrorCodes::LOGICAL_ERROR); + it->second.compressed.next(); + }, {}); } -static bool ColumnIndexLess(const std::pair & a, const std::pair & b) -{ - return a.first < b.first; -} -void LogBlockOutputStream::writeMarks(MarksForColumns marks, bool write_null_marks) +void LogBlockOutputStream::writeMarks(MarksForColumns && marks) { - size_t count = write_null_marks ? storage.null_file_count : storage.file_count; - WriteBufferFromFile & stream = write_null_marks ? *null_marks_stream : marks_stream; - const Names & names = write_null_marks ? storage.null_map_filenames : storage.column_names; - - if (marks.size() != count) + if (marks.size() != storage.file_count) throw Exception("Wrong number of marks generated from block. Makes no sense.", ErrorCodes::LOGICAL_ERROR); - sort(marks.begin(), marks.end(), ColumnIndexLess); + std::sort(marks.begin(), marks.end(), [](const auto & a, const auto & b) { return a.first < b.first; }); - for (size_t i = 0; i < marks.size(); ++i) + for (const auto & mark : marks) { - Mark mark = marks[i].second; + writeIntBinary(mark.second.rows, marks_stream); + writeIntBinary(mark.second.offset, marks_stream); - writeIntBinary(mark.rows, stream); - writeIntBinary(mark.offset, stream); - - size_t column_index = marks[i].first; - storage.files[names[column_index]].marks.push_back(mark); + size_t column_index = mark.first; + storage.files[storage.column_names[column_index]].marks.push_back(mark.second); } } @@ -573,83 +407,45 @@ StorageLog::StorageLog( size_t max_compress_block_size_) : IStorage{materialized_columns_, alias_columns_, column_defaults_}, path(path_), name(name_), columns(columns_), - loaded_marks(false), max_compress_block_size(max_compress_block_size_), + max_compress_block_size(max_compress_block_size_), file_checker(path + escapeForFileName(name) + '/' + "sizes.json") { if (columns->empty()) throw Exception("Empty list of columns passed to StorageLog constructor", ErrorCodes::EMPTY_LIST_OF_COLUMNS_PASSED); - /// create files if they do not exist + /// create files if they do not exist Poco::File(path + escapeForFileName(name) + '/').createDirectories(); for (const auto & column : getColumnsList()) - addFile(column.name, *column.type); + addFiles(column.name, *column.type); marks_file = Poco::File(path + escapeForFileName(name) + '/' + DBMS_STORAGE_LOG_MARKS_FILE_NAME); - - if (has_nullable_columns) - null_marks_file = Poco::File(path + escapeForFileName(name) + '/' + DBMS_STORAGE_LOG_NULL_MARKS_FILE_NAME); } -void StorageLog::addFile(const String & column_name, const IDataType & type, size_t level) +void StorageLog::addFiles(const String & column_name, const IDataType & type) { if (files.end() != files.find(column_name)) throw Exception("Duplicate column with name " + column_name + " in constructor of StorageLog.", ErrorCodes::DUPLICATE_COLUMN); - if (type.isNullable()) + IDataType::StreamCallback stream_callback = [&] (const IDataType::SubstreamPath & substream_path) { - /// First add the file describing the null map of the column. - has_nullable_columns = true; + String stream_name = IDataType::getFileNameForStream(column_name, substream_path); - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & actual_type = *nullable_type.getNestedType(); - - std::string filename = column_name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION; - ColumnData & column_data = files.emplace(filename, ColumnData{}).first->second; - ++null_file_count; - column_data.column_index = null_map_filenames.size(); - column_data.data_file = Poco::File{ - path + escapeForFileName(name) + '/' + escapeForFileName(column_name) - + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION}; - - null_map_filenames.push_back(filename); - - /// Then add the file describing the column data. - addFile(column_name, actual_type, level); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - String size_column_suffix = ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - String size_name = DataTypeNested::extractNestedTableName(column_name) + size_column_suffix; - - if (files.end() == files.find(size_name)) + if (!files.count(stream_name)) { - ColumnData & column_data = files.insert(std::make_pair(size_name, ColumnData())).first->second; - ++file_count; - column_data.column_index = column_names.size(); + ColumnData & column_data = files[stream_name]; + column_data.column_index = file_count; column_data.data_file = Poco::File{ - path + escapeForFileName(name) + '/' - + escapeForFileName(DataTypeNested::extractNestedTableName(column_name)) - + size_column_suffix + DBMS_STORAGE_LOG_DATA_FILE_EXTENSION}; + path + escapeForFileName(name) + '/' + stream_name + DBMS_STORAGE_LOG_DATA_FILE_EXTENSION}; - column_names.push_back(size_name); + column_names.push_back(stream_name); + ++file_count; } + }; - addFile(column_name, *type_arr->getNestedType(), level + 1); - } - else - { - ColumnData & column_data = files.insert(std::make_pair(column_name, ColumnData())).first->second; - ++file_count; - column_data.column_index = column_names.size(); - column_data.data_file = Poco::File{ - path + escapeForFileName(name) + '/' - + escapeForFileName(column_name) + DBMS_STORAGE_LOG_DATA_FILE_EXTENSION}; - - column_names.push_back(column_name); - } + type.enumerateStreams(stream_callback, {}); } @@ -660,45 +456,24 @@ void StorageLog::loadMarks() if (loaded_marks) return; - loadMarksImpl(false); - if (has_nullable_columns) - loadMarksImpl(true); - - loaded_marks = true; -} - - -void StorageLog::loadMarksImpl(bool load_null_marks) -{ using FilesByIndex = std::vector; - size_t count = load_null_marks ? null_file_count : file_count; - Poco::File & marks_file_handle = load_null_marks ? null_marks_file : marks_file; - - FilesByIndex files_by_index(count); + FilesByIndex files_by_index(file_count); for (Files_t::iterator it = files.begin(); it != files.end(); ++it) - { - bool has_null_extension = endsWith(it->first, DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION); - if (!load_null_marks && has_null_extension) - continue; - if (load_null_marks && !has_null_extension) - continue; - files_by_index[it->second.column_index] = it; - } - if (marks_file_handle.exists()) + if (marks_file.exists()) { - size_t file_size = marks_file_handle.getSize(); - if (file_size % (count * sizeof(Mark)) != 0) + size_t file_size = marks_file.getSize(); + if (file_size % (file_count * sizeof(Mark)) != 0) throw Exception("Size of marks file is inconsistent", ErrorCodes::SIZES_OF_MARKS_FILES_ARE_INCONSISTENT); - int marks_count = file_size / (count * sizeof(Mark)); + size_t marks_count = file_size / (file_count * sizeof(Mark)); - for (size_t i = 0; i < files_by_index.size(); ++i) - files_by_index[i]->second.marks.reserve(marks_count); + for (auto & file : files_by_index) + file->second.marks.reserve(marks_count); - ReadBufferFromFile marks_rb(marks_file_handle.path(), 32768); + ReadBufferFromFile marks_rb(marks_file.path(), 32768); while (!marks_rb.eof()) { for (size_t i = 0; i < files_by_index.size(); ++i) @@ -710,12 +485,8 @@ void StorageLog::loadMarksImpl(bool load_null_marks) } } } -} - -size_t StorageLog::marksCount() -{ - return files.begin()->second.marks.size(); + loaded_marks = true; } @@ -730,16 +501,14 @@ void StorageLog::rename(const String & new_path_to_db, const String & new_databa name = new_table_name; file_checker.setPath(path + escapeForFileName(name) + '/' + "sizes.json"); - for (Files_t::iterator it = files.begin(); it != files.end(); ++it) - it->second.data_file = Poco::File(path + escapeForFileName(name) + '/' + Poco::Path(it->second.data_file.path()).getFileName()); + for (auto & file : files) + file.second.data_file = Poco::File(path + escapeForFileName(name) + '/' + Poco::Path(file.second.data_file.path()).getFileName()); marks_file = Poco::File(path + escapeForFileName(name) + '/' + DBMS_STORAGE_LOG_MARKS_FILE_NAME); - if (has_nullable_columns) - null_marks_file = Poco::File(path + escapeForFileName(name) + '/' + DBMS_STORAGE_LOG_NULL_MARKS_FILE_NAME); } -const Marks & StorageLog::getMarksWithRealRowCount() const +const StorageLog::Marks & StorageLog::getMarksWithRealRowCount() const { auto init_column_type = [&]() { @@ -792,71 +561,26 @@ BlockInputStreams StorageLog::read( const Marks & marks = getMarksWithRealRowCount(); size_t marks_size = marks.size(); - /// Given a stream_num, return the start of the area from which - /// it can read data, i.e. a mark number. - auto mark_from_stream_num = [&](size_t stream_num) - { - /// The computation below reflects the fact that marks - /// are uniformly distributed among streams. - return stream_num * marks_size / num_streams; - }; - - /// Given a stream_num, get the parameters that specify the area - /// from which it can read data, i.e. a mark number and a - /// maximum number of rows. - auto get_reader_parameters = [&](size_t stream_num) - { - size_t mark_number = mark_from_stream_num(stream_num); - - size_t cur_total_row_count = stream_num == 0 - ? 0 - : marks[mark_number - 1].rows; - - size_t next_total_row_count = marks[mark_from_stream_num(stream_num + 1) - 1].rows; - size_t rows_limit = next_total_row_count - cur_total_row_count; - - return std::make_pair(mark_number, rows_limit); - }; - if (num_streams > marks_size) num_streams = marks_size; size_t max_read_buffer_size = context.getSettingsRef().max_read_buffer_size; - if (has_nullable_columns) + for (size_t stream = 0; stream < num_streams; ++stream) { - for (size_t stream = 0; stream < num_streams; ++stream) - { - size_t mark_number; - size_t rows_limit; - std::tie(mark_number, rows_limit) = get_reader_parameters(stream); + size_t mark_begin = stream * marks_size / num_streams; + size_t mark_end = (stream + 1) * marks_size / num_streams; - res.push_back(std::make_shared( - max_block_size, - column_names, - *this, - mark_number, - mark_number, - rows_limit, - max_read_buffer_size)); - } - } - else - { - for (size_t stream = 0; stream < num_streams; ++stream) - { - size_t mark_number; - size_t rows_limit; - std::tie(mark_number, rows_limit) = get_reader_parameters(stream); + size_t rows_begin = mark_begin ? marks[mark_begin - 1].rows : 0; + size_t rows_end = mark_end ? marks[mark_end - 1].rows : 0; - res.push_back(std::make_shared( - max_block_size, - column_names, - *this, - mark_number, - rows_limit, - max_read_buffer_size)); - } + res.emplace_back(std::make_shared( + max_block_size, + column_names, + *this, + mark_begin, + rows_end - rows_begin, + max_read_buffer_size)); } return res; diff --git a/dbms/src/Storages/StorageLog.h b/dbms/src/Storages/StorageLog.h index 7aed9b326b5..fad8b2d0309 100644 --- a/dbms/src/Storages/StorageLog.h +++ b/dbms/src/Storages/StorageLog.h @@ -14,27 +14,7 @@ namespace DB { -namespace ErrorCodes -{ - extern const int NO_SUCH_COLUMN_IN_TABLE; -} - - -/** Offsets to every single set of values. - * These sets are the same size in different columns. - * They are needed so that you can read the data in several threads. - */ -struct Mark -{ - size_t rows; /// How many lines are contained in this set and all previous ones. - size_t offset; /// The offset to the set in the compressed file. -}; - -using Marks = std::vector; - - -/** Implements a table engine that is suitable for logs. - * Keys are not supported. +/** Implements simple table engine without support of indices. * The data is stored in a compressed form. */ class StorageLog : public ext::shared_ptr_helper, public IStorage @@ -60,18 +40,6 @@ public: void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override; - /// Column data - struct ColumnData - { - /// Specifies the column number in the marks file. - /// Does not necessarily match the column number among the columns of the table: columns with lengths of arrays are also numbered here. - size_t column_index; - - Poco::File data_file; - Marks marks; - }; - using Files_t = std::map; - bool checkData() const override; protected: @@ -95,20 +63,42 @@ private: mutable std::shared_mutex rwlock; + /** Offsets to some row number in a file for column in table. + * They are needed so that you can read the data in several threads. + */ + struct Mark + { + size_t rows; /// How many rows are before this offset including the block at this offset. + size_t offset; /// The offset in compressed file. + }; + + using Marks = std::vector; + + /// Column data + struct ColumnData + { + /// Specifies the column number in the marks file. + /// Does not necessarily match the column number among the columns of the table: columns with lengths of arrays are also numbered here. + size_t column_index; + + Poco::File data_file; + Marks marks; + }; + using Files_t = std::map; + Files_t files; /// name -> data Names column_names; /// column_index -> name - Names null_map_filenames; Poco::File marks_file; - Poco::File null_marks_file; - bool loaded_marks; - bool has_nullable_columns = false; + /// The order of adding files should not change: it corresponds to the order of the columns in the marks file. + void addFiles(const String & column_name, const IDataType & type); + + bool loaded_marks = false; size_t max_compress_block_size; size_t file_count = 0; - size_t null_file_count = 0; FileChecker file_checker; @@ -117,24 +107,19 @@ private: /// You can not call with a write locked `rwlock`. void loadMarks(); - /// Can be called with any state of `rwlock`. - size_t marksCount(); - - void loadMarksImpl(bool load_null_marks); - /// The order of adding files should not change: it corresponds to the order of the columns in the marks file. void addFile(const String & column_name, const IDataType & type, size_t level = 0); /** For normal columns, the number of rows in the block is specified in the marks. * For array columns and nested structures, there are more than one group of marks that correspond to different files - * - for insides (file name.bin) - the total number of array elements in the block is specified, + * - for elements (file name.bin) - the total number of array elements in the block is specified, * - for array sizes (file name.size0.bin) - the number of rows (the whole arrays themselves) in the block is specified. * * Return the first group of marks that contain the number of rows, but not the internals of the arrays. */ const Marks & getMarksWithRealRowCount() const; - std::string getFullPath() const { return path + escapeForFileName(name) + '/';} + std::string getFullPath() const { return path + escapeForFileName(name) + '/'; } }; } diff --git a/dbms/src/Storages/StorageTinyLog.cpp b/dbms/src/Storages/StorageTinyLog.cpp index a7422918b0a..0c239a30b8a 100644 --- a/dbms/src/Storages/StorageTinyLog.cpp +++ b/dbms/src/Storages/StorageTinyLog.cpp @@ -36,7 +36,6 @@ #include #define DBMS_STORAGE_LOG_DATA_FILE_EXTENSION ".bin" -#define DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION ".null.bin" namespace DB @@ -88,8 +87,7 @@ private: using FileStreams = std::map>; FileStreams streams; - void addStream(const String & name, const IDataType & type, size_t level = 0); - void readData(const String & name, const IDataType & type, IColumn & column, size_t limit, size_t level = 0, bool read_offsets = true); + void readData(const String & name, const IDataType & type, IColumn & column, size_t limit, bool read_offsets = true); }; @@ -99,8 +97,6 @@ public: explicit TinyLogBlockOutputStream(StorageTinyLog & storage_) : storage(storage_) { - for (const auto & col : storage.getColumnsList()) - addStream(col.name, *col.type); } ~TinyLogBlockOutputStream() override @@ -143,10 +139,9 @@ private: using FileStreams = std::map>; FileStreams streams; - using OffsetColumns = std::set; + using WrittenStreams = std::set; - void addStream(const String & name, const IDataType & type, size_t level = 0); - void writeData(const String & name, const IDataType & type, const IColumn & column, OffsetColumns & offset_columns, size_t level = 0); + void writeData(const String & name, const IDataType & type, const IColumn & column, WrittenStreams & written_streams); }; @@ -191,11 +186,10 @@ Block TinyLogBlockInputStream::readImpl() { const auto & name = column_names[i]; column_types[i] = storage.getDataTypeByName(name); - addStream(name, *column_types[i]); } } - /// Pointers to offset columns, mutual for columns from nested data structures + /// Pointers to offset columns, shared for columns from nested data structures using OffsetColumns = std::map; OffsetColumns offset_columns; @@ -209,23 +203,8 @@ Block TinyLogBlockInputStream::readImpl() bool read_offsets = true; - const IDataType * observed_type; - bool is_nullable; - - if (column.type->isNullable()) - { - const DataTypeNullable & nullable_type = static_cast(*column.type); - observed_type = nullable_type.getNestedType().get(); - is_nullable = true; - } - else - { - observed_type = column.type.get(); - is_nullable = false; - } - /// For nested structures, remember pointers to columns with offsets - if (const DataTypeArray * type_arr = typeid_cast(observed_type)) + if (const DataTypeArray * type_arr = typeid_cast(column.type.get())) { String nested_name = DataTypeNested::extractNestedTableName(column.name); @@ -235,15 +214,13 @@ Block TinyLogBlockInputStream::readImpl() read_offsets = false; /// on previous iterations, the offsets were already calculated by `readData` column.column = std::make_shared(type_arr->getNestedType()->createColumn(), offset_columns[nested_name]); - if (is_nullable) - column.column = std::make_shared(column.column, std::make_shared()); } else column.column = column.type->createColumn(); try { - readData(name, *column.type, *column.column, block_size, 0, read_offsets); + readData(name, *column.type, *column.column, block_size, read_offsets); } catch (Exception & e) { @@ -265,139 +242,40 @@ Block TinyLogBlockInputStream::readImpl() } -void TinyLogBlockInputStream::addStream(const String & name, const IDataType & type, size_t level) +void TinyLogBlockInputStream::readData(const String & name, const IDataType & type, IColumn & column, size_t limit, bool with_offsets) { - if (type.isNullable()) + IDataType::InputStreamGetter stream_getter = [&] (const IDataType::SubstreamPath & path) -> ReadBuffer * { - /// First create the stream that handles the null map of the given column. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); - std::string filename = name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION; - streams.emplace(filename, std::make_unique(storage.files[filename].data_file.path(), max_read_buffer_size)); + if (!with_offsets && !path.empty() && path.back().type == IDataType::Substream::ArraySizes) + return nullptr; - /// Then create the stream that handles the data of the given column. - addStream(name, nested_type, level); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /// For arrays separate files are used for sizes. - String size_name = DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - if (!streams.count(size_name)) - streams.emplace(size_name, std::unique_ptr(new Stream(storage.files[size_name].data_file.path(), max_read_buffer_size))); + String stream_name = IDataType::getFileNameForStream(name, path); - addStream(name, *type_arr->getNestedType(), level + 1); - } - else - streams[name] = std::make_unique(storage.files[name].data_file.path(), max_read_buffer_size); -} + if (!streams.count(stream_name)) + streams[stream_name] = std::make_unique(storage.files[stream_name].data_file.path(), max_read_buffer_size); -void TinyLogBlockInputStream::readData(const String & name, const IDataType & type, IColumn & column, size_t limit, size_t level, bool read_offsets) -{ - if (type.isNullable()) - { - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); + return &streams[stream_name]->compressed; + }; - if (!column.isNullable()) - throw Exception{"Internal error: the column " + name + " is not nullable", ErrorCodes::LOGICAL_ERROR}; - - ColumnNullable & nullable_col = static_cast(column); - IColumn & nested_col = *nullable_col.getNestedColumn(); - - /// First read from the null map. - DataTypeUInt8{}.deserializeBinaryBulk(nullable_col.getNullMapConcreteColumn(), - streams[name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION]->compressed, limit, 0); - - /// Then read data. - readData(name, nested_type, nested_col, limit, level, read_offsets); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /// For arrays you first need to deserialize dimensions, and then the values. - if (read_offsets) - { - type_arr->deserializeOffsets( - column, - streams[DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level)]->compressed, - limit); - } - - if (column.size()) - { - IColumn & nested_column = typeid_cast(column).getData(); - size_t nested_limit = typeid_cast(column).getOffsets()[column.size() - 1]; - readData(name, *type_arr->getNestedType(), nested_column, nested_limit, level + 1); - - if (nested_column.size() != nested_limit) - throw Exception("Cannot read array data for all offsets", ErrorCodes::CANNOT_READ_ALL_DATA); - } - } - else - type.deserializeBinaryBulk(column, streams[name]->compressed, limit, 0); /// TODO Use avg_value_size_hint. + type.deserializeBinaryBulkWithMultipleStreams(column, stream_getter, limit, 0, true, {}); /// TODO Use avg_value_size_hint. } -void TinyLogBlockOutputStream::addStream(const String & name, const IDataType & type, size_t level) +void TinyLogBlockOutputStream::writeData(const String & name, const IDataType & type, const IColumn & column, WrittenStreams & written_streams) { - if (type.isNullable()) + IDataType::OutputStreamGetter stream_getter = [&] (const IDataType::SubstreamPath & path) -> WriteBuffer * { - /// First create the stream that handles the null map of the given column. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); + String stream_name = IDataType::getFileNameForStream(name, path); - std::string filename = name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION; - streams.emplace(filename, std::make_unique(storage.files[filename].data_file.path(), storage.max_compress_block_size)); + if (!streams.count(stream_name)) + streams[stream_name] = std::make_unique(storage.files[stream_name].data_file.path(), storage.max_compress_block_size); + else if (!written_streams.insert(stream_name).second) + return nullptr; - /// Then create the stream that handles the data of the given column. - addStream(name, nested_type, level); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /// For arrays separate files are used for sizes. - String size_name = DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - if (!streams.count(size_name)) - streams.emplace(size_name, std::unique_ptr(new Stream(storage.files[size_name].data_file.path(), storage.max_compress_block_size))); + return &streams[stream_name]->compressed; + }; - addStream(name, *type_arr->getNestedType(), level + 1); - } - else - streams[name] = std::make_unique(storage.files[name].data_file.path(), storage.max_compress_block_size); -} - - -void TinyLogBlockOutputStream::writeData(const String & name, const IDataType & type, const IColumn & column, - OffsetColumns & offset_columns, size_t level) -{ - if (type.isNullable()) - { - /// First write to the null map. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & nested_type = *nullable_type.getNestedType(); - - const ColumnNullable & nullable_col = static_cast(column); - const IColumn & nested_col = *nullable_col.getNestedColumn(); - - DataTypeUInt8{}.serializeBinaryBulk(nullable_col.getNullMapConcreteColumn(), - streams[name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION]->compressed, 0, 0); - - /// Then write data. - writeData(name, nested_type, nested_col, offset_columns, level); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - /// For arrays, you first need to serialize the dimensions, and then the values. - String size_name = DataTypeNested::extractNestedTableName(name) + ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - - if (offset_columns.count(size_name) == 0) - { - offset_columns.insert(size_name); - type_arr->serializeOffsets(column, streams[size_name]->compressed, 0, 0); - } - - writeData(name, *type_arr->getNestedType(), typeid_cast(column).getData(), offset_columns, level + 1); - } - else - type.serializeBinaryBulk(column, streams[name]->compressed, 0, 0); + type.serializeBinaryBulkWithMultipleStreams(column, stream_getter, 0, 0, true, {}); } @@ -425,13 +303,13 @@ void TinyLogBlockOutputStream::write(const Block & block) { storage.check(block, true); - /// The set of written offset columns so that you do not write mutual columns for nested structures multiple times - OffsetColumns offset_columns; + /// The set of written offset columns so that you do not write shared columns for nested structures multiple times + WrittenStreams written_streams; for (size_t i = 0; i < block.columns(); ++i) { const ColumnWithTypeAndName & column = block.safeGetByPosition(i); - writeData(column.name, *column.type, *column.column, offset_columns); + writeData(column.name, *column.type, *column.column, written_streams); } } @@ -463,52 +341,29 @@ StorageTinyLog::StorageTinyLog( } for (const auto & col : getColumnsList()) - addFile(col.name, *col.type); + addFiles(col.name, *col.type); } -void StorageTinyLog::addFile(const String & column_name, const IDataType & type, size_t level) +void StorageTinyLog::addFiles(const String & column_name, const IDataType & type) { if (files.end() != files.find(column_name)) throw Exception("Duplicate column with name " + column_name + " in constructor of StorageTinyLog.", ErrorCodes::DUPLICATE_COLUMN); - if (type.isNullable()) + IDataType::StreamCallback stream_callback = [&] (const IDataType::SubstreamPath & substream_path) { - /// First add the file describing the null map of the column. - const DataTypeNullable & nullable_type = static_cast(type); - const IDataType & actual_type = *nullable_type.getNestedType(); - - std::string filename = column_name + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION; - ColumnData & column_data = files.emplace(filename, ColumnData{}).first->second; - column_data.data_file = Poco::File{ - path + escapeForFileName(name) + '/' + escapeForFileName(column_name) + DBMS_STORAGE_LOG_DATA_BINARY_NULL_MAP_EXTENSION}; - - /// Then add the file describing the column data. - addFile(column_name, actual_type, level); - } - else if (const DataTypeArray * type_arr = typeid_cast(&type)) - { - String size_column_suffix = ARRAY_SIZES_COLUMN_NAME_SUFFIX + toString(level); - String size_name = DataTypeNested::extractNestedTableName(column_name) + size_column_suffix; - - if (files.end() == files.find(size_name)) + String stream_name = IDataType::getFileNameForStream(column_name, substream_path); + if (!files.count(stream_name)) { ColumnData column_data; - files.insert(std::make_pair(size_name, column_data)); - files[size_name].data_file = Poco::File( - path + escapeForFileName(name) + '/' + escapeForFileName(DataTypeNested::extractNestedTableName(column_name)) + size_column_suffix + DBMS_STORAGE_LOG_DATA_FILE_EXTENSION); + files.insert(std::make_pair(stream_name, column_data)); + files[stream_name].data_file = Poco::File( + path + escapeForFileName(name) + '/' + stream_name + DBMS_STORAGE_LOG_DATA_FILE_EXTENSION); } + }; - addFile(column_name, *type_arr->getNestedType(), level + 1); - } - else - { - ColumnData column_data; - files.insert(std::make_pair(column_name, column_data)); - files[column_name].data_file = Poco::File( - path + escapeForFileName(name) + '/' + escapeForFileName(column_name) + DBMS_STORAGE_LOG_DATA_FILE_EXTENSION); - } + type.enumerateStreams(stream_callback, {}); } @@ -548,15 +403,6 @@ BlockOutputStreamPtr StorageTinyLog::write( } -void StorageTinyLog::drop() -{ - for (Files_t::iterator it = files.begin(); it != files.end(); ++it) - { - if (it->second.data_file.exists()) - it->second.data_file.remove(); - } -} - bool StorageTinyLog::checkData() const { return file_checker.check(); diff --git a/dbms/src/Storages/StorageTinyLog.h b/dbms/src/Storages/StorageTinyLog.h index 9268941fe16..a5d4930b07f 100644 --- a/dbms/src/Storages/StorageTinyLog.h +++ b/dbms/src/Storages/StorageTinyLog.h @@ -39,8 +39,6 @@ public: BlockOutputStreamPtr write(const ASTPtr & query, const Settings & settings) override; - void drop() override; - void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override; bool checkData() const override; @@ -68,6 +66,7 @@ private: Logger * log; void addFile(const String & column_name, const IDataType & type, size_t level = 0); + void addFiles(const String & column_name, const IDataType & type); protected: StorageTinyLog( diff --git a/dbms/src/Storages/System/StorageSystemSettings.cpp b/dbms/src/Storages/System/StorageSystemSettings.cpp index 59cb22d0cd8..78a38def052 100644 --- a/dbms/src/Storages/System/StorageSystemSettings.cpp +++ b/dbms/src/Storages/System/StorageSystemSettings.cpp @@ -14,9 +14,10 @@ namespace DB StorageSystemSettings::StorageSystemSettings(const std::string & name_) : name(name_) , columns{ - { "name", std::make_shared() }, - { "value", std::make_shared() }, - { "changed", std::make_shared() }, + { "name", std::make_shared() }, + { "value", std::make_shared() }, + { "changed", std::make_shared() }, + { "description", std::make_shared() }, } { } @@ -38,20 +39,22 @@ BlockInputStreams StorageSystemSettings::read( ColumnWithTypeAndName col_name{std::make_shared(), std::make_shared(), "name"}; ColumnWithTypeAndName col_value{std::make_shared(), std::make_shared(), "value"}; ColumnWithTypeAndName col_changed{std::make_shared(), std::make_shared(), "changed"}; + ColumnWithTypeAndName col_description{std::make_shared(), std::make_shared(), "description"}; -#define ADD_SETTING(TYPE, NAME, DEFAULT) \ +#define ADD_SETTING(TYPE, NAME, DEFAULT, DESCRIPTION) \ col_name.column->insert(String(#NAME)); \ col_value.column->insert(settings.NAME.toString()); \ - col_changed.column->insert(UInt64(settings.NAME.changed)); + col_changed.column->insert(UInt64(settings.NAME.changed)); \ + col_description.column->insert(String(DESCRIPTION)); APPLY_FOR_SETTINGS(ADD_SETTING) #undef ADD_SETTING -#define ADD_LIMIT(TYPE, NAME, DEFAULT) \ +#define ADD_LIMIT(TYPE, NAME, DEFAULT, DESCRIPTION) \ col_name.column->insert(String(#NAME)); \ col_value.column->insert(settings.limits.NAME.toString()); \ - col_changed.column->insert(UInt64(settings.limits.NAME.changed)); - + col_changed.column->insert(UInt64(settings.limits.NAME.changed)); \ + col_description.column->insert(String(DESCRIPTION)); APPLY_FOR_LIMITS(ADD_LIMIT) #undef ADD_LIMIT @@ -59,6 +62,7 @@ BlockInputStreams StorageSystemSettings::read( col_name, col_value, col_changed, + col_description, }; return BlockInputStreams(1, std::make_shared(block)); diff --git a/dbms/tests/instructions/heap-profiler.txt b/dbms/tests/instructions/heap-profiler.txt new file mode 100644 index 00000000000..bf9eb7ec3b0 --- /dev/null +++ b/dbms/tests/instructions/heap-profiler.txt @@ -0,0 +1,14 @@ +Build clickhouse without tcmalloc. cmake -D ENABLE_TCMALLOC=0 + +Copy clickhouse binary to your server. +scp dbms/src/Server/clickhouse server:~ + +ssh to your server + +Stop clickhouse: +sudo service clickhouse-server stop + +Run clickhouse with heap profiler from the terminal: +sudo -u clickhouse LD_PRELOAD=/usr/lib/libtcmalloc.so HEAPPROFILE=/var/log/clickhouse-server/heap.hprof ./clickhouse server --config /etc/clickhouse-server/config.xml + +Profiles will appear in /var/log/clickhouse-server/ diff --git a/dbms/tests/queries/0_stateless/00013_1_create_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_1_create_table_with_arrays.reference deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/dbms/tests/queries/0_stateless/00013_1_create_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_1_create_table_with_arrays.sql deleted file mode 100644 index 5a728830a48..00000000000 --- a/dbms/tests/queries/0_stateless/00013_1_create_table_with_arrays.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP TABLE IF EXISTS arrays_test; -CREATE TABLE arrays_test (s String, arr Array(UInt8)) ENGINE = Memory; -INSERT INTO arrays_test VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []); diff --git a/dbms/tests/queries/0_stateless/00013_4_select_from_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_4_select_from_table_with_arrays.reference deleted file mode 100644 index 5a5af40fc00..00000000000 --- a/dbms/tests/queries/0_stateless/00013_4_select_from_table_with_arrays.reference +++ /dev/null @@ -1,3 +0,0 @@ -Hello [1,2] -World [3,4,5] -Goodbye [] diff --git a/dbms/tests/queries/0_stateless/00013_4_select_from_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_4_select_from_table_with_arrays.sql deleted file mode 100644 index af4b5dd8538..00000000000 --- a/dbms/tests/queries/0_stateless/00013_4_select_from_table_with_arrays.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT * FROM arrays_test diff --git a/dbms/tests/queries/0_stateless/00013_5_select_from_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_5_select_from_table_with_arrays.reference deleted file mode 100644 index 02ff6407fd6..00000000000 --- a/dbms/tests/queries/0_stateless/00013_5_select_from_table_with_arrays.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello 1 -Hello 2 -World 3 -World 4 -World 5 diff --git a/dbms/tests/queries/0_stateless/00013_5_select_from_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_5_select_from_table_with_arrays.sql deleted file mode 100644 index 238f888202d..00000000000 --- a/dbms/tests/queries/0_stateless/00013_5_select_from_table_with_arrays.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, arr FROM arrays_test ARRAY JOIN arr diff --git a/dbms/tests/queries/0_stateless/00013_6_select_from_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_6_select_from_table_with_arrays.reference deleted file mode 100644 index 45d362a350e..00000000000 --- a/dbms/tests/queries/0_stateless/00013_6_select_from_table_with_arrays.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello [1,2] 1 -Hello [1,2] 2 -World [3,4,5] 3 -World [3,4,5] 4 -World [3,4,5] 5 diff --git a/dbms/tests/queries/0_stateless/00013_6_select_from_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_6_select_from_table_with_arrays.sql deleted file mode 100644 index d1c9936af30..00000000000 --- a/dbms/tests/queries/0_stateless/00013_6_select_from_table_with_arrays.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, arr, a FROM arrays_test ARRAY JOIN arr AS a \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00013_7_select_from_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_7_select_from_table_with_arrays.reference deleted file mode 100644 index 577260f94f0..00000000000 --- a/dbms/tests/queries/0_stateless/00013_7_select_from_table_with_arrays.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello [1,2] 1 1 -Hello [1,2] 2 2 -World [3,4,5] 3 1 -World [3,4,5] 4 2 -World [3,4,5] 5 3 diff --git a/dbms/tests/queries/0_stateless/00013_7_select_from_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_7_select_from_table_with_arrays.sql deleted file mode 100644 index a75b97e6faa..00000000000 --- a/dbms/tests/queries/0_stateless/00013_7_select_from_table_with_arrays.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, arr, a, num FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00013_8_select_from_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_8_select_from_table_with_arrays.reference deleted file mode 100644 index e29fe6d82a1..00000000000 --- a/dbms/tests/queries/0_stateless/00013_8_select_from_table_with_arrays.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello [1,2] 1 1 [1,2] -Hello [1,2] 2 2 [1,2] -World [3,4,5] 3 1 [1,2,3] -World [3,4,5] 4 2 [1,2,3] -World [3,4,5] 5 3 [1,2,3] diff --git a/dbms/tests/queries/0_stateless/00013_8_select_from_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_8_select_from_table_with_arrays.sql deleted file mode 100644 index d7b3a7b44b9..00000000000 --- a/dbms/tests/queries/0_stateless/00013_8_select_from_table_with_arrays.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, arr, a, num, arrayEnumerate(arr) FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00013_9_select_from_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_9_select_from_table_with_arrays.reference deleted file mode 100644 index 58328ca2588..00000000000 --- a/dbms/tests/queries/0_stateless/00013_9_select_from_table_with_arrays.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello [1,2] 1 2 -Hello [1,2] 2 3 -World [3,4,5] 3 4 -World [3,4,5] 4 5 -World [3,4,5] 5 6 diff --git a/dbms/tests/queries/0_stateless/00013_9_select_from_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_9_select_from_table_with_arrays.sql deleted file mode 100644 index 010faea3d76..00000000000 --- a/dbms/tests/queries/0_stateless/00013_9_select_from_table_with_arrays.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, arr, a, mapped FROM arrays_test ARRAY JOIN arr AS a, arrayMap(x -> x + 1, arr) AS mapped diff --git a/dbms/tests/queries/0_stateless/00013_a_select_from_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_a_select_from_table_with_arrays.reference deleted file mode 100644 index 14686f65be3..00000000000 --- a/dbms/tests/queries/0_stateless/00013_a_select_from_table_with_arrays.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello [1,2] 1 1 2 -Hello [1,2] 2 2 3 -World [3,4,5] 3 1 4 -World [3,4,5] 4 2 5 -World [3,4,5] 5 3 6 diff --git a/dbms/tests/queries/0_stateless/00013_a_select_from_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_a_select_from_table_with_arrays.sql deleted file mode 100644 index 1c4b2b02e19..00000000000 --- a/dbms/tests/queries/0_stateless/00013_a_select_from_table_with_arrays.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, arr, a, num, mapped FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS mapped diff --git a/dbms/tests/queries/0_stateless/00013_b_select_from_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_b_select_from_table_with_arrays.reference deleted file mode 100644 index 725d1e7afd5..00000000000 --- a/dbms/tests/queries/0_stateless/00013_b_select_from_table_with_arrays.reference +++ /dev/null @@ -1 +0,0 @@ -15 15 3 diff --git a/dbms/tests/queries/0_stateless/00013_b_select_from_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_b_select_from_table_with_arrays.sql deleted file mode 100644 index 95106c9748a..00000000000 --- a/dbms/tests/queries/0_stateless/00013_b_select_from_table_with_arrays.sql +++ /dev/null @@ -1,2 +0,0 @@ -SELECT sumArray(arr), sumArrayIf(arr, s LIKE '%l%'), sumArrayIf(arr, s LIKE '%e%') FROM arrays_test - diff --git a/dbms/tests/queries/0_stateless/00013_create_table_with_arrays.reference b/dbms/tests/queries/0_stateless/00013_create_table_with_arrays.reference new file mode 100644 index 00000000000..5c3376dd493 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00013_create_table_with_arrays.reference @@ -0,0 +1,34 @@ +Hello [1,2] +World [3,4,5] +Goodbye [] +Hello 1 +Hello 2 +World 3 +World 4 +World 5 +Hello [1,2] 1 +Hello [1,2] 2 +World [3,4,5] 3 +World [3,4,5] 4 +World [3,4,5] 5 +Hello [1,2] 1 1 +Hello [1,2] 2 2 +World [3,4,5] 3 1 +World [3,4,5] 4 2 +World [3,4,5] 5 3 +Hello [1,2] 1 1 [1,2] +Hello [1,2] 2 2 [1,2] +World [3,4,5] 3 1 [1,2,3] +World [3,4,5] 4 2 [1,2,3] +World [3,4,5] 5 3 [1,2,3] +Hello [1,2] 1 2 +Hello [1,2] 2 3 +World [3,4,5] 3 4 +World [3,4,5] 4 5 +World [3,4,5] 5 6 +Hello [1,2] 1 1 2 +Hello [1,2] 2 2 3 +World [3,4,5] 3 1 4 +World [3,4,5] 4 2 5 +World [3,4,5] 5 3 6 +15 15 3 diff --git a/dbms/tests/queries/0_stateless/00013_create_table_with_arrays.sql b/dbms/tests/queries/0_stateless/00013_create_table_with_arrays.sql new file mode 100644 index 00000000000..bba132d0b3b --- /dev/null +++ b/dbms/tests/queries/0_stateless/00013_create_table_with_arrays.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS arrays_test; +CREATE TABLE arrays_test (s String, arr Array(UInt8)) ENGINE = Memory; +INSERT INTO arrays_test VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []); +SELECT * FROM arrays_test; +SELECT s, arr FROM arrays_test ARRAY JOIN arr; +SELECT s, arr, a FROM arrays_test ARRAY JOIN arr AS a; +SELECT s, arr, a, num FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; +SELECT s, arr, a, num, arrayEnumerate(arr) FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; +SELECT s, arr, a, mapped FROM arrays_test ARRAY JOIN arr AS a, arrayMap(x -> x + 1, arr) AS mapped; +SELECT s, arr, a, num, mapped FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS mapped; +SELECT sumArray(arr), sumArrayIf(arr, s LIKE '%l%'), sumArrayIf(arr, s LIKE '%e%') FROM arrays_test; diff --git a/dbms/tests/queries/0_stateless/00014_1_create_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_1_create_table_with_nested.reference deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/dbms/tests/queries/0_stateless/00014_1_create_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_1_create_table_with_nested.sql deleted file mode 100644 index 56722dee7ac..00000000000 --- a/dbms/tests/queries/0_stateless/00014_1_create_table_with_nested.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP TABLE IF EXISTS nested_test; -CREATE TABLE nested_test (s String, nest Nested(x UInt8, y UInt32)) ENGINE = Memory; -INSERT INTO nested_test VALUES ('Hello', [1,2], [10,20]), ('World', [3,4,5], [30,40,50]), ('Goodbye', [], []); diff --git a/dbms/tests/queries/0_stateless/00014_4_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_4_select_from_table_with_nested.reference deleted file mode 100644 index 32bd08bad02..00000000000 --- a/dbms/tests/queries/0_stateless/00014_4_select_from_table_with_nested.reference +++ /dev/null @@ -1,3 +0,0 @@ -Hello [1,2] [10,20] -World [3,4,5] [30,40,50] -Goodbye [] [] diff --git a/dbms/tests/queries/0_stateless/00014_4_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_4_select_from_table_with_nested.sql deleted file mode 100644 index 509911959ac..00000000000 --- a/dbms/tests/queries/0_stateless/00014_4_select_from_table_with_nested.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT * FROM nested_test diff --git a/dbms/tests/queries/0_stateless/00014_5_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_5_select_from_table_with_nested.reference deleted file mode 100644 index 05200edd33b..00000000000 --- a/dbms/tests/queries/0_stateless/00014_5_select_from_table_with_nested.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello 1 10 -Hello 2 20 -World 3 30 -World 4 40 -World 5 50 diff --git a/dbms/tests/queries/0_stateless/00014_5_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_5_select_from_table_with_nested.sql deleted file mode 100644 index 31e1ac1b05e..00000000000 --- a/dbms/tests/queries/0_stateless/00014_5_select_from_table_with_nested.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest diff --git a/dbms/tests/queries/0_stateless/00014_6_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_6_select_from_table_with_nested.reference deleted file mode 100644 index 8ea4568b73c..00000000000 --- a/dbms/tests/queries/0_stateless/00014_6_select_from_table_with_nested.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello 1 [10,20] -Hello 2 [10,20] -World 3 [30,40,50] -World 4 [30,40,50] -World 5 [30,40,50] diff --git a/dbms/tests/queries/0_stateless/00014_6_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_6_select_from_table_with_nested.sql deleted file mode 100644 index 3648cb4852c..00000000000 --- a/dbms/tests/queries/0_stateless/00014_6_select_from_table_with_nested.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x diff --git a/dbms/tests/queries/0_stateless/00014_7_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_7_select_from_table_with_nested.reference deleted file mode 100644 index 05200edd33b..00000000000 --- a/dbms/tests/queries/0_stateless/00014_7_select_from_table_with_nested.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello 1 10 -Hello 2 20 -World 3 30 -World 4 40 -World 5 50 diff --git a/dbms/tests/queries/0_stateless/00014_7_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_7_select_from_table_with_nested.sql deleted file mode 100644 index 9380d7d285f..00000000000 --- a/dbms/tests/queries/0_stateless/00014_7_select_from_table_with_nested.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x, nest.y \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00014_9_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_9_select_from_table_with_nested.reference deleted file mode 100644 index 05200edd33b..00000000000 --- a/dbms/tests/queries/0_stateless/00014_9_select_from_table_with_nested.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello 1 10 -Hello 2 20 -World 3 30 -World 4 40 -World 5 50 diff --git a/dbms/tests/queries/0_stateless/00014_9_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_9_select_from_table_with_nested.sql deleted file mode 100644 index 945f3dc79a1..00000000000 --- a/dbms/tests/queries/0_stateless/00014_9_select_from_table_with_nested.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, n.x, n.y FROM nested_test ARRAY JOIN nest AS n \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00014_a_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_a_select_from_table_with_nested.reference deleted file mode 100644 index d40754269c6..00000000000 --- a/dbms/tests/queries/0_stateless/00014_a_select_from_table_with_nested.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello 1 10 [1,2] -Hello 2 20 [1,2] -World 3 30 [3,4,5] -World 4 40 [3,4,5] -World 5 50 [3,4,5] diff --git a/dbms/tests/queries/0_stateless/00014_a_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_a_select_from_table_with_nested.sql deleted file mode 100644 index 4e275aa4e12..00000000000 --- a/dbms/tests/queries/0_stateless/00014_a_select_from_table_with_nested.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, n.x, n.y, nest.x FROM nested_test ARRAY JOIN nest AS n \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00014_b_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_b_select_from_table_with_nested.reference deleted file mode 100644 index 7129270657e..00000000000 --- a/dbms/tests/queries/0_stateless/00014_b_select_from_table_with_nested.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello 1 10 [1,2] [10,20] -Hello 2 20 [1,2] [10,20] -World 3 30 [3,4,5] [30,40,50] -World 4 40 [3,4,5] [30,40,50] -World 5 50 [3,4,5] [30,40,50] diff --git a/dbms/tests/queries/0_stateless/00014_b_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_b_select_from_table_with_nested.sql deleted file mode 100644 index 4643e428942..00000000000 --- a/dbms/tests/queries/0_stateless/00014_b_select_from_table_with_nested.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, n.x, n.y, nest.x, nest.y FROM nested_test ARRAY JOIN nest AS n \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00014_c_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_c_select_from_table_with_nested.reference deleted file mode 100644 index fa7a8052ce9..00000000000 --- a/dbms/tests/queries/0_stateless/00014_c_select_from_table_with_nested.reference +++ /dev/null @@ -1,5 +0,0 @@ -Hello 1 10 [1,2] [10,20] 1 -Hello 2 20 [1,2] [10,20] 2 -World 3 30 [3,4,5] [30,40,50] 1 -World 4 40 [3,4,5] [30,40,50] 2 -World 5 50 [3,4,5] [30,40,50] 3 diff --git a/dbms/tests/queries/0_stateless/00014_c_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_c_select_from_table_with_nested.sql deleted file mode 100644 index 6033dd1c011..00000000000 --- a/dbms/tests/queries/0_stateless/00014_c_select_from_table_with_nested.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT s, n.x, n.y, nest.x, nest.y, num FROM nested_test ARRAY JOIN nest AS n, arrayEnumerate(nest.x) AS num \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00014_select_from_table_with_nested.reference b/dbms/tests/queries/0_stateless/00014_select_from_table_with_nested.reference new file mode 100644 index 00000000000..bf1087c9220 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00014_select_from_table_with_nested.reference @@ -0,0 +1,38 @@ +Hello [1,2] [10,20] +World [3,4,5] [30,40,50] +Goodbye [] [] +Hello 1 10 +Hello 2 20 +World 3 30 +World 4 40 +World 5 50 +Hello 1 [10,20] +Hello 2 [10,20] +World 3 [30,40,50] +World 4 [30,40,50] +World 5 [30,40,50] +Hello 1 10 +Hello 2 20 +World 3 30 +World 4 40 +World 5 50 +Hello 1 10 +Hello 2 20 +World 3 30 +World 4 40 +World 5 50 +Hello 1 10 [1,2] +Hello 2 20 [1,2] +World 3 30 [3,4,5] +World 4 40 [3,4,5] +World 5 50 [3,4,5] +Hello 1 10 [1,2] [10,20] +Hello 2 20 [1,2] [10,20] +World 3 30 [3,4,5] [30,40,50] +World 4 40 [3,4,5] [30,40,50] +World 5 50 [3,4,5] [30,40,50] +Hello 1 10 [1,2] [10,20] 1 +Hello 2 20 [1,2] [10,20] 2 +World 3 30 [3,4,5] [30,40,50] 1 +World 4 40 [3,4,5] [30,40,50] 2 +World 5 50 [3,4,5] [30,40,50] 3 diff --git a/dbms/tests/queries/0_stateless/00014_select_from_table_with_nested.sql b/dbms/tests/queries/0_stateless/00014_select_from_table_with_nested.sql new file mode 100644 index 00000000000..a43a102a754 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00014_select_from_table_with_nested.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS nested_test; +CREATE TABLE nested_test (s String, nest Nested(x UInt8, y UInt32)) ENGINE = Memory; +INSERT INTO nested_test VALUES ('Hello', [1,2], [10,20]), ('World', [3,4,5], [30,40,50]), ('Goodbye', [], []); +SELECT * FROM nested_test; +SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest; +SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x; +SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x, nest.y; +SELECT s, n.x, n.y FROM nested_test ARRAY JOIN nest AS n; +SELECT s, n.x, n.y, nest.x FROM nested_test ARRAY JOIN nest AS n; +SELECT s, n.x, n.y, nest.x, nest.y FROM nested_test ARRAY JOIN nest AS n; +SELECT s, n.x, n.y, nest.x, nest.y, num FROM nested_test ARRAY JOIN nest AS n, arrayEnumerate(nest.x) AS num; diff --git a/dbms/tests/queries/0_stateless/00030_1_alter_table.sql b/dbms/tests/queries/0_stateless/00030_1_alter_table.sql deleted file mode 100644 index 036b292f6e9..00000000000 --- a/dbms/tests/queries/0_stateless/00030_1_alter_table.sql +++ /dev/null @@ -1,15 +0,0 @@ -DROP TABLE IF EXISTS alter_test; - -CREATE TABLE alter_test (CounterID UInt32, StartDate Date, UserID UInt32, VisitID UInt32, NestedColumn Nested(A UInt8, S String), ToDrop UInt32) ENGINE = MergeTree(StartDate, intHash32(UserID), (CounterID, StartDate, intHash32(UserID), VisitID), 8192); - -INSERT INTO alter_test VALUES (1, '2014-01-01', 2, 3, [1,2,3], ['a','b','c'], 4); - -ALTER TABLE alter_test ADD COLUMN Added0 UInt32; -ALTER TABLE alter_test ADD COLUMN Added2 UInt32; -ALTER TABLE alter_test ADD COLUMN Added1 UInt32 AFTER Added0; - -ALTER TABLE alter_test ADD COLUMN AddedNested1 Nested(A UInt32, B UInt64) AFTER Added2; -ALTER TABLE alter_test ADD COLUMN AddedNested1.C Array(String) AFTER AddedNested1.B; -ALTER TABLE alter_test ADD COLUMN AddedNested2 Nested(A UInt32, B UInt64) AFTER AddedNested1; - -DESC TABLE alter_test; diff --git a/dbms/tests/queries/0_stateless/00030_2_alter_table.reference b/dbms/tests/queries/0_stateless/00030_2_alter_table.reference deleted file mode 100644 index 545979609b8..00000000000 --- a/dbms/tests/queries/0_stateless/00030_2_alter_table.reference +++ /dev/null @@ -1,11 +0,0 @@ -CounterID UInt32 -StartDate Date -UserID UInt32 -VisitID UInt32 -Added0 String -Added1 UInt32 -Added2 UInt32 -AddedNested1.A Array(UInt32) -AddedNested1.C Array(String) -AddedNested2.A Array(UInt32) -AddedNested2.B Array(UInt64) diff --git a/dbms/tests/queries/0_stateless/00030_2_alter_table.sql b/dbms/tests/queries/0_stateless/00030_2_alter_table.sql deleted file mode 100644 index fb3347a530f..00000000000 --- a/dbms/tests/queries/0_stateless/00030_2_alter_table.sql +++ /dev/null @@ -1,10 +0,0 @@ -ALTER TABLE alter_test DROP COLUMN ToDrop; - -ALTER TABLE alter_test MODIFY COLUMN Added0 String; - -ALTER TABLE alter_test DROP COLUMN NestedColumn.A; -ALTER TABLE alter_test DROP COLUMN NestedColumn.S; - -ALTER TABLE alter_test DROP COLUMN AddedNested1.B; - -DESC TABLE alter_test; diff --git a/dbms/tests/queries/0_stateless/00030_3_alter_table.reference b/dbms/tests/queries/0_stateless/00030_3_alter_table.reference deleted file mode 100644 index ed55f8887ff..00000000000 --- a/dbms/tests/queries/0_stateless/00030_3_alter_table.reference +++ /dev/null @@ -1 +0,0 @@ -1 2014-01-01 2 3 0 0 [] [] [] [] diff --git a/dbms/tests/queries/0_stateless/00030_3_alter_table.sql b/dbms/tests/queries/0_stateless/00030_3_alter_table.sql deleted file mode 100644 index d7ecb07f159..00000000000 --- a/dbms/tests/queries/0_stateless/00030_3_alter_table.sql +++ /dev/null @@ -1,3 +0,0 @@ -SELECT * FROM alter_test; - -DROP TABLE alter_test; diff --git a/dbms/tests/queries/0_stateless/00030_1_alter_table.reference b/dbms/tests/queries/0_stateless/00030_alter_table.reference similarity index 55% rename from dbms/tests/queries/0_stateless/00030_1_alter_table.reference rename to dbms/tests/queries/0_stateless/00030_alter_table.reference index 46a966e23c6..ac2c0af78f4 100644 --- a/dbms/tests/queries/0_stateless/00030_1_alter_table.reference +++ b/dbms/tests/queries/0_stateless/00030_alter_table.reference @@ -13,3 +13,15 @@ AddedNested1.B Array(UInt64) AddedNested1.C Array(String) AddedNested2.A Array(UInt32) AddedNested2.B Array(UInt64) +CounterID UInt32 +StartDate Date +UserID UInt32 +VisitID UInt32 +Added0 String +Added1 UInt32 +Added2 UInt32 +AddedNested1.A Array(UInt32) +AddedNested1.C Array(String) +AddedNested2.A Array(UInt32) +AddedNested2.B Array(UInt64) +1 2014-01-01 2 3 0 0 [] [] [] [] diff --git a/dbms/tests/queries/0_stateless/00030_alter_table.sql b/dbms/tests/queries/0_stateless/00030_alter_table.sql new file mode 100644 index 00000000000..231840818cf --- /dev/null +++ b/dbms/tests/queries/0_stateless/00030_alter_table.sql @@ -0,0 +1,30 @@ +DROP TABLE IF EXISTS test.alter_test; + +CREATE TABLE test.alter_test (CounterID UInt32, StartDate Date, UserID UInt32, VisitID UInt32, NestedColumn Nested(A UInt8, S String), ToDrop UInt32) ENGINE = MergeTree(StartDate, intHash32(UserID), (CounterID, StartDate, intHash32(UserID), VisitID), 8192); + +INSERT INTO test.alter_test VALUES (1, '2014-01-01', 2, 3, [1,2,3], ['a','b','c'], 4); + +ALTER TABLE test.alter_test ADD COLUMN Added0 UInt32; +ALTER TABLE test.alter_test ADD COLUMN Added2 UInt32; +ALTER TABLE test.alter_test ADD COLUMN Added1 UInt32 AFTER Added0; + +ALTER TABLE test.alter_test ADD COLUMN AddedNested1 Nested(A UInt32, B UInt64) AFTER Added2; +ALTER TABLE test.alter_test ADD COLUMN AddedNested1.C Array(String) AFTER AddedNested1.B; +ALTER TABLE test.alter_test ADD COLUMN AddedNested2 Nested(A UInt32, B UInt64) AFTER AddedNested1; + +DESC TABLE test.alter_test; + +ALTER TABLE test.alter_test DROP COLUMN ToDrop; + +ALTER TABLE test.alter_test MODIFY COLUMN Added0 String; + +ALTER TABLE test.alter_test DROP COLUMN NestedColumn.A; +ALTER TABLE test.alter_test DROP COLUMN NestedColumn.S; + +ALTER TABLE test.alter_test DROP COLUMN AddedNested1.B; + +DESC TABLE test.alter_test; + +SELECT * FROM test.alter_test; + +DROP TABLE test.alter_test; diff --git a/dbms/tests/queries/0_stateless/00083_create_merge_tree_zookeeper.sql b/dbms/tests/queries/0_stateless/00083_create_merge_tree_zookeeper.sql index 0d85b1e8b26..ed9dc50fbbc 100644 --- a/dbms/tests/queries/0_stateless/00083_create_merge_tree_zookeeper.sql +++ b/dbms/tests/queries/0_stateless/00083_create_merge_tree_zookeeper.sql @@ -46,26 +46,26 @@ CREATE TABLE test.aggregating_merge_tree_with_sampling (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = AggregatingMergeTree(d, sipHash64(a) + b, (a, sipHash64(a) + b), 111); CREATE TABLE test.replicated_merge_tree - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedMergeTree('/clickhouse/tables/01/replicated_merge_tree/', 'r1', d, (a, b), 111); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedMergeTree('/clickhouse/tables/test/01/replicated_merge_tree/', 'r1', d, (a, b), 111); CREATE TABLE test.replicated_collapsing_merge_tree - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/01/replicated_collapsing_merge_tree/', 'r1', d, (a, b), 111, y); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/test/01/replicated_collapsing_merge_tree/', 'r1', d, (a, b), 111, y); CREATE TABLE test.replicated_summing_merge_tree - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedSummingMergeTree('/clickhouse/tables/01/replicated_summing_merge_tree/', 'r1', d, (a, b), 111); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedSummingMergeTree('/clickhouse/tables/test/01/replicated_summing_merge_tree/', 'r1', d, (a, b), 111); CREATE TABLE test.replicated_summing_merge_tree_with_list_of_columns_to_sum - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedSummingMergeTree('/clickhouse/tables/01/replicated_summing_merge_tree_with_list_of_columns_to_sum/', 'r1', d, (a, b), 111, (y, z)); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedSummingMergeTree('/clickhouse/tables/test/01/replicated_summing_merge_tree_with_list_of_columns_to_sum/', 'r1', d, (a, b), 111, (y, z)); CREATE TABLE test.replicated_aggregating_merge_tree - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/01/replicated_aggregating_merge_tree/', 'r1', d, (a, b), 111); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/test/01/replicated_aggregating_merge_tree/', 'r1', d, (a, b), 111); CREATE TABLE test.replicated_merge_tree_with_sampling - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedMergeTree('/clickhouse/tables/01/replicated_merge_tree_with_sampling/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedMergeTree('/clickhouse/tables/test/01/replicated_merge_tree_with_sampling/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111); CREATE TABLE test.replicated_collapsing_merge_tree_with_sampling - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/01/replicated_collapsing_merge_tree_with_sampling/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111, y); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/test/01/replicated_collapsing_merge_tree_with_sampling/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111, y); CREATE TABLE test.replicated_summing_merge_tree_with_sampling - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedSummingMergeTree('/clickhouse/tables/01/replicated_summing_merge_tree_with_sampling/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedSummingMergeTree('/clickhouse/tables/test/01/replicated_summing_merge_tree_with_sampling/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111); CREATE TABLE test.replicated_summing_merge_tree_with_sampling_with_list_of_columns_to_sum - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedSummingMergeTree('/clickhouse/tables/01/replicated_summing_merge_tree_with_sampling_with_list_of_columns_to_sum/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111, (y, z)); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedSummingMergeTree('/clickhouse/tables/test/01/replicated_summing_merge_tree_with_sampling_with_list_of_columns_to_sum/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111, (y, z)); CREATE TABLE test.replicated_aggregating_merge_tree_with_sampling - (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/01/replicated_aggregating_merge_tree_with_sampling/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111); + (d Date, a String, b UInt8, x String, y Int8, z UInt32) ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/test/01/replicated_aggregating_merge_tree_with_sampling/', 'r1', d, sipHash64(a) + b, (a, sipHash64(a) + b), 111); INSERT INTO test.merge_tree VALUES ('2000-01-01', 'Hello, world!', 123, 'xxx yyy', -123, 123456789); diff --git a/dbms/tests/queries/0_stateless/00236_replicated_drop_on_non_leader_zookeeper.sql b/dbms/tests/queries/0_stateless/00236_replicated_drop_on_non_leader_zookeeper.sql index 7d65e403b83..e64ca7746ba 100644 --- a/dbms/tests/queries/0_stateless/00236_replicated_drop_on_non_leader_zookeeper.sql +++ b/dbms/tests/queries/0_stateless/00236_replicated_drop_on_non_leader_zookeeper.sql @@ -3,8 +3,8 @@ SET replication_alter_partitions_sync = 2; DROP TABLE IF EXISTS test.attach_r1; DROP TABLE IF EXISTS test.attach_r2; -CREATE TABLE test.attach_r1 (d Date) ENGINE = ReplicatedMergeTree('/clickhouse/tables/01/attach', 'r1', d, d, 8192); -CREATE TABLE test.attach_r2 (d Date) ENGINE = ReplicatedMergeTree('/clickhouse/tables/01/attach', 'r2', d, d, 8192); +CREATE TABLE test.attach_r1 (d Date) ENGINE = ReplicatedMergeTree('/clickhouse/tables/test/01/attach', 'r1', d, d, 8192); +CREATE TABLE test.attach_r2 (d Date) ENGINE = ReplicatedMergeTree('/clickhouse/tables/test/01/attach', 'r2', d, d, 8192); INSERT INTO test.attach_r1 VALUES ('2014-01-01'), ('2014-02-01'), ('2014-03-01'); diff --git a/dbms/tests/queries/0_stateless/00302_http_compression.sh b/dbms/tests/queries/0_stateless/00302_http_compression.sh index f71b8975fd0..013f3988d0e 100755 --- a/dbms/tests/queries/0_stateless/00302_http_compression.sh +++ b/dbms/tests/queries/0_stateless/00302_http_compression.sh @@ -1,24 +1,28 @@ #!/usr/bin/env bash -curl -sS 'http://localhost:8123/?enable_http_compression=1' -d 'SELECT number FROM system.numbers LIMIT 10'; -curl -sS 'http://localhost:8123/?enable_http_compression=0' -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10'; -curl -sS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d; -curl -sS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip, deflate' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d; -curl -sS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: zip, eflate' -d 'SELECT number FROM system.numbers LIMIT 10'; +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: deflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip, deflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: zip, eflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -echo "SELECT 1" | curl -sS --data-binary @- 'http://localhost:8123/'; -echo "SELECT 1" | gzip -c | curl -sS --data-binary @- -H 'Content-Encoding: gzip' 'http://localhost:8123/'; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -d 'SELECT number FROM system.numbers LIMIT 10'; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=0" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10'; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip, deflate' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: zip, eflate' -d 'SELECT number FROM system.numbers LIMIT 10'; -echo "'Hello, world'" | curl -sS --data-binary @- 'http://localhost:8123/?query=SELECT'; -echo "'Hello, world'" | gzip -c | curl -sS --data-binary @- -H 'Content-Encoding: gzip' 'http://localhost:8123/?query=SELECT'; +${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?enable_http_compression=1" -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; +${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; +${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: deflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; +${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip, deflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; + -vsS '${CLICKHOUSE_URL}?enable_http_compression=1' -H 'Accept-Encoding: zip, eflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -sS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 0' | wc -c; +echo "SELECT 1" | ${CLICKHOUSE_CURL} -sS --data-binary @- ${CLICKHOUSE_URL}; +echo "SELECT 1" | gzip -c | ${CLICKHOUSE_CURL} -sS --data-binary @- -H 'Content-Encoding: gzip' ${CLICKHOUSE_URL}; + +echo "'Hello, world'" | ${CLICKHOUSE_CURL} -sS --data-binary @- "${CLICKHOUSE_URL}?query=SELECT"; +echo "'Hello, world'" | gzip -c | ${CLICKHOUSE_CURL} -sS --data-binary @- -H 'Content-Encoding: gzip' "${CLICKHOUSE_URL}?query=SELECT"; + +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 0' | wc -c; # POST multiple concatenated gzip streams. -(echo -n "SELECT 'Part1" | gzip -c; echo " Part2'" | gzip -c) | curl -sS -H 'Content-Encoding: gzip' 'http://localhost:8123/?' --data-binary @- +(echo -n "SELECT 'Part1" | gzip -c; echo " Part2'" | gzip -c) | ${CLICKHOUSE_CURL} -sS -H 'Content-Encoding: gzip' "${CLICKHOUSE_URL}?" --data-binary @- diff --git a/debian/changelog b/debian/changelog index 303ed070568..5223e81a8b8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -clickhouse (1.1.54314) unstable; urgency=low +clickhouse (1.1.54319) unstable; urgency=low * Modified source code - -- Tue, 28 Nov 2017 13:25:47 +0300 + -- Fri, 01 Dec 2017 09:36:27 +0300 diff --git a/docs/ru/agg_functions/index.md b/docs/ru/agg_functions/index.md index c12bacebbe2..471edead71d 100644 --- a/docs/ru/agg_functions/index.md +++ b/docs/ru/agg_functions/index.md @@ -1,14 +1,15 @@ -Агрегатные функции -================== +# Агрегатные функции Агрегатные функции работают в [привычном](http://www.sql-tutorial.com/sql-aggregate-functions-sql-tutorial) для специалистов по базам данных смысле. ClickHouse поддерживает также: -> - [Параметрические агрегатные функции](parametric_functions.md#aggregate_functions_parametric), которые помимо стоблцов принимаю и другие параметры. -> - [Комбинаторы](combinators.md#aggregate_functions_combinators), которые изменяют поведение агрегатных фунций. +- [Параметрические агрегатные функции](parametric_functions.md#aggregate_functions_parametric), которые помимо стоблцов принимаю и другие параметры. +- [Комбинаторы](combinators.md#aggregate_functions_combinators), которые изменяют поведение агрегатных фунций. + +**Оглавление раздела** ```eval_rst .. toctree:: diff --git a/docs/ru/agg_functions/reference.md b/docs/ru/agg_functions/reference.md index 57380e178e8..567f35f303d 100644 --- a/docs/ru/agg_functions/reference.md +++ b/docs/ru/agg_functions/reference.md @@ -1,18 +1,17 @@ -Справочник функций -================== +# Справочник функций -count() -------- + +## count() Считает количество строк. Принимает ноль аргументов, возвращает UInt64. Не поддерживается синтаксис `COUNT(DISTINCT x)` - для этого есть отдельная агрегатная функция `uniq`. Запрос вида `SELECT count() FROM table` не оптимизируется, так как количество записей в таблице нигде не хранится отдельно - из таблицы будет выбран какой-нибудь достаточно маленький столбец, и будет посчитано количество значений в нём. -any(x) ------- + +## any(x) Выбирает первое попавшееся значение. Порядок выполнения запроса может быть произвольным и даже каждый раз разным, поэтому результат данной функции недетерминирован. @@ -22,47 +21,73 @@ any(x) При наличии в запросе `SELECT` секции `GROUP BY` или хотя бы одной агрегатной функции, ClickHouse (в отличие от, например, MySQL) требует, чтобы все выражения в секциях `SELECT`, `HAVING`, `ORDER BY` вычислялись из ключей или из агрегатных функций. То есть, каждый выбираемый из таблицы столбец, должен использоваться либо в ключах, либо внутри агрегатных функций. Чтобы получить поведение, как в MySQL, вы можете поместить остальные столбцы в агрегатную функцию `any`. -anyLast(x) ----------- + +## anyHeavy + +Выбирает часто встречающееся значение с помощью алгоритма "[heavy hitters](http://www.cs.umd.edu/~samir/498/karp.pdf)". Если существует значение, которое встречается чаще, чем в половине случаев, в каждом потоке выполнения запроса, то возвращается данное значение. В общем случае, результат недетерминирован. + +``` +anyHeavy(column) +``` + +**Аргументы** +- `column` - Имя столбца. + +**Пример** + +Возьмем набор данных [OnTime](../getting_started/example_datasets/ontime.md#example_datasets-ontime) и выберем произвольное часто встречающееся значение в столбце `AirlineID`. + +```sql +SELECT anyHeavy(AirlineID) AS res +FROM ontime +``` +``` +┌───res─┐ +│ 19690 │ +└───────┘ +``` + + +## anyLast(x) Выбирает последнее попавшееся значение. Результат так же недетерминирован, как и для функции `any`. -min(x) ------- + +## min(x) Вычисляет минимум. -max(x) ------- + +## max(x) Вычисляет максимум. -argMin(arg, val) ----------------- + +## argMin(arg, val) Вычисляет значение arg при минимальном значении val. Если есть несколько разных значений arg для минимальных значений val, то выдаётся первое попавшееся из таких значений. -argMax(arg, val) ----------------- + +## argMax(arg, val) Вычисляет значение arg при максимальном значении val. Если есть несколько разных значений arg для максимальных значений val, то выдаётся первое попавшееся из таких значений. -sum(x) ------- + +## sum(x) Вычисляет сумму. Работает только для чисел. -sumWithOverflow(x) ------------------- + +## sumWithOverflow(x) Вычисляет сумму чисел, используя для результата тот же тип данных, что и для входных параметров. Если сумма выйдет за максимальное значение для заданного типа данных, то функция вернёт ошибку. Работает только для чисел. -sumMap(key, value) ------------------- + +## sumMap(key, value) Производит суммирование массива 'value' по соотвествующим ключам заданным в массиве 'key'. Количество элементов в 'key' и 'value' должно быть одинаковым для каждой строки, для которой происходит суммирование. @@ -98,15 +123,14 @@ GROUP BY timeslot └─────────────────────┴──────────────────────────────────────────────┘ ``` -avg(x) ------- + +## avg(x) Вычисляет среднее. Работает только для чисел. Результат всегда - Float64. -uniq(x) -------- +## uniq(x) Приближённо вычисляет количество различных значений аргумента. Работает для чисел, строк, дат, дат-с-временем, для нескольких аргументов и аргументов-кортежей. @@ -115,8 +139,8 @@ uniq(x) Результат детерминирован (не зависит от порядка выполнения запроса). -uniqCombined(x) ---------------- + +## uniqCombined(x) Приближённо вычисляет количество различных значений аргумента. Работает для чисел, строк, дат, дат-с-временем, для нескольких аргументов и аргументов-кортежей. @@ -126,8 +150,8 @@ uniqCombined(x) Функция `uniqCombined` является хорошим выбором по умолчанию для подсчёта количества различных значений. -uniqHLL12(x) ------------- + +## uniqHLL12(x) Приближённо вычисляет количество различных значений аргумента, используя алгоритм [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog). Используется 212 5-битовых ячеек. Размер состояния чуть больше 2.5 КБ. @@ -136,8 +160,8 @@ uniqHLL12(x) В большинстве случаев, используйте функцию `uniq` или `uniqCombined`. -uniqExact(x) ------------- + +## uniqExact(x) Вычисляет количество различных значений аргумента, точно. Не стоит бояться приближённых расчётов. Поэтому, используйте лучше функцию `uniq`. @@ -145,8 +169,8 @@ uniqExact(x) Функция `uniqExact` расходует больше оперативки, чем функция `uniq`, так как размер состояния неограниченно растёт по мере роста количества различных значений. -groupArray(x), groupArray(max_size)(x) ---------------------------------------- + +## groupArray(x), groupArray(max_size)(x) Составляет массив из значений аргумента. Значения в массив могут быть добавлены в любом (недетерминированном) порядке. @@ -158,8 +182,8 @@ groupArray(x), groupArray(max_size)(x) -groupArrayInsertAt ------------------- + +## groupArrayInsertAt Вставляет в массив значение в заданную позицию. @@ -170,13 +194,13 @@ groupArrayInsertAt - Значение по умолчанию для подстановки на пустые позиции. - Длина результирующего массива. Например, если вы хотите получать массисы одинакового размера для всех агрегатных ключей. При использовании этого параметра значение по умолчанию задавать обязательно. -groupUniqArray(x) ------------------ + +## groupUniqArray(x) Составляет массив из различных значений аргумента. Расход оперативки такой же, как у функции `uniqExact`. -quantile(level)(x) ------------------- + +## quantile(level)(x) Приближённо вычисляет квантиль уровня level. level - константа, число с плавающей запятой от 0 до 1. Рекомендуется использовать значения level в диапазоне 0.01..0.99. @@ -195,8 +219,8 @@ quantile(level)(x) При использовании нескольких функций `quantile` (и аналогичных) с разными уровнями в запросе, внутренние состояния не объединяются (то есть, запрос работает менее эффективно, чем мог бы). В этом случае, используйте функцию `quantiles` (и аналогичные). -quantileDeterministic(level)(x, determinator) ---------------------------------------------- + +## quantileDeterministic(level)(x, determinator) Работает аналогично функции `quantile`, но, в отличие от неё, результат является детерминированным и не зависит от порядка выполнения запроса. @@ -204,8 +228,8 @@ quantileDeterministic(level)(x, determinator) Не используйте эту функцию для рассчёта таймингов. Для этого есть более подходящая функции - `quantileTiming`. -quantileTiming(level)(x) ------------------------- + +## quantileTiming(level)(x) Вычисляет квантиль уровня level с фиксированной точностью. Работает для чисел. Предназначена для расчёта квантилей от времени загрузки страницы в миллисекундах. @@ -227,26 +251,26 @@ quantileTiming(level)(x) Для своей задачи (расчёт квантилей времени загрузки страниц), использование этой функции эффективнее и результат точнее, чем для функции `quantile`. -quantileTimingWeighted(level)(x, weight) ----------------------------------------- + +## quantileTimingWeighted(level)(x, weight) Отличается от функции medianTiming наличием второго аргумента - «веса». Вес - неотрицательное целое число. Результат считается так же, как если бы в функцию medianTiming\` значение x было передано weight количество раз. -quantileExact(level)(x) ------------------------ + +## quantileExact(level)(x) Вычисляет квантиль уровня level точно. Для этого, все переданные значения складываются в массив, который затем частично сортируется. Поэтому, функция потребляет O(n) памяти, где n - количество переданных значений. Впрочем, для случая маленького количества значений, функция весьма эффективна. -quantileExactWeighted(level)(x, weight) ---------------------------------------- + +## quantileExactWeighted(level)(x, weight) Вычисляет квантиль уровня level точно. При этом, каждое значение учитывается с весом weight - как будто оно присутствует weight раз. Аргументы функции можно рассматривать как гистограммы, где значению x соответствует «столбик» гистограммы высоты weight, а саму функцию можно рассматривать как суммирование гистограмм. В качестве алгоритма используется хэш-таблица. Из-за этого, в случае, если передаваемые значения часто повторяются, функция потребляет меньше оперативки, чем `quantileExact`. Вы можете использовать эту функцию вместо `quantileExact`, указав в качестве веса число 1. -quantileTDigest(level)(x) -------------------------- + +## quantileTDigest(level)(x) Вычисляет квантиль уровня level приближённо, с использованием алгоритма [t-digest](https://github.com/tdunning/t-digest/blob/master/docs/t-digest-paper/histo.pdf). Максимальная погрешность составляет 1%. Расход памяти на состояние пропорционален логарифму от количества переданных значений. @@ -254,55 +278,86 @@ quantileTDigest(level)(x) Результат зависит от порядка выполнения запроса, и является недетерминированным. -median ------- + +## median Для всех quantile-функций, также присутствуют соответствующие median-функции: `median`, `medianDeterministic`, `medianTiming`, `medianTimingWeighted`, `medianExact`, `medianExactWeighted`, `medianTDigest`. Они являются синонимами и их поведение ничем не отличается. -quantiles(level1, level2, ...)(x) ---------------------------------- + +## quantiles(level1, level2, ...)(x) Для всех quantile-функций, также присутствуют соответствующие quantiles-функции: `quantiles`, `quantilesDeterministic`, `quantilesTiming`, `quantilesTimingWeighted`, `quantilesExact`, `quantilesExactWeighted`, `quantilesTDigest`. Эти функции за один проход вычисляют все квантили перечисленных уровней и возвращают массив вычисленных значений. -varSamp(x) ----------- -Вычисляет величину `Σ((x - x̅)2) / (n - 1)`, где n - размер выборки, x̅ - среднее значение x. +## varSamp(x) + +Вычисляет величину `Σ((x - x̅)^2) / (n - 1)`, где `n` - размер выборки, `x̅`- среднее значение `x`. Она представляет собой несмещённую оценку дисперсии случайной величины, если переданные в функцию значения являются выборкой этой случайной величины. -Возвращает Float64. В случае, когда `n <= 1`, возвращается +∞. +Возвращает `Float64`. В случае, когда `n <= 1`, возвращается `+∞`. -varPop(x) ---------- +## varPop(x) -Вычисляет величину `Σ((x - x̅)2) / n`, где n - размер выборки, x̅ - среднее значение x. +Вычисляет величину `Σ((x - x̅)^2) / n`, где `n` - размер выборки, `x̅`- среднее значение `x`. -То есть, дисперсию для множества значений. Возвращает Float64. +То есть, дисперсию для множества значений. Возвращает `Float64`. -stddevSamp(x) -------------- +## stddevSamp(x) Результат равен квадратному корню от `varSamp(x)`. -stddevPop(x) ------------- + +## stddevPop(x) Результат равен квадратному корню от `varPop(x)`. -covarSamp(x, y) ---------------- + +## topK + +Возвращает массив наиболее часто встречающихся значений в указанном столбце. Результирующий массив упорядочен по убыванию частоты значения (не по самим значениям). + +Реализует [Filtered Space-Saving](http://www.l2f.inesc-id.pt/~fmmb/wiki/uploads/Work/misnis.ref0a.pdf) алгоритм для анализа TopK, на основе reduce-and-combine +алгоритма из методики [Parallel Space Saving](https://arxiv.org/pdf/1401.0702.pdf). + +``` +topK(N)(column) +``` + +Функция не дает гарантированного результата, при определенных условиях возможны ошибки и вернутся частые, но не наиболее частые значения. + +Рекомендуем использовать значения `N < 10`, при больших `N` снижается производительность. Максимально возможное значение `N = 65536`. + +**Аргументы** +- 'N' - Количество значений. +- 'x' - Столбец. + +**Пример** + +Возьмем набор данных [OnTime](../getting_started/example_datasets/ontime.md#example_datasets-ontime) и выберем 3 наиболее часто встречающихся значения в столбце `AirlineID`. + +```sql +SELECT topK(3)(AirlineID) AS res +FROM ontime +``` +``` +┌─res─────────────────┐ +│ [19393,19790,19805] │ +└─────────────────────┘ +``` + +## covarSamp(x, y) Вычисляет величину `Σ((x - x̅)(y - y̅)) / (n - 1)`. Возвращает Float64. В случае, когда `n <= 1`, возвращается +∞. -covarPop(x, y) --------------- + +## covarPop(x, y) Вычисляет величину `Σ((x - x̅)(y - y̅)) / n`. -corr(x, y) ----------- -Вычисляет коэффициент корреляции Пирсона: `Σ((x - x̅)(y - y̅)) / sqrt(Σ((x - x̅)2) * Σ((y - y̅)2))`. +## corr(x, y) + +Вычисляет коэффициент корреляции Пирсона: `Σ((x - x̅)(y - y̅)) / sqrt(Σ((x - x̅)^2) * Σ((y - y̅)^2))`. diff --git a/docs/ru/getting_started/example_datasets/ontime.md b/docs/ru/getting_started/example_datasets/ontime.md index b2866eac437..923c33befa1 100644 --- a/docs/ru/getting_started/example_datasets/ontime.md +++ b/docs/ru/getting_started/example_datasets/ontime.md @@ -1,5 +1,6 @@ -OnTime -====== + + +# OnTime Данный тест производительности был создан Вадимом Ткаченко, см: