diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2022-09-16 21:59:36 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2022-09-16 21:59:36 +0300 |
commit | acd29eedcf99f811d7a2229a66bacdcce90a34c8 (patch) | |
tree | d9ffe7a884777b905b87e3053648758beb623497 | |
parent | 1474d6ec81020fbf45ab0ac679448deb57e9678f (diff) | |
download | ydb-acd29eedcf99f811d7a2229a66bacdcce90a34c8.tar.gz |
Update boost/container, boost/move, boost/intrusive to 1.80.0
151 files changed, 9832 insertions, 5689 deletions
diff --git a/contrib/restricted/boost/container/LICENSE_1_0.txt b/contrib/restricted/boost/container/LICENSE_1_0.txt new file mode 100644 index 0000000000..36b7cd93cd --- /dev/null +++ b/contrib/restricted/boost/container/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/contrib/restricted/boost/container/README.md b/contrib/restricted/boost/container/README.md new file mode 100644 index 0000000000..cb4fa18863 --- /dev/null +++ b/contrib/restricted/boost/container/README.md @@ -0,0 +1,39 @@ +Boost.Container +========== + +Boost.Container, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), implements several well-known containers, including STL containers. The aim of the library is to offer advanced features not present in standard containers, to offer the latest standard draft features for compilers that don't comply with the latest C++ standard and to offer useful non-STL containers. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +### Properties + +* C++03 +* Mostly header-only, library compilation is required for few features. +* Supports compiler modes without exceptions support (e.g. `-fno-exceptions`). + +### Build Status + +Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | +:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | +[`master`](https://github.com/boostorg/container/tree/master) | [![Build Status](https://travis-ci.org/boostorg/container.svg?branch=master)](https://travis-ci.org/boostorg/container) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/container-0k1xg/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-container) | [![codecov](https://codecov.io/gh/boostorg/container/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/container/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/container.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/container.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/container.html) +[`develop`](https://github.com/boostorg/container/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/container.svg?branch=develop)](https://travis-ci.org/boostorg/container) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/container-0k1xg/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-container) | [![codecov](https://codecov.io/gh/boostorg/container/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/container/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/container.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/container.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/container.html) + +### Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `doc` | documentation | +| `example` | examples | +| `include` | headers | +| `proj` | ide projects | +| `test` | unit tests | + +### More information + +* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-container) +* [Report bugs](https://github.com/boostorg/container/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). +* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[container]` tag at the beginning of the subject line. + diff --git a/contrib/restricted/boost/container/include/boost/container/allocator_traits.hpp b/contrib/restricted/boost/container/include/boost/container/allocator_traits.hpp index af32f182b6..f5f73efa50 100644 --- a/contrib/restricted/boost/container/include/boost/container/allocator_traits.hpp +++ b/contrib/restricted/boost/container/include/boost/container/allocator_traits.hpp @@ -49,6 +49,11 @@ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-result" +#endif + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl { #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} @@ -70,6 +75,10 @@ #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9 #include <boost/intrusive/detail/has_member_function_callable_with.hpp> +#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) +#pragma GCC diagnostic pop +#endif + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { @@ -77,7 +86,7 @@ namespace container { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -template<class Allocator> +template<class T, class VoidAllocator, class Options> class small_vector_allocator; namespace allocator_traits_detail { @@ -99,8 +108,8 @@ template<class T> struct is_std_allocator< std::allocator<T> > { static const bool value = true; }; -template<class T> -struct is_std_allocator< small_vector_allocator< std::allocator<T> > > +template<class T, class Options> +struct is_std_allocator< small_vector_allocator<T, std::allocator<T>, Options > > { static const bool value = true; }; template<class Allocator> @@ -151,7 +160,7 @@ struct allocator_traits //! Allocator::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>. //! typedef see_documentation void_pointer; - //! Allocator::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const + //! Allocator::const_void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const //! typedef see_documentation const_void_pointer; //! Allocator::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type. @@ -469,6 +478,22 @@ struct allocator_traits #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) }; +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template<class T, class AllocatorOrVoid> +struct real_allocator +{ + typedef AllocatorOrVoid type; +}; + +template<class T> +struct real_allocator<T, void> +{ + typedef new_allocator<T> type; +}; + +#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + } //namespace container { } //namespace boost { diff --git a/contrib/restricted/boost/container/include/boost/container/container_fwd.hpp b/contrib/restricted/boost/container/include/boost/container/container_fwd.hpp index e4fe6f85c3..9e82fdef66 100644 --- a/contrib/restricted/boost/container/include/boost/container/container_fwd.hpp +++ b/contrib/restricted/boost/container/include/boost/container/container_fwd.hpp @@ -24,7 +24,9 @@ //! - boost::container::vector //! - boost::container::stable_vector //! - boost::container::static_vector +//! - boost::container::small_vector_base //! - boost::container::small_vector +//! - boost::container::devector //! - boost::container::slist //! - boost::container::list //! - boost::container::set @@ -94,97 +96,186 @@ template<class T> class new_allocator; template <class T - ,class Allocator = new_allocator<T> - ,class Options = void> + ,class Allocator = void + ,class Options = void> class vector; template <class T - ,class Allocator = new_allocator<T> > + ,class Allocator = void > class stable_vector; -template <class T, std::size_t Capacity> +template < class T + , std::size_t Capacity + , class Options = void> class static_vector; -template < class T, std::size_t N - , class Allocator= new_allocator<T> > +template < class T + , class Allocator = void + , class Options = void > +class small_vector_base; + +template < class T + , std::size_t N + , class Allocator = void + , class Options = void > class small_vector; template <class T - ,class Allocator = new_allocator<T> > + ,class Allocator = void + ,class Options = void> +class devector; + +template <class T + ,class Allocator = void + ,class Options = void> class deque; template <class T - ,class Allocator = new_allocator<T> > + ,class Allocator = void > class list; template <class T - ,class Allocator = new_allocator<T> > + ,class Allocator = void > class slist; template <class Key ,class Compare = std::less<Key> - ,class Allocator = new_allocator<Key> + ,class Allocator = void ,class Options = void> class set; template <class Key ,class Compare = std::less<Key> - ,class Allocator = new_allocator<Key> + ,class Allocator = void ,class Options = void > class multiset; template <class Key ,class T ,class Compare = std::less<Key> - ,class Allocator = new_allocator<std::pair<const Key, T> > + ,class Allocator = void ,class Options = void > class map; template <class Key ,class T ,class Compare = std::less<Key> - ,class Allocator = new_allocator<std::pair<const Key, T> > + ,class Allocator = void ,class Options = void > class multimap; template <class Key ,class Compare = std::less<Key> - ,class Allocator = new_allocator<Key> > + ,class Allocator = void > class flat_set; template <class Key ,class Compare = std::less<Key> - ,class Allocator = new_allocator<Key> > + ,class Allocator = void > class flat_multiset; template <class Key ,class T ,class Compare = std::less<Key> - ,class Allocator = new_allocator<std::pair<Key, T> > > + ,class Allocator = void > class flat_map; template <class Key ,class T ,class Compare = std::less<Key> - ,class Allocator = new_allocator<std::pair<Key, T> > > + ,class Allocator = void > class flat_multimap; +#ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES + +//! Alias templates for small_flat_[multi]{set|map} using small_vector as container + +template < class Key + , std::size_t N + , class Compare = std::less<Key> + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +using small_flat_set = flat_set<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions>>; + +template < class Key + , std::size_t N + , class Compare = std::less<Key> + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +using small_flat_multiset = flat_multiset<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions>>; + +template < class Key + , class T + , std::size_t N + , class Compare = std::less<Key> + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +using small_flat_map = flat_map<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions>>; + +template < class Key + , class T + , std::size_t N + , class Compare = std::less<Key> + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +using small_flat_multimap = flat_multimap<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions>>; + +#endif // #ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES + + +//! A portable metafunction to obtain a small_flat_set +template < class Key + , std::size_t N + , class Compare = std::less<Key> + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +struct small_flat_set_of +{ + typedef flat_set<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions> > type; +}; + +//! A portable metafunction to obtain a small_flat_multiset +template < class Key + , std::size_t N + , class Compare = std::less<Key> + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +struct small_flat_multiset_of +{ + typedef flat_multiset<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions> > type; +}; + +//! A portable metafunction to obtain a small_flat_map +template < class Key + , class T + , std::size_t N + , class Compare = std::less<Key> + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +struct small_flat_map_of +{ + typedef flat_map<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions> > type; +}; + +//! A portable metafunction to obtain a small_flat_multimap +template < class Key + , class T + , std::size_t N + , class Compare = std::less<Key> + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +struct small_flat_multimap_of +{ + typedef flat_multimap<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions> > type; +}; + template <class CharT ,class Traits = std::char_traits<CharT> - ,class Allocator = new_allocator<CharT> > + ,class Allocator = void > class basic_string; -typedef basic_string - <char - ,std::char_traits<char> - ,new_allocator<char> > -string; - -typedef basic_string - <wchar_t - ,std::char_traits<wchar_t> - ,new_allocator<wchar_t> > -wstring; +typedef basic_string <char> string; +typedef basic_string<wchar_t> wstring; static const std::size_t ADP_nodes_per_block = 256u; static const std::size_t ADP_max_free_blocks = 2u; @@ -288,6 +379,7 @@ struct dummy } //detail_really_deep_namespace { +typedef const std::piecewise_construct_t & piecewise_construct_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/contrib/restricted/boost/container/include/boost/container/detail/addressof.hpp b/contrib/restricted/boost/container/include/boost/container/detail/addressof.hpp index b3b8a4dd6f..00679b8f79 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/addressof.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/addressof.hpp @@ -18,21 +18,13 @@ # pragma once #endif -#include <cstddef> +#include <boost/move/detail/addressof.hpp> namespace boost { namespace container { namespace dtl { -template <typename T> -BOOST_CONTAINER_FORCEINLINE T* addressof(T& obj) -{ - return static_cast<T*>( - static_cast<void*>( - const_cast<char*>( - &reinterpret_cast<const volatile char&>(obj) - ))); -} +using boost::move_detail::addressof; } //namespace dtl { } //namespace container { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/advanced_insert_int.hpp b/contrib/restricted/boost/container/include/boost/container/detail/advanced_insert_int.hpp index d9cba4858b..18c7935639 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/advanced_insert_int.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/advanced_insert_int.hpp @@ -36,7 +36,9 @@ #include <boost/move/detail/fwd_macros.hpp> #endif // move + #include <boost/move/utility_core.hpp> +#include <boost/move/detail/force_ptr.hpp> // other #include <boost/assert.hpp> #include <boost/core/no_exceptions_support.hpp> @@ -46,20 +48,19 @@ namespace boost { namespace container { namespace dtl { template<class Allocator, class FwdIt, class Iterator> struct move_insert_range_proxy { - typedef typename allocator_traits<Allocator>::size_type size_type; typedef typename allocator_traits<Allocator>::value_type value_type; - explicit move_insert_range_proxy(FwdIt first) + BOOST_CONTAINER_FORCEINLINE explicit move_insert_range_proxy(FwdIt first) : first_(first) {} - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) { this->first_ = ::boost::container::uninitialized_move_alloc_n_source (a, this->first_, n, p); } - void copy_n_and_update(Allocator &, Iterator p, size_type n) + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) { this->first_ = ::boost::container::move_n_source(this->first_, n, p); } @@ -71,19 +72,18 @@ struct move_insert_range_proxy template<class Allocator, class FwdIt, class Iterator> struct insert_range_proxy { - typedef typename allocator_traits<Allocator>::size_type size_type; typedef typename allocator_traits<Allocator>::value_type value_type; - explicit insert_range_proxy(FwdIt first) + BOOST_CONTAINER_FORCEINLINE explicit insert_range_proxy(FwdIt first) : first_(first) {} - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) { this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p); } - void copy_n_and_update(Allocator &, Iterator p, size_type n) + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) { this->first_ = ::boost::container::copy_n_source(this->first_, n, p); } @@ -95,20 +95,21 @@ struct insert_range_proxy template<class Allocator, class Iterator> struct insert_n_copies_proxy { - typedef typename allocator_traits<Allocator>::size_type size_type; typedef typename allocator_traits<Allocator>::value_type value_type; - explicit insert_n_copies_proxy(const value_type &v) + BOOST_CONTAINER_FORCEINLINE explicit insert_n_copies_proxy(const value_type &v) : v_(v) {} - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const { boost::container::uninitialized_fill_alloc_n(a, v_, n, p); } - void copy_n_and_update(Allocator &, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const { - for (; 0 < n; --n, ++p){ + while (n){ + --n; *p = v_; + ++p; } } @@ -119,48 +120,71 @@ template<class Allocator, class Iterator> struct insert_value_initialized_n_proxy { typedef ::boost::container::allocator_traits<Allocator> alloc_traits; - typedef typename allocator_traits<Allocator>::size_type size_type; typedef typename allocator_traits<Allocator>::value_type value_type; + typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t; - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const { boost::container::uninitialized_value_init_alloc_n(a, n, p); } - void copy_n_and_update(Allocator &, Iterator, size_type) const - { BOOST_ASSERT(false); } + void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const + { + while (n){ + --n; + storage_t v; + alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v)); + value_type *vp = move_detail::force_ptr<value_type *>(&v); + value_destructor<Allocator> on_exit(a, *vp); (void)on_exit; + *p = ::boost::move(*vp); + ++p; + } + } }; template<class Allocator, class Iterator> struct insert_default_initialized_n_proxy { typedef ::boost::container::allocator_traits<Allocator> alloc_traits; - typedef typename allocator_traits<Allocator>::size_type size_type; typedef typename allocator_traits<Allocator>::value_type value_type; + typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t; - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const { boost::container::uninitialized_default_init_alloc_n(a, n, p); } - void copy_n_and_update(Allocator &, Iterator, size_type) const - { BOOST_ASSERT(false); } + void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const + { + if(!is_pod<value_type>::value){ + while (n){ + --n; + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; + alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v), default_init); + value_type *vp = move_detail::force_ptr<value_type *>(&v); + value_destructor<Allocator> on_exit(a, *vp); (void)on_exit; + *p = ::boost::move(*vp); + ++p; + } + } + } }; template<class Allocator, class Iterator> struct insert_copy_proxy { typedef boost::container::allocator_traits<Allocator> alloc_traits; - typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::value_type value_type; - explicit insert_copy_proxy(const value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_copy_proxy(const value_type &v) : v_(v) {} - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const { BOOST_ASSERT(n == 1); (void)n; alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_); } - void copy_n_and_update(Allocator &, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const { BOOST_ASSERT(n == 1); (void)n; *p = v_; @@ -174,20 +198,21 @@ template<class Allocator, class Iterator> struct insert_move_proxy { typedef boost::container::allocator_traits<Allocator> alloc_traits; - typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::value_type value_type; - explicit insert_move_proxy(value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_move_proxy(value_type &v) : v_(v) {} - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const { BOOST_ASSERT(n == 1); (void)n; alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) ); } - void copy_n_and_update(Allocator &, Iterator p, size_type n) const + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const { BOOST_ASSERT(n == 1); (void)n; *p = ::boost::move(v_); @@ -197,13 +222,13 @@ struct insert_move_proxy }; template<class It, class Allocator> -insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v) +BOOST_CONTAINER_FORCEINLINE insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v) { return insert_move_proxy<Allocator, It>(v); } template<class It, class Allocator> -insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v) +BOOST_CONTAINER_FORCEINLINE insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v) { return insert_copy_proxy<Allocator, It>(v); } @@ -223,21 +248,21 @@ template<class Allocator, class Iterator, class ...Args> struct insert_nonmovable_emplace_proxy { typedef boost::container::allocator_traits<Allocator> alloc_traits; - typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::value_type value_type; - typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t; - explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args) : args_(args...) {} - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) { this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); } private: template<std::size_t ...IdxPack> - void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n) + BOOST_CONTAINER_FORCEINLINE void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, std::size_t n) { BOOST_ASSERT(n == 1); (void)n; alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... ); @@ -254,26 +279,26 @@ struct insert_emplace_proxy typedef insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t; typedef boost::container::allocator_traits<Allocator> alloc_traits; typedef typename base_t::value_type value_type; - typedef typename base_t::size_type size_type; typedef typename base_t::index_tuple_t index_tuple_t; - explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args) : base_t(::boost::forward<Args>(args)...) {} - void copy_n_and_update(Allocator &a, Iterator p, size_type n) + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); } private: template<std::size_t ...IdxPack> - void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n) + BOOST_CONTAINER_FORCEINLINE void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, std::size_t n) { BOOST_ASSERT(n ==1); (void)n; - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v; - value_type *vp = static_cast<value_type *>(static_cast<void *>(v.data)); - alloc_traits::construct(a, vp, - ::boost::forward<Args>(get<IdxPack>(this->args_))...); + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; + alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v), ::boost::forward<Args>(get<IdxPack>(this->args_))...); + value_type *vp = move_detail::force_ptr<value_type *>(&v); BOOST_TRY{ *p = ::boost::move(*vp); } @@ -291,7 +316,9 @@ template<class Allocator, class Iterator> struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type> : public insert_move_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v) : insert_move_proxy<Allocator, Iterator>(v) {} }; @@ -305,7 +332,10 @@ struct insert_emplace_proxy<Allocator, Iterator > : public insert_copy_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) + + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) : insert_copy_proxy<Allocator, Iterator>(v) {} }; @@ -314,7 +344,9 @@ template<class Allocator, class Iterator> struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &> : public insert_copy_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) : insert_copy_proxy<Allocator, Iterator>(v) {} }; @@ -325,7 +357,9 @@ struct insert_emplace_proxy<Allocator, Iterator > : public insert_copy_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) : insert_copy_proxy<Allocator, Iterator>(v) {} }; @@ -345,19 +379,20 @@ template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ struct insert_nonmovable_emplace_proxy##N\ {\ typedef boost::container::allocator_traits<Allocator> alloc_traits;\ - typedef typename alloc_traits::size_type size_type;\ typedef typename alloc_traits::value_type value_type;\ \ - explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\ + static const bool single_value = true;\ + \ + BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\ BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\ \ - void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\ + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n)\ {\ BOOST_ASSERT(n == 1); (void)n;\ alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ }\ \ - void copy_n_and_update(Allocator &, Iterator, size_type)\ + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator, std::size_t)\ { BOOST_ASSERT(false); }\ \ protected:\ @@ -371,19 +406,19 @@ struct insert_emplace_proxy_arg##N\ typedef insert_nonmovable_emplace_proxy##N\ < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\ typedef typename base_t::value_type value_type;\ - typedef typename base_t::size_type size_type;\ typedef boost::container::allocator_traits<Allocator> alloc_traits;\ \ - explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\ + static const bool single_value = true;\ + \ + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\ : base_t(BOOST_MOVE_FWD##N){}\ \ - void copy_n_and_update(Allocator &a, Iterator p, size_type n)\ + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, std::size_t n)\ {\ BOOST_ASSERT(n == 1); (void)n;\ - typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\ - BOOST_ASSERT((((size_type)(&v)) % alignment_of<value_type>::value) == 0);\ - value_type *vp = static_cast<value_type *>(static_cast<void *>(v.data));\ - alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\ + alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + value_type *vp = move_detail::force_ptr<value_type *>(&v);\ BOOST_TRY{\ *p = ::boost::move(*vp);\ }\ @@ -406,7 +441,9 @@ template<class Allocator, class Iterator> struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> > : public insert_move_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v) : insert_move_proxy<Allocator, Iterator>(v) {} }; @@ -415,7 +452,9 @@ template<class Allocator, class Iterator> struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type> : public insert_copy_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) : insert_copy_proxy<Allocator, Iterator>(v) {} }; @@ -427,7 +466,9 @@ template<class Allocator, class Iterator> struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type> : public insert_move_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v) : insert_move_proxy<Allocator, Iterator>(v) {} }; @@ -441,7 +482,9 @@ struct insert_emplace_proxy_arg1<Allocator, Iterator > : public insert_copy_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) : insert_copy_proxy<Allocator, Iterator>(v) {} }; @@ -450,7 +493,9 @@ template<class Allocator, class Iterator> struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &> : public insert_copy_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) : insert_copy_proxy<Allocator, Iterator>(v) {} }; @@ -461,7 +506,9 @@ struct insert_emplace_proxy_arg1<Allocator, Iterator > : public insert_copy_proxy<Allocator, Iterator> { - explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) : insert_copy_proxy<Allocator, Iterator>(v) {} }; @@ -472,6 +519,40 @@ struct insert_emplace_proxy_arg1<Allocator, Iterator #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +namespace boost { namespace container { namespace dtl { + +template <class T> +struct has_single_value +{ + private: + struct two {char array_[2];}; + template<bool Arg> struct wrapper; + template <class U> static two test(int, ...); + template <class U> static char test(int, const wrapper<U::single_value>*); + public: + static const bool value = sizeof(test<T>(0, 0)) == 1; + void dummy(){} +}; + +template<class InsertionProxy, bool = has_single_value<InsertionProxy>::value> +struct is_single_value_proxy_impl +{ + static const bool value = InsertionProxy::single_value; +}; + +template<class InsertionProxy> +struct is_single_value_proxy_impl<InsertionProxy, false> +{ + static const bool value = false; +}; + +template<class InsertionProxy> +struct is_single_value_proxy + : is_single_value_proxy_impl<InsertionProxy> +{}; + +}}} //namespace boost { namespace container { namespace dtl { + #include <boost/container/detail/config_end.hpp> #endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP diff --git a/contrib/restricted/boost/container/include/boost/container/detail/algorithm.hpp b/contrib/restricted/boost/container/include/boost/container/detail/algorithm.hpp index 11844220e1..ce5582bcc5 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/algorithm.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/algorithm.hpp @@ -118,6 +118,34 @@ InputIt find_if(InputIt first, InputIt last, UnaryPredicate p) return last; } +template<class ForwardIt1, class ForwardIt2, class BinaryPredicate> + ForwardIt1 find_end (ForwardIt1 first1, ForwardIt1 last1 + ,ForwardIt2 first2, ForwardIt2 last2 + ,BinaryPredicate p) +{ + if (first2==last2) + return last1; // specified in C++11 + + ForwardIt1 ret = last1; + + while (first1!=last1) + { + ForwardIt1 it1 = first1; + ForwardIt2 it2 = first2; + while ( p(*it1, *it2) ) { + ++it1; ++it2; + if (it2==last2) { + ret=first1; + break; + } + if (it1==last1) + return ret; + } + ++first1; + } + return ret; +} + template<class InputIt, class ForwardIt, class BinaryPredicate> InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p) { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/alloc_helpers.hpp b/contrib/restricted/boost/container/include/boost/container/detail/alloc_helpers.hpp index 57c59e46c1..5ca2ca727d 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/alloc_helpers.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/alloc_helpers.hpp @@ -27,30 +27,30 @@ namespace container { namespace dtl { template<class AllocatorType> -inline void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type) +BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type) BOOST_NOEXCEPT_OR_NOTHROW {} template<class AllocatorType> -inline void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) +BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) { boost::adl_move_swap(l, r); } template<class AllocatorType> -inline void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type) +BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type) BOOST_NOEXCEPT_OR_NOTHROW {} template<class AllocatorType> -inline void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type) +BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type) { l = r; } template<class AllocatorType> -inline void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type) +BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type) BOOST_NOEXCEPT_OR_NOTHROW {} template<class AllocatorType> -inline void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) +BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) { l = ::boost::move(r); } } //namespace dtl { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/alloc_lib.h b/contrib/restricted/boost/container/include/boost/container/detail/alloc_lib.h index 950ff722a5..f5f505ca6a 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/alloc_lib.h +++ b/contrib/restricted/boost/container/include/boost/container/detail/alloc_lib.h @@ -196,11 +196,11 @@ typedef struct boost_cont_memchain_impl /*!Indicates the all elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays must be contiguous.*/ -#define DL_MULTIALLOC_ALL_CONTIGUOUS ((size_t)(-1)) +#define BOOST_CONTAINER_DL_MULTIALLOC_ALL_CONTIGUOUS ((size_t)(-1)) /*!Indicates the number of contiguous elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays should be selected by those functions.*/ -#define DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0)) +#define BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0)) typedef struct boost_cont_malloc_stats_impl { @@ -225,8 +225,8 @@ enum BOOST_CONTAINER_EXPAND_OR_NEW = BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BOTH }; -//#define BOOST_CONTAINERDLMALLOC__FOOTERS -#ifndef BOOST_CONTAINERDLMALLOC__FOOTERS +//#define BOOST_CONTAINER_DLMALLOC_FOOTERS +#ifndef BOOST_CONTAINER_DLMALLOC_FOOTERS enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t) }; #else enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t)*2 }; diff --git a/contrib/restricted/boost/container/include/boost/container/detail/allocator_version_traits.hpp b/contrib/restricted/boost/container/include/boost/container/detail/allocator_version_traits.hpp index 18460bdf08..d037e0e392 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/allocator_version_traits.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/allocator_version_traits.hpp @@ -93,7 +93,8 @@ struct allocator_version_traits<Allocator, 1> { size_type n = holder.size(); typename multiallocation_chain::iterator it = holder.begin(); - while(n--){ + while(n){ + --n; pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it); ++it; a.deallocate(p, 1); diff --git a/contrib/restricted/boost/container/include/boost/container/detail/block_list.hpp b/contrib/restricted/boost/container/include/boost/container/detail/block_list.hpp index 1a6057cb4a..0ed0e2279a 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/block_list.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/block_list.hpp @@ -27,6 +27,7 @@ #include <boost/intrusive/circular_list_algorithms.hpp> #include <boost/move/detail/type_traits.hpp> #include <boost/assert.hpp> +#include <boost/container/detail/placement_new.hpp> #include <cstddef> @@ -100,7 +101,7 @@ class block_list_base if((size_t(-1) - header_size) < size) throw_bad_alloc(); void *p = mr.allocate(size+header_size); - block_list_header &mb = *::new((void*)p) DerivedFromBlockListHeader; + block_list_header &mb = *::new((void*)p, boost_container_new_t()) DerivedFromBlockListHeader; mb.size = size+header_size; list_algo::link_after(&m_list, &mb); return (char *)p + header_size; diff --git a/contrib/restricted/boost/container/include/boost/container/detail/block_slist.hpp b/contrib/restricted/boost/container/include/boost/container/detail/block_slist.hpp index 278e6414a7..890e72588e 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/block_slist.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/block_slist.hpp @@ -25,6 +25,7 @@ #include <boost/container/container_fwd.hpp> #include <boost/container/pmr/memory_resource.hpp> #include <boost/container/throw_exception.hpp> +#include <boost/container/detail/placement_new.hpp> #include <boost/move/detail/type_traits.hpp> #include <boost/intrusive/linear_slist_algorithms.hpp> @@ -94,7 +95,7 @@ class block_slist_base if((size_t(-1) - header_size) < size) throw_bad_alloc(); void *p = mr.allocate(size+header_size); - block_slist_header &mb = *::new((void*)p) DerivedFromBlockSlistHeader; + block_slist_header &mb = *::new((void*)p, boost_container_new_t()) DerivedFromBlockSlistHeader; mb.size = size+header_size; slist_algo::link_after(&m_slist, &mb); return (char *)p + header_size; diff --git a/contrib/restricted/boost/container/include/boost/container/detail/compare_functors.hpp b/contrib/restricted/boost/container/include/boost/container/detail/compare_functors.hpp index 28f9093b9a..ae4ffcea9d 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/compare_functors.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/compare_functors.hpp @@ -19,55 +19,115 @@ # pragma once #endif +#include <boost/intrusive/detail/ebo_functor_holder.hpp> +#include <boost/container/detail/workaround.hpp> + namespace boost { namespace container { -template<class Allocator> +template<class ValueType> class equal_to_value { - typedef typename Allocator::value_type value_type; + typedef ValueType value_type; const value_type &t_; public: - explicit equal_to_value(const value_type &t) + BOOST_CONTAINER_FORCEINLINE explicit equal_to_value(const value_type &t) : t_(t) {} - bool operator()(const value_type &t)const + BOOST_CONTAINER_FORCEINLINE bool operator()(const value_type &t)const { return t_ == t; } }; -template<class Node, class Pred> +template<class Node, class Pred, class Ret = bool> struct value_to_node_compare : Pred { typedef Pred predicate_type; typedef Node node_type; - value_to_node_compare() + BOOST_CONTAINER_FORCEINLINE value_to_node_compare() : Pred() {} - explicit value_to_node_compare(Pred pred) + BOOST_CONTAINER_FORCEINLINE explicit value_to_node_compare(Pred pred) : Pred(pred) {} - bool operator()(const Node &a, const Node &b) const + BOOST_CONTAINER_FORCEINLINE Ret operator()(const Node &a, const Node &b) const { return static_cast<const Pred&>(*this)(a.get_data(), b.get_data()); } - bool operator()(const Node &a) const + BOOST_CONTAINER_FORCEINLINE Ret operator()(const Node &a) const { return static_cast<const Pred&>(*this)(a.get_data()); } - bool operator()(const Node &a, const Node &b) + BOOST_CONTAINER_FORCEINLINE Ret operator()(const Node &a, const Node &b) { return static_cast<Pred&>(*this)(a.get_data(), b.get_data()); } - bool operator()(const Node &a) + BOOST_CONTAINER_FORCEINLINE Ret operator()(const Node &a) { return static_cast<Pred&>(*this)(a.get_data()); } - predicate_type & predicate() { return static_cast<predicate_type&>(*this); } - const predicate_type & predicate() const { return static_cast<predicate_type&>(*this); } + BOOST_CONTAINER_FORCEINLINE predicate_type & predicate() { return static_cast<predicate_type&>(*this); } + BOOST_CONTAINER_FORCEINLINE const predicate_type & predicate() const { return static_cast<predicate_type&>(*this); } +}; + +template<class KeyPred, class KeyOfValue, class Node, class Ret = bool> +struct key_node_pred + : public boost::intrusive::detail::ebo_functor_holder<KeyPred> +{ + BOOST_CONTAINER_FORCEINLINE explicit key_node_pred(const KeyPred &comp) + : base_t(comp) + {} + + BOOST_CONTAINER_FORCEINLINE explicit key_node_pred() + {} + + typedef boost::intrusive::detail::ebo_functor_holder<KeyPred> base_t; + typedef KeyPred key_predicate; + typedef KeyOfValue key_of_value; + typedef typename KeyOfValue::type key_type; + + + BOOST_CONTAINER_FORCEINLINE static const key_type &key_from(const Node &n) + { + return key_of_value()(n.get_data()); + } + + template <class T> + BOOST_CONTAINER_FORCEINLINE static const T & + key_from(const T &t) + { return t; } + + BOOST_CONTAINER_FORCEINLINE const key_predicate &key_pred() const + { return static_cast<const key_predicate &>(*this); } + + BOOST_CONTAINER_FORCEINLINE key_predicate &key_pred() + { return static_cast<key_predicate &>(*this); } + + BOOST_CONTAINER_FORCEINLINE Ret operator()(const key_type &key) const + { return this->key_pred()(key); } + + template<class U> + BOOST_CONTAINER_FORCEINLINE Ret operator()(const U &nonkey) const + { return this->key_pred()(this->key_from(nonkey)); } + + BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const + { return this->key_pred()(key1, key2); } + + template<class U> + BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const U &nonkey2) const + { return this->key_pred()(key1, this->key_from(nonkey2)); } + + template<class U> + BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2) const + { return this->key_pred()(this->key_from(nonkey1), key2); } + + template<class U, class V> + BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const V &nonkey2) const + { return this->key_pred()(this->key_from(nonkey1), this->key_from(nonkey2)); } }; + } //namespace container { } //namespace boost { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/config_begin.hpp b/contrib/restricted/boost/container/include/boost/container/detail/config_begin.hpp index 4df9e35d8b..172e685c73 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/config_begin.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/config_begin.hpp @@ -20,9 +20,7 @@ #pragma warning (disable : 4127) // conditional expression is constant #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned #pragma warning (disable : 4197) // top-level volatile in cast is ignored - #pragma warning (disable : 4244) // possible loss of data #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2" - #pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier" #pragma warning (disable : 4284) // odd return type for operator-> #pragma warning (disable : 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) @@ -42,7 +40,6 @@ #pragma warning (disable : 4671) // the copy constructor is inaccessible #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter - #pragma warning (disable : 4702) // unreachable code #pragma warning (disable : 4706) // assignment within conditional expression #pragma warning (disable : 4710) // function not inlined #pragma warning (disable : 4714) // "function": marked as __forceinline not inlined diff --git a/contrib/restricted/boost/container/include/boost/container/detail/construct_in_place.hpp b/contrib/restricted/boost/container/include/boost/container/detail/construct_in_place.hpp index b131f06a86..d824d814af 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/construct_in_place.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/construct_in_place.hpp @@ -30,30 +30,32 @@ namespace container { //In place construction +struct iterator_arg_t{}; + template<class Allocator, class T, class InpIt> BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source) { boost::container::allocator_traits<Allocator>::construct(a, dest, *source); } -template<class Allocator, class T, class U, class D> -BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>) +template<class Allocator, class T, class U> +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U>) { boost::container::allocator_traits<Allocator>::construct(a, dest); } -template <class T, class Difference> +template <class T> class default_init_construct_iterator; -template<class Allocator, class T, class U, class D> -BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>) +template<class Allocator, class T, class U> +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U>) { boost::container::allocator_traits<Allocator>::construct(a, dest, default_init); } -template <class T, class EmplaceFunctor, class Difference> +template <class T, class EmplaceFunctor> class emplace_iterator; -template<class Allocator, class T, class U, class EF, class D> -BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei) +template<class Allocator, class T, class U, class EF> +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF> ei) { ei.construct_in_place(a, dest); } @@ -64,28 +66,28 @@ template<class DstIt, class InpIt> BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source) { *dest = *source; } -template<class DstIt, class U, class D> -BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator<U, D>) +template<class DstIt, class U> +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator<U>) { dtl::value_init<U> val; *dest = boost::move(val.get()); } -template <class DstIt, class Difference> +template <class DstIt> class default_init_construct_iterator; template<class DstIt, class U, class D> -BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator<U, D>) +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator<U>) { U u; *dest = boost::move(u); } -template <class T, class EmplaceFunctor, class Difference> +template <class T, class EmplaceFunctor> class emplace_iterator; -template<class DstIt, class U, class EF, class D> -BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator<U, EF, D> ei) +template<class DstIt, class U, class EF> +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator<U, EF> ei) { ei.assign_in_place(dest); } diff --git a/contrib/restricted/boost/container/include/boost/container/detail/copy_move_algo.hpp b/contrib/restricted/boost/container/include/boost/container/detail/copy_move_algo.hpp index cc87e4abc0..9c76f8d69c 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/copy_move_algo.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/copy_move_algo.hpp @@ -26,6 +26,7 @@ #include <boost/container/detail/mpl.hpp> #include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/construct_in_place.hpp> +#include <boost/container/detail/destroyers.hpp> // move #include <boost/move/adl_move_swap.hpp> @@ -34,7 +35,21 @@ // other #include <boost/core/no_exceptions_support.hpp> // std -#include <cstring> //for emmove/memcpy +#include <cstring> //for memmove/memcpy + +#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) +#pragma GCC diagnostic push +//pair memcpy optimizations rightfully detected by GCC +# if defined(BOOST_GCC) && (BOOST_GCC >= 80000) +# pragma GCC diagnostic ignored "-Wclass-memaccess" +# endif +//GCC 8 seems a bit confused about array access error with static_vector +//when out of bound exceptions are being thrown. +# if defined(BOOST_GCC) && (BOOST_GCC >= 80000) && (BOOST_GCC < 80200) +# pragma GCC diagnostic ignored "-Wstringop-overflow" +# endif +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif namespace boost { namespace container { @@ -112,7 +127,7 @@ struct are_contiguous_and_same : boost::move_detail::and_ < are_elements_contiguous<I> , are_elements_contiguous<O> - , is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type + , is_same< typename remove_const< typename ::boost::container::iter_value<I>::type >::type , typename ::boost::container::iterator_traits<O>::value_type > > @@ -122,7 +137,7 @@ template <typename I, typename O> struct is_memtransfer_copy_assignable : boost::move_detail::and_ < are_contiguous_and_same<I, O> - , dtl::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type > + , dtl::is_trivially_copy_assignable< typename ::boost::container::iter_value<I>::type > > {}; @@ -130,7 +145,7 @@ template <typename I, typename O> struct is_memtransfer_copy_constructible : boost::move_detail::and_ < are_contiguous_and_same<I, O> - , dtl::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type > + , dtl::is_trivially_copy_constructible< typename ::boost::container::iter_value<I>::type > > {}; @@ -157,56 +172,72 @@ struct disable_if_memtransfer_copy_assignable template <typename I, // I models InputIterator typename F> // F models ForwardIterator -inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW { - typedef typename boost::container::iterator_traits<I>::value_type value_type; - typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l); - if(n){ - std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); - boost::container::iterator_advance(r, n); + typedef typename boost::container::iter_value<I>::type value_type; + typedef typename boost::container::iterator_traits<F>::difference_type r_difference_type; + value_type *const dest_raw = boost::movelib::iterator_to_raw_pointer(r); + const value_type *const beg_raw = boost::movelib::iterator_to_raw_pointer(f); + const value_type *const end_raw = boost::movelib::iterator_to_raw_pointer(l); + if(BOOST_LIKELY(beg_raw != end_raw && dest_raw && beg_raw)){ + const std::size_t n = std::size_t(end_raw - beg_raw) ; + std::memmove(dest_raw, beg_raw, sizeof(value_type)*n); + r += static_cast<r_difference_type>(n); } return r; } template <typename I, // I models InputIterator - typename U, // U models unsigned integral constant typename F> // F models ForwardIterator -F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE F memmove_n(I f, std::size_t n, F r) BOOST_NOEXCEPT_OR_NOTHROW { - typedef typename boost::container::iterator_traits<I>::value_type value_type; - if(n){ - std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); - boost::container::iterator_advance(r, n); + typedef typename boost::container::iter_value<I>::type value_type; + typedef typename boost::container::iterator_traits<F>::difference_type r_difference_type; + if(BOOST_LIKELY(n != 0)){ + void *dst = boost::movelib::iterator_to_raw_pointer(r); + const void *src = boost::movelib::iterator_to_raw_pointer(f); + if (dst && src) + std::memmove(dst, src, sizeof(value_type)*n); + r += static_cast<r_difference_type>(n); } + return r; } template <typename I, // I models InputIterator - typename U, // U models unsigned integral constant typename F> // F models ForwardIterator -I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE I memmove_n_source(I f, std::size_t n, F r) BOOST_NOEXCEPT_OR_NOTHROW { - if(n){ - typedef typename boost::container::iterator_traits<I>::value_type value_type; - std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); - boost::container::iterator_advance(f, n); + if(BOOST_LIKELY(n != 0)){ + typedef typename boost::container::iter_value<I>::type value_type; + typedef typename boost::container::iterator_traits<I>::difference_type i_difference_type; + void *dst = boost::movelib::iterator_to_raw_pointer(r); + const void *src = boost::movelib::iterator_to_raw_pointer(f); + if (dst && src) + std::memmove(dst, src, sizeof(value_type)*n); + f += static_cast<i_difference_type>(n); } return f; } template <typename I, // I models InputIterator - typename U, // U models unsigned integral constant typename F> // F models ForwardIterator -I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE I memmove_n_source_dest(I f, std::size_t n, F &r) BOOST_NOEXCEPT_OR_NOTHROW { - typedef typename boost::container::iterator_traits<I>::value_type value_type; - if(n){ - std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); - boost::container::iterator_advance(f, n); - boost::container::iterator_advance(r, n); + typedef typename boost::container::iter_value<I>::type value_type; + typedef typename boost::container::iterator_traits<F>::difference_type i_difference_type; + typedef typename boost::container::iterator_traits<F>::difference_type f_difference_type; + + if(BOOST_LIKELY(n != 0)){ + void *dst = boost::movelib::iterator_to_raw_pointer(r); + const void *src = boost::movelib::iterator_to_raw_pointer(f); + if (dst && src) + std::memmove(dst, src, sizeof(value_type)*n); + f += i_difference_type(n); + r += f_difference_type(n); } return f; } @@ -242,14 +273,14 @@ struct disable_if_memzero_initializable template <typename I, typename R> struct enable_if_trivially_destructible : enable_if_c < dtl::is_trivially_destructible - <typename boost::container::iterator_traits<I>::value_type>::value + <typename boost::container::iter_value<I>::type>::value , R> {}; template <typename I, typename R> struct disable_if_trivially_destructible : enable_if_c <!dtl::is_trivially_destructible - <typename boost::container::iterator_traits<I>::value_type>::value + <typename boost::container::iter_value<I>::type>::value , R> {}; @@ -297,7 +328,7 @@ template <typename Allocator, typename I, // I models InputIterator typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove(f, l, r); } @@ -319,11 +350,12 @@ template typename I, // I models InputIterator typename F> // F models ForwardIterator inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, F>::type - uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) + uninitialized_move_alloc_n(Allocator &a, I f, std::size_t n, F r) { F back = r; BOOST_TRY{ - while (n--) { + while (n) { + --n; allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); ++f; ++r; } @@ -342,8 +374,8 @@ template <typename Allocator, typename I, // I models InputIterator typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type - uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type + uninitialized_move_alloc_n(Allocator &, I f, std::size_t n, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -364,11 +396,12 @@ template typename I, // I models InputIterator typename F> // F models ForwardIterator inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, I>::type - uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) + uninitialized_move_alloc_n_source(Allocator &a, I f, std::size_t n, F r) { F back = r; BOOST_TRY{ - while (n--) { + while (n) { + --n; allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); ++f; ++r; } @@ -387,8 +420,8 @@ template <typename Allocator, typename I, // I models InputIterator typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type - uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type + uninitialized_move_alloc_n_source(Allocator &, I f, std::size_t n, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n_source(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -432,7 +465,7 @@ template <typename Allocator, typename I, // I models InputIterator typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove(f, l, r); } @@ -454,11 +487,12 @@ template typename I, // I models InputIterator typename F> // F models ForwardIterator inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, F>::type - uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) + uninitialized_copy_alloc_n(Allocator &a, I f, std::size_t n, F r) { F back = r; BOOST_TRY{ - while (n--) { + while (n) { + --n; allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f); ++f; ++r; } @@ -477,8 +511,8 @@ template <typename Allocator, typename I, // I models InputIterator typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type - uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type + uninitialized_copy_alloc_n(Allocator &, I f, std::size_t n, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -499,13 +533,13 @@ template typename I, // I models InputIterator typename F> // F models ForwardIterator inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, I>::type - uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) + uninitialized_copy_alloc_n_source(Allocator &a, I f, std::size_t n, F r) { F back = r; BOOST_TRY{ - while (n--) { + while (n) { boost::container::construct_in_place(a, boost::movelib::iterator_to_raw_pointer(r), f); - ++f; ++r; + ++f; ++r; --n; } } BOOST_CATCH(...){ @@ -522,8 +556,8 @@ template <typename Allocator, typename I, // I models InputIterator typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type - uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type + uninitialized_copy_alloc_n_source(Allocator &, I f, std::size_t n, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n_source(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -543,11 +577,12 @@ template <typename Allocator, typename F> // F models ForwardIterator inline typename dtl::disable_if_memzero_initializable<F, F>::type - uninitialized_value_init_alloc_n(Allocator &a, typename boost::container::allocator_traits<Allocator>::size_type n, F r) + uninitialized_value_init_alloc_n(Allocator &a, std::size_t n, F r) { F back = r; BOOST_TRY{ - while (n--) { + while (n) { + --n; allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r)); ++r; } @@ -565,12 +600,16 @@ inline typename dtl::disable_if_memzero_initializable<F, F>::type template <typename Allocator, typename F> // F models ForwardIterator -inline typename dtl::enable_if_memzero_initializable<F, F>::type - uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits<Allocator>::size_type n, F r) +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memzero_initializable<F, F>::type + uninitialized_value_init_alloc_n(Allocator &, std::size_t n, F r) { typedef typename boost::container::iterator_traits<F>::value_type value_type; - std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n); - boost::container::iterator_advance(r, n); + typedef typename boost::container::iterator_traits<F>::difference_type r_difference_type; + + if (BOOST_LIKELY(n != 0)){ + std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n); + r += static_cast<r_difference_type>(n); + } return r; } @@ -590,11 +629,12 @@ inline typename dtl::enable_if_memzero_initializable<F, F>::type template <typename Allocator, typename F> // F models ForwardIterator -inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::container::allocator_traits<Allocator>::size_type n, F r) +inline F uninitialized_default_init_alloc_n(Allocator &a, std::size_t n, F r) { F back = r; BOOST_TRY{ - while (n--) { + while (n) { + --n; allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init); ++r; } @@ -662,11 +702,12 @@ template <typename Allocator, typename T, typename F> // F models ForwardIterator -inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::container::allocator_traits<Allocator>::size_type n, F r) +inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, std::size_t n, F r) { F back = r; BOOST_TRY{ - while (n--) { + while (n) { + --n; allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), v); ++r; } @@ -720,7 +761,8 @@ typename F> // F models ForwardIterator inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type copy_n(I f, U n, F r) { - while (n--) { + while (n) { + --n; *r = *f; ++f; ++r; } @@ -731,7 +773,7 @@ template <typename I, // I models InputIterator typename U, // U models unsigned integral constant typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type copy_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n(f, n, r); } @@ -748,7 +790,8 @@ typename F> // F models ForwardIterator inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type copy_n_source(I f, U n, F r) { - while (n--) { + while (n) { + --n; boost::container::assign_in_place(r, f); ++f; ++r; } @@ -757,10 +800,9 @@ inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type template <typename I, // I models InputIterator -typename U, // U models unsigned integral constant typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type - copy_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type + copy_n_source(I f, std::size_t n, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n_source(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -771,12 +813,12 @@ inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type template <typename I, // I models InputIterator -typename U, // U models unsigned integral constant typename F> // F models ForwardIterator inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type - copy_n_source_dest(I f, U n, F &r) + copy_n_source_dest(I f, std::size_t n, F &r) { - while (n--) { + while (n) { + --n; *r = *f; ++f; ++r; } @@ -785,10 +827,9 @@ inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type template <typename I, // I models InputIterator -typename U, // U models unsigned integral constant typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type - copy_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type + copy_n_source_dest(I f, std::size_t n, F &r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n_source_dest(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -830,7 +871,8 @@ typename F> // F models ForwardIterator inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type move_n(I f, U n, F r) { - while (n--) { + while (n) { + --n; *r = ::boost::move(*f); ++f; ++r; } @@ -841,7 +883,7 @@ template <typename I, // I models InputIterator typename U, // U models unsigned integral constant typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type move_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n(f, n, r); } @@ -868,13 +910,15 @@ inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type template <typename I, // I models InputIterator typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type move_backward(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW { - typedef typename boost::container::iterator_traits<I>::value_type value_type; - const typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l); - r -= n; - std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n); + typedef typename boost::container::iter_value<I>::type value_type; + const std::size_t n = boost::container::iterator_udistance(f, l); + if (BOOST_LIKELY(n != 0)){ + r -= n; + std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n); + } return r; } @@ -891,7 +935,8 @@ template inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type move_n_source_dest(I f, U n, F &r) { - while (n--) { + while (n) { + --n; *r = ::boost::move(*f); ++f; ++r; } @@ -900,10 +945,9 @@ inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type template <typename I // I models InputIterator -,typename U // U models unsigned integral constant ,typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type - move_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type + move_n_source_dest(I f, std::size_t n, F &r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n_source_dest(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -919,7 +963,8 @@ template inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type move_n_source(I f, U n, F r) { - while (n--) { + while (n) { + --n; *r = ::boost::move(*f); ++f; ++r; } @@ -928,10 +973,9 @@ inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type template <typename I // I models InputIterator -,typename U // U models unsigned integral constant ,typename F> // F models ForwardIterator -inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type - move_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type + move_n_source(I f, std::size_t n, F r) BOOST_NOEXCEPT_OR_NOTHROW { return dtl::memmove_n_source(f, n, r); } ////////////////////////////////////////////////////////////////////////////// @@ -958,7 +1002,7 @@ template <typename Allocator ,typename I // I models InputIterator ,typename U> // U models unsigned integral constant -inline typename dtl::enable_if_trivially_destructible<I, void>::type +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_trivially_destructible<I, void>::type destroy_alloc_n(Allocator &, I, U) {} @@ -975,15 +1019,14 @@ template ,typename G // G models ForwardIterator > inline typename dtl::disable_if_memtransfer_copy_assignable<F, G, void>::type - deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i - , G large_range_f, typename allocator_traits<Allocator>::size_type n_j) + deep_swap_alloc_n( Allocator &a, F short_range_f, std::size_t n_i, G large_range_f, std::size_t n_j) { - typename allocator_traits<Allocator>::size_type n = 0; + std::size_t n = 0; for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){ boost::adl_move_swap(*short_range_f, *large_range_f); } - boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw - boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); + boost::container::uninitialized_move_alloc_n(a, large_range_f, std::size_t(n_j - n_i), short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, std::size_t(n_j - n_i)); } static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes @@ -997,8 +1040,7 @@ template inline typename dtl::enable_if_c < dtl::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false , void>::type - deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i - , G large_range_f, typename allocator_traits<Allocator>::size_type n_j) + deep_swap_alloc_n( Allocator &a, F short_range_f, std::size_t n_i, G large_range_f, std::size_t n_j) { typedef typename allocator_traits<Allocator>::value_type value_type; typedef typename dtl::aligned_storage @@ -1012,10 +1054,10 @@ inline typename dtl::enable_if_c std::memcpy(stora_ptr, large_ptr, n_i_bytes); std::memcpy(large_ptr, short_ptr, n_i_bytes); std::memcpy(short_ptr, stora_ptr, n_i_bytes); - boost::container::iterator_advance(large_range_f, n_i); - boost::container::iterator_advance(short_range_f, n_i); - boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw - boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); + boost::container::iterator_uadvance(large_range_f, n_i); + boost::container::iterator_uadvance(short_range_f, n_i); + boost::container::uninitialized_move_alloc_n(a, large_range_f, std::size_t(n_j - n_i), short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, std::size_t(n_j - n_i)); } template @@ -1027,8 +1069,7 @@ template inline typename dtl::enable_if_c < dtl::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage) , void>::type - deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i - , G large_range_f, typename allocator_traits<Allocator>::size_type n_j) + deep_swap_alloc_n( Allocator &a, F short_range_f, std::size_t n_i, G large_range_f, std::size_t n_j) { typedef typename allocator_traits<Allocator>::value_type value_type; typedef typename dtl::aligned_storage @@ -1083,10 +1124,10 @@ inline typename dtl::enable_if_c std::memcpy(stora_ptr, large_ptr, szt_rem); std::memcpy(large_ptr, short_ptr, szt_rem); std::memcpy(short_ptr, stora_ptr, szt_rem); - boost::container::iterator_advance(large_range_f, n_i); - boost::container::iterator_advance(short_range_f, n_i); - boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw - boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); + boost::container::iterator_uadvance(large_range_f, n_i); + boost::container::iterator_uadvance(short_range_f, n_i); + boost::container::uninitialized_move_alloc_n(a, large_range_f, std::size_t(n_j - n_i), short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, std::size_t(n_j - n_i)); } @@ -1101,16 +1142,15 @@ template ,typename I // F models InputIterator ,typename O // G models OutputIterator > -void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i - , O out_start, typename allocator_traits<Allocator>::size_type n_o ) +void copy_assign_range_alloc_n( Allocator &a, I inp_start, std::size_t n_i, O out_start, std::size_t n_o ) { if (n_o < n_i){ inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw - boost::container::uninitialized_copy_alloc_n(a, inp_start, n_i - n_o, out_start);// may throw + boost::container::uninitialized_copy_alloc_n(a, inp_start, std::size_t(n_i - n_o), out_start);// may throw } else{ out_start = boost::container::copy_n(inp_start, n_i, out_start); // may throw - boost::container::destroy_alloc_n(a, out_start, n_o - n_i); + boost::container::destroy_alloc_n(a, out_start, std::size_t(n_o - n_i)); } } @@ -1125,20 +1165,117 @@ template ,typename I // F models InputIterator ,typename O // G models OutputIterator > -void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i - , O out_start, typename allocator_traits<Allocator>::size_type n_o ) +void move_assign_range_alloc_n( Allocator &a, I inp_start, std::size_t n_i, O out_start, std::size_t n_o ) { if (n_o < n_i){ inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw - boost::container::uninitialized_move_alloc_n(a, inp_start, n_i - n_o, out_start); // may throw + boost::container::uninitialized_move_alloc_n(a, inp_start, std::size_t(n_i - n_o), out_start); // may throw } else{ out_start = boost::container::move_n(inp_start, n_i, out_start); // may throw - boost::container::destroy_alloc_n(a, out_start, n_o - n_i); + boost::container::destroy_alloc_n(a, out_start, std::size_t(n_o - n_i)); + } +} + +template<class Allocator, class Iterator> +struct array_destructor +{ + typedef typename ::boost::container::iterator_traits<Iterator>::value_type value_type; + typedef typename dtl::if_c + <dtl::is_trivially_destructible<value_type>::value + ,dtl::null_scoped_destructor_range<Allocator> + ,dtl::scoped_destructor_range<Allocator> + >::type type; +}; + +template + <typename Allocator + ,typename F // F models ForwardIterator + ,typename O // G models OutputIterator + ,typename InsertionProxy + > +void uninitialized_move_and_insert_alloc + ( Allocator &a + , F first + , F pos + , F last + , O d_first + , std::size_t n + , InsertionProxy insert_range_proxy) +{ + typedef typename array_destructor<Allocator, F>::type array_destructor_t; + + //Anti-exception rollbacks + array_destructor_t new_values_destroyer(d_first, d_first, a); + + //Initialize with [begin(), pos) old buffer + //the start of the new buffer + O d_last = ::boost::container::uninitialized_move_alloc(a, first, pos, d_first); + new_values_destroyer.set_end(d_last); + //Initialize new objects, starting from previous point + insert_range_proxy.uninitialized_copy_n_and_update(a, d_last, n); + d_last += n; + new_values_destroyer.set_end(d_last); + //Initialize from the rest of the old buffer, + //starting from previous point + (void) ::boost::container::uninitialized_move_alloc(a, pos, last, d_last); + //All construction successful, disable rollbacks + new_values_destroyer.release(); +} + +template + <typename Allocator + ,typename F // F models ForwardIterator + ,typename InsertionProxy + > +void expand_forward_and_insert_alloc + ( Allocator &a + , F pos + , F last + , std::size_t n + , InsertionProxy insert_range_proxy) +{ + typedef typename array_destructor<Allocator, F>::type array_destructor_t; + + if (BOOST_UNLIKELY(!n)){ + return; + } + else if (last == pos){ + insert_range_proxy.uninitialized_copy_n_and_update(a, last, n); + } + else{ + const std::size_t elems_after = static_cast<std::size_t>(last - pos); + if(elems_after >= n){ + //New elements can be just copied. + //Move to uninitialized memory last objects + ::boost::container::uninitialized_move_alloc_n(a, last - n, n, last); + array_destructor_t on_exception(last, last, a); + //Copy previous to last objects to the initialized end + boost::container::move_backward(pos, last - n, last); + //Insert new objects in the pos + insert_range_proxy.copy_n_and_update(a, pos, n); + on_exception.release(); + } + else { + //The new elements don't fit in the [pos, end()) range. + //Copy old [pos, end()) elements to the uninitialized memory (a gap is created) + F new_last = ::boost::container::uninitialized_move_alloc(a, pos, last, pos + n); + array_destructor_t on_exception(pos + n, new_last, a); + //Copy first new elements in pos (gap is still there) + insert_range_proxy.copy_n_and_update(a, pos, elems_after); + //Copy to the beginning of the unallocated zone the last new elements (the gap is closed). + insert_range_proxy.uninitialized_copy_n_and_update(a, last, std::size_t(n - elems_after)); + on_exception.release(); + } } } } //namespace container { } //namespace boost { +//#pragma GCC diagnostic ignored "-Wclass-memaccess" +#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) +#pragma GCC diagnostic pop +#endif + #endif //#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP diff --git a/contrib/restricted/boost/container/include/boost/container/detail/destroyers.hpp b/contrib/restricted/boost/container/include/boost/container/detail/destroyers.hpp index 9b0be44e66..45bc431ce2 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/destroyers.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/destroyers.hpp @@ -83,9 +83,8 @@ struct null_scoped_deallocator { typedef boost::container::allocator_traits<Allocator> AllocTraits; typedef typename AllocTraits::pointer pointer; - typedef typename AllocTraits::size_type size_type; - null_scoped_deallocator(pointer, Allocator&, size_type) + null_scoped_deallocator(pointer, Allocator&, std::size_t) {} void release() @@ -107,11 +106,11 @@ struct scoped_array_deallocator typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::size_type size_type; - scoped_array_deallocator(pointer p, Allocator& a, size_type length) + scoped_array_deallocator(pointer p, Allocator& a, std::size_t length) : m_ptr(p), m_alloc(a), m_length(length) {} ~scoped_array_deallocator() - { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); } + { if (m_ptr) m_alloc.deallocate(m_ptr, size_type(m_length)); } void release() { m_ptr = 0; } @@ -119,7 +118,7 @@ struct scoped_array_deallocator private: pointer m_ptr; Allocator& m_alloc; - size_type m_length; + std::size_t m_length; }; template <class Allocator> @@ -127,9 +126,8 @@ struct null_scoped_array_deallocator { typedef boost::container::allocator_traits<Allocator> AllocTraits; typedef typename AllocTraits::pointer pointer; - typedef typename AllocTraits::size_type size_type; - null_scoped_array_deallocator(pointer, Allocator&, size_type) + null_scoped_array_deallocator(pointer, Allocator&, std::size_t) {} void release() @@ -137,22 +135,21 @@ struct null_scoped_array_deallocator }; template <class Allocator> -struct scoped_destroy_deallocator +struct scoped_node_destroy_deallocator { typedef boost::container::allocator_traits<Allocator> AllocTraits; typedef typename AllocTraits::pointer pointer; - typedef typename AllocTraits::size_type size_type; typedef dtl::integral_constant<unsigned, boost::container::dtl:: version<Allocator>::value> alloc_version; - scoped_destroy_deallocator(pointer p, Allocator& a) + scoped_node_destroy_deallocator(pointer p, Allocator& a) : m_ptr(p), m_alloc(a) {} - ~scoped_destroy_deallocator() + ~scoped_node_destroy_deallocator() { if(m_ptr){ - AllocTraits::destroy(m_alloc, boost::movelib::to_raw_pointer(m_ptr)); + boost::movelib::to_raw_pointer(m_ptr)->destructor(m_alloc); priv_deallocate(m_ptr, alloc_version()); } } @@ -181,37 +178,39 @@ struct scoped_destructor_n typedef boost::container::allocator_traits<Allocator> AllocTraits; typedef typename AllocTraits::pointer pointer; typedef typename AllocTraits::value_type value_type; - typedef typename AllocTraits::size_type size_type; - scoped_destructor_n(pointer p, Allocator& a, size_type n) + BOOST_CONTAINER_FORCEINLINE scoped_destructor_n(pointer p, Allocator& a, std::size_t n) : m_p(p), m_a(a), m_n(n) {} - void release() - { m_p = 0; } + BOOST_CONTAINER_FORCEINLINE void release() + { m_p = 0; m_n = 0; } - void increment_size(size_type inc) + BOOST_CONTAINER_FORCEINLINE void increment_size(std::size_t inc) { m_n += inc; } - void increment_size_backwards(size_type inc) - { m_n += inc; m_p -= inc; } + BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(std::size_t inc) + { m_n += inc; m_p -= std::ptrdiff_t(inc); } - void shrink_forward(size_type inc) - { m_n -= inc; m_p += inc; } + BOOST_CONTAINER_FORCEINLINE void shrink_forward(std::size_t inc) + { m_n -= inc; m_p += std::ptrdiff_t(inc); } ~scoped_destructor_n() { - if(!m_p) return; - value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p); - while(m_n--){ - AllocTraits::destroy(m_a, raw_ptr++); + if(m_n){ + value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p); + do { + --m_n; + AllocTraits::destroy(m_a, raw_ptr); + ++raw_ptr; + } while(m_n); } } private: pointer m_p; Allocator & m_a; - size_type m_n; + std::size_t m_n; }; //!A deleter for scoped_ptr that destroys @@ -221,48 +220,113 @@ struct null_scoped_destructor_n { typedef boost::container::allocator_traits<Allocator> AllocTraits; typedef typename AllocTraits::pointer pointer; - typedef typename AllocTraits::size_type size_type; - null_scoped_destructor_n(pointer, Allocator&, size_type) + BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_n(pointer, Allocator&, std::size_t) {} - void increment_size(size_type) + BOOST_CONTAINER_FORCEINLINE void increment_size(std::size_t) {} - void increment_size_backwards(size_type) + BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(std::size_t) {} - void shrink_forward(size_type) + BOOST_CONTAINER_FORCEINLINE void shrink_forward(std::size_t) {} - void release() + BOOST_CONTAINER_FORCEINLINE void release() + {} +}; + + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template <class Allocator> +struct scoped_destructor_range +{ + typedef boost::container::allocator_traits<Allocator> AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::value_type value_type; + + BOOST_CONTAINER_FORCEINLINE scoped_destructor_range(pointer p, pointer e, Allocator& a) + : m_p(p), m_e(e), m_a(a) + {} + + BOOST_CONTAINER_FORCEINLINE void release() + { m_p = pointer(); m_e = pointer(); } + + BOOST_CONTAINER_FORCEINLINE void set_end(pointer e) + { m_e = e; } + + BOOST_CONTAINER_FORCEINLINE void set_begin(pointer b) + { m_p = b; } + + BOOST_CONTAINER_FORCEINLINE void set_range(pointer b, pointer e) + { m_p = b; m_e = e; } + + ~scoped_destructor_range() + { + while(m_p != m_e){ + value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p); + AllocTraits::destroy(m_a, raw_ptr); + ++m_p; + } + } + + private: + pointer m_p; + pointer m_e; + Allocator & m_a; +}; + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template <class Allocator> +struct null_scoped_destructor_range +{ + typedef boost::container::allocator_traits<Allocator> AllocTraits; + typedef typename AllocTraits::pointer pointer; + + BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_range(pointer, pointer, Allocator&) + {} + + BOOST_CONTAINER_FORCEINLINE void release() + {} + + BOOST_CONTAINER_FORCEINLINE void set_end(pointer) + {} + + BOOST_CONTAINER_FORCEINLINE void set_begin(pointer) + {} + + BOOST_CONTAINER_FORCEINLINE void set_range(pointer, pointer) {} }; + template<class Allocator> class scoped_destructor { typedef boost::container::allocator_traits<Allocator> AllocTraits; public: typedef typename Allocator::value_type value_type; - scoped_destructor(Allocator &a, value_type *pv) + BOOST_CONTAINER_FORCEINLINE scoped_destructor(Allocator &a, value_type *pv) : pv_(pv), a_(a) {} - ~scoped_destructor() + BOOST_CONTAINER_FORCEINLINE ~scoped_destructor() { if(pv_){ AllocTraits::destroy(a_, pv_); } } - void release() + BOOST_CONTAINER_FORCEINLINE void release() { pv_ = 0; } - void set(value_type *ptr) { pv_ = ptr; } + BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; } - value_type *get() const { return pv_; } + BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; } private: value_type *pv_; @@ -276,11 +340,11 @@ class value_destructor typedef boost::container::allocator_traits<Allocator> AllocTraits; public: typedef Value value_type; - value_destructor(Allocator &a, value_type &rv) + BOOST_CONTAINER_FORCEINLINE value_destructor(Allocator &a, value_type &rv) : rv_(rv), a_(a) {} - ~value_destructor() + BOOST_CONTAINER_FORCEINLINE ~value_destructor() { AllocTraits::destroy(a_, &rv_); } @@ -291,7 +355,7 @@ class value_destructor }; template <class Allocator> -class allocator_destroyer +class allocator_node_destroyer { typedef boost::container::allocator_traits<Allocator> AllocTraits; typedef typename AllocTraits::value_type value_type; @@ -304,26 +368,58 @@ class allocator_destroyer Allocator & a_; private: - void priv_deallocate(const pointer &p, version_1) + BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_1) { AllocTraits::deallocate(a_,p, 1); } - void priv_deallocate(const pointer &p, version_2) + BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_2) { a_.deallocate_one(p); } public: - explicit allocator_destroyer(Allocator &a) + BOOST_CONTAINER_FORCEINLINE explicit allocator_node_destroyer(Allocator &a) : a_(a) {} - void operator()(const pointer &p) + BOOST_CONTAINER_FORCEINLINE void operator()(const pointer &p) { - AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p)); + boost::movelib::to_raw_pointer(p)->destructor(a_); this->priv_deallocate(p, alloc_version()); } }; +template<class Allocator> +class scoped_node_destructor +{ + typedef boost::container::allocator_traits<Allocator> AllocTraits; + public: + typedef typename Allocator::value_type value_type; + BOOST_CONTAINER_FORCEINLINE scoped_node_destructor(Allocator &a, value_type *pv) + : pv_(pv), a_(a) + {} + + BOOST_CONTAINER_FORCEINLINE ~scoped_node_destructor() + { + if(pv_){ + pv_->destructor(a_); + } + } + + BOOST_CONTAINER_FORCEINLINE void release() + { pv_ = 0; } + + + BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; } + + BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; } + + private: + value_type *pv_; + Allocator &a_; +}; + + + template <class Allocator> -class allocator_destroyer_and_chain_builder +class allocator_node_destroyer_and_chain_builder { typedef allocator_traits<Allocator> allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; @@ -333,13 +429,13 @@ class allocator_destroyer_and_chain_builder multiallocation_chain &c_; public: - allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c) + BOOST_CONTAINER_FORCEINLINE allocator_node_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c) : a_(a), c_(c) {} - void operator()(const typename Allocator::pointer &p) + BOOST_CONTAINER_FORCEINLINE void operator()(const typename Allocator::pointer &p) { - allocator_traits<Allocator>::destroy(a_, boost::movelib::to_raw_pointer(p)); + boost::movelib::to_raw_pointer(p)->destructor(a_); c_.push_back(p); } }; @@ -350,20 +446,20 @@ class allocator_multialloc_chain_node_deallocator typedef allocator_traits<Allocator> allocator_traits_type; typedef typename allocator_traits_type::value_type value_type; typedef typename Allocator::multiallocation_chain multiallocation_chain; - typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder; + typedef allocator_node_destroyer_and_chain_builder<Allocator> chain_builder; Allocator & a_; multiallocation_chain c_; public: - allocator_multialloc_chain_node_deallocator(Allocator &a) + BOOST_CONTAINER_FORCEINLINE allocator_multialloc_chain_node_deallocator(Allocator &a) : a_(a), c_() {} - chain_builder get_chain_builder() + BOOST_CONTAINER_FORCEINLINE chain_builder get_chain_builder() { return chain_builder(a_, c_); } - ~allocator_multialloc_chain_node_deallocator() + BOOST_CONTAINER_FORCEINLINE ~allocator_multialloc_chain_node_deallocator() { a_.deallocate_individual(c_); } diff --git a/contrib/restricted/boost/container/include/boost/container/detail/dispatch_uses_allocator.hpp b/contrib/restricted/boost/container/include/boost/container/detail/dispatch_uses_allocator.hpp index 0b8cfea66c..800b1b3aa8 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/dispatch_uses_allocator.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/dispatch_uses_allocator.hpp @@ -23,11 +23,13 @@ #include <boost/container/detail/addressof.hpp> #include <boost/container/detail/mpl.hpp> -#include <boost/container/detail/pair.hpp> +#include <boost/container/detail/is_pair.hpp> #include <boost/container/detail/type_traits.hpp> #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include <boost/move/detail/fwd_macros.hpp> +#else +#include <boost/container/detail/variadic_templates_tools.hpp> #endif #include <boost/move/utility_core.hpp> @@ -110,10 +112,10 @@ template < typename ConstructAlloc , typename T , class ...Args > -inline typename dtl::enable_if_and +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and < void , dtl::is_not_pair<T> - , dtl::not_< uses_allocator<T, ArgAlloc> > + , dtl::not_< uses_allocator<T, typename remove_cvref<ArgAlloc>::type > > >::type dispatch_uses_allocator ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args) { @@ -127,10 +129,10 @@ template < typename ConstructAlloc , typename T , class ...Args > -inline typename dtl::enable_if_and +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and < void , dtl::is_not_pair<T> - , uses_allocator<T, ArgAlloc> + , uses_allocator<T, typename remove_cvref<ArgAlloc>::type> , is_constructible_with_allocator_prefix<T, ArgAlloc, Args...> >::type dispatch_uses_allocator ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args) ...args) @@ -146,10 +148,10 @@ template < typename ConstructAlloc , typename T , class ...Args > -inline typename dtl::enable_if_and +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and < void , dtl::is_not_pair<T> - , uses_allocator<T, ArgAlloc> + , uses_allocator<T, typename remove_cvref<ArgAlloc>::type> , dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc, Args...> > >::type dispatch_uses_allocator ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args) @@ -162,10 +164,10 @@ inline typename dtl::enable_if_and #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \ template <typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ - inline typename dtl::enable_if_and\ + BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\ < void\ , dtl::is_not_pair<T>\ - , dtl::not_<uses_allocator<T, ArgAlloc> >\ + , dtl::not_<uses_allocator<T, typename remove_cvref<ArgAlloc>::type> >\ >::type\ dispatch_uses_allocator\ (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ @@ -179,10 +181,10 @@ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \ template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ - inline typename dtl::enable_if_and\ + BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\ < void\ , dtl::is_not_pair<T>\ - , uses_allocator<T, ArgAlloc>\ + , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\ , is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>\ >::type\ dispatch_uses_allocator\ @@ -197,10 +199,10 @@ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \ template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ - inline typename dtl::enable_if_and\ + BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\ < void\ , dtl::is_not_pair<T>\ - , uses_allocator<T, ArgAlloc>\ + , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\ , dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N> >\ >::type\ dispatch_uses_allocator\ @@ -219,15 +221,15 @@ template < typename ConstructAlloc , typename ArgAlloc , typename Pair > inline -BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> >::type) +BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> BOOST_MOVE_I void >::type) dispatch_uses_allocator ( ConstructAlloc & construct_alloc , BOOST_FWD_REF(ArgAlloc) arg_alloc , Pair* p) { - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first)); + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first)); BOOST_TRY{ - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second)); + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second)); } BOOST_CATCH(...) { allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first)); @@ -240,15 +242,15 @@ BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> >::type) template < typename ConstructAlloc , typename ArgAlloc , class Pair, class U, class V> -BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> >::type) +BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> BOOST_MOVE_I void>::type) dispatch_uses_allocator ( ConstructAlloc & construct_alloc , BOOST_FWD_REF(ArgAlloc) arg_alloc , Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y) { - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<U>(x)); + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<U>(x)); BOOST_TRY{ - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<V>(y)); + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<V>(y)); } BOOST_CATCH(...){ allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first)); @@ -260,12 +262,12 @@ BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> >::type) template < typename ConstructAlloc , typename ArgAlloc , class Pair, class Pair2> -BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if< dtl::is_pair<Pair> >::type) +BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void >::type) dispatch_uses_allocator (ConstructAlloc & construct_alloc , BOOST_FWD_REF(ArgAlloc) arg_alloc , Pair* p, Pair2& x) -{ (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, x.first, x.second); } +{ dispatch_uses_allocator(construct_alloc, arg_alloc, p, x.first, x.second); } template < typename ConstructAlloc , typename ArgAlloc @@ -278,7 +280,7 @@ typename dtl::enable_if_and (ConstructAlloc & construct_alloc , BOOST_FWD_REF(ArgAlloc) arg_alloc , Pair* p, BOOST_RV_REF_BEG Pair2 BOOST_RV_REF_END x) -{ (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, ::boost::move(x.first), ::boost::move(x.second)); } +{ dispatch_uses_allocator(construct_alloc, arg_alloc, p, ::boost::move(x.first), ::boost::move(x.second)); } //piecewise construction from boost::tuple @@ -286,16 +288,16 @@ typename dtl::enable_if_and template< typename ConstructAlloc, typename ArgAlloc, class Pair \ , template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \ BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ -typename dtl::enable_if< dtl::is_pair<Pair> >::type\ +typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\ dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ , BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\ , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\ {\ (void)p; (void)q;\ - (dispatch_uses_allocator)\ + dispatch_uses_allocator\ (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_TMPL_GET##N);\ BOOST_TRY{\ - (dispatch_uses_allocator)\ + dispatch_uses_allocator\ (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_TMPL_GETQ##M);\ }\ BOOST_CATCH(...) {\ @@ -317,9 +319,9 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO , Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>) { (void)t1; (void)t2; - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(pair->first), ::boost::forward<Args1>(get<Indexes1>(t1))...); + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(pair->first), ::boost::forward<Args1>(get<Indexes1>(t1))...); BOOST_TRY{ - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(pair->second), ::boost::forward<Args2>(get<Indexes2>(t2))...); + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(pair->second), ::boost::forward<Args2>(get<Indexes2>(t2))...); } BOOST_CATCH(...){ allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first)); @@ -330,7 +332,7 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO template< typename ConstructAlloc, typename ArgAlloc, class Pair , template<class ...> class Tuple, class... Args1, class... Args2> - typename dtl::enable_if< dtl::is_pair<Pair> >::type + typename dtl::enable_if< dtl::is_pair<Pair>, void >::type dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t , Tuple<Args1...> t1, Tuple<Args2...> t2) { @@ -346,16 +348,16 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO template< typename ConstructAlloc, typename ArgAlloc, class Pair\ , template<class, class, class, class, class, class, class, class, class, class> class StdTuple\ BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ - typename dtl::enable_if< dtl::is_pair<Pair> >::type\ + typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\ dispatch_uses_allocator(ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\ , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\ {\ (void)p; (void)q;\ - (dispatch_uses_allocator)\ + dispatch_uses_allocator\ (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\ BOOST_TRY{\ - (dispatch_uses_allocator)\ + dispatch_uses_allocator\ (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\ }\ BOOST_CATCH(...) {\ @@ -380,17 +382,17 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO template< typename ConstructAlloc, typename ArgAlloc, class Pair\ , template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \ BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ - typename dtl::enable_if< dtl::is_pair<Pair> >::type\ + typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\ dispatch_uses_allocator\ ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\ , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\ {\ (void)p; (void)q;\ - (dispatch_uses_allocator)\ + dispatch_uses_allocator\ (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\ BOOST_TRY{\ - (dispatch_uses_allocator)\ + dispatch_uses_allocator\ (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\ }\ BOOST_CATCH(...) {\ @@ -415,9 +417,9 @@ typename dtl::enable_if< dtl::is_pair<Pair>, void >::type dispatch_uses_allocator (ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args) { - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k)); + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k)); BOOST_TRY{ - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<Args>(args)...); + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<Args>(args)...); } BOOST_CATCH(...) { allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first)); @@ -431,14 +433,14 @@ typename dtl::enable_if< dtl::is_pair<Pair>, void >::type #define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE(N) \ template <typename ConstructAlloc, typename ArgAlloc, class Pair, class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ inline typename dtl::enable_if\ - < dtl::is_pair<Pair>, void >::type\ + < dtl::is_pair<Pair> BOOST_MOVE_I void >::type\ dispatch_uses_allocator\ (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, \ BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ {\ - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));\ + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));\ BOOST_TRY{\ - (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ }\ BOOST_CATCH(...) {\ allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));\ diff --git a/contrib/restricted/boost/container/include/boost/container/detail/is_pair.hpp b/contrib/restricted/boost/container/include/boost/container/detail/is_pair.hpp new file mode 100644 index 0000000000..239e36e114 --- /dev/null +++ b/contrib/restricted/boost/container/include/boost/container/detail/is_pair.hpp @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. +// +// 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/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_IS_PAIR_HPP +#define BOOST_CONTAINER_CONTAINER_DETAIL_IS_PAIR_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include <boost/container/detail/config_begin.hpp> +#include <boost/container/detail/workaround.hpp> +#include <boost/container/detail/std_fwd.hpp> + +#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520) +//MSVC 2010 tuple marker +namespace std { namespace tr1 { struct _Nil; }} +#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540) +//MSVC 2012 tuple marker +namespace std { struct _Nil; } +#endif + +namespace boost { +namespace tuples { + +struct null_type; + +template < + class T0, class T1, class T2, + class T3, class T4, class T5, + class T6, class T7, class T8, + class T9> +class tuple; + +} //namespace tuples { +} //namespace boost { + +namespace boost { +namespace container { + +struct try_emplace_t{}; + +namespace dtl { + +template <class T1, class T2> +struct pair; + +template <class T> +struct is_pair +{ + static const bool value = false; +}; + +template <class T1, class T2> +struct is_pair< pair<T1, T2> > +{ + static const bool value = true; +}; + +template <class T1, class T2> +struct is_pair< std::pair<T1, T2> > +{ + static const bool value = true; +}; + +template <class T> +struct is_not_pair +{ + static const bool value = !is_pair<T>::value; +}; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#include <boost/container/detail/config_end.hpp> + +#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_IS_PAIR_HPP diff --git a/contrib/restricted/boost/container/include/boost/container/detail/iterator.hpp b/contrib/restricted/boost/container/include/boost/container/detail/iterator.hpp index 2ceaf26001..ce37adcfff 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/iterator.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/iterator.hpp @@ -23,13 +23,20 @@ #include <boost/intrusive/detail/iterator.hpp> #include <boost/move/utility_core.hpp> +#include <boost/container/detail/mpl.hpp> namespace boost { namespace container { using ::boost::intrusive::iterator_traits; +using ::boost::intrusive::iter_difference; +using ::boost::intrusive::iter_category; +using ::boost::intrusive::iter_value; +using ::boost::intrusive::iter_size; using ::boost::intrusive::iterator_distance; +using ::boost::intrusive::iterator_udistance; using ::boost::intrusive::iterator_advance; +using ::boost::intrusive::iterator_uadvance; using ::boost::intrusive::iterator; using ::boost::intrusive::iterator_enable_if_tag; using ::boost::intrusive::iterator_disable_if_tag; @@ -63,6 +70,21 @@ class back_emplacer back_emplacer& operator++(int){ return *this; } }; +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template<class InputIterator> +using it_based_non_const_first_type_t = typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type; + +template<class InputIterator> +using it_based_const_first_type_t = const typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type; + +template<class InputIterator> +using it_based_second_type_t = typename iterator_traits<InputIterator>::value_type::second_type; + +template<class InputIterator> +using it_based_value_type_t = typename iterator_traits<InputIterator>::value_type; + +#endif } //namespace container { } //namespace boost { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/iterators.hpp b/contrib/restricted/boost/container/include/boost/container/detail/iterators.hpp index 1676be8be9..c503916a96 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/iterators.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/iterators.hpp @@ -41,191 +41,210 @@ namespace boost { namespace container { -template <class T, class Difference = std::ptrdiff_t> +template <class T> class constant_iterator : public ::boost::container::iterator - <std::random_access_iterator_tag, T, Difference, const T*, const T &> + <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> { - typedef constant_iterator<T, Difference> this_type; + typedef constant_iterator<T> this_type; public: - explicit constant_iterator(const T &ref, Difference range_size) + BOOST_CONTAINER_FORCEINLINE explicit constant_iterator(const T &ref, std::size_t range_size) : m_ptr(&ref), m_num(range_size){} //Constructors - constant_iterator() + BOOST_CONTAINER_FORCEINLINE constant_iterator() : m_ptr(0), m_num(0){} - constant_iterator& operator++() + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator++() { increment(); return *this; } - constant_iterator operator++(int) + BOOST_CONTAINER_FORCEINLINE constant_iterator operator++(int) { constant_iterator result (*this); increment(); return result; } - constant_iterator& operator--() + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator--() { decrement(); return *this; } - constant_iterator operator--(int) + BOOST_CONTAINER_FORCEINLINE constant_iterator operator--(int) { constant_iterator result (*this); decrement(); return result; } - friend bool operator== (const constant_iterator& i, const constant_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const constant_iterator& i, const constant_iterator& i2) { return i.equal(i2); } - friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) { return !(i == i2); } - friend bool operator< (const constant_iterator& i, const constant_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const constant_iterator& i, const constant_iterator& i2) { return i.less(i2); } - friend bool operator> (const constant_iterator& i, const constant_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const constant_iterator& i, const constant_iterator& i2) { return i2 < i; } - friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) { return !(i > i2); } - friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) { return !(i < i2); } - friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const constant_iterator& i, const constant_iterator& i2) { return i2.distance_to(i); } - //Arithmetic - constant_iterator& operator+=(Difference off) + //Arithmetic signed + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator+=(std::ptrdiff_t off) { this->advance(off); return *this; } - constant_iterator operator+(Difference off) const + BOOST_CONTAINER_FORCEINLINE constant_iterator operator+(std::ptrdiff_t off) const { constant_iterator other(*this); other.advance(off); return other; } - friend constant_iterator operator+(Difference off, const constant_iterator& right) + BOOST_CONTAINER_FORCEINLINE friend constant_iterator operator+(std::ptrdiff_t off, const constant_iterator& right) { return right + off; } - constant_iterator& operator-=(Difference off) + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator-=(std::ptrdiff_t off) { this->advance(-off); return *this; } - constant_iterator operator-(Difference off) const + BOOST_CONTAINER_FORCEINLINE constant_iterator operator-(std::ptrdiff_t off) const { return *this + (-off); } - const T& operator*() const + BOOST_CONTAINER_FORCEINLINE const T& operator[] (std::ptrdiff_t ) const { return dereference(); } - const T& operator[] (Difference ) const + BOOST_CONTAINER_FORCEINLINE const T& operator*() const { return dereference(); } - const T* operator->() const + BOOST_CONTAINER_FORCEINLINE const T* operator->() const { return &(dereference()); } + //Arithmetic unsigned + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator+=(std::size_t off) + { return *this += std::ptrdiff_t(off); } + + BOOST_CONTAINER_FORCEINLINE constant_iterator operator+(std::size_t off) const + { return *this + std::ptrdiff_t(off); } + + BOOST_CONTAINER_FORCEINLINE friend constant_iterator operator+(std::size_t off, const constant_iterator& right) + { return std::ptrdiff_t(off) + right; } + + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator-=(std::size_t off) + { return *this -= std::ptrdiff_t(off); } + + BOOST_CONTAINER_FORCEINLINE constant_iterator operator-(std::size_t off) const + { return *this - std::ptrdiff_t(off); } + + BOOST_CONTAINER_FORCEINLINE const T& operator[] (std::size_t off) const + { return (*this)[std::ptrdiff_t(off)]; } + private: const T * m_ptr; - Difference m_num; + std::size_t m_num; - void increment() + BOOST_CONTAINER_FORCEINLINE void increment() { --m_num; } - void decrement() + BOOST_CONTAINER_FORCEINLINE void decrement() { ++m_num; } - bool equal(const this_type &other) const + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const { return m_num == other.m_num; } - bool less(const this_type &other) const + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const { return other.m_num < m_num; } - const T & dereference() const + BOOST_CONTAINER_FORCEINLINE const T & dereference() const { return *m_ptr; } - void advance(Difference n) - { m_num -= n; } + BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n) + { m_num = std::size_t(std::ptrdiff_t(m_num) - n); } - Difference distance_to(const this_type &other)const - { return m_num - other.m_num; } + BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const + { return std::ptrdiff_t(m_num - other.m_num); } }; -template <class T, class Difference> +template <class T> class value_init_construct_iterator : public ::boost::container::iterator - <std::random_access_iterator_tag, T, Difference, const T*, const T &> + <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> { - typedef value_init_construct_iterator<T, Difference> this_type; + typedef value_init_construct_iterator<T> this_type; public: - explicit value_init_construct_iterator(Difference range_size) + BOOST_CONTAINER_FORCEINLINE explicit value_init_construct_iterator(std::size_t range_size) : m_num(range_size){} //Constructors - value_init_construct_iterator() + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator() : m_num(0){} - value_init_construct_iterator& operator++() + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator++() { increment(); return *this; } - value_init_construct_iterator operator++(int) + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator++(int) { value_init_construct_iterator result (*this); increment(); return result; } - value_init_construct_iterator& operator--() + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator--() { decrement(); return *this; } - value_init_construct_iterator operator--(int) + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator--(int) { value_init_construct_iterator result (*this); decrement(); return result; } - friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return i.equal(i2); } - friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return !(i == i2); } - friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return i.less(i2); } - friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return i2 < i; } - friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return !(i > i2); } - friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return !(i < i2); } - friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return i2.distance_to(i); } //Arithmetic - value_init_construct_iterator& operator+=(Difference off) + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator+=(std::ptrdiff_t off) { this->advance(off); return *this; } - value_init_construct_iterator operator+(Difference off) const + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator+(std::ptrdiff_t off) const { value_init_construct_iterator other(*this); other.advance(off); return other; } - friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right) + BOOST_CONTAINER_FORCEINLINE friend value_init_construct_iterator operator+(std::ptrdiff_t off, const value_init_construct_iterator& right) { return right + off; } - value_init_construct_iterator& operator-=(Difference off) + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator-=(std::ptrdiff_t off) { this->advance(-off); return *this; } - value_init_construct_iterator operator-(Difference off) const + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator-(std::ptrdiff_t off) const { return *this + (-off); } //This pseudo-iterator's dereference operations have no sense since value is not @@ -236,107 +255,107 @@ class value_init_construct_iterator //const T* operator->() const; private: - Difference m_num; + std::size_t m_num; - void increment() + BOOST_CONTAINER_FORCEINLINE void increment() { --m_num; } - void decrement() + BOOST_CONTAINER_FORCEINLINE void decrement() { ++m_num; } - bool equal(const this_type &other) const + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const { return m_num == other.m_num; } - bool less(const this_type &other) const + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const { return other.m_num < m_num; } - const T & dereference() const + BOOST_CONTAINER_FORCEINLINE const T & dereference() const { static T dummy; return dummy; } - void advance(Difference n) - { m_num -= n; } + BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n) + { m_num = std::size_t(std::ptrdiff_t(m_num) - n); } - Difference distance_to(const this_type &other)const - { return m_num - other.m_num; } + BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const + { return std::ptrdiff_t(m_num - other.m_num); } }; -template <class T, class Difference> +template <class T> class default_init_construct_iterator : public ::boost::container::iterator - <std::random_access_iterator_tag, T, Difference, const T*, const T &> + <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> { - typedef default_init_construct_iterator<T, Difference> this_type; + typedef default_init_construct_iterator<T> this_type; public: - explicit default_init_construct_iterator(Difference range_size) + BOOST_CONTAINER_FORCEINLINE explicit default_init_construct_iterator(std::size_t range_size) : m_num(range_size){} //Constructors - default_init_construct_iterator() + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator() : m_num(0){} - default_init_construct_iterator& operator++() + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator++() { increment(); return *this; } - default_init_construct_iterator operator++(int) + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator++(int) { default_init_construct_iterator result (*this); increment(); return result; } - default_init_construct_iterator& operator--() + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator--() { decrement(); return *this; } - default_init_construct_iterator operator--(int) + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator--(int) { default_init_construct_iterator result (*this); decrement(); return result; } - friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) { return i.equal(i2); } - friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) { return !(i == i2); } - friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) { return i.less(i2); } - friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) { return i2 < i; } - friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) { return !(i > i2); } - friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) { return !(i < i2); } - friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) { return i2.distance_to(i); } //Arithmetic - default_init_construct_iterator& operator+=(Difference off) + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator+=(std::ptrdiff_t off) { this->advance(off); return *this; } - default_init_construct_iterator operator+(Difference off) const + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator+(std::ptrdiff_t off) const { default_init_construct_iterator other(*this); other.advance(off); return other; } - friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right) + BOOST_CONTAINER_FORCEINLINE friend default_init_construct_iterator operator+(std::ptrdiff_t off, const default_init_construct_iterator& right) { return right + off; } - default_init_construct_iterator& operator-=(Difference off) + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator-=(std::ptrdiff_t off) { this->advance(-off); return *this; } - default_init_construct_iterator operator-(Difference off) const + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator-(std::ptrdiff_t off) const { return *this + (-off); } //This pseudo-iterator's dereference operations have no sense since value is not @@ -347,153 +366,153 @@ class default_init_construct_iterator //const T* operator->() const; private: - Difference m_num; + std::size_t m_num; - void increment() + BOOST_CONTAINER_FORCEINLINE void increment() { --m_num; } - void decrement() + BOOST_CONTAINER_FORCEINLINE void decrement() { ++m_num; } - bool equal(const this_type &other) const + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const { return m_num == other.m_num; } - bool less(const this_type &other) const + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const { return other.m_num < m_num; } - const T & dereference() const + BOOST_CONTAINER_FORCEINLINE const T & dereference() const { static T dummy; return dummy; } - void advance(Difference n) - { m_num -= n; } + BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n) + { m_num = std::size_t(std::ptrdiff_t(m_num) - n); } - Difference distance_to(const this_type &other)const - { return m_num - other.m_num; } + BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other) const + { return std::ptrdiff_t(m_num - other.m_num); } }; -template <class T, class Difference = std::ptrdiff_t> +template <class T> class repeat_iterator : public ::boost::container::iterator - <std::random_access_iterator_tag, T, Difference, T*, T&> + <std::random_access_iterator_tag, T, std::ptrdiff_t, T*, T&> { - typedef repeat_iterator<T, Difference> this_type; + typedef repeat_iterator<T> this_type; public: - explicit repeat_iterator(T &ref, Difference range_size) + BOOST_CONTAINER_FORCEINLINE explicit repeat_iterator(T &ref, std::size_t range_size) : m_ptr(&ref), m_num(range_size){} //Constructors - repeat_iterator() + BOOST_CONTAINER_FORCEINLINE repeat_iterator() : m_ptr(0), m_num(0){} - this_type& operator++() + BOOST_CONTAINER_FORCEINLINE this_type& operator++() { increment(); return *this; } - this_type operator++(int) + BOOST_CONTAINER_FORCEINLINE this_type operator++(int) { this_type result (*this); increment(); return result; } - this_type& operator--() + BOOST_CONTAINER_FORCEINLINE this_type& operator--() { increment(); return *this; } - this_type operator--(int) + BOOST_CONTAINER_FORCEINLINE this_type operator--(int) { this_type result (*this); increment(); return result; } - friend bool operator== (const this_type& i, const this_type& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2) { return i.equal(i2); } - friend bool operator!= (const this_type& i, const this_type& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2) { return !(i == i2); } - friend bool operator< (const this_type& i, const this_type& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2) { return i.less(i2); } - friend bool operator> (const this_type& i, const this_type& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2) { return i2 < i; } - friend bool operator<= (const this_type& i, const this_type& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2) { return !(i > i2); } - friend bool operator>= (const this_type& i, const this_type& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2) { return !(i < i2); } - friend Difference operator- (const this_type& i, const this_type& i2) + BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2) { return i2.distance_to(i); } //Arithmetic - this_type& operator+=(Difference off) + BOOST_CONTAINER_FORCEINLINE this_type& operator+=(std::ptrdiff_t off) { this->advance(off); return *this; } - this_type operator+(Difference off) const + BOOST_CONTAINER_FORCEINLINE this_type operator+(std::ptrdiff_t off) const { this_type other(*this); other.advance(off); return other; } - friend this_type operator+(Difference off, const this_type& right) + BOOST_CONTAINER_FORCEINLINE friend this_type operator+(std::ptrdiff_t off, const this_type& right) { return right + off; } - this_type& operator-=(Difference off) + BOOST_CONTAINER_FORCEINLINE this_type& operator-=(std::ptrdiff_t off) { this->advance(-off); return *this; } - this_type operator-(Difference off) const + BOOST_CONTAINER_FORCEINLINE this_type operator-(std::ptrdiff_t off) const { return *this + (-off); } - T& operator*() const + BOOST_CONTAINER_FORCEINLINE T& operator*() const { return dereference(); } - T& operator[] (Difference ) const + BOOST_CONTAINER_FORCEINLINE T& operator[] (std::ptrdiff_t ) const { return dereference(); } - T *operator->() const + BOOST_CONTAINER_FORCEINLINE T *operator->() const { return &(dereference()); } private: T * m_ptr; - Difference m_num; + std::size_t m_num; - void increment() + BOOST_CONTAINER_FORCEINLINE void increment() { --m_num; } - void decrement() + BOOST_CONTAINER_FORCEINLINE void decrement() { ++m_num; } - bool equal(const this_type &other) const + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const { return m_num == other.m_num; } - bool less(const this_type &other) const + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const { return other.m_num < m_num; } - T & dereference() const + BOOST_CONTAINER_FORCEINLINE T & dereference() const { return *m_ptr; } - void advance(Difference n) - { m_num -= n; } + BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n) + { m_num = std::size_t(std::ptrdiff_t(m_num - n)); } - Difference distance_to(const this_type &other)const - { return m_num - other.m_num; } + BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const + { return std::ptrdiff_t(m_num - other.m_num); } }; -template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/> +template <class T, class EmplaceFunctor> class emplace_iterator : public ::boost::container::iterator - <std::random_access_iterator_tag, T, Difference, const T*, const T &> + <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> { typedef emplace_iterator this_type; public: - typedef Difference difference_type; + typedef std::ptrdiff_t difference_type; BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e) : m_num(1), m_pe(&e){} @@ -503,7 +522,7 @@ class emplace_iterator BOOST_CONTAINER_FORCEINLINE this_type& operator++() { increment(); return *this; } - this_type operator++(int) + BOOST_CONTAINER_FORCEINLINE this_type operator++(int) { this_type result (*this); increment(); @@ -513,7 +532,7 @@ class emplace_iterator BOOST_CONTAINER_FORCEINLINE this_type& operator--() { decrement(); return *this; } - this_type operator--(int) + BOOST_CONTAINER_FORCEINLINE this_type operator--(int) { this_type result (*this); decrement(); @@ -545,7 +564,7 @@ class emplace_iterator BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off) { this->advance(off); return *this; } - this_type operator+(difference_type off) const + BOOST_CONTAINER_FORCEINLINE this_type operator+(difference_type off) const { this_type other(*this); other.advance(off); @@ -571,15 +590,15 @@ class emplace_iterator public: template<class Allocator> - void construct_in_place(Allocator &a, T* ptr) + BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* ptr) { (*m_pe)(a, ptr); } template<class DestIt> - void assign_in_place(DestIt dest) + BOOST_CONTAINER_FORCEINLINE void assign_in_place(DestIt dest) { (*m_pe)(dest); } private: - difference_type m_num; + std::size_t m_num; EmplaceFunctor * m_pe; BOOST_CONTAINER_FORCEINLINE void increment() @@ -614,7 +633,7 @@ struct emplace_functor { typedef typename dtl::build_number_seq<sizeof...(Args)>::type index_tuple_t; - emplace_functor(BOOST_FWD_REF(Args)... args) + BOOST_CONTAINER_FORCEINLINE emplace_functor(BOOST_FWD_REF(Args)... args) : args_(args...) {} @@ -661,15 +680,15 @@ struct emplace_functor_type; BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ struct emplace_functor##N\ {\ - explicit emplace_functor##N( BOOST_MOVE_UREF##N )\ + BOOST_CONTAINER_FORCEINLINE explicit emplace_functor##N( BOOST_MOVE_UREF##N )\ BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ \ template<class Allocator, class T>\ - void operator()(Allocator &a, T *ptr)\ + BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)\ { allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\ \ template<class DestIt>\ - void operator()(DestIt dest)\ + BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)\ {\ typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\ BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), dtl::value_init<value_type> tmp) ;\ @@ -864,7 +883,7 @@ class iterator_from_iiterator { return l.m_iit == r.m_iit; } BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW - { return !(l == r); } + { return l.m_iit != r.m_iit; } BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW { return this->m_iit->get_data(); } diff --git a/contrib/restricted/boost/container/include/boost/container/detail/mpl.hpp b/contrib/restricted/boost/container/include/boost/container/detail/mpl.hpp index 4bb3cc7d22..ffae180c85 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/mpl.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/mpl.hpp @@ -61,6 +61,7 @@ using boost::move_detail::enable_if_and; using boost::move_detail::disable_if_and; using boost::move_detail::enable_if_or; using boost::move_detail::disable_if_or; +using boost::move_detail::remove_const; template <class FirstType> struct select1st @@ -68,14 +69,71 @@ struct select1st typedef FirstType type; template<class T> - const type& operator()(const T& x) const + BOOST_CONTAINER_FORCEINLINE const type& operator()(const T& x) const { return x.first; } template<class T> - type& operator()(T& x) + BOOST_CONTAINER_FORCEINLINE type& operator()(T& x) { return const_cast<type&>(x.first); } }; + +template<typename T> +struct void_t { typedef void type; }; + +template <class T, class=void> +struct is_transparent_base +{ + static const bool value = false; +}; + +template <class T> +struct is_transparent_base<T, typename void_t<typename T::is_transparent>::type> +{ + static const bool value = true; +}; + +template <class T> +struct is_transparent + : is_transparent_base<T> +{}; + +template <typename C, class /*Dummy*/, typename R> +struct enable_if_transparent + : boost::move_detail::enable_if_c<dtl::is_transparent<C>::value, R> +{}; + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +// void_t (void_t for C++11) +template<typename...> using variadic_void_t = void; + +// Trait to detect Allocator-like types. +template<typename Allocator, typename = void> +struct is_allocator +{ + static const bool value = false; +}; + +template <typename T> +T&& ctad_declval(); + +template<typename Allocator> +struct is_allocator < Allocator, + variadic_void_t< typename Allocator::value_type + , decltype(ctad_declval<Allocator&>().allocate(size_t{})) >> +{ + static const bool value = true; +}; + +template<class T> +using require_allocator_t = typename enable_if_c<is_allocator<T>::value, T>::type; + +template<class T> +using require_nonallocator_t = typename enable_if_c<!is_allocator<T>::value, T>::type; + +#endif + } //namespace dtl { } //namespace container { } //namespace boost { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/multiallocation_chain.hpp b/contrib/restricted/boost/container/include/boost/container/detail/multiallocation_chain.hpp index c10f809bb4..749ef5a0ad 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/multiallocation_chain.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/multiallocation_chain.hpp @@ -27,9 +27,11 @@ #include <boost/move/detail/to_raw_pointer.hpp> #include <boost/container/detail/transform_iterator.hpp> #include <boost/container/detail/type_traits.hpp> +#include <boost/container/detail/placement_new.hpp> // intrusive #include <boost/intrusive/slist.hpp> #include <boost/intrusive/pointer_traits.hpp> +#include <boost/intrusive/detail/twin.hpp> // move #include <boost/move/utility_core.hpp> @@ -78,6 +80,7 @@ class basic_multiallocation_chain typedef VoidPointer void_pointer; typedef typename slist_impl_t::iterator iterator; typedef typename slist_impl_t::size_type size_type; + typedef boost::intrusive::twin<void_pointer> pointer_pair; basic_multiallocation_chain() : slist_impl_() @@ -150,9 +153,9 @@ class basic_multiallocation_chain char_ptr elem = char_pointer_traits::static_cast_from(b); if(num_units){ char_ptr prev_elem = elem; - elem += unit_bytes; - for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){ - ::new (boost::movelib::to_raw_pointer(prev_elem)) void_pointer(elem); + elem += difference_type(unit_bytes); + for(size_type i = 0; i != num_units-1u; ++i, elem += difference_type(unit_bytes)){ + ::new (boost::movelib::to_raw_pointer(prev_elem), boost_container_new_t()) void_pointer(elem); prev_elem = elem; } slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units); @@ -169,13 +172,18 @@ class basic_multiallocation_chain static iterator iterator_to(const void_pointer &p) { return slist_impl_t::s_iterator_to(to_node(p)); } - std::pair<void_pointer, void_pointer> extract_data() + pointer_pair extract_data() { - std::pair<void_pointer, void_pointer> ret - (slist_impl_.begin().operator->() - ,slist_impl_.last().operator->()); - slist_impl_.clear(); - return ret; + if(BOOST_LIKELY(!slist_impl_.empty())){ + pointer_pair ret + (slist_impl_.begin().operator->() + ,slist_impl_.last().operator->()); + slist_impl_.clear(); + return ret; + } + else { + return pointer_pair(); + } } }; @@ -211,8 +219,9 @@ class transform_multiallocation_chain public: typedef transform_iterator < typename MultiallocationChain::iterator - , dtl::cast_functor <T> > iterator; + , dtl::cast_functor <T> > iterator; typedef typename MultiallocationChain::size_type size_type; + typedef boost::intrusive::twin<pointer> pointer_pair; transform_multiallocation_chain() : MultiallocationChain() @@ -231,56 +240,56 @@ class transform_multiallocation_chain return static_cast<MultiallocationChain&> (this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other)))); } -/* + void push_front(const pointer &mem) - { holder_.push_front(mem); } + { this->MultiallocationChain::push_front(mem); } void push_back(const pointer &mem) - { return holder_.push_back(mem); } + { return this->MultiallocationChain::push_back(mem); } void swap(transform_multiallocation_chain &other_chain) - { holder_.swap(other_chain.holder_); } + { this->MultiallocationChain::swap(other_chain); } void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) - { holder_.splice_after(after_this.base(), x.holder_, before_b.base(), before_e.base(), n); } + { this->MultiallocationChain::splice_after(after_this.base(), x, before_b.base(), before_e.base(), n); } void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n) - { holder_.incorporate_after(after_this.base(), b, before_e, n); } -*/ + { this->MultiallocationChain::incorporate_after(after_this.base(), b, before_e, n); } + pointer pop_front() { return cast(this->MultiallocationChain::pop_front()); } -/* + bool empty() const - { return holder_.empty(); } + { return this->MultiallocationChain::empty(); } iterator before_begin() - { return iterator(holder_.before_begin()); } -*/ + { return iterator(this->MultiallocationChain::before_begin()); } + iterator begin() { return iterator(this->MultiallocationChain::begin()); } -/* - iterator end() - { return iterator(holder_.end()); } iterator last() - { return iterator(holder_.last()); } + { return iterator(this->MultiallocationChain::last()); } + + iterator end() + { return iterator(this->MultiallocationChain::end()); } size_type size() const - { return holder_.size(); } + { return this->MultiallocationChain::size(); } void clear() - { holder_.clear(); } -*/ + { this->MultiallocationChain::clear(); } + iterator insert_after(iterator it, pointer m) { return iterator(this->MultiallocationChain::insert_after(it.base(), m)); } static iterator iterator_to(const pointer &p) { return iterator(MultiallocationChain::iterator_to(p)); } - std::pair<pointer, pointer> extract_data() + pointer_pair extract_data() { - std::pair<void_pointer, void_pointer> data(this->MultiallocationChain::extract_data()); - return std::pair<pointer, pointer>(cast(data.first), cast(data.second)); + typename MultiallocationChain::pointer_pair data(this->MultiallocationChain::extract_data()); + return pointer_pair(cast(data.first), cast(data.second)); } /* MultiallocationChain &extract_multiallocation_chain() diff --git a/contrib/restricted/boost/container/include/boost/container/detail/next_capacity.hpp b/contrib/restricted/boost/container/include/boost/container/detail/next_capacity.hpp index 7e6554ded0..9777b1473b 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/next_capacity.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/next_capacity.hpp @@ -18,6 +18,9 @@ # pragma once #endif +#include <boost/container/detail/config_begin.hpp> +#include <boost/container/detail/workaround.hpp> + // container #include <boost/container/throw_exception.hpp> // container/detail @@ -45,15 +48,20 @@ struct grow_factor_ratio SizeType new_cap = 0; if(cur_cap <= overflow_limit){ - new_cap = cur_cap * Numerator / Denominator; + new_cap = SizeType(cur_cap * Numerator / Denominator); } else if(Denominator == 1 || (SizeType(new_cap = cur_cap) / Denominator) > overflow_limit){ new_cap = (SizeType)-1; } else{ - new_cap *= Numerator; + new_cap = SizeType(new_cap*Numerator); } - return max_value(SizeType(Minimum), max_value(cur_cap+add_min_cap, min_value(max_cap, new_cap))); + return max_value<SizeType> + ( SizeType(Minimum) + , max_value<SizeType> + ( SizeType(cur_cap+add_min_cap) + , min_value<SizeType>(max_cap, new_cap)) + ); } }; @@ -71,7 +79,20 @@ struct growth_factor_100 : dtl::grow_factor_ratio<0, 2, 1> {}; +template<class SizeType> +BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &, SizeType) +{} + +template<class SizeType, class SomeStoredSizeType> +BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &s, SomeStoredSizeType) +{ + if (s >= SomeStoredSizeType(-1) ) + s = SomeStoredSizeType(-1); +} + } //namespace container { } //namespace boost { +#include <boost/container/detail/config_end.hpp> + #endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP diff --git a/contrib/restricted/boost/container/include/boost/container/detail/node_alloc_holder.hpp b/contrib/restricted/boost/container/include/boost/container/detail/node_alloc_holder.hpp index ad7b713d6e..3efdb0f8ce 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/node_alloc_holder.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/node_alloc_holder.hpp @@ -36,6 +36,7 @@ #include <boost/move/detail/to_raw_pointer.hpp> #include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/version_type.hpp> +#include <boost/container/detail/is_pair.hpp> // intrusive #include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/options.hpp> @@ -50,28 +51,187 @@ namespace boost { namespace container { + +//This trait is used to type-pun std::pair because in C++03 +//compilers std::pair is useless for C++11 features +template<class T, bool> +struct node_internal_data_type +{ + typedef T type; +}; + +template<class T> +struct node_internal_data_type< T, true> +{ + typedef dtl::pair< typename dtl::remove_const<typename T::first_type>::type + , typename T::second_type> + type; +}; + +template <class T, class HookDefiner, bool PairBased = false> +struct base_node + : public HookDefiner::type +{ + public: + typedef T value_type; + typedef typename node_internal_data_type<T, PairBased && dtl::is_pair<T>::value>::type internal_type; + typedef typename HookDefiner::type hook_type; + + typedef typename dtl::aligned_storage<sizeof(T), dtl::alignment_of<T>::value>::type storage_t; + storage_t m_storage; + + #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) && (BOOST_GCC < 80000) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" + #define BOOST_CONTAINER_DISABLE_ALIASING_WARNING + # endif + public: + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template<class Alloc, class ...Args> + explicit base_node(Alloc &a, Args &&...args) + : hook_type() + { + ::boost::container::allocator_traits<Alloc>::construct + (a, &this->get_real_data(), ::boost::forward<Args>(args)...); + } + + #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + #define BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL(N) \ + template< class Alloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ + explicit base_node(Alloc &a BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + : hook_type()\ + {\ + ::boost::container::allocator_traits<Alloc>::construct\ + (a, &this->get_real_data() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL) + #undef BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL + + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template<class Alloc, class It> + explicit base_node(iterator_arg_t, Alloc &a, It it) + : hook_type() + { + ::boost::container::construct_in_place(a, &this->get_real_data(), it); + } + + BOOST_CONTAINER_FORCEINLINE T &get_data() + { return *move_detail::force_ptr<T*>(this->m_storage.data); } + + BOOST_CONTAINER_FORCEINLINE const T &get_data() const + { return *move_detail::force_ptr<const T*>(this->m_storage.data); } + + BOOST_CONTAINER_FORCEINLINE internal_type &get_real_data() + { return *move_detail::force_ptr<internal_type*>(this->m_storage.data); } + + BOOST_CONTAINER_FORCEINLINE const internal_type &get_real_data() const + { return *move_detail::force_ptr<const internal_type*>(this->m_storage.data); } + + #if defined(BOOST_CONTAINER_DISABLE_ALIASING_WARNING) + #pragma GCC diagnostic pop + #undef BOOST_CONTAINER_DISABLE_ALIASING_WARNING + # endif + + template<class Alloc> + BOOST_CONTAINER_FORCEINLINE void destructor(Alloc &a) BOOST_NOEXCEPT + { + allocator_traits<Alloc>::destroy + (a, &this->get_real_data()); + this->~base_node(); + } + + template<class Pair> + BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if< dtl::is_pair<Pair>, void >::type + do_assign(const Pair &p) + { + typedef typename Pair::first_type first_type; + const_cast<typename dtl::remove_const<first_type>::type &>(this->get_real_data().first) = p.first; + this->get_real_data().second = p.second; + } + + template<class V> + BOOST_CONTAINER_FORCEINLINE + typename dtl::disable_if< dtl::is_pair<V>, void >::type + do_assign(const V &v) + { this->get_real_data() = v; } + + template<class Pair> + BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if< dtl::is_pair<Pair>, void >::type + do_move_assign(Pair &p) + { + typedef typename Pair::first_type first_type; + const_cast<first_type&>(this->get_real_data().first) = ::boost::move(p.first); + this->get_real_data().second = ::boost::move(p.second); + } + + template<class V> + BOOST_CONTAINER_FORCEINLINE + typename dtl::disable_if< dtl::is_pair<V>, void >::type + do_move_assign(V &v) + { this->get_real_data() = ::boost::move(v); } + + private: + base_node(); + + BOOST_CONTAINER_FORCEINLINE ~base_node() + { } +}; + + namespace dtl { -BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_compare) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_equal) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(hasher) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(bucket_traits) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(bucket_type) template<class Allocator, class ICont> struct node_alloc_holder + : public allocator_traits<Allocator>::template + portable_rebind_alloc<typename ICont::value_type>::type //NodeAlloc { //If the intrusive container is an associative container, obtain the predicate, which will - //be of type node_compare<>. If not an associative container value_compare will be a "nat" type. + //be of type node_compare<>. If not an associative container val_compare will be a "nat" type. typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT ( boost::container::dtl:: - , ICont, value_compare, dtl::nat) intrusive_value_compare; + , ICont, key_compare, dtl::nat) intrusive_key_compare; + + //If the intrusive container is a hash container, obtain the predicate, which will + //be of type node_compare<>. If not an associative container val_equal will be a "nat" type. + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (boost::container::dtl:: + , ICont, key_equal, dtl::nat2) intrusive_val_equal; + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (boost::container::dtl:: + , ICont, hasher, dtl::nat3) intrusive_val_hasher; + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (boost::container::dtl:: + , ICont, bucket_traits, dtl::natN<0>) intrusive_bucket_traits; + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (boost::container::dtl:: + , ICont, bucket_type, dtl::natN<1>) intrusive_bucket_type; //In that case obtain the value predicate from the node predicate via predicate_type - //if intrusive_value_compare is node_compare<>, nat otherwise + //if intrusive_key_compare is node_compare<>, nat otherwise typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT - ( boost::container::dtl:: - , intrusive_value_compare - , predicate_type, dtl::nat) value_compare; + (boost::container::dtl:: + , intrusive_val_equal + , predicate_type, dtl::nat2) val_equal; + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (boost::container::dtl:: + , intrusive_val_hasher + , predicate_type, dtl::nat3) val_hasher; typedef allocator_traits<Allocator> allocator_traits_type; - typedef typename allocator_traits_type::value_type value_type; + typedef typename allocator_traits_type::value_type val_type; typedef ICont intrusive_container; typedef typename ICont::value_type Node; typedef typename allocator_traits_type::template @@ -88,7 +248,7 @@ struct node_alloc_holder version<NodeAlloc>::value> alloc_version; typedef typename ICont::iterator icont_iterator; typedef typename ICont::const_iterator icont_citerator; - typedef allocator_destroyer<NodeAlloc> Destroyer; + typedef allocator_node_destroyer<NodeAlloc> Destroyer; typedef allocator_traits<NodeAlloc> NodeAllocTraits; typedef allocator_version_traits<NodeAlloc> AllocVersionTraits; @@ -98,64 +258,113 @@ struct node_alloc_holder public: //Constructors for sequence containers - node_alloc_holder() - : members_() + BOOST_CONTAINER_FORCEINLINE node_alloc_holder() + {} + + explicit node_alloc_holder(const intrusive_bucket_traits& bt) + : m_icont(bt) {} explicit node_alloc_holder(const ValAlloc &a) - : members_(a) + : NodeAlloc(a) + {} + + node_alloc_holder(const intrusive_bucket_traits& bt, const ValAlloc& a) + : NodeAlloc(a) + , m_icont(bt) {} //Constructors for associative containers - node_alloc_holder(const value_compare &c, const ValAlloc &a) - : members_(a, c) + node_alloc_holder(const intrusive_key_compare &c, const ValAlloc &a) + : NodeAlloc(a), m_icont(c) + {} + + node_alloc_holder(const intrusive_bucket_traits & bt, const val_hasher &hf, const val_equal &eql, const ValAlloc &a) + : NodeAlloc(a) + , m_icont(bt + , typename ICont::hasher(hf) + , typename ICont::key_equal(eql)) + {} + + node_alloc_holder(const intrusive_bucket_traits& bt, const val_hasher &hf, const ValAlloc &a) + : NodeAlloc(a) + , m_icont(bt + , typename ICont::hasher(hf) + , typename ICont::key_equal()) + {} + + node_alloc_holder(const intrusive_bucket_traits& bt, const val_hasher &hf) + : m_icont(bt + , typename ICont::hasher(hf) + , typename ICont::key_equal()) {} explicit node_alloc_holder(const node_alloc_holder &x) - : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) + : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) + {} + + node_alloc_holder(const node_alloc_holder &x, const intrusive_key_compare &c) + : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) + , m_icont(c) {} - node_alloc_holder(const node_alloc_holder &x, const value_compare &c) - : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c) + node_alloc_holder(const node_alloc_holder &x, const intrusive_bucket_traits& bt, const val_hasher &hf, const val_equal &eql) + : NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) + , m_icont( bt + , typename ICont::hasher(hf) + , typename ICont::key_equal(eql)) + {} + + node_alloc_holder(const val_hasher &hf, const intrusive_bucket_traits& bt, const val_equal &eql) + : m_icont(bt + , typename ICont::hasher(hf) + , typename ICont::key_equal(eql)) {} explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x) - : members_(boost::move(x.node_alloc())) + : NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc())) { this->icont().swap(x.icont()); } - explicit node_alloc_holder(const value_compare &c) - : members_(c) + explicit node_alloc_holder(const intrusive_key_compare &c) + : m_icont(c) {} //helpers for move assignments - explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const value_compare &c) - : members_(boost::move(x.node_alloc()), c) + explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const intrusive_key_compare &c) + : NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc())), m_icont(c) { this->icont().swap(x.icont()); } - void copy_assign_alloc(const node_alloc_holder &x) + explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const intrusive_bucket_traits& bt, const val_hasher &hf, const val_equal &eql) + : NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc())) + , m_icont( bt + , typename ICont::hasher(hf) + , typename ICont::key_equal(eql)) + { this->icont().swap(BOOST_MOVE_TO_LV(x).icont()); } + + BOOST_CONTAINER_FORCEINLINE void copy_assign_alloc(const node_alloc_holder &x) { dtl::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag; - dtl::assign_alloc( static_cast<NodeAlloc &>(this->members_) - , static_cast<const NodeAlloc &>(x.members_), flag); + dtl::assign_alloc( static_cast<NodeAlloc &>(*this) + , static_cast<const NodeAlloc &>(x), flag); } - void move_assign_alloc( node_alloc_holder &x) + BOOST_CONTAINER_FORCEINLINE void move_assign_alloc( node_alloc_holder &x) { dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag; - dtl::move_alloc( static_cast<NodeAlloc &>(this->members_) - , static_cast<NodeAlloc &>(x.members_), flag); + dtl::move_alloc( static_cast<NodeAlloc &>(*this) + , static_cast<NodeAlloc &>(x), flag); } - ~node_alloc_holder() + BOOST_CONTAINER_FORCEINLINE ~node_alloc_holder() { this->clear(alloc_version()); } - size_type max_size() const + BOOST_CONTAINER_FORCEINLINE size_type max_size() const { return allocator_traits_type::max_size(this->node_alloc()); } - NodePtr allocate_one() + BOOST_CONTAINER_FORCEINLINE NodePtr allocate_one() { return AllocVersionTraits::allocate_one(this->node_alloc()); } - void deallocate_one(const NodePtr &p) + BOOST_CONTAINER_FORCEINLINE void deallocate_one(const NodePtr &p) { AllocVersionTraits::deallocate_one(this->node_alloc(), p); } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -164,14 +373,11 @@ struct node_alloc_holder NodePtr create_node(Args &&...args) { NodePtr p = this->allocate_one(); - Deallocator node_deallocator(p, this->node_alloc()); - allocator_traits<NodeAlloc>::construct - ( this->node_alloc() - , dtl::addressof(p->m_data), boost::forward<Args>(args)...); + NodeAlloc &nalloc = this->node_alloc(); + Deallocator node_deallocator(p, nalloc); + ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) + Node(nalloc, boost::forward<Args>(args)...); node_deallocator.release(); - //This does not throw - typedef typename Node::hook_type hook_type; - ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type; return (p); } @@ -182,14 +388,11 @@ struct node_alloc_holder NodePtr create_node(BOOST_MOVE_UREF##N)\ {\ NodePtr p = this->allocate_one();\ - Deallocator node_deallocator(p, this->node_alloc());\ - allocator_traits<NodeAlloc>::construct\ - ( this->node_alloc()\ - , dtl::addressof(p->m_data)\ - BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + NodeAlloc &nalloc = this->node_alloc();\ + Deallocator node_deallocator(p, nalloc);\ + ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t())\ + Node(nalloc BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ node_deallocator.release();\ - typedef typename Node::hook_type hook_type;\ - ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type;\ return (p);\ }\ // @@ -202,12 +405,11 @@ struct node_alloc_holder NodePtr create_node_from_it(const It &it) { NodePtr p = this->allocate_one(); - Deallocator node_deallocator(p, this->node_alloc()); - ::boost::container::construct_in_place(this->node_alloc(), dtl::addressof(p->m_data), it); + NodeAlloc &nalloc = this->node_alloc(); + Deallocator node_deallocator(p, nalloc); + ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) + Node(iterator_arg_t(), nalloc, it); node_deallocator.release(); - //This does not throw - typedef typename Node::hook_type hook_type; - ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type; return (p); } @@ -215,28 +417,32 @@ struct node_alloc_holder NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key) { NodePtr p = this->allocate_one(); - NodeAlloc &na = this->node_alloc(); - Deallocator node_deallocator(p, this->node_alloc()); - node_allocator_traits_type::construct - (na, dtl::addressof(p->m_data.first), boost::forward<KeyConvertible>(key)); BOOST_TRY{ - node_allocator_traits_type::construct(na, dtl::addressof(p->m_data.second)); + ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node; + NodeAlloc &na = this->node_alloc(); + node_allocator_traits_type::construct + (na, dtl::addressof(p->get_real_data().first), boost::forward<KeyConvertible>(key)); + BOOST_TRY{ + node_allocator_traits_type::construct(na, dtl::addressof(p->get_real_data().second)); + } + BOOST_CATCH(...){ + node_allocator_traits_type::destroy(na, dtl::addressof(p->get_real_data().first)); + BOOST_RETHROW; + } + BOOST_CATCH_END } - BOOST_CATCH(...){ - node_allocator_traits_type::destroy(na, dtl::addressof(p->m_data.first)); - BOOST_RETHROW; + BOOST_CATCH(...) { + p->destroy_header(); + this->node_alloc().deallocate(p, 1); + BOOST_RETHROW } BOOST_CATCH_END - node_deallocator.release(); - //This does not throw - typedef typename Node::hook_type hook_type; - ::new(static_cast<hook_type*>(boost::movelib::to_raw_pointer(p)), boost_container_new_t()) hook_type; return (p); } void destroy_node(const NodePtr &nodep) { - allocator_traits<NodeAlloc>::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(nodep)); + boost::movelib::to_raw_pointer(nodep)->destructor(this->node_alloc()); this->deallocate_one(nodep); } @@ -249,57 +455,57 @@ struct node_alloc_holder template<class FwdIterator, class Inserter> void allocate_many_and_construct - (FwdIterator beg, difference_type n, Inserter inserter) + (FwdIterator beg, size_type n, Inserter inserter) { if(n){ - typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain; + typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain_t; //Try to allocate memory in a single block - typedef typename multiallocation_chain::iterator multialloc_iterator; - multiallocation_chain mem; + typedef typename multiallocation_chain_t::iterator multialloc_iterator_t; + multiallocation_chain_t chain; NodeAlloc &nalloc = this->node_alloc(); - node_allocator_version_traits_type::allocate_individual(nalloc, n, mem); - multialloc_iterator itbeg(mem.begin()), itlast(mem.last()); - mem.clear(); + node_allocator_version_traits_type::allocate_individual(nalloc, n, chain); + multialloc_iterator_t itbeg = chain.begin(); + multialloc_iterator_t itlast = chain.last(); + chain.clear(); + Node *p = 0; - BOOST_TRY{ + BOOST_TRY{ Deallocator node_deallocator(NodePtr(), nalloc); - dtl::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0); - while(n--){ + dtl::scoped_node_destructor<NodeAlloc> sdestructor(nalloc, 0); + while(n){ + --n; p = boost::movelib::iterator_to_raw_pointer(itbeg); - node_deallocator.set(p); - ++itbeg; - //This can throw - boost::container::construct_in_place(nalloc, dtl::addressof(p->m_data), beg); + ++itbeg; //Increment iterator before overwriting pointed memory + //This does not throw + ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) + Node(iterator_arg_t(), nalloc, beg); sdestructor.set(p); ++beg; - //This does not throw - typedef typename Node::hook_type hook_type; - ::new(static_cast<hook_type*>(p), boost_container_new_t()) hook_type; //This can throw in some containers (predicate might throw). //(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception) inserter(*p); - sdestructor.set(0); + sdestructor.release(); } sdestructor.release(); node_deallocator.release(); } BOOST_CATCH(...){ - mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n); - node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem); + chain.incorporate_after(chain.last(), &*itbeg, &*itlast, n); + node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), chain); BOOST_RETHROW } BOOST_CATCH_END } } - void clear(version_1) + BOOST_CONTAINER_FORCEINLINE void clear(version_1) { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); } void clear(version_2) { typename NodeAlloc::multiallocation_chain chain; - allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain); + allocator_node_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain); this->icont().clear_and_dispose(builder); //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true)); if(!chain.empty()) @@ -311,105 +517,86 @@ struct node_alloc_holder icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2) { - typedef typename NodeAlloc::multiallocation_chain multiallocation_chain; NodeAlloc & nalloc = this->node_alloc(); - multiallocation_chain chain; - allocator_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain); + typename NodeAlloc::multiallocation_chain chain; + allocator_node_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain); icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder); nalloc.deallocate_individual(chain); return ret_it; } - template<class Key, class Comparator> - size_type erase_key(const Key& k, const Comparator &comp, version_1) - { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); } + template<class Key> + BOOST_CONTAINER_FORCEINLINE size_type erase_key(const Key& k, version_1) + { return this->icont().erase_and_dispose(k, Destroyer(this->node_alloc())); } - template<class Key, class Comparator> - size_type erase_key(const Key& k, const Comparator &comp, version_2) + template<class Key> + BOOST_CONTAINER_FORCEINLINE size_type erase_key(const Key& k, version_2) { allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc()); - return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder()); + return this->icont().erase_and_dispose(k, chain_holder.get_chain_builder()); } protected: struct cloner { - explicit cloner(node_alloc_holder &holder) + BOOST_CONTAINER_FORCEINLINE explicit cloner(node_alloc_holder &holder) : m_holder(holder) {} - NodePtr operator()(const Node &other) const - { return m_holder.create_node(other.m_data); } + BOOST_CONTAINER_FORCEINLINE NodePtr operator()(const Node &other) const + { return m_holder.create_node(other.get_real_data()); } node_alloc_holder &m_holder; }; struct move_cloner { - move_cloner(node_alloc_holder &holder) + BOOST_CONTAINER_FORCEINLINE move_cloner(node_alloc_holder &holder) : m_holder(holder) {} - NodePtr operator()(Node &other) - { //Use m_data instead of get_data to allow moving const key in [multi]map - return m_holder.create_node(::boost::move(other.m_data)); + BOOST_CONTAINER_FORCEINLINE NodePtr operator()(Node &other) + { //Use get_real_data() instead of get_real_data to allow moving const key in [multi]map + return m_holder.create_node(::boost::move(other.get_real_data())); } node_alloc_holder &m_holder; }; - struct members_holder - : public NodeAlloc - { - private: - members_holder(const members_holder&); - members_holder & operator=(const members_holder&); - - public: - members_holder() - : NodeAlloc(), m_icont() - {} - - template<class ConvertibleToAlloc> - explicit members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc) - : NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc)) - , m_icont() - {} - - template<class ConvertibleToAlloc> - members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c) - : NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc)) - , m_icont(typename ICont::key_compare(c)) - {} + BOOST_CONTAINER_FORCEINLINE ICont &non_const_icont() const + { return const_cast<ICont&>(this->m_icont); } - explicit members_holder(const value_compare &c) - : NodeAlloc() - , m_icont(typename ICont::key_compare(c)) - {} + BOOST_CONTAINER_FORCEINLINE NodeAlloc &node_alloc() + { return static_cast<NodeAlloc &>(*this); } - //The intrusive container - ICont m_icont; - }; + BOOST_CONTAINER_FORCEINLINE const NodeAlloc &node_alloc() const + { return static_cast<const NodeAlloc &>(*this); } - ICont &non_const_icont() const - { return const_cast<ICont&>(this->members_.m_icont); } + public: + BOOST_CONTAINER_FORCEINLINE ICont &icont() + { return this->m_icont; } - NodeAlloc &node_alloc() - { return static_cast<NodeAlloc &>(this->members_); } + BOOST_CONTAINER_FORCEINLINE const ICont &icont() const + { return this->m_icont; } - const NodeAlloc &node_alloc() const - { return static_cast<const NodeAlloc &>(this->members_); } + protected: + //The intrusive container + ICont m_icont; +}; - members_holder members_; +template<class Node, class KeyOfValue> +struct key_of_node : KeyOfValue +{ + typedef typename KeyOfValue::type type; - public: - ICont &icont() - { return this->members_.m_icont; } + BOOST_CONTAINER_FORCEINLINE key_of_node() + {} - const ICont &icont() const - { return this->members_.m_icont; } + BOOST_CONTAINER_FORCEINLINE const type& operator()(const Node& x) const + { return this->KeyOfValue::operator()(x.get_data()); } }; + } //namespace dtl { } //namespace container { } //namespace boost { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/pair.hpp b/contrib/restricted/boost/container/include/boost/container/detail/pair.hpp index 6b00db1483..56b2fb8311 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/pair.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/pair.hpp @@ -22,12 +22,15 @@ #endif #include <boost/container/detail/config_begin.hpp> +#include <boost/container/container_fwd.hpp> #include <boost/container/detail/workaround.hpp> +#include <boost/static_assert.hpp> #include <boost/container/detail/mpl.hpp> #include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/mpl.hpp> #include <boost/container/detail/std_fwd.hpp> +#include <boost/container/detail/is_pair.hpp> #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) # include <boost/container/detail/variadic_templates_tools.hpp> #endif @@ -38,21 +41,6 @@ #include <boost/move/detail/fwd_macros.hpp> namespace boost { -namespace tuples { - -struct null_type; - -template < - class T0, class T1, class T2, - class T3, class T4, class T5, - class T6, class T7, class T8, - class T9> -class tuple; - -} //namespace tuples { -} //namespace boost { - -namespace boost { namespace container { namespace pair_impl { @@ -89,19 +77,7 @@ struct is_tuple_null<boost::tuples::null_type> static const bool value = true; }; -}}} - -#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520) -//MSVC 2010 tuple marker -namespace std { namespace tr1 { struct _Nil; }} -#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540) -//MSVC 2012 tuple marker -namespace std { struct _Nil; } -#endif - - -namespace boost { -namespace container { +} //namespace detail { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -115,10 +91,6 @@ namespace container { ::std::piecewise_construct_t *std_piecewise_construct_holder<Dummy>::dummy = reinterpret_cast< ::std::piecewise_construct_t *>(0x01234); //Avoid sanitizer errors on references to null pointers -typedef const std::piecewise_construct_t & piecewise_construct_t; - -struct try_emplace_t{}; - #else //! The piecewise_construct_t struct is an empty structure type used as a unique type to @@ -142,54 +114,43 @@ struct piecewise_construct_use { (void)&::boost::container::piecewise_construct; } }; -template <class T1, class T2> -struct pair; - -template <class T> -struct is_pair -{ - static const bool value = false; -}; +struct pair_nat; -template <class T1, class T2> -struct is_pair< pair<T1, T2> > -{ - static const bool value = true; -}; +template<typename T, typename U, typename V> +void get(T); //to enable ADL -template <class T1, class T2> -struct is_pair< std::pair<T1, T2> > -{ - static const bool value = true; -}; +///@endcond -template <class T> -struct is_not_pair +#ifdef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR +//Libc++, in some versions, has an ABI breakage that needs some +//padding in dtl::pair, as "std::pair::first" is not at offset zero. +//See: https://reviews.llvm.org/D56357 for more information. +// +template <class T1, class T2, std::size_t N> +struct pair_padding { - static const bool value = !is_pair<T>::value; + char padding[N]; }; -template <class T> -struct is_std_pair +template <class T1, class T2> +struct pair_padding<T1, T2, 0> { - static const bool value = false; }; template <class T1, class T2> -struct is_std_pair< std::pair<T1, T2> > +struct simple_pair { - static const bool value = true; + T1 first; + T2 second; }; -struct pair_nat; - -template<typename T, typename U, typename V> -void get(T); //to enable ADL - -///@endcond +#endif template <class T1, class T2> struct pair +#ifdef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR + : pair_padding<T1, T2, sizeof(std::pair<T1, T2>) - sizeof(simple_pair<T1, T2>)> +#endif { private: BOOST_COPYABLE_AND_MOVABLE(pair) @@ -204,64 +165,88 @@ struct pair //Default constructor pair() : first(), second() - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } //pair copy assignment pair(const pair& x) : first(x.first), second(x.second) - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } //pair move constructor pair(BOOST_RV_REF(pair) p) - : first(::boost::move(p.first)), second(::boost::move(p.second)) - {} + : first(::boost::move(BOOST_MOVE_TO_LV(p).first)), second(::boost::move(BOOST_MOVE_TO_LV(p).second)) + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } template <class D, class S> pair(const pair<D, S> &p) : first(p.first), second(p.second) - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } template <class D, class S> pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p) - : first(::boost::move(p.first)), second(::boost::move(p.second)) - {} + : first(::boost::move(BOOST_MOVE_TO_LV(p).first)), second(::boost::move(BOOST_MOVE_TO_LV(p).second)) + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } //pair from two values pair(const T1 &t1, const T2 &t2) : first(t1) , second(t2) - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } template<class U, class V> pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v) : first(::boost::forward<U>(u)) , second(::boost::forward<V>(v)) - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } //And now compatibility with std::pair pair(const std::pair<T1, T2>& x) : first(x.first), second(x.second) - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } template <class D, class S> pair(const std::pair<D, S>& p) : first(p.first), second(p.second) - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p) - : first(::boost::move(p.first)), second(::boost::move(p.second)) - {} + : first(::boost::move(BOOST_MOVE_TO_LV(p).first)), second(::boost::move(BOOST_MOVE_TO_LV(p).second)) + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } template <class D, class S> pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p) - : first(::boost::move(p.first)), second(::boost::move(p.second)) - {} + : first(::boost::move(BOOST_MOVE_TO_LV(p).first)), second(::boost::move(BOOST_MOVE_TO_LV(p).second)) + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template< class KeyType, class ...Args> pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args) : first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\ - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } #else //piecewise construction from boost::tuple @@ -269,7 +254,9 @@ struct pair template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\ : first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\ - {}\ + {\ + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\ + }\ // BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE) #undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE @@ -289,7 +276,9 @@ struct pair >::type* = 0\ )\ : first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\ - { (void)p; (void)q; }\ + { (void)p; (void)q;\ + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\ + }\ // BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE) #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE @@ -309,7 +298,9 @@ struct pair , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type> pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2) : pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type()) - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } # else //piecewise construction from variadic tuple (suboptimal, without delegating constructors) private: @@ -327,7 +318,9 @@ struct pair pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2) : first (build_from_args<first_type> (::boost::move(t1))) , second (build_from_args<second_type>(::boost::move(t2))) - {} + { + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); + } # endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520) //MSVC 2010 tuple implementation @@ -338,7 +331,9 @@ struct pair , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\ , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\ : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\ - { (void)p; (void)q; }\ + { (void)p; (void)q;\ + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\ + }\ // BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE) #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE @@ -357,7 +352,9 @@ struct pair , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\ , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\ : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\ - { (void)p; (void)q; }\ + { (void)p; (void)q;\ + BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\ + }\ // BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE) #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE @@ -375,8 +372,8 @@ struct pair //pair move assignment pair& operator=(BOOST_RV_REF(pair) p) { - first = ::boost::move(p.first); - second = ::boost::move(p.second); + first = ::boost::move(BOOST_MOVE_TO_LV(p).first); + second = ::boost::move(BOOST_MOVE_TO_LV(p).second); return *this; } @@ -401,8 +398,8 @@ struct pair >::type operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p) { - first = ::boost::move(p.first); - second = ::boost::move(p.second); + first = ::boost::move(BOOST_MOVE_TO_LV(p).first); + second = ::boost::move(BOOST_MOVE_TO_LV(p).second); return *this; } //std::pair copy assignment @@ -424,16 +421,16 @@ struct pair //std::pair move assignment pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p) { - first = ::boost::move(p.first); - second = ::boost::move(p.second); + first = ::boost::move(BOOST_MOVE_TO_LV(p).first); + second = ::boost::move(BOOST_MOVE_TO_LV(p).second); return *this; } template <class D, class S> pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p) { - first = ::boost::move(p.first); - second = ::boost::move(p.second); + first = ::boost::move(BOOST_MOVE_TO_LV(p).first); + second = ::boost::move(BOOST_MOVE_TO_LV(p).second); return *this; } @@ -550,6 +547,57 @@ struct is_class< std::pair<T1, T2> > static const bool value = true; }; + +//Triviality of pair +template<class T> +struct is_trivially_copy_constructible; + +template<class A, class B> +struct is_trivially_copy_assignable + <boost::container::dtl::pair<A,B> > +{ + static const bool value = false ; +}; + +template<class T> +struct is_trivially_move_constructible; + +template<class A, class B> +struct is_trivially_move_assignable + <boost::container::dtl::pair<A,B> > +{ + static const bool value = false; +}; + +template<class T> +struct is_trivially_copy_assignable; + +template<class A, class B> +struct is_trivially_copy_constructible<boost::container::dtl::pair<A,B> > +{ + static const bool value = false; +}; + +template<class T> +struct is_trivially_move_assignable; + +template<class A, class B> +struct is_trivially_move_constructible<boost::container::dtl::pair<A,B> > +{ + static const bool value = false; +}; + +template<class T> +struct is_trivially_destructible; + +template<class A, class B> +struct is_trivially_destructible<boost::container::dtl::pair<A,B> > +{ + static const bool value = boost::move_detail::is_trivially_destructible<A>::value && + boost::move_detail::is_trivially_destructible<B>::value ; +}; + + } //namespace move_detail{ } //namespace boost { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/placement_new.hpp b/contrib/restricted/boost/container/include/boost/container/detail/placement_new.hpp index c50981f685..73db6c1827 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/placement_new.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/placement_new.hpp @@ -18,6 +18,8 @@ # pragma once #endif +#include <cstddef> + struct boost_container_new_t{}; //avoid including <new> diff --git a/contrib/restricted/boost/container/include/boost/container/detail/pool_resource.hpp b/contrib/restricted/boost/container/include/boost/container/detail/pool_resource.hpp index e5f59f5186..87eecacce1 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/pool_resource.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/pool_resource.hpp @@ -100,7 +100,7 @@ class pool_resource //! <b>Effects</b>: Calls //! `this->release()`. - virtual ~pool_resource(); + ~pool_resource(); //! <b>Effects</b>: Calls Calls `upstream_resource()->deallocate()` as necessary //! to release all allocated memory. [ Note: memory is released back to @@ -131,18 +131,14 @@ class pool_resource //! using `upstream_resource()->allocate()`. //! //! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws. - virtual void* do_allocate(std::size_t bytes, std::size_t alignment); + void* do_allocate(std::size_t bytes, std::size_t alignment); //! <b>Effects</b>: Return the memory at p to the pool. It is unspecified if or under //! what circumstances this operation will result in a call to //! `upstream_resource()->deallocate()`. //! //! <b>Throws</b>: Nothing. - virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment); - - //! <b>Returns</b>: - //! `this == dynamic_cast<const pool_resource*>(&other)`. - virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT; + void do_deallocate(void* p, std::size_t bytes, std::size_t alignment); //Non-standard observers public: diff --git a/contrib/restricted/boost/container/include/boost/container/detail/singleton.hpp b/contrib/restricted/boost/container/include/boost/container/detail/singleton.hpp new file mode 100644 index 0000000000..7601c3ca8c --- /dev/null +++ b/contrib/restricted/boost/container/include/boost/container/detail/singleton.hpp @@ -0,0 +1,121 @@ +// Copyright (C) 2000 Stephen Cleary +// Copyright (C) 2008 Ion Gaztanaga +// +// 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. +// +// This file is a modified file from Boost.Pool + +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013. 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/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP +#define BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include <boost/container/detail/config_begin.hpp> +#include <boost/container/detail/workaround.hpp> + +// +// The following helper classes are placeholders for a generic "singleton" +// class. The classes below support usage of singletons, including use in +// program startup/shutdown code, AS LONG AS there is only one thread +// running before main() begins, and only one thread running after main() +// exits. +// +// This class is also limited in that it can only provide singleton usage for +// classes with default constructors. +// + +// The design of this class is somewhat twisted, but can be followed by the +// calling inheritance. Let us assume that there is some user code that +// calls "singleton_default<T>::instance()". The following (convoluted) +// sequence ensures that the same function will be called before main(): +// instance() contains a call to create_object.do_nothing() +// Thus, object_creator is implicitly instantiated, and create_object +// must exist. +// Since create_object is a static member, its constructor must be +// called before main(). +// The constructor contains a call to instance(), thus ensuring that +// instance() will be called before main(). +// The first time instance() is called (i.e., before main()) is the +// latest point in program execution where the object of type T +// can be created. +// Thus, any call to instance() will auto-magically result in a call to +// instance() before main(), unless already present. +// Furthermore, since the instance() function contains the object, instead +// of the singleton_default class containing a static instance of the +// object, that object is guaranteed to be constructed (at the latest) in +// the first call to instance(). This permits calls to instance() from +// static code, even if that code is called before the file-scope objects +// in this file have been initialized. + +namespace boost { +namespace container { +namespace dtl { + +// T must be: no-throw default constructible and no-throw destructible +template <typename T> +struct singleton_default +{ + private: + struct object_creator + { + // This constructor does nothing more than ensure that instance() + // is called before main() begins, thus creating the static + // T object before multithreading race issues can come up. + object_creator() { singleton_default<T>::instance(); } + inline void do_nothing() const { } + }; + static object_creator create_object; + + singleton_default(); + + public: + typedef T object_type; + + // If, at any point (in user code), singleton_default<T>::instance() + // is called, then the following function is instantiated. + static object_type & instance() + { + // This is the object that we return a reference to. + // It is guaranteed to be created before main() begins because of + // the next line. + static object_type obj; + + // The following line does nothing else than force the instantiation + // of singleton_default<T>::create_object, whose constructor is + // called before main() begins. + create_object.do_nothing(); + + return obj; + } +}; +template <typename T> +typename singleton_default<T>::object_creator +singleton_default<T>::create_object; + +} // namespace dtl +} // namespace container +} // namespace boost + +#include <boost/container/detail/config_end.hpp> + +#endif //BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP diff --git a/contrib/restricted/boost/container/include/boost/container/detail/std_fwd.hpp b/contrib/restricted/boost/container/include/boost/container/detail/std_fwd.hpp index 09678123ff..d67f66929c 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/std_fwd.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/std_fwd.hpp @@ -32,6 +32,9 @@ class allocator; template<class T> struct less; +template<class T> +struct equal_to; + template<class T1, class T2> struct pair; @@ -50,6 +53,9 @@ struct allocator_arg_t; struct piecewise_construct_t; +template <class Ptr> +struct pointer_traits; + BOOST_MOVE_STD_NS_END #include <boost/move/detail/std_ns_end.hpp> diff --git a/contrib/restricted/boost/container/include/boost/container/detail/thread_mutex.hpp b/contrib/restricted/boost/container/include/boost/container/detail/thread_mutex.hpp new file mode 100644 index 0000000000..0f15c686ae --- /dev/null +++ b/contrib/restricted/boost/container/include/boost/container/detail/thread_mutex.hpp @@ -0,0 +1,181 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2018-2018. 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/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// +// This code is partially based on the lightweight mutex implemented +// by Boost.SmartPtr: +// +// Copyright (c) 2002, 2003 Peter Dimov +// Copyright (c) Microsoft Corporation 2014 +// +// 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_CONFIG_HPP +# include <boost/config.hpp> +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP +#define BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP + +#include <boost/container/detail/config_begin.hpp> +#include <boost/container/detail/workaround.hpp> + +#if defined(BOOST_HAS_PTHREADS) + +#include <pthread.h> +#include <boost/assert.hpp> + +namespace boost{ +namespace container { +namespace dtl { + +class thread_mutex +{ + public: + thread_mutex() + { + BOOST_VERIFY(pthread_mutex_init(&m_mut, 0) == 0); + } + + ~thread_mutex() + { + BOOST_VERIFY(pthread_mutex_destroy(&m_mut) == 0); + } + + void lock() + { + BOOST_VERIFY(pthread_mutex_lock( &m_mut) == 0); + } + + void unlock() + { + BOOST_VERIFY(pthread_mutex_unlock(&m_mut) == 0); + } + + private: + thread_mutex(thread_mutex const &); + thread_mutex & operator=(thread_mutex const &); + + pthread_mutex_t m_mut; +}; + +} // namespace dtl { +} // namespace container { +} // namespace boost { + +#else //!BOOST_HAS_PTHREADS (Windows implementation) + +#ifdef BOOST_USE_WINDOWS_H + +#include <windows.h> + +namespace boost{ +namespace container { +namespace dtl { + +typedef ::CRITICAL_SECTION win_critical_section; + +} // namespace dtl { +} // namespace container { +} // namespace boost { + +#else //! BOOST_USE_WINDOWS_H + +struct _RTL_CRITICAL_SECTION_DEBUG; +struct _RTL_CRITICAL_SECTION; + +namespace boost{ +namespace container { +namespace dtl { + +#ifdef BOOST_PLAT_WINDOWS_UWP +extern "C" __declspec(dllimport) int __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long); +#else +extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *); +#endif +extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *); +extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *); +extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *); + +struct win_critical_section +{ + struct _RTL_CRITICAL_SECTION_DEBUG * DebugInfo; + long LockCount; + long RecursionCount; + void * OwningThread; + void * LockSemaphore; + #if defined(_WIN64) + unsigned __int64 SpinCount; + #else + unsigned long SpinCount; + #endif +}; + +} // namespace dtl { +} // namespace container { +} // namespace boost { + +#endif //BOOST_USE_WINDOWS_H + +namespace boost{ +namespace container { +namespace dtl { + +class thread_mutex +{ + public: + thread_mutex() + { + #ifdef BOOST_PLAT_WINDOWS_UWP + (InitializeCriticalSectionEx)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect), 4000, 0); + #else + (InitializeCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + #endif + } + + void lock() + { + (EnterCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + } + + void unlock() + { + (LeaveCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + } + + ~thread_mutex() + { + (DeleteCriticalSection)(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + } + + private: + thread_mutex(thread_mutex const &); + thread_mutex & operator=(thread_mutex const &); + + win_critical_section m_crit_sect; +}; + +} // namespace dtl { +} // namespace container { +} // namespace boost { + +#endif //BOOST_HAS_PTHREADS + +#include <boost/container/detail/config_end.hpp> + +#endif // #ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP diff --git a/contrib/restricted/boost/container/include/boost/container/detail/transform_iterator.hpp b/contrib/restricted/boost/container/include/boost/container/detail/transform_iterator.hpp index ce81813ebb..5c7bbf2dd0 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/transform_iterator.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/transform_iterator.hpp @@ -33,13 +33,13 @@ namespace container { template <class PseudoReference> struct operator_arrow_proxy { - operator_arrow_proxy(const PseudoReference &px) + BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy(const PseudoReference &px) : m_value(px) {} typedef PseudoReference element_type; - PseudoReference* operator->() const { return &m_value; } + BOOST_CONTAINER_FORCEINLINE PseudoReference* operator->() const { return &m_value; } mutable PseudoReference m_value; }; @@ -47,13 +47,13 @@ struct operator_arrow_proxy template <class T> struct operator_arrow_proxy<T&> { - operator_arrow_proxy(T &px) + BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy(T &px) : m_value(px) {} typedef T element_type; - T* operator->() const { return const_cast<T*>(&m_value); } + BOOST_CONTAINER_FORCEINLINE T* operator->() const { return const_cast<T*>(&m_value); } T &m_value; }; @@ -69,29 +69,29 @@ class transform_iterator , typename UnaryFunction::result_type> { public: - explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction()) + BOOST_CONTAINER_FORCEINLINE explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction()) : UnaryFunction(f), m_it(it) {} - explicit transform_iterator() + BOOST_CONTAINER_FORCEINLINE explicit transform_iterator() : UnaryFunction(), m_it() {} //Constructors - transform_iterator& operator++() + BOOST_CONTAINER_FORCEINLINE transform_iterator& operator++() { increment(); return *this; } - transform_iterator operator++(int) + BOOST_CONTAINER_FORCEINLINE transform_iterator operator++(int) { transform_iterator result (*this); increment(); return result; } - friend bool operator== (const transform_iterator& i, const transform_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const transform_iterator& i, const transform_iterator& i2) { return i.equal(i2); } - friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) { return !(i == i2); } /* @@ -104,69 +104,69 @@ class transform_iterator friend bool operator>= (const transform_iterator& i, const transform_iterator& i2) { return !(i < i2); } */ - friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) + BOOST_CONTAINER_FORCEINLINE friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) { return i2.distance_to(i); } //Arithmetic - transform_iterator& operator+=(typename Iterator::difference_type off) + BOOST_CONTAINER_FORCEINLINE transform_iterator& operator+=(typename Iterator::difference_type off) { this->advance(off); return *this; } - transform_iterator operator+(typename Iterator::difference_type off) const + BOOST_CONTAINER_FORCEINLINE transform_iterator operator+(typename Iterator::difference_type off) const { transform_iterator other(*this); other.advance(off); return other; } - friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right) + BOOST_CONTAINER_FORCEINLINE friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right) { return right + off; } - transform_iterator& operator-=(typename Iterator::difference_type off) + BOOST_CONTAINER_FORCEINLINE transform_iterator& operator-=(typename Iterator::difference_type off) { this->advance(-off); return *this; } - transform_iterator operator-(typename Iterator::difference_type off) const + BOOST_CONTAINER_FORCEINLINE transform_iterator operator-(typename Iterator::difference_type off) const { return *this + (-off); } - typename UnaryFunction::result_type operator*() const + BOOST_CONTAINER_FORCEINLINE typename UnaryFunction::result_type operator*() const { return dereference(); } - operator_arrow_proxy<typename UnaryFunction::result_type> + BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy<typename UnaryFunction::result_type> operator->() const { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); } - Iterator & base() + BOOST_CONTAINER_FORCEINLINE Iterator & base() { return m_it; } - const Iterator & base() const + BOOST_CONTAINER_FORCEINLINE const Iterator & base() const { return m_it; } private: Iterator m_it; - void increment() + BOOST_CONTAINER_FORCEINLINE void increment() { ++m_it; } - void decrement() + BOOST_CONTAINER_FORCEINLINE void decrement() { --m_it; } - bool equal(const transform_iterator &other) const + BOOST_CONTAINER_FORCEINLINE bool equal(const transform_iterator &other) const { return m_it == other.m_it; } - bool less(const transform_iterator &other) const + BOOST_CONTAINER_FORCEINLINE bool less(const transform_iterator &other) const { return other.m_it < m_it; } - typename UnaryFunction::result_type dereference() const + BOOST_CONTAINER_FORCEINLINE typename UnaryFunction::result_type dereference() const { return UnaryFunction::operator()(*m_it); } - void advance(typename Iterator::difference_type n) + BOOST_CONTAINER_FORCEINLINE void advance(typename Iterator::difference_type n) { boost::container::iterator_advance(m_it, n); } - typename Iterator::difference_type distance_to(const transform_iterator &other)const + BOOST_CONTAINER_FORCEINLINE typename Iterator::difference_type distance_to(const transform_iterator &other)const { return boost::container::iterator_distance(other.m_it, m_it); } }; template <class Iterator, class UnaryFunc> -transform_iterator<Iterator, UnaryFunc> +BOOST_CONTAINER_FORCEINLINE transform_iterator<Iterator, UnaryFunc> make_transform_iterator(Iterator it, UnaryFunc fun) { return transform_iterator<Iterator, UnaryFunc>(it, fun); diff --git a/contrib/restricted/boost/container/include/boost/container/detail/tree.hpp b/contrib/restricted/boost/container/include/boost/container/detail/tree.hpp index 8d41158490..7f26e1f712 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/tree.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/tree.hpp @@ -52,6 +52,7 @@ #include <boost/move/detail/fwd_macros.hpp> #endif #include <boost/move/detail/move_helpers.hpp> +#include <boost/move/detail/force_ptr.hpp> // other #include <boost/core/no_exceptions_support.hpp> @@ -120,77 +121,9 @@ struct tree_internal_data_type< std::pair<T1, T2> > typedef pair<typename boost::move_detail::remove_const<T1>::type, T2> type; }; -//The node to be store in the tree template <class T, class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize> -struct tree_node - : public intrusive_tree_hook<VoidPointer, tree_type_value, OptimizeSize>::type +struct iiterator_node_value_type< base_node<T, intrusive_tree_hook<VoidPointer, tree_type_value, OptimizeSize>, true > > { - private: - //BOOST_COPYABLE_AND_MOVABLE(tree_node) - tree_node(); - - public: - typedef typename intrusive_tree_hook - <VoidPointer, tree_type_value, OptimizeSize>::type hook_type; - typedef T value_type; - typedef typename tree_internal_data_type<T>::type internal_type; - - typedef tree_node< T, VoidPointer - , tree_type_value, OptimizeSize> node_t; - - BOOST_CONTAINER_FORCEINLINE T &get_data() - { - T* ptr = reinterpret_cast<T*>(&this->m_data); - return *ptr; - } - - BOOST_CONTAINER_FORCEINLINE const T &get_data() const - { - const T* ptr = reinterpret_cast<const T*>(&this->m_data); - return *ptr; - } - - internal_type m_data; - - template<class T1, class T2> - BOOST_CONTAINER_FORCEINLINE void do_assign(const std::pair<const T1, T2> &p) - { - const_cast<T1&>(m_data.first) = p.first; - m_data.second = p.second; - } - - template<class T1, class T2> - BOOST_CONTAINER_FORCEINLINE void do_assign(const pair<const T1, T2> &p) - { - const_cast<T1&>(m_data.first) = p.first; - m_data.second = p.second; - } - - template<class V> - BOOST_CONTAINER_FORCEINLINE void do_assign(const V &v) - { m_data = v; } - - template<class T1, class T2> - BOOST_CONTAINER_FORCEINLINE void do_move_assign(std::pair<const T1, T2> &p) - { - const_cast<T1&>(m_data.first) = ::boost::move(p.first); - m_data.second = ::boost::move(p.second); - } - - template<class T1, class T2> - BOOST_CONTAINER_FORCEINLINE void do_move_assign(pair<const T1, T2> &p) - { - const_cast<T1&>(m_data.first) = ::boost::move(p.first); - m_data.second = ::boost::move(p.second); - } - - template<class V> - BOOST_CONTAINER_FORCEINLINE void do_move_assign(V &v) - { m_data = ::boost::move(v); } -}; - -template <class T, class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize> -struct iiterator_node_value_type< tree_node<T, VoidPointer, tree_type_value, OptimizeSize> > { typedef T type; }; @@ -226,88 +159,95 @@ class push_back_functor namespace dtl { -template< class NodeType, class NodeCompareType - , class SizeType, class HookType +template< class NodeType + , class KeyOfNode + , class KeyCompare + , class HookType , boost::container::tree_type_enum tree_type_value> struct intrusive_tree_dispatch; -template<class NodeType, class NodeCompareType, class SizeType, class HookType> +template<class NodeType, class KeyOfNode, class KeyCompare, class HookType> struct intrusive_tree_dispatch - <NodeType, NodeCompareType, SizeType, HookType, boost::container::red_black_tree> + <NodeType, KeyOfNode, KeyCompare, HookType, boost::container::red_black_tree> { typedef typename dtl::bi::make_rbtree <NodeType - ,dtl::bi::compare<NodeCompareType> + ,dtl::bi::key_of_value<KeyOfNode> + ,dtl::bi::compare<KeyCompare> ,dtl::bi::base_hook<HookType> ,dtl::bi::constant_time_size<true> - ,dtl::bi::size_type<SizeType> >::type type; }; -template<class NodeType, class NodeCompareType, class SizeType, class HookType> +template<class NodeType, class KeyOfNode, class KeyCompare, class HookType> struct intrusive_tree_dispatch - <NodeType, NodeCompareType, SizeType, HookType, boost::container::avl_tree> + <NodeType, KeyOfNode, KeyCompare, HookType, boost::container::avl_tree> { typedef typename dtl::bi::make_avltree <NodeType - ,dtl::bi::compare<NodeCompareType> + ,dtl::bi::key_of_value<KeyOfNode> + ,dtl::bi::compare<KeyCompare> ,dtl::bi::base_hook<HookType> ,dtl::bi::constant_time_size<true> - ,dtl::bi::size_type<SizeType> >::type type; }; -template<class NodeType, class NodeCompareType, class SizeType, class HookType> +template<class NodeType, class KeyOfNode, class KeyCompare, class HookType> struct intrusive_tree_dispatch - <NodeType, NodeCompareType, SizeType, HookType, boost::container::scapegoat_tree> + <NodeType, KeyOfNode, KeyCompare, HookType, boost::container::scapegoat_tree> { typedef typename dtl::bi::make_sgtree <NodeType - ,dtl::bi::compare<NodeCompareType> + ,dtl::bi::key_of_value<KeyOfNode> + ,dtl::bi::compare<KeyCompare> ,dtl::bi::base_hook<HookType> ,dtl::bi::floating_point<true> - ,dtl::bi::size_type<SizeType> >::type type; }; -template<class NodeType, class NodeCompareType, class SizeType, class HookType> +template<class NodeType, class KeyOfNode, class KeyCompare, class HookType> struct intrusive_tree_dispatch - <NodeType, NodeCompareType, SizeType, HookType, boost::container::splay_tree> + <NodeType, KeyOfNode, KeyCompare, HookType, boost::container::splay_tree> { typedef typename dtl::bi::make_splaytree <NodeType - ,dtl::bi::compare<NodeCompareType> + ,dtl::bi::key_of_value<KeyOfNode> + ,dtl::bi::compare<KeyCompare> ,dtl::bi::base_hook<HookType> ,dtl::bi::constant_time_size<true> - ,dtl::bi::size_type<SizeType> >::type type; }; -template<class Allocator, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize> +template < class Allocator + , class KeyOfValue + , class KeyCompare + , boost::container::tree_type_enum tree_type_value + , bool OptimizeSize> struct intrusive_tree_type { private: typedef typename boost::container:: - allocator_traits<Allocator>::value_type value_type; - typedef typename boost::container:: - allocator_traits<Allocator>::void_pointer void_pointer; + allocator_traits<Allocator>::value_type value_type; typedef typename boost::container:: - allocator_traits<Allocator>::size_type size_type; - typedef typename dtl::tree_node - < value_type, void_pointer - , tree_type_value, OptimizeSize> node_t; - typedef value_to_node_compare - <node_t, ValueCompare> node_compare_type; + allocator_traits<Allocator>::void_pointer void_pointer; + typedef base_node<value_type, intrusive_tree_hook + <void_pointer, tree_type_value, OptimizeSize>, true > node_t; //Deducing the hook type from node_t (e.g. node_t::hook_type) would //provoke an early instantiation of node_t that could ruin recursive //tree definitions, so retype the complete type to avoid any problem. typedef typename intrusive_tree_hook <void_pointer, tree_type_value - , OptimizeSize>::type hook_type; + , OptimizeSize>::type hook_type; + + typedef key_of_node + <node_t, KeyOfValue> key_of_node_t; + public: typedef typename intrusive_tree_dispatch - < node_t, node_compare_type - , size_type, hook_type + < node_t + , key_of_node_t + , KeyCompare + , hook_type , tree_type_value>::type type; }; @@ -360,13 +300,14 @@ class RecyclingCloner : m_holder(holder), m_icont(itree) {} - BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type &p, const node_t &other, bool_<true>) - { p->do_move_assign(const_cast<node_t &>(other).m_data); } + BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type p, node_t &other, bool_<true>) + { p->do_move_assign(other.get_real_data()); } - BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type &p, const node_t &other, bool_<false>) - { p->do_assign(other.m_data); } + BOOST_CONTAINER_FORCEINLINE static void do_assign(node_ptr_type p, const node_t &other, bool_<false>) + { p->do_assign(other.get_real_data()); } - node_ptr_type operator()(const node_t &other) const + node_ptr_type operator() + (typename dtl::if_c<DoMove, node_t &, const node_t&>::type other) const { if(node_ptr_type p = m_icont.unlink_leftmost_without_rebalance()){ //First recycle a node (this can't throw) @@ -386,7 +327,7 @@ class RecyclingCloner BOOST_CATCH_END } else{ - return m_holder.create_node(other.m_data); + return m_holder.create_node(boost::move(other.get_real_data())); } } @@ -394,41 +335,6 @@ class RecyclingCloner intrusive_container &m_icont; }; -template<class KeyCompare, class KeyOfValue> -struct key_node_compare - : public boost::intrusive::detail::ebo_functor_holder<KeyCompare> -{ - BOOST_CONTAINER_FORCEINLINE explicit key_node_compare(const KeyCompare &comp) - : base_t(comp) - {} - - typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t; - typedef KeyCompare key_compare; - typedef KeyOfValue key_of_value; - typedef typename KeyOfValue::type key_type; - - BOOST_CONTAINER_FORCEINLINE const key_compare &key_comp() const - { return static_cast<const key_compare &>(*this); } - - BOOST_CONTAINER_FORCEINLINE key_compare &key_comp() - { return static_cast<key_compare &>(*this); } - - BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const - { return this->key_comp()(key1, key2); } - - template<class U> - BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const U &nonkey2) const - { return this->key_comp()(key1, key_of_value()(nonkey2.get_data())); } - - template<class U> - BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2) const - { return this->key_comp()(key_of_value()(nonkey1.get_data()), key2); } - - template<class U, class V> - BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const V &nonkey2) const - { return this->key_comp()(key_of_value()(nonkey1.get_data()), key_of_value()(nonkey2.get_data())); } -}; - template<class Options> struct get_tree_opt { @@ -441,32 +347,69 @@ struct get_tree_opt<void> typedef tree_assoc_defaults type; }; +template<class, class KeyOfValue> +struct tree_key_of_value +{ + typedef KeyOfValue type; +}; + +template<class T> +struct tree_key_of_value<T, void> +{ + typedef dtl::identity<T> type; +}; + +template<class T1, class T2> +struct tree_key_of_value<std::pair<T1, T2>, int> +{ + typedef dtl::select1st<T1> type; +}; + +template<class T1, class T2> +struct tree_key_of_value<boost::container::dtl::pair<T1, T2>, int> +{ + typedef dtl::select1st<T1> type; +}; + + template <class T, class KeyOfValue, class Compare, class Allocator, class Options> -class tree - : public dtl::node_alloc_holder - < Allocator - , typename dtl::intrusive_tree_type - < Allocator, tree_value_compare - <typename allocator_traits<Allocator>::pointer, Compare, KeyOfValue> +struct make_intrusive_tree_type + : dtl::intrusive_tree_type + < typename real_allocator<T, Allocator>::type + , typename tree_key_of_value<T, KeyOfValue>::type + , Compare , get_tree_opt<Options>::type::tree_type , get_tree_opt<Options>::type::optimize_size - >::type + > +{}; + + +template <class T, class KeyOfValue, class Compare, class Allocator, class Options> +class tree + : public dtl::node_alloc_holder + < typename real_allocator<T, Allocator>::type + , typename make_intrusive_tree_type<T, KeyOfValue, Compare, Allocator, Options>::type > { + typedef tree < T, KeyOfValue + , Compare, Allocator, Options> ThisType; + public: + typedef typename real_allocator<T, Allocator>::type allocator_type; + + private: + typedef allocator_traits<allocator_type> allocator_traits_t; + typedef typename tree_key_of_value<T, KeyOfValue>::type key_of_value_t; typedef tree_value_compare - < typename allocator_traits<Allocator>::pointer - , Compare, KeyOfValue> ValComp; + < typename allocator_traits_t::pointer + , Compare + , key_of_value_t> ValComp; typedef typename get_tree_opt<Options>::type options_type; - typedef typename dtl::intrusive_tree_type - < Allocator, ValComp - , options_type::tree_type - , options_type::optimize_size - >::type Icont; + typedef typename make_intrusive_tree_type + <T, KeyOfValue, Compare, Allocator, Options>::type Icont; typedef dtl::node_alloc_holder - <Allocator, Icont> AllocHolder; + <allocator_type, Icont> AllocHolder; typedef typename AllocHolder::NodePtr NodePtr; - typedef tree < T, KeyOfValue - , Compare, Allocator, Options> ThisType; + typedef typename AllocHolder::NodeAlloc NodeAlloc; typedef boost::container:: allocator_traits<NodeAlloc> allocator_traits_type; @@ -474,7 +417,7 @@ class tree typedef typename AllocHolder::Node Node; typedef typename Icont::iterator iiterator; typedef typename Icont::const_iterator iconst_iterator; - typedef dtl::allocator_destroyer<NodeAlloc> Destroyer; + typedef dtl::allocator_node_destroyer<NodeAlloc> Destroyer; typedef typename AllocHolder::alloc_version alloc_version; typedef intrusive_tree_proxy<options_type::tree_type> intrusive_tree_proxy_t; @@ -482,41 +425,40 @@ class tree public: - typedef typename KeyOfValue::type key_type; - typedef T value_type; - typedef Allocator allocator_type; - typedef Compare key_compare; - typedef ValComp value_compare; + typedef typename key_of_value_t::type key_type; + typedef T value_type; + typedef Compare key_compare; + typedef ValComp value_compare; typedef typename boost::container:: - allocator_traits<Allocator>::pointer pointer; + allocator_traits<allocator_type>::pointer pointer; typedef typename boost::container:: - allocator_traits<Allocator>::const_pointer const_pointer; + allocator_traits<allocator_type>::const_pointer const_pointer; typedef typename boost::container:: - allocator_traits<Allocator>::reference reference; + allocator_traits<allocator_type>::reference reference; typedef typename boost::container:: - allocator_traits<Allocator>::const_reference const_reference; + allocator_traits<allocator_type>::const_reference const_reference; typedef typename boost::container:: - allocator_traits<Allocator>::size_type size_type; + allocator_traits<allocator_type>::size_type size_type; typedef typename boost::container:: - allocator_traits<Allocator>::difference_type difference_type; + allocator_traits<allocator_type>::difference_type difference_type; typedef dtl::iterator_from_iiterator - <iiterator, false> iterator; + <iiterator, false> iterator; typedef dtl::iterator_from_iiterator - <iiterator, true > const_iterator; + <iiterator, true > const_iterator; typedef boost::container::reverse_iterator - <iterator> reverse_iterator; + <iterator> reverse_iterator; typedef boost::container::reverse_iterator - <const_iterator> const_reverse_iterator; + <const_iterator> const_reverse_iterator; typedef node_handle - < NodeAlloc, void> node_type; + < NodeAlloc, void> node_type; typedef insert_return_type_base - <iterator, node_type> insert_return_type; + <iterator, node_type> insert_return_type; - typedef NodeAlloc stored_allocator_type; + typedef NodeAlloc stored_allocator_type; private: - typedef key_node_compare<key_compare, KeyOfValue> KeyNodeCompare; + typedef key_node_pred<key_compare, key_of_value_t, Node> KeyNodeCompare; public: @@ -594,7 +536,7 @@ class tree if(unique_insertion){ const const_iterator end_it(this->cend()); for ( ; first != last; ++first){ - this->insert_unique_convertible(end_it, *first); + this->insert_unique_hint_convertible(end_it, *first); } } else{ @@ -618,7 +560,7 @@ class tree //for the constructor const const_iterator end_it(this->cend()); for ( ; first != last; ++first){ - this->insert_equal_convertible(end_it, *first); + this->insert_equal_hint_convertible(end_it, *first); } } @@ -635,7 +577,7 @@ class tree { //Optimized allocation and construction this->allocate_many_and_construct - ( first, boost::container::iterator_distance(first, last) + ( first, boost::container::iterator_udistance(first, last) , insert_equal_end_hint_functor<Node, Icont>(this->icont())); } @@ -652,7 +594,7 @@ class tree { //Optimized allocation and construction this->allocate_many_and_construct - ( first, boost::container::iterator_distance(first, last) + ( first, boost::container::iterator_udistance(first, last) , dtl::push_back_functor<Node, Icont>(this->icont())); //AllocHolder clears in case of exception } @@ -713,7 +655,7 @@ class tree tree& operator=(BOOST_COPY_ASSIGN_REF(tree) x) { - if (&x != this){ + if (BOOST_LIKELY(this != &x)) { NodeAlloc &this_alloc = this->get_stored_allocator(); const NodeAlloc &x_alloc = x.get_stored_allocator(); dtl::bool_<allocator_traits<NodeAlloc>:: @@ -747,39 +689,40 @@ class tree allocator_traits_type::is_always_equal::value) && boost::container::dtl::is_nothrow_move_assignable<Compare>::value) { - BOOST_ASSERT(this != &x); - NodeAlloc &this_alloc = this->node_alloc(); - NodeAlloc &x_alloc = x.node_alloc(); - const bool propagate_alloc = allocator_traits<NodeAlloc>:: - propagate_on_container_move_assignment::value; - const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; - //Resources can be transferred if both allocators are - //going to be equal after this function (either propagated or already equal) - if(propagate_alloc || allocators_equal){ - //Destroy - this->clear(); - //Move allocator if needed - this->AllocHolder::move_assign_alloc(x); - //Obtain resources - this->icont() = boost::move(x.icont()); - } - //Else do a one by one move - else{ - //Transfer all the nodes to a temporary tree - //If anything goes wrong, all the nodes will be destroyed - //automatically - Icont other_tree(::boost::move(this->icont())); - - //Now recreate the source tree reusing nodes stored by other_tree - this->icont().clone_from - (::boost::move(x.icont()) - , RecyclingCloner<AllocHolder, true>(*this, other_tree) - , Destroyer(this->node_alloc())); - - //If there are remaining nodes, destroy them - NodePtr p; - while((p = other_tree.unlink_leftmost_without_rebalance())){ - AllocHolder::destroy_node(p); + if (BOOST_LIKELY(this != &x)) { + NodeAlloc &this_alloc = this->node_alloc(); + NodeAlloc &x_alloc = x.node_alloc(); + const bool propagate_alloc = allocator_traits<NodeAlloc>:: + propagate_on_container_move_assignment::value; + const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; + //Resources can be transferred if both allocators are + //going to be equal after this function (either propagated or already equal) + if(propagate_alloc || allocators_equal){ + //Destroy + this->clear(); + //Move allocator if needed + this->AllocHolder::move_assign_alloc(x); + //Obtain resources + this->icont() = boost::move(x.icont()); + } + //Else do a one by one move + else{ + //Transfer all the nodes to a temporary tree + //If anything goes wrong, all the nodes will be destroyed + //automatically + Icont other_tree(::boost::move(this->icont())); + + //Now recreate the source tree reusing nodes stored by other_tree + this->icont().clone_from + (::boost::move(x.icont()) + , RecyclingCloner<AllocHolder, true>(*this, other_tree) + , Destroyer(this->node_alloc())); + + //If there are remaining nodes, destroy them + NodePtr p; + while((p = other_tree.unlink_leftmost_without_rebalance())){ + AllocHolder::destroy_node(p); + } } } return *this; @@ -787,43 +730,57 @@ class tree public: // accessors: - BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const - { return this->icont().value_comp().predicate(); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + value_compare value_comp() const + { return value_compare(this->key_comp()); } - BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const - { return this->icont().value_comp().predicate().key_comp(); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + key_compare key_comp() const + { return this->icont().key_comp(); } - BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + allocator_type get_allocator() const { return allocator_type(this->node_alloc()); } - BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const stored_allocator_type &get_stored_allocator() const { return this->node_alloc(); } - BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + stored_allocator_type &get_stored_allocator() { return this->node_alloc(); } - BOOST_CONTAINER_FORCEINLINE iterator begin() + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + iterator begin() { return iterator(this->icont().begin()); } - BOOST_CONTAINER_FORCEINLINE const_iterator begin() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator begin() const { return this->cbegin(); } - BOOST_CONTAINER_FORCEINLINE iterator end() + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + iterator end() { return iterator(this->icont().end()); } - BOOST_CONTAINER_FORCEINLINE const_iterator end() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator end() const { return this->cend(); } - BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reverse_iterator rbegin() { return reverse_iterator(end()); } - BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reverse_iterator rbegin() const { return this->crbegin(); } - BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reverse_iterator rend() { return reverse_iterator(begin()); } - BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reverse_iterator rend() const { return this->crend(); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. @@ -831,7 +788,8 @@ class tree //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator cbegin() const { return const_iterator(this->non_const_icont().begin()); } //! <b>Effects</b>: Returns a const_iterator to the end of the container. @@ -839,7 +797,8 @@ class tree //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_iterator cend() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator cend() const { return const_iterator(this->non_const_icont().end()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning @@ -848,7 +807,8 @@ class tree //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end @@ -857,16 +817,20 @@ class tree //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); } - BOOST_CONTAINER_FORCEINLINE bool empty() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + bool empty() const { return !this->size(); } - BOOST_CONTAINER_FORCEINLINE size_type size() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type size() const { return this->icont().size(); } - BOOST_CONTAINER_FORCEINLINE size_type max_size() const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type max_size() const { return AllocHolder::max_size(); } BOOST_CONTAINER_FORCEINLINE void swap(ThisType& x) @@ -883,7 +847,7 @@ class tree (const key_type& key, insert_commit_data &data) { std::pair<iiterator, bool> ret = - this->icont().insert_unique_check(key, KeyNodeCompare(key_comp()), data); + this->icont().insert_unique_check(key, data); return std::pair<iterator, bool>(iterator(ret.first), ret.second); } @@ -892,7 +856,7 @@ class tree { BOOST_ASSERT((priv_is_linked)(hint)); std::pair<iiterator, bool> ret = - this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(key_comp()), data); + this->icont().insert_unique_check(hint.get(), key, data); return std::pair<iterator, bool>(iterator(ret.first), ret.second); } @@ -901,24 +865,37 @@ class tree (BOOST_FWD_REF(MovableConvertible) v, insert_commit_data &data) { NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(v)); - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); iterator ret(this->icont().insert_unique_commit(*tmp, data)); destroy_deallocator.release(); return ret; } template<class MovableConvertible> - std::pair<iterator,bool> insert_unique(BOOST_FWD_REF(MovableConvertible) v) + std::pair<iterator,bool> insert_unique_convertible(BOOST_FWD_REF(MovableConvertible) v) { insert_commit_data data; std::pair<iterator,bool> ret = - this->insert_unique_check(KeyOfValue()(v), data); + this->insert_unique_check(key_of_value_t()(v), data); if(ret.second){ ret.first = this->insert_unique_commit(boost::forward<MovableConvertible>(v), data); } return ret; } + template<class MovableConvertible> + iterator insert_unique_hint_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v) + { + BOOST_ASSERT((priv_is_linked)(hint)); + insert_commit_data data; + std::pair<iterator,bool> ret = + this->insert_unique_check(hint, key_of_value_t()(v), data); + if(!ret.second) + return ret.first; + return this->insert_unique_commit(boost::forward<MovableConvertible>(v), data); + } + + private: template<class KeyConvertible, class M> @@ -926,7 +903,7 @@ class tree (BOOST_FWD_REF(KeyConvertible) key, BOOST_FWD_REF(M) obj, insert_commit_data &data) { NodePtr tmp = AllocHolder::create_node(boost::forward<KeyConvertible>(key), boost::forward<M>(obj)); - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); iiterator ret(this->icont().insert_unique_commit(*tmp, data)); destroy_deallocator.release(); return ret; @@ -949,13 +926,13 @@ class tree this->icont().push_back(*tmp); } - std::pair<iterator, bool> emplace_unique_impl(NodePtr p) + std::pair<iterator, bool> emplace_unique_node(NodePtr p) { value_type &v = p->get_data(); insert_commit_data data; - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(p, this->node_alloc()); + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(p, this->node_alloc()); std::pair<iterator,bool> ret = - this->insert_unique_check(KeyOfValue()(v), data); + this->insert_unique_check(key_of_value_t()(v), data); if(!ret.second){ return ret; } @@ -966,14 +943,15 @@ class tree , true ); } - iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p) + iterator emplace_hint_unique_node(const_iterator hint, NodePtr p) { BOOST_ASSERT((priv_is_linked)(hint)); value_type &v = p->get_data(); insert_commit_data data; std::pair<iterator,bool> ret = - this->insert_unique_check(hint, KeyOfValue()(v), data); + this->insert_unique_check(hint, key_of_value_t()(v), data); if(!ret.second){ + //Destroy unneeded node Destroyer(this->node_alloc())(p); return ret.first; } @@ -986,17 +964,17 @@ class tree template <class... Args> BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args) - { return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); } + { return this->emplace_unique_node(AllocHolder::create_node(boost::forward<Args>(args)...)); } template <class... Args> BOOST_CONTAINER_FORCEINLINE iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args) - { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...)); } + { return this->emplace_hint_unique_node(hint, AllocHolder::create_node(boost::forward<Args>(args)...)); } template <class... Args> iterator emplace_equal(BOOST_FWD_REF(Args)... args) { NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...)); - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); destroy_deallocator.release(); return ret; @@ -1007,7 +985,7 @@ class tree { BOOST_ASSERT((priv_is_linked)(hint)); NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...)); - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); iterator ret(this->icont().insert_equal(hint.get(), *tmp)); destroy_deallocator.release(); return ret; @@ -1020,8 +998,8 @@ class tree insert_commit_data data; const key_type & k = key; //Support emulated rvalue references std::pair<iiterator, bool> ret = - hint == const_iterator() ? this->icont().insert_unique_check( k, KeyNodeCompare(key_comp()), data) - : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data); + hint == const_iterator() ? this->icont().insert_unique_check( k, data) + : this->icont().insert_unique_check(hint.get(), k, data); if(ret.second){ ret.first = this->icont().insert_unique_commit (*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key), boost::forward<Args>(args)...), data); @@ -1034,17 +1012,17 @@ class tree #define BOOST_CONTAINER_TREE_EMPLACE_CODE(N) \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\ - { return this->emplace_unique_impl(AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\ + { return this->emplace_unique_node(AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\ \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ - { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\ + { return this->emplace_hint_unique_node(hint, AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\ \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ iterator emplace_equal(BOOST_MOVE_UREF##N)\ {\ NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\ - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\ + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\ iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));\ destroy_deallocator.release();\ return ret;\ @@ -1055,7 +1033,7 @@ class tree {\ BOOST_ASSERT((priv_is_linked)(hint));\ NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\ - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\ + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\ iterator ret(this->icont().insert_equal(hint.get(), *tmp));\ destroy_deallocator.release();\ return ret;\ @@ -1068,8 +1046,8 @@ class tree insert_commit_data data;\ const key_type & k = key;\ std::pair<iiterator, bool> ret =\ - hint == const_iterator() ? this->icont().insert_unique_check( k, KeyNodeCompare(key_comp()), data)\ - : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);\ + hint == const_iterator() ? this->icont().insert_unique_check( k, data)\ + : this->icont().insert_unique_check(hint.get(), k, data);\ if(ret.second){\ ret.first = this->icont().insert_unique_commit\ (*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N), data);\ @@ -1082,64 +1060,44 @@ class tree #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template<class MovableConvertible> - iterator insert_unique_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v) - { - BOOST_ASSERT((priv_is_linked)(hint)); - insert_commit_data data; - std::pair<iterator,bool> ret = - this->insert_unique_check(hint, KeyOfValue()(v), data); - if(!ret.second) - return ret.first; - return this->insert_unique_commit(boost::forward<MovableConvertible>(v), data); - } - - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_unique, value_type, iterator, this->insert_unique_convertible, const_iterator, const_iterator) + //BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_unique, value_type, iterator, this->insert_unique_hint_convertible, const_iterator, const_iterator) template <class InputIterator> - void insert_unique(InputIterator first, InputIterator last) + void insert_unique_range(InputIterator first, InputIterator last) { for( ; first != last; ++first) - this->insert_unique(*first); - } - - iterator insert_equal(const value_type& v) - { - NodePtr tmp(AllocHolder::create_node(v)); - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); - iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); - destroy_deallocator.release(); - return ret; + this->insert_unique_convertible(*first); } template<class MovableConvertible> - iterator insert_equal(BOOST_FWD_REF(MovableConvertible) v) + iterator insert_equal_convertible(BOOST_FWD_REF(MovableConvertible) v) { NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v))); - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); destroy_deallocator.release(); return ret; } template<class MovableConvertible> - iterator insert_equal_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v) + iterator insert_equal_hint_convertible(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v) { BOOST_ASSERT((priv_is_linked)(hint)); NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v))); - scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); + scoped_node_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); iterator ret(this->icont().insert_equal(hint.get(), *tmp)); destroy_deallocator.release(); return ret; } - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_equal, value_type, iterator, this->insert_equal_convertible, const_iterator, const_iterator) + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG + (insert_equal, value_type, iterator, this->insert_equal_hint_convertible, const_iterator, const_iterator) template <class InputIterator> - void insert_equal(InputIterator first, InputIterator last) + void insert_equal_range(InputIterator first, InputIterator last) { for( ; first != last; ++first) - this->insert_equal(*first); + this->insert_equal_convertible(*first); } template<class KeyType, class M> @@ -1148,8 +1106,8 @@ class tree insert_commit_data data; const key_type & k = key; //Support emulated rvalue references std::pair<iiterator, bool> ret = - hint == const_iterator() ? this->icont().insert_unique_check(k, KeyNodeCompare(key_comp()), data) - : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data); + hint == const_iterator() ? this->icont().insert_unique_check(k, data) + : this->icont().insert_unique_check(hint.get(), k, data); if(ret.second){ ret.first = this->priv_insert_or_assign_commit(boost::forward<KeyType>(key), boost::forward<M>(obj), data); } @@ -1166,7 +1124,16 @@ class tree } BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& k) - { return AllocHolder::erase_key(k, KeyNodeCompare(key_comp()), alloc_version()); } + { return AllocHolder::erase_key(k, alloc_version()); } + + size_type erase_unique(const key_type& k) + { + iterator i = this->find(k); + size_type ret = static_cast<size_type>(i != this->end()); + if (ret) + this->erase(i); + return ret; + } iterator erase(const_iterator first, const_iterator last) { @@ -1203,7 +1170,7 @@ class tree if(!nh.empty()){ insert_commit_data data; std::pair<iterator,bool> ret = - this->insert_unique_check(hint, KeyOfValue()(nh.value()), data); + this->insert_unique_check(hint, key_of_value_t()(nh.value()), data); if(ret.second){ irt.inserted = true; irt.position = iterator(this->icont().insert_unique_commit(*nh.get(), data)); @@ -1254,53 +1221,157 @@ class tree // search operations. Const and non-const overloads even if no iterator is returned // so splay implementations can to their rebalancing when searching in non-const versions - BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& k) - { return iterator(this->icont().find(k, KeyNodeCompare(key_comp()))); } - - BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& k) const - { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(key_comp()))); } - - BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& k) const - { return size_type(this->icont().count(k, KeyNodeCompare(key_comp()))); } - - BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k) - { return iterator(this->icont().lower_bound(k, KeyNodeCompare(key_comp()))); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + iterator find(const key_type& k) + { return iterator(this->icont().find(k)); } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator find(const key_type& k) const + { return const_iterator(this->non_const_icont().find(k)); } + + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, iterator>::type + find(const K& k) + { return iterator(this->icont().find(k, KeyNodeCompare())); } + + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, const_iterator>::type + find(const K& k) const + { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare())); } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type count(const key_type& k) const + { return size_type(this->icont().count(k)); } + + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, size_type>::type + count(const K& k) const + { return size_type(this->icont().count(k, KeyNodeCompare())); } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + bool contains(const key_type& x) const + { return this->find(x) != this->cend(); } + + template<typename K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, bool>::type + contains(const K& x) const + { return this->find(x) != this->cend(); } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + iterator lower_bound(const key_type& k) + { return iterator(this->icont().lower_bound(k)); } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator lower_bound(const key_type& k) const + { return const_iterator(this->non_const_icont().lower_bound(k)); } + + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, iterator>::type + lower_bound(const K& k) + { return iterator(this->icont().lower_bound(k, KeyNodeCompare())); } + + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, const_iterator>::type + lower_bound(const K& k) const + { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare())); } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + iterator upper_bound(const key_type& k) + { return iterator(this->icont().upper_bound(k)); } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator upper_bound(const key_type& k) const + { return const_iterator(this->non_const_icont().upper_bound(k)); } + + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, iterator>::type + upper_bound(const K& k) + { return iterator(this->icont().upper_bound(k, KeyNodeCompare())); } + + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, const_iterator>::type + upper_bound(const K& k) const + { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare())); } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + std::pair<iterator,iterator> equal_range(const key_type& k) + { + std::pair<iiterator, iiterator> ret = this->icont().equal_range(k); + return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second)); + } - BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& k) const - { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(key_comp()))); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const + { + std::pair<iiterator, iiterator> ret = + this->non_const_icont().equal_range(k); + return std::pair<const_iterator,const_iterator> + (const_iterator(ret.first), const_iterator(ret.second)); + } - BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& k) - { return iterator(this->icont().upper_bound(k, KeyNodeCompare(key_comp()))); } + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, std::pair<iterator,iterator> >::type + equal_range(const K& k) + { + std::pair<iiterator, iiterator> ret = + this->icont().equal_range(k, KeyNodeCompare()); + return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second)); + } - BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& k) const - { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(key_comp()))); } + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, std::pair<const_iterator, const_iterator> >::type + equal_range(const K& k) const + { + std::pair<iiterator, iiterator> ret = + this->non_const_icont().equal_range(k, KeyNodeCompare()); + return std::pair<const_iterator,const_iterator> + (const_iterator(ret.first), const_iterator(ret.second)); + } - std::pair<iterator,iterator> equal_range(const key_type& k) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + std::pair<iterator,iterator> lower_bound_range(const key_type& k) { std::pair<iiterator, iiterator> ret = - this->icont().equal_range(k, KeyNodeCompare(key_comp())); + this->icont().lower_bound_range(k); return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second)); } - std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const { std::pair<iiterator, iiterator> ret = - this->non_const_icont().equal_range(k, KeyNodeCompare(key_comp())); + this->non_const_icont().lower_bound_range(k); return std::pair<const_iterator,const_iterator> (const_iterator(ret.first), const_iterator(ret.second)); } - std::pair<iterator,iterator> lower_bound_range(const key_type& k) + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, std::pair<iterator,iterator> >::type + lower_bound_range(const K& k) { std::pair<iiterator, iiterator> ret = - this->icont().lower_bound_range(k, KeyNodeCompare(key_comp())); + this->icont().lower_bound_range(k, KeyNodeCompare()); return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second)); } - std::pair<const_iterator, const_iterator> lower_bound_range(const key_type& k) const + template <class K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + typename dtl::enable_if_transparent<key_compare, K, std::pair<const_iterator, const_iterator> >::type + lower_bound_range(const K& k) const { std::pair<iiterator, iiterator> ret = - this->non_const_icont().lower_bound_range(k, KeyNodeCompare(key_comp())); + this->non_const_icont().lower_bound_range(k, KeyNodeCompare()); return std::pair<const_iterator,const_iterator> (const_iterator(ret.first), const_iterator(ret.second)); } @@ -1308,25 +1379,33 @@ class tree BOOST_CONTAINER_FORCEINLINE void rebalance() { intrusive_tree_proxy_t::rebalance(this->icont()); } - BOOST_CONTAINER_FORCEINLINE friend bool operator==(const tree& x, const tree& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator==(const tree& x, const tree& y) { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } - BOOST_CONTAINER_FORCEINLINE friend bool operator<(const tree& x, const tree& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator<(const tree& x, const tree& y) { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const tree& x, const tree& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator!=(const tree& x, const tree& y) { return !(x == y); } - BOOST_CONTAINER_FORCEINLINE friend bool operator>(const tree& x, const tree& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator>(const tree& x, const tree& y) { return y < x; } - BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const tree& x, const tree& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator<=(const tree& x, const tree& y) { return !(y < x); } - BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const tree& x, const tree& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator>=(const tree& x, const tree& y) { return !(x < y); } BOOST_CONTAINER_FORCEINLINE friend void swap(tree& x, tree& y) + BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value + && boost::container::dtl::is_nothrow_swappable<Compare>::value ) { x.swap(y); } }; @@ -1345,8 +1424,9 @@ struct has_trivial_destructor_after_move <T, KeyOfValue, Compare, Allocator, Options> > { - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && + typedef typename ::boost::container::dtl::tree<T, KeyOfValue, Compare, Allocator, Options>::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value && ::boost::has_trivial_destructor_after_move<pointer>::value && ::boost::has_trivial_destructor_after_move<Compare>::value; }; diff --git a/contrib/restricted/boost/container/include/boost/container/detail/type_traits.hpp b/contrib/restricted/boost/container/include/boost/container/detail/type_traits.hpp index 686cc409b7..ffa061b523 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/type_traits.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/type_traits.hpp @@ -40,6 +40,7 @@ using ::boost::move_detail::add_const; using ::boost::move_detail::add_const_reference; using ::boost::move_detail::remove_const; using ::boost::move_detail::remove_reference; +using ::boost::move_detail::remove_cvref; using ::boost::move_detail::make_unsigned; using ::boost::move_detail::is_floating_point; using ::boost::move_detail::is_integral; @@ -61,7 +62,11 @@ using ::boost::move_detail::is_nothrow_swappable; using ::boost::move_detail::alignment_of; using ::boost::move_detail::aligned_storage; using ::boost::move_detail::nat; +using ::boost::move_detail::nat2; +using ::boost::move_detail::nat3; +using ::boost::move_detail::natN; using ::boost::move_detail::max_align_t; +using ::boost::move_detail::is_convertible; } //namespace dtl { } //namespace container { diff --git a/contrib/restricted/boost/container/include/boost/container/detail/value_functors.hpp b/contrib/restricted/boost/container/include/boost/container/detail/value_functors.hpp index a2c494c5e7..39fb37c345 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/value_functors.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/value_functors.hpp @@ -18,19 +18,15 @@ # pragma once #endif -//Functors for member algorithm defaults -template<class ValueType> -struct value_less -{ - bool operator()(const ValueType &a, const ValueType &b) const - { return a < b; } -}; +#include <boost/intrusive/detail/value_functors.hpp> -template<class ValueType> -struct value_equal -{ - bool operator()(const ValueType &a, const ValueType &b) const - { return a == b; } -}; +namespace boost { +namespace container { + +using ::boost::intrusive::value_less; +using ::boost::intrusive::value_equal; + +} //namespace container { +} //namespace boost { #endif //BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP diff --git a/contrib/restricted/boost/container/include/boost/container/detail/variadic_templates_tools.hpp b/contrib/restricted/boost/container/include/boost/container/detail/variadic_templates_tools.hpp index 1e6f3df742..4f16fb0453 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/variadic_templates_tools.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/variadic_templates_tools.hpp @@ -78,7 +78,7 @@ class tuple<Head, Tail...> template<typename... Values> -tuple<Values&&...> forward_as_tuple(Values&&... values) +tuple<Values&&...> forward_as_tuple_impl(Values&&... values) { return tuple<Values&&...>(::boost::forward<Values>(values)...); } template<int I, typename Tuple> diff --git a/contrib/restricted/boost/container/include/boost/container/detail/version_type.hpp b/contrib/restricted/boost/container/include/boost/container/detail/version_type.hpp index c2531ccc31..389606a567 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/version_type.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/version_type.hpp @@ -39,23 +39,14 @@ struct version_type : public dtl::integral_constant<unsigned, V> { typedef T type; - - version_type(const version_type<T, 0>&); }; namespace impl{ -template <class T, - bool = dtl::is_convertible<version_type<T, 0>, typename T::version>::value> -struct extract_version -{ - static const unsigned value = 1; -}; - template <class T> -struct extract_version<T, true> +struct extract_version { - static const unsigned value = T::version::value; + typedef typename T::version type; }; template <class T> @@ -79,7 +70,7 @@ struct version template <class T> struct version<T, true> { - static const unsigned value = extract_version<T>::value; + static const unsigned value = extract_version<T>::type::value; }; } //namespace impl diff --git a/contrib/restricted/boost/container/include/boost/container/detail/workaround.hpp b/contrib/restricted/boost/container/include/boost/container/detail/workaround.hpp index 736326b779..3cb731f0ee 100644 --- a/contrib/restricted/boost/container/include/boost/container/detail/workaround.hpp +++ b/contrib/restricted/boost/container/include/boost/container/detail/workaround.hpp @@ -98,14 +98,61 @@ #define BOOST_CONTAINER_FORCEINLINE inline #elif defined(BOOST_CONTAINER_FORCEINLINE_IS_BOOST_FORCELINE) #define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE -#elif defined(BOOST_MSVC) && defined(_DEBUG) - //"__forceinline" and MSVC seems to have some bugs in debug mode +#elif defined(BOOST_MSVC) && (_MSC_VER < 1900 || defined(_DEBUG)) + //"__forceinline" and MSVC seems to have some bugs in old versions and in debug mode #define BOOST_CONTAINER_FORCEINLINE inline -#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) +//#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) +#elif defined(__GNUC__) && (__GNUC__ <= 5) //Older GCCs have problems with forceinline #define BOOST_CONTAINER_FORCEINLINE inline #else #define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE #endif +//#define BOOST_CONTAINER_DISABLE_NOINLINE + +#if defined(BOOST_CONTAINER_DISABLE_NOINLINE) + #define BOOST_CONTAINER_NOINLINE +#else + #define BOOST_CONTAINER_NOINLINE BOOST_NOINLINE +#endif + + +#if !defined(__has_feature) +#define BOOST_CONTAINER_HAS_FEATURE(feature) 0 +#else +#define BOOST_CONTAINER_HAS_FEATURE(feature) __has_feature(feature) +#endif + +//Detect address sanitizer +#if defined(__SANITIZE_ADDRESS__) || BOOST_CONTAINER_HAS_FEATURE(address_sanitizer) +#define BOOST_CONTAINER_ASAN +#endif + + +#if (BOOST_CXX_VERSION < 201703L) || !defined(__cpp_deduction_guides) + #define BOOST_CONTAINER_NO_CXX17_CTAD +#endif + +#if defined(BOOST_CONTAINER_DISABLE_ATTRIBUTE_NODISCARD) + #define BOOST_CONTAINER_ATTRIBUTE_NODISCARD +#else + #if defined(BOOST_GCC) && ((BOOST_GCC < 100000) || (__cplusplus < 201703L)) + //Avoid using it in C++ < 17 and GCC < 10 because it warns in SFINAE contexts + //(see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89070) + #define BOOST_CONTAINER_ATTRIBUTE_NODISCARD + #else + #define BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_ATTRIBUTE_NODISCARD + #endif +#endif + + +//Configuration options: + +//Define this to use std exception types instead of boost::container's own exception types +//#define BOOST_CONTAINER_USE_STD_EXCEPTIONS + + + + #endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP diff --git a/contrib/restricted/boost/container/include/boost/container/map.hpp b/contrib/restricted/boost/container/include/boost/container/map.hpp index 63e10b4af0..30c7b83e95 100644 --- a/contrib/restricted/boost/container/include/boost/container/map.hpp +++ b/contrib/restricted/boost/container/include/boost/container/map.hpp @@ -72,7 +72,7 @@ namespace container { //! (e.g. <i>allocator< std::pair<const Key, T> > </i>). //! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options. template < class Key, class T, class Compare = std::less<Key> - , class Allocator = new_allocator< std::pair< const Key, T> >, class Options = tree_assoc_defaults > + , class Allocator = void, class Options = tree_assoc_defaults > #else template <class Key, class T, class Compare, class Allocator, class Options> #endif @@ -80,7 +80,7 @@ class map ///@cond : public dtl::tree < std::pair<const Key, T> - , dtl::select1st<Key> + , int , Compare, Allocator, Options> ///@endcond { @@ -88,11 +88,11 @@ class map private: BOOST_COPYABLE_AND_MOVABLE(map) - typedef dtl::select1st<Key> select_1st_t; + typedef int select_1st_t; typedef std::pair<const Key, T> value_type_impl; typedef dtl::tree <value_type_impl, select_1st_t, Compare, Allocator, Options> base_t; - typedef dtl::pair <Key, T> movable_value_type_impl; + typedef dtl::pair <Key, T> movable_value_type_impl; typedef typename base_t::value_compare value_compare_impl; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -103,26 +103,26 @@ class map // ////////////////////////////////////////////// - typedef Key key_type; - typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type; - typedef T mapped_type; - typedef typename boost::container::allocator_traits<Allocator>::value_type value_type; - typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; - typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer; - typedef typename boost::container::allocator_traits<Allocator>::reference reference; - typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; - typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; - typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; - typedef Allocator allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; - typedef Compare key_compare; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; - typedef std::pair<key_type, mapped_type> nonconst_value_type; - typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; + typedef Key key_type; + typedef T mapped_type; + typedef typename base_t::allocator_type allocator_type; + typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type; + typedef typename boost::container::allocator_traits<allocator_type>::value_type value_type; + typedef typename boost::container::allocator_traits<allocator_type>::pointer pointer; + typedef typename boost::container::allocator_traits<allocator_type>::const_pointer const_pointer; + typedef typename boost::container::allocator_traits<allocator_type>::reference reference; + typedef typename boost::container::allocator_traits<allocator_type>::const_reference const_reference; + typedef typename boost::container::allocator_traits<allocator_type>::size_type size_type; + typedef typename boost::container::allocator_traits<allocator_type>::difference_type difference_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef Compare key_compare; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + //typedef std::pair<key_type, mapped_type> nonconst_value_type; + typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; typedef BOOST_CONTAINER_IMPDEF(node_handle< typename base_t::stored_allocator_type BOOST_MOVE_I pair_key_mapped_of_value @@ -143,7 +143,7 @@ class map //! //! <b>Complexity</b>: Constant. BOOST_CONTAINER_FORCEINLINE - map() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value && + map() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value && dtl::is_nothrow_default_constructible<Compare>::value) : base_t() {} @@ -256,6 +256,22 @@ class map : base_t(ordered_range, first, last, comp, a) {} + //! <b>Effects</b>: Constructs an empty map using the specified allocator object and + //! inserts elements from the ordered unique range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be + //! unique values. + //! + //! <b>Complexity</b>: Linear in N. + //! + //! <b>Note</b>: Non-standard extension. + template <class InputIterator> + BOOST_CONTAINER_FORCEINLINE map(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) + : base_t(ordered_range, first, last, Compare(), a) + {} + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! <b>Effects</b>: Constructs an empty map and //! inserts elements from the range [il.begin(), il.end()). @@ -613,7 +629,7 @@ class map //! the new element is inserted just before hint. template <class M> BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, const key_type& k, BOOST_FWD_REF(M) obj) - { return this->base_t::insert_or_assign(hint, k, ::boost::forward<M>(obj)); } + { return this->base_t::insert_or_assign(hint, k, ::boost::forward<M>(obj)).first; } //! <b>Effects</b>: If a key equivalent to k already exists in the container, assigns forward<M>(obj) //! to the mapped_type corresponding to the key k. If the key does not exist, inserts the new value @@ -631,7 +647,7 @@ class map //! the new element is inserted just before hint. template <class M> BOOST_CONTAINER_FORCEINLINE iterator insert_or_assign(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(M) obj) - { return this->base_t::insert_or_assign(hint, ::boost::move(k), ::boost::forward<M>(obj)); } + { return this->base_t::insert_or_assign(hint, ::boost::move(k), ::boost::forward<M>(obj)).first; } //! <b>Returns</b>: A reference to the element whose key is equivalent to x. //! Throws: An exception object of type out_of_range if no such element is present. @@ -648,7 +664,7 @@ class map //! <b>Returns</b>: A reference to the element whose key is equivalent to x. //! Throws: An exception object of type out_of_range if no such element is present. //! <b>Complexity</b>: logarithmic. - const T& at(const key_type& k) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD const T& at(const key_type& k) const { const_iterator i = this->find(k); if(i == this->end()){ @@ -672,51 +688,51 @@ class map //! //! <b>Complexity</b>: Logarithmic. BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const value_type& x) - { return this->base_t::insert_unique(x); } + { return this->base_t::insert_unique_convertible(x); } - //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if - //! there is no element in the container with key equivalent to the key of x. + //! <b>Effects</b>: Move constructs a new value from x if and only if there is + //! no element in the container with key equivalent to the key of x. //! //! <b>Returns</b>: The bool component of the returned pair is true if and only //! if the insertion takes place, and the iterator component of the pair //! points to the element with key equivalent to the key of x. //! //! <b>Complexity</b>: Logarithmic. - BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(const nonconst_value_type& x) - { return this->try_emplace(x.first, x.second); } + BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x) + { return this->base_t::insert_unique_convertible(boost::move(x)); } - //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and - //! only if there is no element in the container with key equivalent to the key of x. + //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if + //! there is no element in the container with key equivalent to the key of x. //! //! <b>Returns</b>: The bool component of the returned pair is true if and only //! if the insertion takes place, and the iterator component of the pair //! points to the element with key equivalent to the key of x. //! //! <b>Complexity</b>: Logarithmic. - BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x) - { return this->try_emplace(boost::move(x.first), boost::move(x.second)); } + template <class Pair> + BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST + ( std::pair<iterator BOOST_MOVE_I bool> + , typename dtl::enable_if_c< + dtl::is_convertible<Pair BOOST_MOVE_I value_type>::value || + dtl::is_convertible<Pair BOOST_MOVE_I movable_value_type>::value + BOOST_MOVE_I std::pair<iterator BOOST_MOVE_I bool> >::type) + insert(BOOST_FWD_REF(Pair) x) + { return this->base_t::emplace_unique(boost::forward<Pair>(x)); } - //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and - //! only if there is no element in the container with key equivalent to the key of x. - //! - //! <b>Returns</b>: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. - //! - //! <b>Complexity</b>: Logarithmic. - BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x) - { return this->try_emplace(boost::move(x.first), boost::move(x.second)); } + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x) + { return this->base_t::insert_unique_hint_convertible(p, x); } - //! <b>Effects</b>: Move constructs a new value from x if and only if there is + //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is //! no element in the container with key equivalent to the key of x. + //! p is a hint pointing to where the insert should start to search. //! - //! <b>Returns</b>: The bool component of the returned pair is true if and only - //! if the insertion takes place, and the iterator component of the pair - //! points to the element with key equivalent to the key of x. + //! <b>Returns</b>: An iterator pointing to the element with key equivalent + //! to the key of x. //! - //! <b>Complexity</b>: Logarithmic. - BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x) - { return this->base_t::insert_unique(boost::move(x)); } + //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t + //! is inserted right before p. + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) + { return this->base_t::insert_unique_hint_convertible(p, boost::move(x)); } //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is //! no element in the container with key equivalent to the key of x. @@ -727,9 +743,18 @@ class map //! //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x) - { return this->base_t::insert_unique(p, x); } - + template <class Pair> + BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST + ( iterator + , typename dtl::enable_if_c< + dtl::is_convertible<Pair BOOST_MOVE_I value_type>::value || + dtl::is_convertible<Pair BOOST_MOVE_I movable_value_type>::value + BOOST_MOVE_I iterator >::type) + insert(const_iterator p, BOOST_FWD_REF(Pair) x) + { return this->base_t::emplace_hint_unique(p, boost::forward<Pair>(x)); } + + +/* //! <b>Effects</b>: Move constructs a new value from x if and only if there is //! no element in the container with key equivalent to the key of x. //! p is a hint pointing to where the insert should start to search. @@ -760,18 +785,11 @@ class map //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. //! //! <b>Complexity</b>: Logarithmic. - iterator insert(const_iterator p, const nonconst_value_type& x) + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const nonconst_value_type& x) { return this->try_emplace(p, x.first, x.second); } - //! <b>Effects</b>: Inserts an element move constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. - //! - //! <b>Complexity</b>: Logarithmic. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) - { return this->base_t::insert_unique(p, boost::move(x)); } +*/ //! <b>Requires</b>: first, last are not iterators into *this. //! //! <b>Effects</b>: inserts each element from the range [first,last) if and only @@ -780,7 +798,7 @@ class map //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) template <class InputIterator> BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->base_t::insert_unique(first, last); } + { this->base_t::insert_unique_range(first, last); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only @@ -788,7 +806,7 @@ class map //! //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end()) BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il) - { this->base_t::insert_unique(il.begin(), il.end()); } + { this->base_t::insert_unique_range(il.begin(), il.end()); } #endif //! <b>Requires</b>: nh is empty or this->get_allocator() == nh.get_allocator(). @@ -946,6 +964,14 @@ class map #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + //! <b>Effects</b>: If present, erases the element in the container with key equivalent to x. + //! + //! <b>Returns</b>: Returns the number of erased elements (0/1). + //! + //! <b>Complexity</b>: log(size()) + count(k) + BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x) + { return this->base_t::erase_unique(x); } + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! <b>Effects</b>: Erases the element pointed to by p. @@ -957,13 +983,6 @@ class map //! <b>Complexity</b>: Amortized constant time iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW; - //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. - //! - //! <b>Returns</b>: Returns the number of erased elements. - //! - //! <b>Complexity</b>: log(size()) + count(k) - size_type erase(const key_type& x) BOOST_NOEXCEPT_OR_NOTHROW; - //! <b>Effects</b>: Erases all the elements in the range [first, last). //! //! <b>Returns</b>: Returns last. @@ -971,13 +990,15 @@ class map //! <b>Complexity</b>: log(size())+N where N is the distance from first to last. iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW; - #endif + #else + using base_t::erase; + #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! <b>Effects</b>: Removes the first element in the container with key equivalent to k. //! //! <b>Returns</b>: A node_type owning the element if found, otherwise an empty node_type. //! - //! <b>Complexity</b>: log(a.size()). + //! <b>Complexity</b>: log(size()). node_type extract(const key_type& k) { typename base_t::node_type base_nh(this->base_t::extract(k)); @@ -1010,7 +1031,7 @@ class map //! //! <b>Throws</b>: Nothing unless the comparison object throws. //! - //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size()) + //! <b>Complexity</b>: N log(size() + N) (N has the value source.size()) template<class C2> BOOST_CONTAINER_FORCEINLINE void merge(map<Key, T, C2, Allocator, Options>& source) { @@ -1046,9 +1067,9 @@ class map //! <b>Complexity</b>: Constant. void swap(map& x) BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value - && boost::container::dtl::is_nothrow_swappable<Compare>::value ) + && boost::container::dtl::is_nothrow_swappable<Compare>::value ); - //! <b>Effects</b>: erase(a.begin(),a.end()). + //! <b>Effects</b>: erase(begin(),end()). //! //! <b>Postcondition</b>: size() == 0. //! @@ -1079,40 +1100,128 @@ class map //! <b>Complexity</b>: Logarithmic. const_iterator find(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic. + template<typename K> + iterator find(const K& x); + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: A const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic. + template<typename K> + const_iterator find(const K& x) const; + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! <b>Returns</b>: The number of elements with key equivalent to x. //! //! <b>Complexity</b>: log(size())+count(k) - BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type count(const key_type& x) const + { return static_cast<size_type>(this->find(x) != this->cend()); } + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: The number of elements with key equivalent to x. + //! + //! <b>Complexity</b>: log(size())+count(k) + template<typename K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type count(const K& x) const { return static_cast<size_type>(this->find(x) != this->cend()); } #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! <b>Returns</b>: Returns true if there is an element with key + //! equivalent to key in the container, otherwise false. + //! + //! <b>Complexity</b>: log(size()). + bool contains(const key_type& x) const; + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: Returns true if there is an element with key + //! equivalent to key in the container, otherwise false. + //! + //! <b>Complexity</b>: log(size()). + template<typename K> + bool contains(const K& x) const; + //! <b>Returns</b>: An iterator pointing to the first element with key not less - //! than k, or a.end() if such an element is not found. + //! than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic iterator lower_bound(const key_type& x); //! <b>Returns</b>: A const iterator pointing to the first element with key not - //! less than k, or a.end() if such an element is not found. + //! less than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic const_iterator lower_bound(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Returns</b>: An iterator pointing to the first element with key not less //! than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic - iterator upper_bound(const key_type& x); + template<typename K> + iterator lower_bound(const K& x); + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Returns</b>: A const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic + template<typename K> + const_iterator lower_bound(const K& x) const; + + //! <b>Returns</b>: An iterator pointing to the first element with key greater + //! than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + iterator upper_bound(const key_type& x); + + //! <b>Returns</b>: A const iterator pointing to the first element with key + //! greater than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic const_iterator upper_bound(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: An iterator pointing to the first element with key greater + //! than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + iterator upper_bound(const K& x); + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: A const iterator pointing to the first element with key + //! greater than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + const_iterator upper_bound(const K& x) const; + //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! <b>Complexity</b>: Logarithmic @@ -1123,6 +1232,24 @@ class map //! <b>Complexity</b>: Logarithmic std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + std::pair<iterator,iterator> equal_range(const K& x); + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + std::pair<const_iterator,const_iterator> equal_range(const K& x) const; + //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees. //! //! <b>Complexity</b>: Linear @@ -1161,7 +1288,9 @@ class map //! <b>Effects</b>: x.swap(y) //! //! <b>Complexity</b>: Constant. - friend void swap(map& x, map& y); + friend void swap(map& x, map& y) + BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value + && boost::container::dtl::is_nothrow_swappable<Compare>::value ); #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1175,6 +1304,70 @@ class map #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template <typename InputIterator> +map(InputIterator, InputIterator) -> + map< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator>>; + +template < typename InputIterator, typename AllocatorOrCompare> + map(InputIterator, InputIterator, AllocatorOrCompare const&) -> + map< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator> + , typename dtl::if_c< // Compare + dtl::is_allocator<AllocatorOrCompare>::value + , std::less<it_based_non_const_first_type_t<InputIterator>> + , AllocatorOrCompare + >::type + , typename dtl::if_c< // Allocator + dtl::is_allocator<AllocatorOrCompare>::value + , AllocatorOrCompare + , new_allocator<std::pair<it_based_const_first_type_t<InputIterator>, it_based_second_type_t<InputIterator>>> + >::type + >; + +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t<Compare> + , typename = dtl::require_allocator_t<Allocator>> +map(InputIterator, InputIterator, Compare const&, Allocator const&) -> + map< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator> + , Compare + , Allocator>; + +template <typename InputIterator> +map(ordered_unique_range_t, InputIterator, InputIterator) -> + map< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator>>; + +template < typename InputIterator, typename AllocatorOrCompare> +map(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> + map< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator> + , typename dtl::if_c< // Compare + dtl::is_allocator<AllocatorOrCompare>::value + , std::less<it_based_non_const_first_type_t<InputIterator>> + , AllocatorOrCompare + >::type + , typename dtl::if_c< // Allocator + dtl::is_allocator<AllocatorOrCompare>::value + , AllocatorOrCompare + , new_allocator<std::pair<it_based_const_first_type_t<InputIterator>, it_based_second_type_t<InputIterator>>> + >::type + >; + +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t<Compare> + , typename = dtl::require_allocator_t<Allocator>> +map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + map< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator> + , Compare + , Allocator>; + +#endif + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -1182,13 +1375,11 @@ class map //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template <class Key, class T, class Compare, class Allocator> -struct has_trivial_destructor_after_move<boost::container::map<Key, T, Compare, Allocator> > +template <class Key, class T, class Compare, class Allocator, class Options> +struct has_trivial_destructor_after_move<boost::container::map<Key, T, Compare, Allocator, Options> > { - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && - ::boost::has_trivial_destructor_after_move<pointer>::value && - ::boost::has_trivial_destructor_after_move<Compare>::value; + typedef ::boost::container::dtl::tree<std::pair<const Key, T>, int, Compare, Allocator, Options> tree; + static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value; }; namespace container { @@ -1221,7 +1412,7 @@ class multimap ///@cond : public dtl::tree < std::pair<const Key, T> - , dtl::select1st<Key> + , int , Compare, Allocator, Options> ///@endcond { @@ -1229,7 +1420,7 @@ class multimap private: BOOST_COPYABLE_AND_MOVABLE(multimap) - typedef dtl::select1st<Key> select_1st_t; + typedef int select_1st_t; typedef std::pair<const Key, T> value_type_impl; typedef dtl::tree <value_type_impl, select_1st_t, Compare, Allocator, Options> base_t; @@ -1237,8 +1428,6 @@ class multimap typedef typename base_t::value_compare value_compare_impl; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type; - public: ////////////////////////////////////////////// // @@ -1246,25 +1435,26 @@ class multimap // ////////////////////////////////////////////// - typedef Key key_type; - typedef T mapped_type; - typedef typename boost::container::allocator_traits<Allocator>::value_type value_type; - typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; - typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer; - typedef typename boost::container::allocator_traits<Allocator>::reference reference; - typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; - typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; - typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; - typedef Allocator allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; - typedef Compare key_compare; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; - typedef std::pair<key_type, mapped_type> nonconst_value_type; - typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; + typedef Key key_type; + typedef T mapped_type; + typedef typename base_t::allocator_type allocator_type; + typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type; + typedef typename boost::container::allocator_traits<allocator_type>::value_type value_type; + typedef typename boost::container::allocator_traits<allocator_type>::pointer pointer; + typedef typename boost::container::allocator_traits<allocator_type>::const_pointer const_pointer; + typedef typename boost::container::allocator_traits<allocator_type>::reference reference; + typedef typename boost::container::allocator_traits<allocator_type>::const_reference const_reference; + typedef typename boost::container::allocator_traits<allocator_type>::size_type size_type; + typedef typename boost::container::allocator_traits<allocator_type>::difference_type difference_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; + typedef Compare key_compare; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + //typedef std::pair<key_type, mapped_type> nonconst_value_type; + typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; typedef BOOST_CONTAINER_IMPDEF(node_handle< typename base_t::stored_allocator_type BOOST_MOVE_I pair_key_mapped_of_value @@ -1283,7 +1473,7 @@ class multimap //! //! <b>Complexity</b>: Constant. BOOST_CONTAINER_FORCEINLINE multimap() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value && + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value && dtl::is_nothrow_default_constructible<Compare>::value) : base_t() {} @@ -1394,6 +1584,20 @@ class multimap : base_t(ordered_range, first, last, comp, a) {} + //! <b>Effects</b>: Constructs an empty multimap using the specified allocator and + //! inserts elements from the ordered range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! <b>Requires</b>: [first ,last) must be ordered according to the predicate. + //! + //! <b>Complexity</b>: Linear in N. + //! + //! <b>Note</b>: Non-standard extension. + template <class InputIterator> + BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const allocator_type& a) + : base_t(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! <b>Effects</b>: Constructs an empty multimap and //! and inserts elements from the range [il.begin(), il.end()). @@ -1639,28 +1843,28 @@ class multimap //! //! <b>Complexity</b>: Logarithmic. BOOST_CONTAINER_FORCEINLINE iterator insert(const value_type& x) - { return this->base_t::insert_equal(x); } - - //! <b>Effects</b>: Inserts a new value constructed from x and returns - //! the iterator pointing to the newly inserted element. - //! - //! <b>Complexity</b>: Logarithmic. - BOOST_CONTAINER_FORCEINLINE iterator insert(const nonconst_value_type& x) - { return this->base_t::emplace_equal(x); } + { return this->base_t::insert_equal_convertible(x); } //! <b>Effects</b>: Inserts a new value move-constructed from x and returns //! the iterator pointing to the newly inserted element. //! //! <b>Complexity</b>: Logarithmic. - BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(nonconst_value_type) x) - { return this->base_t::emplace_equal(boost::move(x)); } + BOOST_CONTAINER_FORCEINLINE iterator insert(BOOST_RV_REF(value_type) x) + { return this->base_t::insert_equal_convertible(boost::move(x)); } - //! <b>Effects</b>: Inserts a new value move-constructed from x and returns + //! <b>Effects</b>: Inserts a new value constructed from x and returns //! the iterator pointing to the newly inserted element. //! //! <b>Complexity</b>: Logarithmic. - iterator insert(BOOST_RV_REF(movable_value_type) x) - { return this->base_t::emplace_equal(boost::move(x)); } + template<class Pair> + BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST + ( iterator + , typename dtl::enable_if_c< + dtl::is_convertible<Pair BOOST_MOVE_I value_type>::value || + dtl::is_convertible<Pair BOOST_MOVE_I movable_value_type>::value + BOOST_MOVE_I iterator >::type) + insert(BOOST_FWD_REF(Pair) x) + { return this->base_t::emplace_equal(boost::forward<Pair>(x)); } //! <b>Effects</b>: Inserts a copy of x in the container. //! p is a hint pointing to where the insert should start to search. @@ -1671,18 +1875,7 @@ class multimap //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t //! is inserted right before p. BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const value_type& x) - { return this->base_t::insert_equal(p, x); } - - //! <b>Effects</b>: Inserts a new value constructed from x in the container. - //! p is a hint pointing to where the insert should start to search. - //! - //! <b>Returns</b>: An iterator pointing to the element with key equivalent - //! to the key of x. - //! - //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t - //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, const nonconst_value_type& x) - { return this->base_t::emplace_hint_equal(p, x); } + { return this->base_t::insert_equal_hint_convertible(p, x); } //! <b>Effects</b>: Inserts a new value move constructed from x in the container. //! p is a hint pointing to where the insert should start to search. @@ -1692,10 +1885,10 @@ class multimap //! //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x) - { return this->base_t::emplace_hint_equal(p, boost::move(x)); } + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x) + { return this->base_t::insert_equal_hint_convertible(p, boost::move(x)); } - //! <b>Effects</b>: Inserts a new value move constructed from x in the container. + //! <b>Effects</b>: Inserts a new value constructed from x in the container. //! p is a hint pointing to where the insert should start to search. //! //! <b>Returns</b>: An iterator pointing to the element with key equivalent @@ -1703,8 +1896,15 @@ class multimap //! //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t //! is inserted right before p. - BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x) - { return this->base_t::emplace_hint_equal(p, boost::move(x)); } + template<class Pair> + BOOST_CONTAINER_FORCEINLINE BOOST_CONTAINER_DOC1ST + ( iterator + , typename dtl::enable_if_c< + dtl::is_convertible<Pair BOOST_MOVE_I value_type>::value || + dtl::is_convertible<Pair BOOST_MOVE_I movable_value_type>::value + BOOST_MOVE_I iterator>::type) + insert(const_iterator p, BOOST_FWD_REF(Pair) x) + { return this->base_t::emplace_hint_equal(p, boost::forward<Pair>(x)); } //! <b>Requires</b>: first, last are not iterators into *this. //! @@ -1713,14 +1913,14 @@ class multimap //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) template <class InputIterator> BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->base_t::insert_equal(first, last); } + { this->base_t::insert_equal_range(first, last); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! <b>Effects</b>: inserts each element from the range [il.begin(), il.end(). //! //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end()) BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il) - { this->base_t::insert_equal(il.begin(), il.end()); } + { this->base_t::insert_equal_range(il.begin(), il.end()); } #endif //! <b>Requires</b>: nh is empty or this->get_allocator() == nh.get_allocator(). @@ -1786,7 +1986,7 @@ class multimap //! //! <b>Throws</b>: Nothing unless the comparison object throws. //! - //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size()) + //! <b>Complexity</b>: N log(size() + N) (N has the value source.size()) template<class C2> BOOST_CONTAINER_FORCEINLINE void merge(multimap<Key, T, C2, Allocator, Options>& source) { @@ -1841,35 +2041,120 @@ class multimap //! <b>Complexity</b>: Logarithmic. const_iterator find(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic. + template<typename K> + iterator find(const K& x); + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: A const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic. + template<typename K> + const_iterator find(const K& x) const; + //! <b>Returns</b>: The number of elements with key equivalent to x. //! //! <b>Complexity</b>: log(size())+count(k) size_type count(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: The number of elements with key equivalent to x. + //! + //! <b>Complexity</b>: log(size())+count(k) + template<typename K> + size_type count(const K& x) const; + + //! <b>Returns</b>: Returns true if there is an element with key + //! equivalent to key in the container, otherwise false. + //! + //! <b>Complexity</b>: log(size()). + bool contains(const key_type& x) const; + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: Returns true if there is an element with key + //! equivalent to key in the container, otherwise false. + //! + //! <b>Complexity</b>: log(size()). + template<typename K> + bool contains(const K& x) const; + //! <b>Returns</b>: An iterator pointing to the first element with key not less - //! than k, or a.end() if such an element is not found. + //! than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic iterator lower_bound(const key_type& x); //! <b>Returns</b>: A const iterator pointing to the first element with key not - //! less than k, or a.end() if such an element is not found. + //! less than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic const_iterator lower_bound(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Returns</b>: An iterator pointing to the first element with key not less //! than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic - iterator upper_bound(const key_type& x); + template<typename K> + iterator lower_bound(const K& x); + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Returns</b>: A const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic + template<typename K> + const_iterator lower_bound(const K& x) const; + + //! <b>Returns</b>: An iterator pointing to the first element with key greater + //! than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + iterator upper_bound(const key_type& x); + + //! <b>Returns</b>: A const iterator pointing to the first element with key + //! greater than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic const_iterator upper_bound(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: An iterator pointing to the first element with key greater + //! than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + iterator upper_bound(const K& x); + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: A const iterator pointing to the first element with key + //! greater than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + const_iterator upper_bound(const K& x) const; + //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! <b>Complexity</b>: Logarithmic @@ -1880,6 +2165,24 @@ class multimap //! <b>Complexity</b>: Logarithmic std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + std::pair<iterator,iterator> equal_range(const K& x); + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + std::pair<const_iterator,const_iterator> equal_range(const K& x) const; + //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees. //! //! <b>Complexity</b>: Linear @@ -1918,24 +2221,87 @@ class multimap //! <b>Effects</b>: x.swap(y) //! //! <b>Complexity</b>: Constant. - friend void swap(multimap& x, multimap& y); + friend void swap(multimap& x, multimap& y) + BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value + && boost::container::dtl::is_nothrow_swappable<Compare>::value ); #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) }; +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template <typename InputIterator> +multimap(InputIterator, InputIterator) -> + multimap< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator>>; + +template < typename InputIterator, typename AllocatorOrCompare> +multimap(InputIterator, InputIterator, AllocatorOrCompare const&) -> + multimap< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator> + , typename dtl::if_c< // Compare + dtl::is_allocator<AllocatorOrCompare>::value + , std::less<it_based_non_const_first_type_t<InputIterator>> + , AllocatorOrCompare + >::type + , typename dtl::if_c< // Allocator + dtl::is_allocator<AllocatorOrCompare>::value + , AllocatorOrCompare + , new_allocator<std::pair<it_based_const_first_type_t<InputIterator>, it_based_second_type_t<InputIterator>>> + >::type + >; + +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t<Compare> + , typename = dtl::require_allocator_t<Allocator>> +multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> + multimap< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator> + , Compare + , Allocator>; + +template <typename InputIterator> +multimap(ordered_range_t, InputIterator, InputIterator) -> + multimap< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator>>; + +template < typename InputIterator, typename AllocatorOrCompare> +multimap(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> + multimap< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator> + , typename dtl::if_c< // Compare + dtl::is_allocator<AllocatorOrCompare>::value + , std::less<it_based_const_first_type_t<InputIterator>> + , AllocatorOrCompare + >::type + , typename dtl::if_c< // Allocator + dtl::is_allocator<AllocatorOrCompare>::value + , AllocatorOrCompare + , new_allocator<std::pair<it_based_const_first_type_t<InputIterator>, it_based_second_type_t<InputIterator>>> + >::type + >; + +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t<Compare> + , typename = dtl::require_allocator_t<Allocator>> +multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + multimap< it_based_non_const_first_type_t<InputIterator> + , it_based_second_type_t<InputIterator> + , Compare + , Allocator>; +#endif + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED } //namespace container { //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template <class Key, class T, class Compare, class Allocator> -struct has_trivial_destructor_after_move<boost::container::multimap<Key, T, Compare, Allocator> > +template <class Key, class T, class Compare, class Allocator, class Options> +struct has_trivial_destructor_after_move<boost::container::multimap<Key, T, Compare, Allocator, Options> > { - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && - ::boost::has_trivial_destructor_after_move<pointer>::value && - ::boost::has_trivial_destructor_after_move<Compare>::value; + typedef ::boost::container::dtl::tree<std::pair<const Key, T>, int, Compare, Allocator, Options> tree; + static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value; }; namespace container { diff --git a/contrib/restricted/boost/container/include/boost/container/new_allocator.hpp b/contrib/restricted/boost/container/include/boost/container/new_allocator.hpp index 9af015d1d6..82c42a957c 100644 --- a/contrib/restricted/boost/container/include/boost/container/new_allocator.hpp +++ b/contrib/restricted/boost/container/include/boost/container/new_allocator.hpp @@ -151,23 +151,31 @@ class new_allocator {} //!Allocates memory for an array of count elements. - //!Throws std::bad_alloc if there is no enough memory + //!Throws bad_alloc if there is no enough memory pointer allocate(size_type count) { - if(BOOST_UNLIKELY(count > this->max_size())) + const std::size_t max_count = std::size_t(-1)/(2*sizeof(T)); + if(BOOST_UNLIKELY(count > max_count)) throw_bad_alloc(); return static_cast<T*>(::operator new(count*sizeof(T))); } //!Deallocates previously allocated memory. //!Never throws - void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW - { ::operator delete((void*)ptr); } + void deallocate(pointer ptr, size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + (void)n; + # if __cpp_sized_deallocation + ::operator delete((void*)ptr, n * sizeof(T)); + #else + ::operator delete((void*)ptr); + # endif + } //!Returns the maximum number of elements that could be allocated. //!Never throws size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW - { return size_type(-1)/sizeof(T); } + { return std::size_t(-1)/(2*sizeof(T)); } //!Swaps two allocators, does nothing //!because this new_allocator is stateless diff --git a/contrib/restricted/boost/container/include/boost/container/node_handle.hpp b/contrib/restricted/boost/container/include/boost/container/node_handle.hpp index ef1d71f355..803271141c 100644 --- a/contrib/restricted/boost/container/include/boost/container/node_handle.hpp +++ b/contrib/restricted/boost/container/include/boost/container/node_handle.hpp @@ -123,7 +123,7 @@ class node_handle void destroy_deallocate_node() { - nator_traits::destroy(this->node_alloc(), boost::movelib::to_raw_pointer(m_ptr)); + boost::movelib::to_raw_pointer(m_ptr)->destructor(this->node_alloc()); nator_traits::deallocate(this->node_alloc(), m_ptr, 1u); } @@ -418,8 +418,8 @@ struct insert_return_type_base {} template<class RelatedIt, class RelatedNode> - insert_return_type_base(bool insert, RelatedIt it, BOOST_RV_REF(RelatedNode) node) - : inserted(insert), position(it), node(boost::move(node)) + insert_return_type_base(bool insert, RelatedIt it, BOOST_RV_REF(RelatedNode) n) + : inserted(insert), position(it), node(boost::move(n)) {} insert_return_type_base & operator=(BOOST_RV_REF(insert_return_type_base) other) diff --git a/contrib/restricted/boost/container/include/boost/container/options.hpp b/contrib/restricted/boost/container/include/boost/container/options.hpp index 2ac7783e46..4bdd33e891 100644 --- a/contrib/restricted/boost/container/include/boost/container/options.hpp +++ b/contrib/restricted/boost/container/include/boost/container/options.hpp @@ -24,6 +24,7 @@ #include <boost/container/detail/config_begin.hpp> #include <boost/container/container_fwd.hpp> #include <boost/intrusive/pack_options.hpp> +#include <boost/static_assert.hpp> namespace boost { namespace container { @@ -101,6 +102,82 @@ using tree_assoc_options_t = typename boost::container::tree_assoc_options<Optio #endif + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR ASSOCIATIVE HASH-BASED CONTAINERS +// +// +//////////////////////////////////////////////////////////////// + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template<bool StoreHash, bool CacheBegin, bool LinearBuckets, bool FastmodBuckets> +struct hash_opt +{ + static const bool store_hash = StoreHash; + static const bool cache_begin = CacheBegin; + static const bool linear_buckets = LinearBuckets; + static const bool fastmod_buckets = FastmodBuckets; +}; + +typedef hash_opt<false, false, false, false> hash_assoc_defaults; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//!This option setter specifies if nodes also store the hash value +//!so that search and rehashing for hash-expensive types is improved. +//!This option might degrade performance for easy to hash types (like integers) +BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash) + +//!This option setter specifies if the container will cache the first +//!non-empty bucket so that begin() is O(1) instead of searching for the +//!first non-empty bucket (which can be O(bucket_size())) +BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin) + +BOOST_INTRUSIVE_OPTION_CONSTANT(linear_buckets, bool, Enabled, linear_buckets) + +BOOST_INTRUSIVE_OPTION_CONSTANT(fastmod_buckets, bool, Enabled, fastmod_buckets) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::hash_set, \c boost::container::hash_multiset +//! \c boost::container::hash_map and \c boost::container::hash_multimap. +//! Supported options are: \c boost::container::store_hash +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template<class ...Options> +#else +template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> +#endif +struct hash_assoc_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < hash_assoc_defaults, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef hash_opt<packed_options::store_hash + ,packed_options::cache_begin + ,packed_options::linear_buckets + ,packed_options::fastmod_buckets + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by hash-based associative containers +template<class ...Options> +using hash_assoc_options_t = typename boost::container::hash_assoc_options<Options...>::type; + +#endif + //////////////////////////////////////////////////////////////// // // @@ -111,6 +188,22 @@ using tree_assoc_options_t = typename boost::container::tree_assoc_options<Optio #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) +template<class T, class Default> +struct default_if_void +{ + typedef T type; +}; + +template<class Default> +struct default_if_void<void, Default> +{ + typedef Default type; +}; + +#endif + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + template<class AllocTraits, class StoredSizeType> struct get_stored_size_type_with_alloctraits { @@ -139,6 +232,13 @@ class default_next_capacity; typedef vector_opt<void, void> vector_null_opt; +template<class GrowthType, class StoredSizeType> +struct devector_opt + : vector_opt<GrowthType, StoredSizeType> +{}; + +typedef devector_opt<void, void> devector_null_opt; + #else //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //!This growth factor argument specifies that the container should increase it's @@ -177,7 +277,7 @@ BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_fa //!This option specifies the unsigned integer type that a user wants the container //!to use to hold size-related information inside a container (e.g. current size, current capacity). //! -//!\tparam StoredSizeType A unsigned integer type. It shall be smaller than than the size +//!\tparam StoredSizeType An unsigned integer type. It shall be smaller than than the size //! of the size_type deduced from `allocator_traits<A>::size_type` or the same type. //! //!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit @@ -185,7 +285,7 @@ BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_fa //!memory can be saved for empty vectors. This could potentially performance benefits due to better //!cache usage. //! -//!Note that alignment requirements can disallow theoritical space savings. Example: +//!Note that alignment requirements can disallow theoretical space savings. Example: //!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine //!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes) //!will not save space when comparing two 16-bit size types because usually @@ -236,6 +336,240 @@ using vector_options_t = typename boost::container::vector_options<Options...>:: #endif +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR SMALL-VECTOR CONTAINER +// +// +//////////////////////////////////////////////////////////////// + +//! This option specifies the desired alignment for the value_type stored +//! in the container. +//! A value zero represents the natural alignment. +//! +//!\tparam Alignment An unsigned integer value. Must be power of two. +BOOST_INTRUSIVE_OPTION_CONSTANT(inplace_alignment, std::size_t, Alignment, inplace_alignment) + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template<class GrowthType, std::size_t InplaceAlignment> +struct small_vector_opt +{ + typedef GrowthType growth_factor_type; + static const std::size_t inplace_alignment = InplaceAlignment; +}; + +typedef small_vector_opt<void, 0u> small_vector_null_opt; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::small_vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::inplace_alignment +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template<class ...Options> +#else +template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> +#endif +struct small_vector_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < small_vector_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef small_vector_opt< typename packed_options::growth_factor_type + , packed_options::inplace_alignment> implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::small_vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +template<class ...Options> +using small_vector_options_t = typename boost::container::small_vector_options<Options...>::type; + +#endif + + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR STATIC-VECTOR CONTAINER +// +// +//////////////////////////////////////////////////////////////// + +//!This option specifies if the container will throw if in +//!the static capacity is not sufficient to hold the required +//!values. If false is specified, insufficient capacity will +//!lead to BOOST_ASSERT, and if this assertion returns, to undefined behaviour, +//!which potentially can lead to better static_vector performance. +//!The default value is true. +//! +//!\tparam ThrowOnExhaustion A boolean value. True if throw is required. +BOOST_INTRUSIVE_OPTION_CONSTANT(throw_on_overflow, bool, ThrowOnOverflow, throw_on_overflow) + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template<bool ThrowOnOverflow, std::size_t InplaceAlignment> +struct static_vector_opt +{ + static const bool throw_on_overflow = ThrowOnOverflow; + static const std::size_t inplace_alignment = InplaceAlignment; +}; + +typedef static_vector_opt<true, 0u> static_vector_null_opt; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::static_vector. +//! Supported options are: \c boost::container::throw_on_overflow and \c boost::container::inplace_alignment +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template<class ...Options> +#else +template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> +#endif +struct static_vector_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < static_vector_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef static_vector_opt< packed_options::throw_on_overflow + , packed_options::inplace_alignment> implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::static_vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +template<class ...Options> +using static_vector_options_t = typename boost::container::static_vector_options<Options...>::type; + +#endif + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::devector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template<class ...Options> +#else +template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> +#endif +struct devector_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < devector_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef devector_opt< typename packed_options::growth_factor_type + , typename packed_options::stored_size_type> implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::devector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +template<class ...Options> +using devector_options_t = typename boost::container::devector_options<Options...>::type; + +#endif + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR DEQUE-BASED CONTAINERS +// +// +//////////////////////////////////////////////////////////////// + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template<std::size_t BlockBytes, std::size_t BlockSize> +struct deque_opt +{ + static const std::size_t block_bytes = BlockBytes; + static const std::size_t block_size = BlockSize; + BOOST_STATIC_ASSERT_MSG(!(block_bytes && block_size), "block_bytes and block_size can't be specified at the same time"); +}; + +typedef deque_opt<0u, 0u> deque_null_opt; + +#endif + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::deque. +//! Supported options are: \c boost::container::block_bytes +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template<class ...Options> +#else +template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> +#endif +struct deque_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < deque_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef deque_opt< packed_options::block_bytes, packed_options::block_size > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::deque. +//! Supported options are: \c boost::container::block_bytes +template<class ...Options> +using deque_options_t = typename boost::container::deque_options<Options...>::type; + +#endif + +//!This option specifies the maximum size of a block in bytes: this delimites the number of contiguous elements +//!that will be allocated by deque as min(1u, BlockBytes/sizeof(value_type)) +//!A value zero represents the default value. +//! +//!\tparam BlockBytes An unsigned integer value. +BOOST_INTRUSIVE_OPTION_CONSTANT(block_bytes, std::size_t, BlockBytes, block_bytes) + +//!This option specifies the size of a block, delimites the number of contiguous elements +//!that will be allocated by deque as BlockSize. +//!A value zero represents the default value. +//! +//!\tparam BlockBytes An unsigned integer value. +BOOST_INTRUSIVE_OPTION_CONSTANT(block_size, std::size_t, BlockSize, block_size) } //namespace container { } //namespace boost { diff --git a/contrib/restricted/boost/container/include/boost/container/pmr/global_resource.hpp b/contrib/restricted/boost/container/include/boost/container/pmr/global_resource.hpp index 219309b072..4071c211fc 100644 --- a/contrib/restricted/boost/container/include/boost/container/pmr/global_resource.hpp +++ b/contrib/restricted/boost/container/include/boost/container/pmr/global_resource.hpp @@ -18,6 +18,7 @@ #include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/workaround.hpp> #include <boost/container/detail/auto_link.hpp> +#include <boost/container/container_fwd.hpp> #include <cstddef> @@ -25,10 +26,6 @@ namespace boost { namespace container { namespace pmr { -/// @cond -class memory_resource; -/// @endcond - //! <b>Returns</b>: A pointer to a static-duration object of a type derived from //! memory_resource that can serve as a resource for allocating memory using //! global `operator new` and global `operator delete`. The same value is returned every time this function diff --git a/contrib/restricted/boost/container/include/boost/container/pmr/memory_resource.hpp b/contrib/restricted/boost/container/include/boost/container/pmr/memory_resource.hpp index 72338a7559..e99fd0206a 100644 --- a/contrib/restricted/boost/container/include/boost/container/pmr/memory_resource.hpp +++ b/contrib/restricted/boost/container/include/boost/container/pmr/memory_resource.hpp @@ -17,7 +17,9 @@ #include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/workaround.hpp> +#include <boost/container/container_fwd.hpp> #include <boost/move/detail/type_traits.hpp> +#include <boost/container/detail/placement_new.hpp> #include <cstddef> namespace boost { @@ -40,7 +42,11 @@ class memory_resource //! <b>Effects</b>: Equivalent to //! `return do_allocate(bytes, alignment);` void* allocate(std::size_t bytes, std::size_t alignment = max_align) - { return this->do_allocate(bytes, alignment); } + { + //Obtain a pointer to enough storage and initialize the lifetime + //of an array object of the given size in the address + return ::operator new(bytes, this->do_allocate(bytes, alignment), boost_container_new_t()); + } //! <b>Effects</b>: Equivalent to //! `return do_deallocate(bytes, alignment);` @@ -51,6 +57,8 @@ class memory_resource //! `return return do_is_equal(other);` bool is_equal(const memory_resource& other) const BOOST_NOEXCEPT { return this->do_is_equal(other); } + + #if !defined(BOOST_EMBTC) //! <b>Returns</b>: //! `&a == &b || a.is_equal(b)`. @@ -61,6 +69,18 @@ class memory_resource //! !(a == b). friend bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT { return !(a == b); } + + #else + + //! <b>Returns</b>: + //! `&a == &b || a.is_equal(b)`. + friend bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT; + + //! <b>Returns</b>: + //! !(a == b). + friend bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT; + + #endif protected: //! <b>Requires</b>: Alignment shall be a power of two. @@ -92,6 +112,20 @@ class memory_resource virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT = 0; }; +#if defined(BOOST_EMBTC) + +//! <b>Returns</b>: +//! `&a == &b || a.is_equal(b)`. +inline bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT +{ return &a == &b || a.is_equal(b); } + +//! <b>Returns</b>: +//! !(a == b). +inline bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT +{ return !(a == b); } + +#endif + } //namespace pmr { } //namespace container { } //namespace boost { diff --git a/contrib/restricted/boost/container/include/boost/container/pmr/monotonic_buffer_resource.hpp b/contrib/restricted/boost/container/include/boost/container/pmr/monotonic_buffer_resource.hpp index dfffe87dc3..6799f4f278 100644 --- a/contrib/restricted/boost/container/include/boost/container/pmr/monotonic_buffer_resource.hpp +++ b/contrib/restricted/boost/container/include/boost/container/pmr/monotonic_buffer_resource.hpp @@ -18,6 +18,7 @@ #include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/workaround.hpp> #include <boost/container/detail/auto_link.hpp> +#include <boost/container/container_fwd.hpp> #include <boost/container/pmr/memory_resource.hpp> #include <boost/container/detail/block_slist.hpp> @@ -51,9 +52,11 @@ class BOOST_CONTAINER_DECL monotonic_buffer_resource : public memory_resource { block_slist m_memory_blocks; - void* m_current_buffer; + void * m_current_buffer; std::size_t m_current_buffer_size; std::size_t m_next_buffer_size; + void * const m_initial_buffer; + std::size_t const m_initial_buffer_size; /// @cond void increase_next_buffer(); @@ -106,7 +109,7 @@ class BOOST_CONTAINER_DECL monotonic_buffer_resource //! <b>Effects</b>: Calls //! `this->release()`. - virtual ~monotonic_buffer_resource(); + ~monotonic_buffer_resource() BOOST_OVERRIDE; //! <b>Effects</b>: `upstream_resource()->deallocate()` as necessary to release all allocated memory. //! [Note: memory is released back to `upstream_resource()` even if some blocks that were allocated @@ -131,7 +134,7 @@ class BOOST_CONTAINER_DECL monotonic_buffer_resource std::size_t remaining_storage(std::size_t alignment = 1u) const BOOST_NOEXCEPT; //! <b>Returns</b>: - //! The number of bytes of storage available for the specified alignment. + //! The address pointing to the start of the current free storage. //! //! <b>Note</b>: Non-standard extension. const void *current_buffer() const BOOST_NOEXCEPT; @@ -157,18 +160,18 @@ class BOOST_CONTAINER_DECL monotonic_buffer_resource //! then allocate the return block from the newly-allocated internal `current_buffer`. //! //! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws. - virtual void* do_allocate(std::size_t bytes, std::size_t alignment); + virtual void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE; //! <b>Effects</b>: None //! //! <b>Throws</b>: Nothing //! //! <b>Remarks</b>: Memory used by this resource increases monotonically until its destruction. - virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_NOEXCEPT; + virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_NOEXCEPT BOOST_OVERRIDE; //! <b>Returns</b>: //! `this == dynamic_cast<const monotonic_buffer_resource*>(&other)`. - virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT; + virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE; }; } //namespace pmr { diff --git a/contrib/restricted/boost/container/include/boost/container/pmr/synchronized_pool_resource.hpp b/contrib/restricted/boost/container/include/boost/container/pmr/synchronized_pool_resource.hpp index e4d4dd54a1..c4186f338e 100644 --- a/contrib/restricted/boost/container/include/boost/container/pmr/synchronized_pool_resource.hpp +++ b/contrib/restricted/boost/container/include/boost/container/pmr/synchronized_pool_resource.hpp @@ -20,6 +20,7 @@ #include <boost/container/detail/auto_link.hpp> #include <boost/container/pmr/memory_resource.hpp> #include <boost/container/detail/pool_resource.hpp> +#include <boost/container/detail/thread_mutex.hpp> #include <cstddef> @@ -60,8 +61,8 @@ namespace pmr { class BOOST_CONTAINER_DECL synchronized_pool_resource : public memory_resource { - pool_resource m_pool_resource; - void *m_opaque_sync; + dtl::thread_mutex m_mut; + pool_resource m_pool_resource; public: @@ -88,7 +89,7 @@ class BOOST_CONTAINER_DECL synchronized_pool_resource #endif //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::~unsynchronized_pool_resource() - virtual ~synchronized_pool_resource(); + ~synchronized_pool_resource() BOOST_OVERRIDE; //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::release() void release(); @@ -102,13 +103,13 @@ class BOOST_CONTAINER_DECL synchronized_pool_resource protected: //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_allocate() - virtual void* do_allocate(std::size_t bytes, std::size_t alignment); + virtual void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE; //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_deallocate(void*,std::size_t,std::size_t) - virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment); + virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE; //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_is_equal(const memory_resource&)const - virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT; + virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE; //Non-standard observers public: diff --git a/contrib/restricted/boost/container/include/boost/container/pmr/unsynchronized_pool_resource.hpp b/contrib/restricted/boost/container/include/boost/container/pmr/unsynchronized_pool_resource.hpp index 21d30b1ebc..65439d9ef2 100644 --- a/contrib/restricted/boost/container/include/boost/container/pmr/unsynchronized_pool_resource.hpp +++ b/contrib/restricted/boost/container/include/boost/container/pmr/unsynchronized_pool_resource.hpp @@ -103,7 +103,7 @@ class BOOST_CONTAINER_DECL unsynchronized_pool_resource //! <b>Effects</b>: Calls //! `this->release()`. - virtual ~unsynchronized_pool_resource(); + ~unsynchronized_pool_resource() BOOST_OVERRIDE; //! <b>Effects</b>: Calls Calls `upstream_resource()->deallocate()` as necessary //! to release all allocated memory. [ Note: memory is released back to @@ -134,18 +134,18 @@ class BOOST_CONTAINER_DECL unsynchronized_pool_resource //! using `upstream_resource()->allocate()`. //! //! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws. - virtual void* do_allocate(std::size_t bytes, std::size_t alignment); + virtual void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE; //! <b>Effects</b>: Return the memory at p to the pool. It is unspecified if or under //! what circumstances this operation will result in a call to //! `upstream_resource()->deallocate()`. //! //! <b>Throws</b>: Nothing. - virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment); + virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE; //! <b>Returns</b>: //! `this == dynamic_cast<const unsynchronized_pool_resource*>(&other)`. - virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT; + virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE; //Non-standard observers public: diff --git a/contrib/restricted/boost/container/include/boost/container/scoped_allocator.hpp b/contrib/restricted/boost/container/include/boost/container/scoped_allocator.hpp index 6cd69fe430..e9720fe2c8 100644 --- a/contrib/restricted/boost/container/include/boost/container/scoped_allocator.hpp +++ b/contrib/restricted/boost/container/include/boost/container/scoped_allocator.hpp @@ -79,10 +79,10 @@ struct outermost_allocator_imp { typedef MaybeScopedAlloc type; - static type &get(MaybeScopedAlloc &a) + BOOST_CONTAINER_FORCEINLINE static type &get(MaybeScopedAlloc &a) { return a; } - static const type &get(const MaybeScopedAlloc &a) + BOOST_CONTAINER_FORCEINLINE static const type &get(const MaybeScopedAlloc &a) { return a; } }; @@ -92,10 +92,10 @@ struct outermost_allocator_imp<MaybeScopedAlloc, true> typedef typename MaybeScopedAlloc::outer_allocator_type outer_type; typedef typename outermost_allocator_type_impl<outer_type>::type type; - static type &get(MaybeScopedAlloc &a) + BOOST_CONTAINER_FORCEINLINE static type &get(MaybeScopedAlloc &a) { return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); } - static const type &get(const MaybeScopedAlloc &a) + BOOST_CONTAINER_FORCEINLINE static const type &get(const MaybeScopedAlloc &a) { return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); } }; @@ -112,12 +112,12 @@ struct outermost_allocator {}; template <typename Allocator> -typename outermost_allocator<Allocator>::type & +BOOST_CONTAINER_FORCEINLINE typename outermost_allocator<Allocator>::type & get_outermost_allocator(Allocator &a) { return outermost_allocator<Allocator>::get(a); } template <typename Allocator> -const typename outermost_allocator<Allocator>::type & +BOOST_CONTAINER_FORCEINLINE const typename outermost_allocator<Allocator>::type & get_outermost_allocator(const Allocator &a) { return outermost_allocator<Allocator>::get(a); } @@ -161,34 +161,34 @@ class scoped_allocator_adaptor_base inner_allocator_type::is_always_equal::value > is_always_equal; - scoped_allocator_adaptor_base() + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base() {} template <class OuterA2> - scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args) : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) , m_inner(args...) {} - scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) : outer_allocator_type(other.outer_allocator()) , m_inner(other.inner_allocator()) {} - scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) : outer_allocator_type(::boost::move(other.outer_allocator())) , m_inner(::boost::move(other.inner_allocator())) {} template <class OuterA2> - scoped_allocator_adaptor_base + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base (const scoped_allocator_adaptor_base<OuterA2, InnerAllocs...>& other) : outer_allocator_type(other.outer_allocator()) , m_inner(other.inner_allocator()) {} template <class OuterA2> - scoped_allocator_adaptor_base + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base (BOOST_RV_REF_BEG scoped_allocator_adaptor_base <OuterA2, InnerAllocs...> BOOST_RV_REF_END other) : outer_allocator_type(other.outer_allocator()) @@ -199,7 +199,7 @@ class scoped_allocator_adaptor_base struct internal_type_t{}; template <class OuterA2> - scoped_allocator_adaptor_base + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base ( internal_type_t , BOOST_FWD_REF(OuterA2) outerAlloc , const inner_allocator_type &inner) @@ -209,7 +209,7 @@ class scoped_allocator_adaptor_base public: - scoped_allocator_adaptor_base &operator= + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator= (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) { outer_allocator_type::operator=(other.outer_allocator()); @@ -217,35 +217,35 @@ class scoped_allocator_adaptor_base return *this; } - scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) { outer_allocator_type::operator=(boost::move(other.outer_allocator())); m_inner = ::boost::move(other.inner_allocator()); return *this; } - void swap(scoped_allocator_adaptor_base &r) + BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r) { boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); boost::adl_move_swap(this->m_inner, r.inner_allocator()); } - friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) + BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) { l.swap(r); } - inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW { return m_inner; } - inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW { return m_inner; } - outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW { return static_cast<outer_allocator_type&>(*this); } - const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW { return static_cast<const outer_allocator_type&>(*this); } - scoped_allocator_type select_on_container_copy_construction() const + BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const { return scoped_allocator_type (internal_type_t() @@ -304,33 +304,33 @@ class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\ inner_allocator_type::is_always_equal::value\ > is_always_equal;\ \ - scoped_allocator_adaptor_base(){}\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(){}\ \ template <class OuterA2>\ - scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\ : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\ , m_inner(BOOST_MOVE_ARG##N)\ {}\ \ - scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\ : outer_allocator_type(other.outer_allocator())\ , m_inner(other.inner_allocator())\ {}\ \ - scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ : outer_allocator_type(::boost::move(other.outer_allocator()))\ , m_inner(::boost::move(other.inner_allocator()))\ {}\ \ template <class OuterA2>\ - scoped_allocator_adaptor_base\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\ (const scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N>& other)\ : outer_allocator_type(other.outer_allocator())\ , m_inner(other.inner_allocator())\ {}\ \ template <class OuterA2>\ - scoped_allocator_adaptor_base\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\ (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> BOOST_RV_REF_END other)\ : outer_allocator_type(other.outer_allocator())\ , m_inner(other.inner_allocator())\ @@ -340,14 +340,14 @@ class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\ struct internal_type_t{};\ \ template <class OuterA2>\ - scoped_allocator_adaptor_base\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base\ ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\ : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\ , m_inner(inner)\ {}\ \ public:\ - scoped_allocator_adaptor_base &operator=\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=\ (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\ {\ outer_allocator_type::operator=(other.outer_allocator());\ @@ -355,35 +355,35 @@ class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\ return *this;\ }\ \ - scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ {\ outer_allocator_type::operator=(boost::move(other.outer_allocator()));\ m_inner = ::boost::move(other.inner_allocator());\ return *this;\ }\ \ - void swap(scoped_allocator_adaptor_base &r)\ + BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r)\ {\ boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\ boost::adl_move_swap(this->m_inner, r.inner_allocator());\ }\ \ - friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\ + BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\ { l.swap(r); }\ \ - inner_allocator_type& inner_allocator()\ + BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator()\ { return m_inner; }\ \ - inner_allocator_type const& inner_allocator() const\ + BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const\ { return m_inner; }\ \ - outer_allocator_type & outer_allocator()\ + BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator()\ { return static_cast<outer_allocator_type&>(*this); }\ \ - const outer_allocator_type &outer_allocator() const\ + BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const\ { return static_cast<const outer_allocator_type&>(*this); }\ \ - scoped_allocator_type select_on_container_copy_construction() const\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const\ {\ return scoped_allocator_type\ (internal_type_t()\ @@ -440,30 +440,30 @@ class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMM typedef typename outer_traits_type:: is_always_equal is_always_equal; - scoped_allocator_adaptor_base() + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base() {} template <class OuterA2> - scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc) : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) {} - scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) : outer_allocator_type(other.outer_allocator()) {} - scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) : outer_allocator_type(::boost::move(other.outer_allocator())) {} template <class OuterA2> - scoped_allocator_adaptor_base + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base (const scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>& other) : outer_allocator_type(other.outer_allocator()) {} template <class OuterA2> - scoped_allocator_adaptor_base + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other) : outer_allocator_type(other.outer_allocator()) {} @@ -472,44 +472,44 @@ class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMM struct internal_type_t{}; template <class OuterA2> - scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &) : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) {} public: - scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) { outer_allocator_type::operator=(other.outer_allocator()); return *this; } - scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) { outer_allocator_type::operator=(boost::move(other.outer_allocator())); return *this; } - void swap(scoped_allocator_adaptor_base &r) + BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r) { boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); } - friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) + BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) { l.swap(r); } - inner_allocator_type& inner_allocator() + BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator() { return static_cast<inner_allocator_type&>(*this); } - inner_allocator_type const& inner_allocator() const + BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const { return static_cast<const inner_allocator_type&>(*this); } - outer_allocator_type & outer_allocator() + BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator() { return static_cast<outer_allocator_type&>(*this); } - const outer_allocator_type &outer_allocator() const + BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const { return static_cast<const outer_allocator_type&>(*this); } - scoped_allocator_type select_on_container_copy_construction() const + BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const { return scoped_allocator_type (internal_type_t() @@ -641,21 +641,21 @@ class scoped_allocator_adaptor //! <b>Effects</b>: value-initializes the OuterAlloc base class //! and the inner allocator object. - scoped_allocator_adaptor() + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor() {} - ~scoped_allocator_adaptor() + BOOST_CONTAINER_FORCEINLINE ~scoped_allocator_adaptor() {} //! <b>Effects</b>: initializes each allocator within the adaptor with //! the corresponding allocator from other. - scoped_allocator_adaptor(const scoped_allocator_adaptor& other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor& other) : base_type(other.base()) {} //! <b>Effects</b>: move constructs each allocator within the adaptor with //! the corresponding allocator from other. - scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other) : base_type(::boost::move(other.base())) {} @@ -667,14 +667,14 @@ class scoped_allocator_adaptor //! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the //! corresponding allocator from the argument list). template <class OuterA2> - scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs) : base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...) {} #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\ template <class OuterA2>\ - scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\ + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\ : base_type(::boost::forward<OuterA2>(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\ {}\ // @@ -687,7 +687,7 @@ class scoped_allocator_adaptor //! //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other. template <class OuterA2> - scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other) : base_type(other.base()) {} @@ -696,15 +696,15 @@ class scoped_allocator_adaptor //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator //! rvalue from other. template <class OuterA2> - scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor <OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> BOOST_RV_REF_END other) : base_type(::boost::move(other.base())) {} - scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other) { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); } - scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -736,13 +736,13 @@ class scoped_allocator_adaptor //! <b>Returns</b>: //! <code>allocator_traits<OuterAlloc>:: max_size(outer_allocator())</code>. - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW { return outer_traits_type::max_size(this->outer_allocator()); } //! <b>Effects</b>: //! calls <code>OUTERMOST_ALLOC_TRAITS(*this):: destroy(OUTERMOST(*this), p)</code>. template <class T> - void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW { allocator_traits<typename outermost_allocator<OuterAlloc>::type> ::destroy(get_outermost_allocator(this->outer_allocator()), p); @@ -750,17 +750,17 @@ class scoped_allocator_adaptor //! <b>Returns</b>: //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>. - pointer allocate(size_type n) + BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n) { return outer_traits_type::allocate(this->outer_allocator(), n); } //! <b>Returns</b>: //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>. - pointer allocate(size_type n, const_void_pointer hint) + BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n, const_void_pointer hint) { return outer_traits_type::allocate(this->outer_allocator(), n, hint); } //! <b>Effects</b>: //! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>. - void deallocate(pointer p, size_type n) + BOOST_CONTAINER_FORCEINLINE void deallocate(pointer p, size_type n) { outer_traits_type::deallocate(this->outer_allocator(), p, n); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -772,9 +772,9 @@ class scoped_allocator_adaptor #endif //BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - base_type &base() { return *this; } + BOOST_CONTAINER_FORCEINLINE base_type &base() { return *this; } - const base_type &base() const { return *this; } + BOOST_CONTAINER_FORCEINLINE const base_type &base() const { return *this; } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -808,7 +808,7 @@ class scoped_allocator_adaptor //! to true but the specific constructor does not take an allocator. This definition prevents a silent //! failure to pass an inner allocator to a contained element. -end note] template < typename T, class ...Args> - void construct(T* p, BOOST_FWD_REF(Args)...args) + BOOST_CONTAINER_FORCEINLINE void construct(T* p, BOOST_FWD_REF(Args)...args) { dtl::dispatch_uses_allocator ( (get_outermost_allocator)(this->outer_allocator()) @@ -821,7 +821,7 @@ class scoped_allocator_adaptor //overload selection problems when the first parameter is a pair. #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \ template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ - void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + BOOST_CONTAINER_FORCEINLINE void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ {\ dtl::dispatch_uses_allocator\ ( (get_outermost_allocator)(this->outer_allocator())\ @@ -838,7 +838,7 @@ class scoped_allocator_adaptor public: //Internal function template <class OuterA2> - scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner) + BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner) : base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner) {} @@ -853,17 +853,17 @@ struct scoped_allocator_operator_equal //Optimize equal outer allocator types with //allocator_traits::equal which uses is_always_equal template<class IA> - static bool equal_outer(const IA &l, const IA &r) + BOOST_CONTAINER_FORCEINLINE static bool equal_outer(const IA &l, const IA &r) { return allocator_traits<IA>::equal(l, r); } //Otherwise compare it normally template<class IA1, class IA2> - static bool equal_outer(const IA1 &l, const IA2 &r) + BOOST_CONTAINER_FORCEINLINE static bool equal_outer(const IA1 &l, const IA2 &r) { return l == r; } //Otherwise compare it normally template<class IA> - static bool equal_inner(const IA &l, const IA &r) + BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA &l, const IA &r) { return allocator_traits<IA>::equal(l, r); } }; @@ -875,14 +875,14 @@ struct scoped_allocator_operator_equal<true> //inner_allocator_type is the same as outer_allocator_type //so both types can be different in operator== template<class IA1, class IA2> - static bool equal_inner(const IA1 &, const IA2 &) + BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA1 &, const IA2 &) { return true; } }; /// @endcond template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS> -inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a +BOOST_CONTAINER_FORCEINLINE bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b) { #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -896,7 +896,7 @@ inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_S } template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS> -inline bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a +BOOST_CONTAINER_FORCEINLINE bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b) { return !(a == b); } diff --git a/contrib/restricted/boost/container/include/boost/container/set.hpp b/contrib/restricted/boost/container/include/boost/container/set.hpp index f6cde190de..f8a2efad2f 100644 --- a/contrib/restricted/boost/container/include/boost/container/set.hpp +++ b/contrib/restricted/boost/container/include/boost/container/set.hpp @@ -67,14 +67,14 @@ template <class Key, class Compare, class Allocator, class Options> class set ///@cond : public dtl::tree - < Key, dtl::identity<Key>, Compare, Allocator, Options> + < Key, void, Compare, Allocator, Options> ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(set) typedef dtl::tree - < Key, dtl::identity<Key>, Compare, Allocator, Options> base_t; + < Key, void, Compare, Allocator, Options> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -83,25 +83,25 @@ class set // types // ////////////////////////////////////////////// - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef Compare value_compare; - typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type; - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits<Allocator>::reference reference; - typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference; - typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type; - typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type; - typedef Allocator allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type) node_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::insert_return_type) insert_return_type; + typedef Key key_type; + typedef Key value_type; + typedef Compare key_compare; + typedef key_compare value_compare; + typedef typename base_t::allocator_type allocator_type; + typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer; + typedef typename ::boost::container::allocator_traits<allocator_type>::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits<allocator_type>::reference reference; + typedef typename ::boost::container::allocator_traits<allocator_type>::const_reference const_reference; + typedef typename ::boost::container::allocator_traits<allocator_type>::size_type size_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::difference_type difference_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type) node_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::insert_return_type) insert_return_type; ////////////////////////////////////////////// // @@ -114,7 +114,7 @@ class set //! <b>Complexity</b>: Constant. BOOST_CONTAINER_FORCEINLINE set() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value && + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value && dtl::is_nothrow_default_constructible<Compare>::value) : base_t() {} @@ -227,6 +227,21 @@ class set : base_t(ordered_range, first, last, comp, a) {} + //! <b>Effects</b>: Constructs an empty set using the specified allocator and + //! inserts elements from the ordered unique range [first ,last). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be + //! unique values. + //! + //! <b>Complexity</b>: Linear in N. + //! + //! <b>Note</b>: Non-standard extension. + template <class InputIterator> + BOOST_CONTAINER_FORCEINLINE set(ordered_unique_range_t, InputIterator first, InputIterator last, const allocator_type& a) + : base_t(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! <b>Effects</b>: Constructs an empty set and //! inserts elements from the range [il.begin(), il.end()). @@ -582,7 +597,8 @@ class set private: typedef std::pair<iterator, bool> insert_return_pair; public: - BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->priv_insert) + BOOST_MOVE_CONVERSION_AWARE_CATCH + (insert, value_type, insert_return_pair, this->base_t::insert_unique_convertible) #endif #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -605,7 +621,8 @@ class set //! <b>Complexity</b>: Logarithmic. iterator insert(const_iterator p, value_type &&x); #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator) + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG + (insert, value_type, iterator, this->base_t::insert_unique_hint_convertible, const_iterator, const_iterator) #endif //! <b>Requires</b>: first, last are not iterators into *this. @@ -616,7 +633,7 @@ class set //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) template <class InputIterator> BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->base_t::insert_unique(first, last); } + { this->base_t::insert_unique_range(first, last); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! <b>Effects</b>: inserts each element from the range [il.begin(),il.end()) if and only @@ -624,7 +641,7 @@ class set //! //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from il.begin() to il.end()) BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il) - { this->base_t::insert_unique(il.begin(), il.end()); } + { this->base_t::insert_unique_range(il.begin(), il.end()); } #endif //! @copydoc ::boost::container::map::insert(node_type&&) @@ -640,7 +657,7 @@ class set BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source) { typedef dtl::tree - <Key, dtl::identity<Key>, C2, Allocator, Options> base2_t; + <Key, void, C2, Allocator, Options> base2_t; this->base_t::merge_unique(static_cast<base2_t&>(source)); } @@ -654,7 +671,7 @@ class set BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source) { typedef dtl::tree - <Key, dtl::identity<Key>, C2, Allocator, Options> base2_t; + <Key, void, C2, Allocator, Options> base2_t; this->base_t::merge_unique(static_cast<base2_t&>(source)); } @@ -663,6 +680,14 @@ class set BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source) { return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source)); } + //! <b>Effects</b>: If present, erases the element in the container with key equivalent to x. + //! + //! <b>Returns</b>: Returns the number of erased elements (0/1). + //! + //! <b>Complexity</b>: log(size()) + count(k) + BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& x) + { return this->base_t::erase_unique(x); } + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! <b>Effects</b>: Erases the element pointed to by p. @@ -674,13 +699,6 @@ class set //! <b>Complexity</b>: Amortized constant time iterator erase(const_iterator p); - //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. - //! - //! <b>Returns</b>: Returns the number of erased elements. - //! - //! <b>Complexity</b>: log(size()) + count(k) - size_type erase(const key_type& x); - //! <b>Effects</b>: Erases all the elements in the range [first, last). //! //! <b>Returns</b>: Returns last. @@ -703,7 +721,7 @@ class set BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value && boost::container::dtl::is_nothrow_swappable<Compare>::value ); - //! <b>Effects</b>: erase(a.begin(),a.end()). + //! <b>Effects</b>: erase(begin(),end()). //! //! <b>Postcondition</b>: size() == 0. //! @@ -734,46 +752,130 @@ class set //! <b>Complexity</b>: Logarithmic. const_iterator find(const key_type& x) const; - #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: An iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic. + template<typename K> + iterator find(const K& x); + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: A const_iterator pointing to an element with the key + //! equivalent to x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic. + template<typename K> + const_iterator find(const K& x) const; + + #else + using base_t::erase; + #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! <b>Returns</b>: The number of elements with key equivalent to x. //! //! <b>Complexity</b>: log(size())+count(k) - BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type count(const key_type& x) const { return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend()); } + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Returns</b>: The number of elements with key equivalent to x. //! //! <b>Complexity</b>: log(size())+count(k) - BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) - { return static_cast<size_type>(this->base_t::find(x) != this->base_t::end()); } + template<typename K> + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type count(const K& x) const + { return static_cast<size_type>(this->find(x) != this->cend()); } #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! <b>Returns</b>: Returns true if there is an element with key + //! equivalent to key in the container, otherwise false. + //! + //! <b>Complexity</b>: log(size()). + bool contains(const key_type& x) const; + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: Returns true if there is an element with key + //! equivalent to key in the container, otherwise false. + //! + //! <b>Complexity</b>: log(size()). + template<typename K> + bool contains(const K& x) const; + //! <b>Returns</b>: An iterator pointing to the first element with key not less - //! than k, or a.end() if such an element is not found. + //! than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic iterator lower_bound(const key_type& x); //! <b>Returns</b>: A const iterator pointing to the first element with key not - //! less than k, or a.end() if such an element is not found. + //! less than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic const_iterator lower_bound(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Returns</b>: An iterator pointing to the first element with key not less //! than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic - iterator upper_bound(const key_type& x); + template<typename K> + iterator lower_bound(const K& x); + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Returns</b>: A const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! <b>Complexity</b>: Logarithmic + template<typename K> + const_iterator lower_bound(const K& x) const; + + //! <b>Returns</b>: An iterator pointing to the first element with key greater + //! than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + iterator upper_bound(const key_type& x); + + //! <b>Returns</b>: A const iterator pointing to the first element with key + //! greater than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic const_iterator upper_bound(const key_type& x) const; + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: An iterator pointing to the first element with key greater + //! than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + iterator upper_bound(const K& x); + + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! + //! <b>Returns</b>: A const iterator pointing to the first element with key + //! greater than x, or end() if such an element is not found. + //! + //! <b>Complexity</b>: Logarithmic + template<typename K> + const_iterator upper_bound(const K& x) const; + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). @@ -788,17 +890,27 @@ class set BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const { return this->base_t::lower_bound_range(x); } - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! <b>Complexity</b>: Logarithmic - std::pair<iterator,iterator> equal_range(const key_type& x); + template<typename K> + BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const K& x) + { return this->base_t::lower_bound_range(x); } + //! <b>Requires</b>: This overload is available only if + //! key_compare::is_transparent exists. + //! //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! <b>Complexity</b>: Logarithmic - std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const; + template<typename K> + BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator,const_iterator> equal_range(const K& x) const + { return this->base_t::lower_bound_range(x); } + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees. //! @@ -838,21 +950,71 @@ class set //! <b>Effects</b>: x.swap(y) //! //! <b>Complexity</b>: Constant. - friend void swap(set& x, set& y); + friend void swap(set& x, set& y) + BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value + && boost::container::dtl::is_nothrow_swappable<Compare>::value ); #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) +}; - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - template <class KeyType> - BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x) - { return this->base_t::insert_unique(::boost::forward<KeyType>(x)); } +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template <typename InputIterator> +set(InputIterator, InputIterator) -> + set< it_based_value_type_t<InputIterator> >; + +template < typename InputIterator, typename AllocatorOrCompare> + set(InputIterator, InputIterator, AllocatorOrCompare const&) -> + set< it_based_value_type_t<InputIterator> + , typename dtl::if_c< // Compare + dtl::is_allocator<AllocatorOrCompare>::value + , std::less<it_based_value_type_t<InputIterator>> + , AllocatorOrCompare + >::type + , typename dtl::if_c< // Allocator + dtl::is_allocator<AllocatorOrCompare>::value + , AllocatorOrCompare + , new_allocator<it_based_value_type_t<InputIterator>> + >::type + >; + +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t<Compare> + , typename = dtl::require_allocator_t<Allocator>> +set(InputIterator, InputIterator, Compare const&, Allocator const&) -> + set< it_based_value_type_t<InputIterator> + , Compare + , Allocator>; + +template <typename InputIterator> +set(ordered_unique_range_t, InputIterator, InputIterator) -> + set< it_based_value_type_t<InputIterator>>; + + +template < typename InputIterator, typename AllocatorOrCompare> + set(ordered_unique_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> + set< it_based_value_type_t<InputIterator> + , typename dtl::if_c< // Compare + dtl::is_allocator<AllocatorOrCompare>::value + , std::less<it_based_value_type_t<InputIterator>> + , AllocatorOrCompare + >::type + , typename dtl::if_c< // Allocator + dtl::is_allocator<AllocatorOrCompare>::value + , AllocatorOrCompare + , new_allocator<it_based_value_type_t<InputIterator>> + >::type + >; + +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t<Compare> + , typename = dtl::require_allocator_t<Allocator>> +set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + set< it_based_value_type_t<InputIterator> + , Compare + , Allocator>; - template <class KeyType> - BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) - { return this->base_t::insert_unique(p, ::boost::forward<KeyType>(x)); } - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; +#endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -860,13 +1022,11 @@ class set //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template <class Key, class Compare, class Options, class Allocator> +template <class Key, class Compare, class Allocator, class Options> struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, Options> > { - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && - ::boost::has_trivial_destructor_after_move<pointer>::value && - ::boost::has_trivial_destructor_after_move<Compare>::value; + typedef ::boost::container::dtl::tree<Key, void, Compare, Allocator, Options> tree; + static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value; }; namespace container { @@ -894,14 +1054,14 @@ template <class Key, class Compare, class Allocator, class Options> class multiset /// @cond : public dtl::tree - <Key,dtl::identity<Key>, Compare, Allocator, Options> + <Key, void, Compare, Allocator, Options> /// @endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(multiset) typedef dtl::tree - <Key,dtl::identity<Key>, Compare, Allocator, Options> base_t; + <Key, void, Compare, Allocator, Options> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -911,24 +1071,24 @@ class multiset // types // ////////////////////////////////////////////// - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef Compare value_compare; - typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type; - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits<Allocator>::reference reference; - typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference; - typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type; - typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type; - typedef Allocator allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type) node_type; + typedef Key key_type; + typedef Key value_type; + typedef Compare key_compare; + typedef key_compare value_compare; + typedef typename base_t::allocator_type allocator_type; + typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer; + typedef typename ::boost::container::allocator_traits<allocator_type>::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits<allocator_type>::reference reference; + typedef typename ::boost::container::allocator_traits<allocator_type>::const_reference const_reference; + typedef typename ::boost::container::allocator_traits<allocator_type>::size_type size_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::difference_type difference_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::node_type) node_type; ////////////////////////////////////////////// // @@ -938,7 +1098,7 @@ class multiset //! @copydoc ::boost::container::set::set() BOOST_CONTAINER_FORCEINLINE multiset() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value && + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value && dtl::is_nothrow_default_constructible<Compare>::value) : base_t() {} @@ -1024,6 +1184,20 @@ class multiset : base_t(ordered_range, first, last, comp, a) {} + //! <b>Effects</b>: Constructs an empty multiset using the specified allocator and + //! inserts elements from the ordered range [first ,last ). This function + //! is more efficient than the normal range creation for ordered ranges. + //! + //! <b>Requires</b>: [first ,last) must be ordered according to the predicate. + //! + //! <b>Complexity</b>: Linear in N. + //! + //! <b>Note</b>: Non-standard extension. + template <class InputIterator> + BOOST_CONTAINER_FORCEINLINE multiset(ordered_range_t, InputIterator first, InputIterator last, const allocator_type &a) + : base_t(ordered_range, first, last, Compare(), a) + {} + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>) BOOST_CONTAINER_FORCEINLINE multiset(std::initializer_list<value_type> il) @@ -1215,7 +1389,7 @@ class multiset //! is inserted right before p. iterator insert(value_type &&x); #else - BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->priv_insert) + BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->base_t::insert_equal_convertible) #endif #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1239,7 +1413,8 @@ class multiset //! is inserted right before p. iterator insert(const_iterator p, value_type &&x); #else - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator) + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG + (insert, value_type, iterator, this->base_t::insert_equal_hint_convertible, const_iterator, const_iterator) #endif //! <b>Requires</b>: first, last are not iterators into *this. @@ -1249,12 +1424,12 @@ class multiset //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) template <class InputIterator> BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last) - { this->base_t::insert_equal(first, last); } + { this->base_t::insert_equal_range(first, last); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! @copydoc ::boost::container::set::insert(std::initializer_list<value_type>) BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il) - { this->base_t::insert_equal(il.begin(), il.end()); } + { this->base_t::insert_equal_range(il.begin(), il.end()); } #endif //! @copydoc ::boost::container::multimap::insert(node_type&&) @@ -1270,7 +1445,7 @@ class multiset BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source) { typedef dtl::tree - <Key, dtl::identity<Key>, C2, Allocator, Options> base2_t; + <Key, void, C2, Allocator, Options> base2_t; this->base_t::merge_equal(static_cast<base2_t&>(source)); } @@ -1284,7 +1459,7 @@ class multiset BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source) { typedef dtl::tree - <Key, dtl::identity<Key>, C2, Allocator, Options> base2_t; + <Key, void, C2, Allocator, Options> base2_t; this->base_t::merge_equal(static_cast<base2_t&>(source)); } @@ -1330,27 +1505,70 @@ class multiset //! @copydoc ::boost::container::set::find(const key_type& ) const const_iterator find(const key_type& x) const; + //! @copydoc ::boost::container::set::find(const K& ) + template<typename K> + iterator find(const K& x); + + //! @copydoc ::boost::container::set::find(const K& ) + template<typename K> + const_iterator find(const K& x) const; + //! @copydoc ::boost::container::set::count(const key_type& ) const size_type count(const key_type& x) const; + //! @copydoc ::boost::container::set::count(const K& ) const + template<typename K> + size_type count(const K& x) const; + + //! @copydoc ::boost::container::set::contains(const key_type& ) const + bool contains(const key_type& x) const; + + //! @copydoc ::boost::container::set::contains(const K& ) const + template<typename K> + bool contains(const K& x) const; + //! @copydoc ::boost::container::set::lower_bound(const key_type& ) iterator lower_bound(const key_type& x); //! @copydoc ::boost::container::set::lower_bound(const key_type& ) const const_iterator lower_bound(const key_type& x) const; + //! @copydoc ::boost::container::set::lower_bound(const K& ) + template<typename K> + iterator lower_bound(const K& x); + + //! @copydoc ::boost::container::set::lower_bound(const K& ) const + template<typename K> + const_iterator lower_bound(const K& x) const; + //! @copydoc ::boost::container::set::upper_bound(const key_type& ) iterator upper_bound(const key_type& x); //! @copydoc ::boost::container::set::upper_bound(const key_type& ) const const_iterator upper_bound(const key_type& x) const; + //! @copydoc ::boost::container::set::upper_bound(const K& ) + template<typename K> + iterator upper_bound(const K& x); + + //! @copydoc ::boost::container::set::upper_bound(const K& ) const + template<typename K> + const_iterator upper_bound(const K& x) const; + //! @copydoc ::boost::container::set::equal_range(const key_type& ) const std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const; //! @copydoc ::boost::container::set::equal_range(const key_type& ) std::pair<iterator,iterator> equal_range(const key_type& x); + //! @copydoc ::boost::container::set::equal_range(const K& ) const + template<typename K> + std::pair<const_iterator, const_iterator> equal_range(const K& x) const; + + //! @copydoc ::boost::container::set::equal_range(const K& ) + template<typename K> + std::pair<iterator,iterator> equal_range(const K& x); + //! @copydoc ::boost::container::set::rebalance() void rebalance(); @@ -1387,22 +1605,71 @@ class multiset //! <b>Effects</b>: x.swap(y) //! //! <b>Complexity</b>: Constant. - friend void swap(multiset& x, multiset& y); + friend void swap(multiset& x, multiset& y) + BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value + && boost::container::dtl::is_nothrow_swappable<Compare>::value ); #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) +}; - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - private: - template <class KeyType> - BOOST_CONTAINER_FORCEINLINE iterator priv_insert(BOOST_FWD_REF(KeyType) x) - { return this->base_t::insert_equal(::boost::forward<KeyType>(x)); } - - template <class KeyType> - BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) - { return this->base_t::insert_equal(p, ::boost::forward<KeyType>(x)); } +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template <typename InputIterator> +multiset(InputIterator, InputIterator) -> + multiset< it_based_value_type_t<InputIterator> >; + + +template < typename InputIterator, typename AllocatorOrCompare> +multiset(InputIterator, InputIterator, AllocatorOrCompare const&) -> + multiset < it_based_value_type_t<InputIterator> + , typename dtl::if_c< // Compare + dtl::is_allocator<AllocatorOrCompare>::value + , std::less<it_based_value_type_t<InputIterator>> + , AllocatorOrCompare + >::type + , typename dtl::if_c< // Allocator + dtl::is_allocator<AllocatorOrCompare>::value + , AllocatorOrCompare + , new_allocator<it_based_value_type_t<InputIterator>> + >::type + >; + +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t<Compare> + , typename = dtl::require_allocator_t<Allocator>> +multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> + multiset< it_based_value_type_t<InputIterator> + , Compare + , Allocator>; + +template <typename InputIterator> +multiset(ordered_range_t, InputIterator, InputIterator) -> + multiset< it_based_value_type_t<InputIterator>>; + +template < typename InputIterator, typename AllocatorOrCompare> +multiset(ordered_range_t, InputIterator, InputIterator, AllocatorOrCompare const&) -> + multiset < it_based_value_type_t<InputIterator> + , typename dtl::if_c< // Compare + dtl::is_allocator<AllocatorOrCompare>::value + , std::less<it_based_value_type_t<InputIterator>> + , AllocatorOrCompare + >::type + , typename dtl::if_c< // Allocator + dtl::is_allocator<AllocatorOrCompare>::value + , AllocatorOrCompare + , new_allocator<it_based_value_type_t<InputIterator>> + >::type + >; + +template < typename InputIterator, typename Compare, typename Allocator + , typename = dtl::require_nonallocator_t<Compare> + , typename = dtl::require_allocator_t<Allocator>> +multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + multiset< it_based_value_type_t<InputIterator> + , Compare + , Allocator>; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -}; +#endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -1413,10 +1680,8 @@ class multiset template <class Key, class Compare, class Allocator, class Options> struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, Options> > { - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && - ::boost::has_trivial_destructor_after_move<pointer>::value && - ::boost::has_trivial_destructor_after_move<Compare>::value; + typedef ::boost::container::dtl::tree<Key, void, Compare, Allocator, Options> tree; + static const bool value = ::boost::has_trivial_destructor_after_move<tree>::value; }; namespace container { diff --git a/contrib/restricted/boost/container/include/boost/container/small_vector.hpp b/contrib/restricted/boost/container/include/boost/container/small_vector.hpp index 70704d6b63..2ad0410d3d 100644 --- a/contrib/restricted/boost/container/include/boost/container/small_vector.hpp +++ b/contrib/restricted/boost/container/include/boost/container/small_vector.hpp @@ -39,6 +39,7 @@ #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include <boost/move/detail/fwd_macros.hpp> #endif +#include <boost/move/detail/force_ptr.hpp> //std #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) @@ -48,12 +49,48 @@ namespace boost { namespace container { -#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +namespace dtl{ -template <class T, class Allocator = new_allocator<T> > -class small_vector_base; +template<class Options> +struct get_small_vector_opt +{ + typedef Options type; +}; -#endif +template<> +struct get_small_vector_opt<void> +{ + typedef small_vector_null_opt type; +}; + +template<class Options> +struct get_vopt_from_svopt + : get_small_vector_opt<Options>::type +{ + typedef typename get_small_vector_opt<Options>::type options_t; + typedef vector_opt< typename options_t::growth_factor_type, void> type; +}; + +template<> +struct get_vopt_from_svopt<void> +{ + typedef void type; +}; + +template <class T, class SecAlloc, class Options> +struct vector_for_small_vector +{ + typedef vector + < T + , small_vector_allocator + < T + , typename allocator_traits<typename real_allocator<T, SecAlloc>::type>::template portable_rebind_alloc<void>::type + , Options> + , typename dtl::get_vopt_from_svopt<Options>::type + > type; +}; + +} //namespace dtl //! A non-standard allocator used to implement `small_vector`. //! Users should never use it directly. It is described here @@ -78,45 +115,47 @@ class small_vector_base; //! is being used to store vector elements. //! //! `small_vector_allocator` assumes that will be instantiated as -//! `boost::container::vector< T, small_vector_allocator<Allocator> >` +//! `boost::container::vector< T, small_vector_allocator<T, Allocator> >` //! and internal storage can be obtained downcasting that vector //! to `small_vector_base<T>`. -template<class Allocator> +template<class T, class VoidAlloc BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void)> class small_vector_allocator - : public Allocator + : public allocator_traits<VoidAlloc>::template portable_rebind_alloc<T>::type { typedef unsigned int allocation_type; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: + typedef typename allocator_traits<VoidAlloc>::template portable_rebind_alloc<T>::type allocator_type; + BOOST_COPYABLE_AND_MOVABLE(small_vector_allocator) - BOOST_CONTAINER_FORCEINLINE const Allocator &as_base() const - { return static_cast<const Allocator&>(*this); } + BOOST_CONTAINER_FORCEINLINE const allocator_type &as_base() const BOOST_NOEXCEPT + { return static_cast<const allocator_type&>(*this); } - BOOST_CONTAINER_FORCEINLINE Allocator &as_base() - { return static_cast<Allocator&>(*this); } + BOOST_CONTAINER_FORCEINLINE allocator_type &as_base() BOOST_NOEXCEPT + { return static_cast<allocator_type&>(*this); } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef allocator_traits<Allocator> allocator_traits_type; + typedef allocator_traits<allocator_type> allocator_traits_type; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef typename allocator_traits<Allocator>::value_type value_type; - typedef typename allocator_traits<Allocator>::pointer pointer; - typedef typename allocator_traits<Allocator>::const_pointer const_pointer; - typedef typename allocator_traits<Allocator>::reference reference; - typedef typename allocator_traits<Allocator>::const_reference const_reference; - typedef typename allocator_traits<Allocator>::size_type size_type; - typedef typename allocator_traits<Allocator>::difference_type difference_type; - typedef typename allocator_traits<Allocator>::void_pointer void_pointer; - typedef typename allocator_traits<Allocator>::const_void_pointer const_void_pointer; - - typedef typename allocator_traits<Allocator>::propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - typedef typename allocator_traits<Allocator>::propagate_on_container_move_assignment propagate_on_container_move_assignment; - typedef typename allocator_traits<Allocator>::propagate_on_container_swap propagate_on_container_swap; + typedef typename allocator_traits<allocator_type>::value_type value_type; + typedef typename allocator_traits<allocator_type>::pointer pointer; + typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; + typedef typename allocator_traits<allocator_type>::reference reference; + typedef typename allocator_traits<allocator_type>::const_reference const_reference; + typedef typename allocator_traits<allocator_type>::size_type size_type; + typedef typename allocator_traits<allocator_type>::difference_type difference_type; + typedef typename allocator_traits<allocator_type>::void_pointer void_pointer; + typedef typename allocator_traits<allocator_type>::const_void_pointer const_void_pointer; + + typedef typename allocator_traits<allocator_type>::propagate_on_container_copy_assignment propagate_on_container_copy_assignment; + typedef typename allocator_traits<allocator_type>::propagate_on_container_move_assignment propagate_on_container_move_assignment; + typedef typename allocator_traits<allocator_type>::propagate_on_container_swap propagate_on_container_swap; //! An integral constant with member `value == false` typedef BOOST_CONTAINER_IMPDEF(dtl::bool_<false>) is_always_equal; //! An integral constant with member `value == true` @@ -129,81 +168,80 @@ class small_vector_allocator template<class T2> struct rebind { - typedef typename allocator_traits<Allocator>::template rebind_alloc<T2>::type other; + typedef typename allocator_traits<allocator_type>::template portable_rebind_alloc<T2>::type other; }; - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //!Constructor from arbitrary arguments - template<class ...Args> - BOOST_CONTAINER_FORCEINLINE explicit small_vector_allocator(BOOST_FWD_REF(Args) ...args) - : Allocator(::boost::forward<Args>(args)...) - {} - #else - #define BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE(N) \ - BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - BOOST_CONTAINER_FORCEINLINE explicit small_vector_allocator(BOOST_MOVE_UREF##N)\ - : Allocator(BOOST_MOVE_FWD##N)\ - {}\ - // - BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE) - #undef BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE - #endif + BOOST_CONTAINER_FORCEINLINE small_vector_allocator() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value) + {} //!Constructor from other small_vector_allocator. //!Never throws BOOST_CONTAINER_FORCEINLINE small_vector_allocator (const small_vector_allocator &other) BOOST_NOEXCEPT_OR_NOTHROW - : Allocator(other.as_base()) + : allocator_type(other.as_base()) {} //!Move constructor from small_vector_allocator. //!Never throws BOOST_CONTAINER_FORCEINLINE small_vector_allocator (BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - : Allocator(::boost::move(other.as_base())) + : allocator_type(::boost::move(other.as_base())) {} //!Constructor from related small_vector_allocator. //!Never throws - template<class OtherAllocator> + template<class U, class OtherVoidAllocator, class OtherOptions> BOOST_CONTAINER_FORCEINLINE small_vector_allocator - (const small_vector_allocator<OtherAllocator> &other) BOOST_NOEXCEPT_OR_NOTHROW - : Allocator(other.as_base()) + (const small_vector_allocator<U, OtherVoidAllocator, OtherOptions> &other) BOOST_NOEXCEPT_OR_NOTHROW + : allocator_type(other.as_base()) {} //!Move constructor from related small_vector_allocator. //!Never throws - template<class OtherAllocator> + template<class U, class OtherVoidAllocator, class OtherOptions> BOOST_CONTAINER_FORCEINLINE small_vector_allocator - (BOOST_RV_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW - : Allocator(::boost::move(other.as_base())) + (BOOST_RV_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I OtherOptions>) other) BOOST_NOEXCEPT_OR_NOTHROW + : allocator_type(::boost::move(other.as_base())) + {} + + //!Constructor from allocator_type. + //!Never throws + BOOST_CONTAINER_FORCEINLINE explicit small_vector_allocator + (const allocator_type &other) BOOST_NOEXCEPT_OR_NOTHROW + : allocator_type(other) {} //!Assignment from other small_vector_allocator. //!Never throws BOOST_CONTAINER_FORCEINLINE small_vector_allocator & operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast<small_vector_allocator&>(this->Allocator::operator=(other.as_base())); } + { return static_cast<small_vector_allocator&>(this->allocator_type::operator=(other.as_base())); } - //!Move constructor from other small_vector_allocator. + //!Move assignment from other small_vector_allocator. //!Never throws BOOST_CONTAINER_FORCEINLINE small_vector_allocator & operator=(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast<small_vector_allocator&>(this->Allocator::operator=(::boost::move(other.as_base()))); } + { return static_cast<small_vector_allocator&>(this->allocator_type::operator=(::boost::move(other.as_base()))); } //!Assignment from related small_vector_allocator. //!Never throws - template<class OtherAllocator> + template<class U, class OtherVoidAllocator> BOOST_CONTAINER_FORCEINLINE small_vector_allocator & - operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast<small_vector_allocator&>(this->Allocator::operator=(other.as_base())); } + operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I Options>) other) BOOST_NOEXCEPT_OR_NOTHROW + { return static_cast<small_vector_allocator&>(this->allocator_type::operator=(other.as_base())); } //!Move assignment from related small_vector_allocator. //!Never throws - template<class OtherAllocator> + template<class U, class OtherVoidAllocator> BOOST_CONTAINER_FORCEINLINE small_vector_allocator & - operator=(BOOST_RV_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW - { return static_cast<small_vector_allocator&>(this->Allocator::operator=(::boost::move(other.as_base()))); } + operator=(BOOST_RV_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I Options>) other) BOOST_NOEXCEPT_OR_NOTHROW + { return static_cast<small_vector_allocator&>(this->allocator_type::operator=(::boost::move(other.as_base()))); } + + //!Move assignment from allocator_type. + //!Never throws + BOOST_CONTAINER_FORCEINLINE small_vector_allocator & + operator=(const allocator_type &other) BOOST_NOEXCEPT_OR_NOTHROW + { return static_cast<small_vector_allocator&>(this->allocator_type::operator=(other)); } //!Allocates storage from the standard-conforming allocator BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type count, const_void_pointer hint = const_void_pointer()) @@ -244,57 +282,36 @@ class small_vector_allocator { return !(l == r); } #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - /* - //!An advanced function that offers in-place expansion shrink to fit and new allocation - //!capabilities. Memory allocated with this function can only be deallocated with deallocate() - //!or deallocate_many(). - //!This function is available only with Version == 2 - pointer allocation_command(allocation_type command, - size_type limit_size, - size_type &prefer_in_recvd_out_size, - pointer &reuse) - { return allocator_traits_type::allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); } - - //!Returns maximum the number of objects the previously allocated memory - //!pointed by p can hold. - //!Memory must not have been allocated with - //!allocate_one or allocate_individual. - //!This function is available only with Version == 2 - size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW - { return allocator_traits_type::size(p); } - */ private: - /* - //!Allocates just one object. Memory allocated with this function - //!must be deallocated only with deallocate_one(). - //!Throws bad_alloc if there is no enough memory - //!This function is available only with Version == 2 - using Allocator::allocate_one; - using Allocator::allocate_individual; - using Allocator::deallocate_one; - using Allocator::deallocate_individual; - using Allocator::allocate_many; - using Allocator::deallocate_many;*/ - - BOOST_CONTAINER_FORCEINLINE bool is_internal_storage(pointer p) const + + typedef small_vector_base<value_type, allocator_type, Options> derived_type; + typedef typename dtl::vector_for_small_vector + <value_type, allocator_type, Options>::type vector_type; + + BOOST_CONTAINER_FORCEINLINE bool is_internal_storage(const_pointer p) const { return this->internal_storage() == p; } - pointer internal_storage() const - { - typedef typename Allocator::value_type value_type; - typedef typename allocator_traits_type::size_type size_type; - typedef vector_alloc_holder< small_vector_allocator<Allocator>, size_type > vector_alloc_holder_t; - typedef vector<value_type, small_vector_allocator<Allocator> > vector_base; - typedef small_vector_base<value_type, Allocator> derived_type; - // - const vector_alloc_holder_t &v_holder = static_cast<const vector_alloc_holder_t &>(*this); - const vector_base &v_base = reinterpret_cast<const vector_base &>(v_holder); - const derived_type &d_base = static_cast<const derived_type &>(v_base); - return d_base.internal_storage(); - } + public: + BOOST_CONTAINER_FORCEINLINE const_pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW; + BOOST_CONTAINER_FORCEINLINE pointer internal_storage() BOOST_NOEXCEPT_OR_NOTHROW; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; +template<class T, std::size_t N, std::size_t Alignment> +struct small_vector_storage +{ + typedef typename dtl::aligned_storage + <sizeof(T)*N, Alignment>::type storage_type; + storage_type m_storage; + static const std::size_t sms_size = sizeof(storage_type)/sizeof(T); +}; + +template<class T, std::size_t Alignment> +struct small_vector_storage<T, 0u, Alignment> +{ + static const std::size_t sms_size = 0u; +}; + //! This class consists of common code from all small_vector<T, N> types that don't depend on the //! "N" template parameter. This class is non-copyable and non-destructible, so this class typically //! used as reference argument to functions that read or write small vectors. Since `small_vector<T, N>` @@ -320,35 +337,44 @@ class small_vector_allocator //! //! All `boost::container:vector` member functions are inherited. See `vector` documentation for details. //! -template <class T, class SecondaryAllocator> +template <class T, class SecAlloc, class Options> class small_vector_base - : public vector<T, small_vector_allocator<SecondaryAllocator> > + : public dtl::vector_for_small_vector<T, SecAlloc, Options>::type { - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKEDVECTOR public: //Make it public as it will be inherited by small_vector and container //must have this public member - typedef typename allocator_traits<SecondaryAllocator>::pointer pointer; + typedef typename real_allocator<T, SecAlloc>::type secondary_allocator_t; + typedef typename allocator_traits<secondary_allocator_t>:: + template portable_rebind_alloc<void>::type void_allocator_t; + typedef typename dtl::get_small_vector_opt<Options>::type options_t; + typedef typename dtl::vector_for_small_vector + <T, SecAlloc, Options>::type base_type; + typedef typename allocator_traits<secondary_allocator_t>::pointer pointer; + typedef typename allocator_traits<secondary_allocator_t>::const_pointer const_pointer; + typedef typename allocator_traits<secondary_allocator_t>::void_pointer void_pointer; + typedef typename allocator_traits<secondary_allocator_t>::const_void_pointer const_void_pointer; + typedef small_vector_allocator<T, void_allocator_t, Options> allocator_type; private: BOOST_COPYABLE_AND_MOVABLE(small_vector_base) - friend class small_vector_allocator<SecondaryAllocator>; + friend class small_vector_allocator<T, void_allocator_t, Options>; - pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW - { - return boost::intrusive::pointer_traits<pointer>::pointer_to - (*const_cast<T*>(static_cast<const T*>(static_cast<const void*>(m_storage_start.data)))); - } + BOOST_CONTAINER_FORCEINLINE + const_pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->base_type::get_stored_allocator().internal_storage(); } + + BOOST_CONTAINER_FORCEINLINE + pointer internal_storage() BOOST_NOEXCEPT_OR_NOTHROW + { return this->base_type::get_stored_allocator().internal_storage(); } - typedef vector<T, small_vector_allocator<SecondaryAllocator> > base_type; + private: base_type &as_base() { return static_cast<base_type&>(*this); } const base_type &as_base() const { return static_cast<const base_type&>(*this); } public: - typedef typename dtl::aligned_storage - <sizeof(T), dtl::alignment_of<T>::value>::type storage_type; - typedef small_vector_allocator<SecondaryAllocator> allocator_type; protected: @@ -362,11 +388,6 @@ class small_vector_base {} //~small_vector_base(){} - - private: - //The only member - storage_type m_storage_start; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -390,6 +411,7 @@ class small_vector_base this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin())) , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end ())) ); + x.clear(); } } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -399,61 +421,73 @@ class small_vector_base ///////////////////////////////////////////////////// // -// small_vector_storage_calculator +// small_vector_storage_definer // ///////////////////////////////////////////////////// -template<std::size_t Needed, std::size_t Hdr, std::size_t SSize, bool NeedsZero = (0u == Needed || Needed <= Hdr)> -struct small_vector_storage_calculator_helper +template<class T, std::size_t N, class Options> +struct small_vector_storage_definer { - static const std::size_t value = (Needed - Hdr - 1u)/SSize + 1u; + typedef typename dtl::get_small_vector_opt<Options>::type options_t; + static const std::size_t final_alignment = + options_t::inplace_alignment ? options_t::inplace_alignment : dtl::alignment_of<T>::value; + typedef small_vector_storage<T, N, final_alignment> type; }; -template<std::size_t Needed, std::size_t Hdr, std::size_t SSize> -struct small_vector_storage_calculator_helper<Needed, Hdr, SSize, true> +template <class T, class SecAlloc, class Options> +struct small_vector_storage_strawman + : public small_vector_base<T, SecAlloc, Options> + , public small_vector_storage_definer<T, 1, Options>::type { - static const std::size_t value = 0u; + typedef typename small_vector_storage_definer<T, 1, Options>::type sm_storage_t; }; -template<class Storage, class Allocator, class T, std::size_t N> -struct small_vector_storage_calculator +//Internal storage hack +template<class T, class VoidAlloc, class Options> +BOOST_CONTAINER_FORCEINLINE typename small_vector_allocator<T, VoidAlloc, Options>::const_pointer + small_vector_allocator<T, VoidAlloc, Options>::internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW { - typedef small_vector_base<T, Allocator> svh_type; - typedef vector<T, small_vector_allocator<Allocator> > svhb_type; - static const std::size_t s_align = dtl::alignment_of<Storage>::value; - static const std::size_t s_size = sizeof(Storage); - static const std::size_t svh_sizeof = sizeof(svh_type); - static const std::size_t svhb_sizeof = sizeof(svhb_type); - static const std::size_t s_start = ((svhb_sizeof-1)/s_align+1)*s_align; - static const std::size_t header_bytes = svh_sizeof-s_start; - static const std::size_t needed_bytes = sizeof(T)*N; - static const std::size_t needed_extra_storages = - small_vector_storage_calculator_helper<needed_bytes, header_bytes, s_size>::value; -}; + typedef small_vector_storage_strawman<T, allocator_type, Options> strawman_t; + typedef typename strawman_t::sm_storage_t sm_storage_t; + + //These warnings are false positives, as we know the alignment is correct + //and aligned storage is allowed to hold any type + #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + #pragma GCC diagnostic ignored "-Wstrict-aliasing" + #endif + const vector_type& v = reinterpret_cast<const vector_type&>(*this); + BOOST_ASSERT((std::size_t(this) % dtl::alignment_of<strawman_t>::value) == 0); + const strawman_t &straw = static_cast<const strawman_t&>(v); + const sm_storage_t& stor = static_cast<const sm_storage_t&>(straw); + return boost::intrusive::pointer_traits<const_pointer>::pointer_to(*((const T*)stor.m_storage.data)); + #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) + #pragma GCC diagnostic pop + #endif +} -///////////////////////////////////////////////////// -// -// small_vector_storage_definer -// -///////////////////////////////////////////////////// -template<class Storage, std::size_t N> -struct small_vector_storage +template <class T, class VoidAlloc, class Options> +BOOST_CONTAINER_FORCEINLINE typename small_vector_allocator<T, VoidAlloc, Options>::pointer + small_vector_allocator<T, VoidAlloc, Options>::internal_storage() BOOST_NOEXCEPT_OR_NOTHROW { - Storage m_rest_of_storage[N]; -}; + typedef small_vector_storage_strawman<T, allocator_type, Options> strawman_t; + typedef typename strawman_t::sm_storage_t sm_storage_t; -template<class Storage> -struct small_vector_storage<Storage, 0> -{}; + #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + #pragma GCC diagnostic ignored "-Wstrict-aliasing" + #endif + vector_type& v = reinterpret_cast<vector_type&>(*this); + BOOST_ASSERT((std::size_t(this) % dtl::alignment_of<strawman_t>::value) == 0); + strawman_t &straw = static_cast<strawman_t&>(v); + sm_storage_t& stor = static_cast<sm_storage_t&>(straw); + return boost::intrusive::pointer_traits<pointer>::pointer_to(*((T*)stor.m_storage.data)); + #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) + #pragma GCC diagnostic pop + #endif +} -template<class Allocator, std::size_t N> -struct small_vector_storage_definer -{ - typedef typename Allocator::value_type value_type; - typedef typename small_vector_base<value_type, Allocator>::storage_type storage_type; - static const std::size_t needed_extra_storages = - small_vector_storage_calculator<storage_type, Allocator, value_type, N>::needed_extra_storages; - typedef small_vector_storage<storage_type, needed_extra_storages> type; -}; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -461,52 +495,49 @@ struct small_vector_storage_definer //! It contains some preallocated elements in-place, which can avoid the use of dynamic storage allocation //! when the actual number of elements is below that preallocated threshold. //! -//! `small_vector<T, N, Allocator>` is convertible to `small_vector_base<T, Allocator>` that is independent +//! `small_vector<T, N, Allocator, Options>` is convertible to `small_vector_base<T, Allocator, Options>` that is independent //! from the preallocated element capacity, so client code does not need to be templated on that N argument. //! //! All `boost::container::vector` member functions are inherited. See `vector` documentation for details. //! +//! Any change to the capacity of the vector, including decreasing its size such as with the shrink_to_fit method, will +//! cause the vector to permanently switch to dynamically allocated storage. +//! //! \tparam T The type of object that is stored in the small_vector //! \tparam N The number of preallocated elements stored inside small_vector. It shall be less than Allocator::max_size(); -//! \tparam Allocator The allocator used for memory management when the number of elements exceeds N. -template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>) > -class small_vector : public small_vector_base<T, Allocator> +//! \tparam Allocator The allocator used for memory management when the number of elements exceeds N. Use void +//! for the default allocator +//! \tparam Options A type produced from \c boost::container::small_vector_options. +template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void) > +class small_vector + : public small_vector_base<T, Allocator, Options> #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - , private small_vector_storage_definer<Allocator, N>::type + , private small_vector_storage_definer<T, N, Options>::type #endif { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef small_vector_base<T, Allocator> base_type; - typedef typename small_vector_storage_definer<Allocator, N>::type remaining_storage_holder; BOOST_COPYABLE_AND_MOVABLE(small_vector) - typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type; - public: - typedef small_vector_storage_calculator< typename small_vector_base<T, Allocator> - ::storage_type, Allocator, T, N> storage_test; - - static const std::size_t needed_extra_storages = storage_test::needed_extra_storages; - static const std::size_t needed_bytes = storage_test::needed_bytes; - static const std::size_t header_bytes = storage_test::header_bytes; - static const std::size_t s_start = storage_test::s_start; - + typedef small_vector_base<T, Allocator, Options> base_type; typedef typename base_type::allocator_type allocator_type; typedef typename base_type::size_type size_type; typedef typename base_type::value_type value_type; BOOST_CONTAINER_FORCEINLINE static std::size_t internal_capacity() - { return (sizeof(small_vector) - storage_test::s_start)/sizeof(T); } + { return static_capacity; } + + typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! @brief The capacity/max size of the container - static const size_type static_capacity = N; + static const size_type static_capacity = small_vector_storage_definer<T, N, Options>::type::sms_size; public: BOOST_CONTAINER_FORCEINLINE small_vector() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value) + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value) : base_type(initial_capacity_t(), internal_capacity()) {} @@ -575,6 +606,7 @@ class small_vector : public small_vector_base<T, Allocator> { this->move_construct_impl(other, other.get_stored_allocator()); } BOOST_CONTAINER_FORCEINLINE small_vector(BOOST_RV_REF(small_vector) other) + BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<value_type>::value) : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator())) { this->move_construct_impl(other, other.get_stored_allocator()); } @@ -594,6 +626,9 @@ class small_vector : public small_vector_base<T, Allocator> { return static_cast<small_vector&>(this->base_type::operator=(static_cast<base_type const&>(other))); } BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_RV_REF(small_vector) other) + BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_assignable<value_type>::value + && (allocator_traits_type::propagate_on_container_move_assignment::value + || allocator_traits_type::is_always_equal::value)) { return static_cast<small_vector&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); } BOOST_CONTAINER_FORCEINLINE small_vector& operator=(const base_type &other) diff --git a/contrib/restricted/boost/container/include/boost/container/string.hpp b/contrib/restricted/boost/container/include/boost/container/string.hpp index 8829fdaadb..fbe0986d67 100644 --- a/contrib/restricted/boost/container/include/boost/container/string.hpp +++ b/contrib/restricted/boost/container/include/boost/container/string.hpp @@ -38,22 +38,22 @@ #include <boost/move/detail/to_raw_pointer.hpp> #include <boost/container/detail/version_type.hpp> #include <boost/container/detail/type_traits.hpp> -#include <boost/container/detail/minimal_char_traits_header.hpp> #include <boost/container/detail/algorithm.hpp> - +#include <boost/container/detail/minimal_char_traits_header.hpp> // for char_traits +//intrusive #include <boost/intrusive/pointer_traits.hpp> - +#include <boost/intrusive/detail/hash_combine.hpp> +#include <boost/move/detail/force_ptr.hpp> +//move #include <boost/move/utility_core.hpp> #include <boost/move/adl_move_swap.hpp> #include <boost/move/traits.hpp> #include <boost/static_assert.hpp> #include <boost/core/no_exceptions_support.hpp> -#include <boost/functional/hash.hpp> -#include <algorithm> -#include <iosfwd> -#include <istream> +#include <iosfwd> +#include <istream> // #include <ostream> #include <ios> #include <locale> @@ -87,42 +87,42 @@ class basic_string_base basic_string_base & operator=(const basic_string_base &); basic_string_base(const basic_string_base &); - typedef allocator_traits<Allocator> allocator_traits_type; + typedef Allocator allocator_type; public: - typedef Allocator allocator_type; - typedef allocator_type stored_allocator_type; - typedef typename allocator_traits_type::pointer pointer; - typedef typename allocator_traits_type::value_type value_type; - typedef typename allocator_traits_type::size_type size_type; + typedef allocator_traits<allocator_type> allocator_traits_type; + typedef allocator_type stored_allocator_type; + typedef typename allocator_traits_type::pointer pointer; + typedef typename allocator_traits_type::value_type value_type; + typedef typename allocator_traits_type::size_type size_type; + typedef typename allocator_traits_type::difference_type difference_type; + typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits; - basic_string_base() + BOOST_CONTAINER_FORCEINLINE basic_string_base() : members_() - { init(); } + {} - explicit basic_string_base(const allocator_type& a) + BOOST_CONTAINER_FORCEINLINE explicit basic_string_base(const allocator_type& a) : members_(a) - { init(); } + {} - explicit basic_string_base(BOOST_RV_REF(allocator_type) a) + BOOST_CONTAINER_FORCEINLINE explicit basic_string_base(BOOST_RV_REF(allocator_type) a) : members_(boost::move(a)) - { this->init(); } + {} - basic_string_base(const allocator_type& a, size_type n) + BOOST_CONTAINER_FORCEINLINE basic_string_base(const allocator_type& a, size_type n) : members_(a) { - this->init(); this->allocate_initial_block(n); } - explicit basic_string_base(size_type n) + BOOST_CONTAINER_FORCEINLINE explicit basic_string_base(size_type n) : members_() { - this->init(); this->allocate_initial_block(n); } - ~basic_string_base() + BOOST_CONTAINER_FORCEINLINE ~basic_string_base() { if(!this->is_short()){ this->deallocate(this->priv_long_addr(), this->priv_long_storage()); @@ -139,10 +139,15 @@ class basic_string_base size_type storage; pointer start; - long_t() + BOOST_CONTAINER_FORCEINLINE long_t() + : is_short(0) + {} + + BOOST_CONTAINER_FORCEINLINE long_t(size_type len, size_type stor, pointer ptr) + : is_short(0), length(len), storage(stor), start(ptr) {} - long_t(const long_t &other) + BOOST_CONTAINER_FORCEINLINE long_t(const long_t &other) { this->is_short = false; length = other.length; @@ -150,7 +155,7 @@ class basic_string_base start = other.start; } - long_t &operator= (const long_t &other) + BOOST_CONTAINER_FORCEINLINE long_t &operator= (const long_t &other) { length = other.length; storage = other.storage; @@ -190,43 +195,57 @@ class basic_string_base value_type data[UnalignedFinalInternalBufferChars]; }; - union repr_t + union repr_t_size_t { long_raw_t r; short_t s; + }; - const short_t &short_repr() const - { return s; } - - const long_t &long_repr() const - { return *static_cast<const long_t*>(static_cast<const void*>(r.data)); } - - short_t &short_repr() - { return s; } - - long_t &long_repr() - { return *static_cast<long_t*>(static_cast<void*>(&r)); } + union repr_t + { + long_raw_t r_aligner; + short_t s_aligner; + unsigned char data[sizeof(repr_t_size_t)]; }; struct members_holder - : public Allocator + : public allocator_type { - members_holder() - : Allocator() - {} + BOOST_CONTAINER_FORCEINLINE void init() + { + short_t &s = *::new(this->m_repr.data) short_t; + s.h.is_short = 1; + s.h.length = 0; + } + + BOOST_CONTAINER_FORCEINLINE members_holder() + : allocator_type() + { this->init(); } template<class AllocatorConvertible> - explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a) - : Allocator(boost::forward<AllocatorConvertible>(a)) - {} + BOOST_CONTAINER_FORCEINLINE explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a) + : allocator_type(boost::forward<AllocatorConvertible>(a)) + { this->init(); } + + BOOST_CONTAINER_FORCEINLINE const short_t *pshort_repr() const + { return move_detail::force_ptr<const short_t*>(m_repr.data); } + + BOOST_CONTAINER_FORCEINLINE const long_t *plong_repr() const + { return move_detail::force_ptr<const long_t*>(m_repr.data); } + + BOOST_CONTAINER_FORCEINLINE short_t *pshort_repr() + { return move_detail::force_ptr<short_t*>(m_repr.data); } + + BOOST_CONTAINER_FORCEINLINE long_t *plong_repr() + { return move_detail::force_ptr<long_t*>(m_repr.data); } repr_t m_repr; } members_; - const Allocator &alloc() const + BOOST_CONTAINER_FORCEINLINE const allocator_type &alloc() const { return members_; } - Allocator &alloc() + BOOST_CONTAINER_FORCEINLINE allocator_type &alloc() { return members_; } static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type); @@ -236,7 +255,7 @@ class basic_string_base static const size_type MinAllocation = InternalBufferChars*2; protected: - bool is_short() const + BOOST_CONTAINER_FORCEINLINE bool is_short() const { //Access and copy (to avoid UB) the first byte of the union to know if the //active representation is short or long @@ -246,36 +265,55 @@ class basic_string_base return hdr.is_short != 0; } - void is_short(bool yes) + BOOST_CONTAINER_FORCEINLINE short_t *construct_short() { - const bool was_short = this->is_short(); - if(yes && !was_short){ - allocator_traits_type::destroy - ( this->alloc() - , static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r)) - ); - this->members_.m_repr.s.h.is_short = true; - } - else if(!yes && was_short){ - allocator_traits_type::construct - ( this->alloc() - , static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r)) - ); - this->members_.m_repr.s.h.is_short = false; + short_t *ps = ::new(this->members_.m_repr.data) short_t; + ps->h.is_short = 1; + return ps; + } + + BOOST_CONTAINER_FORCEINLINE void destroy_short() + { + BOOST_ASSERT(this->is_short()); + this->members_.pshort_repr()->~short_t(); + } + + short_t *assure_short() + { + if (!this->is_short()){ + this->destroy_long(); + return construct_short(); } + return this->members_.pshort_repr(); } - private: - void init() + BOOST_CONTAINER_FORCEINLINE long_t *construct_long() + { + long_t *pl = ::new(this->members_.m_repr.data) long_t; + //is_short flag is written in the constructor + return pl; + } + + BOOST_CONTAINER_FORCEINLINE void destroy_long() { - this->members_.m_repr.s.h.is_short = 1; - this->members_.m_repr.s.h.length = 0; + BOOST_ASSERT(!this->is_short()); + this->members_.plong_repr()->~long_t(); + } + + long_t *assure_long() + { + if (this->is_short()){ + this->destroy_short(); + return this->construct_long(); + } + return this->members_.plong_repr(); } + protected: typedef dtl::integral_constant<unsigned, - boost::container::dtl::version<Allocator>::value> alloc_version; + boost::container::dtl::version<allocator_type>::value> alloc_version; pointer allocation_command(allocation_type command, size_type limit_size, @@ -286,7 +324,7 @@ class basic_string_base reuse = 0; command &= ~(expand_fwd | expand_bwd); } - return dtl::allocator_version_traits<Allocator>::allocation_command + return dtl::allocator_version_traits<allocator_type>::allocation_command (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse); } @@ -302,7 +340,7 @@ class basic_string_base this->alloc().deallocate(p, n); } - void construct(pointer p, const value_type &value = value_type()) + BOOST_CONTAINER_FORCEINLINE void construct(pointer p, const value_type &value = value_type()) { allocator_traits_type::construct ( this->alloc() @@ -319,7 +357,7 @@ class basic_string_base } } - void destroy(pointer p) + BOOST_CONTAINER_FORCEINLINE void destroy(pointer p) { allocator_traits_type::destroy ( this->alloc() @@ -334,7 +372,8 @@ class basic_string_base size_type new_cap = this->next_capacity(n); pointer reuse = 0; pointer p = this->allocation_command(allocate_new, n, new_cap, reuse); - this->is_short(false); + BOOST_ASSERT(this->is_short()); + this->construct_long(); this->priv_long_addr(p); this->priv_long_size(0); this->priv_storage(new_cap); @@ -345,23 +384,29 @@ class basic_string_base } } - void deallocate_block() + BOOST_CONTAINER_FORCEINLINE void deallocate_block() { this->deallocate(this->priv_addr(), this->priv_storage()); } - size_type max_size() const + BOOST_CONTAINER_FORCEINLINE size_type max_size() const { return allocator_traits_type::max_size(this->alloc()) - 1; } protected: - size_type priv_capacity() const + BOOST_CONTAINER_FORCEINLINE size_type priv_capacity() const { return this->priv_storage() - 1; } - pointer priv_short_addr() const - { return pointer_traits::pointer_to(const_cast<value_type&>(this->members_.m_repr.short_repr().data[0])); } + BOOST_CONTAINER_FORCEINLINE pointer priv_short_addr() const + { return pointer_traits::pointer_to(const_cast<value_type&>(this->members_.pshort_repr()->data[0])); } - pointer priv_long_addr() const - { return this->members_.m_repr.long_repr().start; } + //GCC seems a bit confused about uninitialized accesses + #if defined(BOOST_GCC) && (BOOST_GCC >= 40700) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + #endif + + BOOST_CONTAINER_FORCEINLINE pointer priv_long_addr() const + { return this->members_.plong_repr()->start; } - pointer priv_addr() const + BOOST_CONTAINER_FORCEINLINE pointer priv_addr() const { return this->is_short() ? priv_short_addr() @@ -369,47 +414,47 @@ class basic_string_base ; } - pointer priv_end_addr() const + BOOST_CONTAINER_FORCEINLINE pointer priv_end_addr() const { return this->is_short() - ? this->priv_short_addr() + this->priv_short_size() - : this->priv_long_addr() + this->priv_long_size() + ? this->priv_short_addr() + difference_type(this->priv_short_size()) + : this->priv_long_addr() + difference_type(this->priv_long_size()) ; } - void priv_long_addr(pointer addr) - { this->members_.m_repr.long_repr().start = addr; } + BOOST_CONTAINER_FORCEINLINE void priv_long_addr(pointer addr) + { this->members_.plong_repr()->start = addr; } - size_type priv_storage() const + BOOST_CONTAINER_FORCEINLINE size_type priv_storage() const { return this->is_short() ? priv_short_storage() : priv_long_storage(); } - size_type priv_short_storage() const + BOOST_CONTAINER_FORCEINLINE size_type priv_short_storage() const { return InternalBufferChars; } - size_type priv_long_storage() const - { return this->members_.m_repr.long_repr().storage; } + BOOST_CONTAINER_FORCEINLINE size_type priv_long_storage() const + { return this->members_.plong_repr()->storage; } - void priv_storage(size_type storage) + BOOST_CONTAINER_FORCEINLINE void priv_storage(size_type storage) { if(!this->is_short()) this->priv_long_storage(storage); } - void priv_long_storage(size_type storage) + BOOST_CONTAINER_FORCEINLINE void priv_long_storage(size_type storage) { - this->members_.m_repr.long_repr().storage = storage; + this->members_.plong_repr()->storage = storage; } - size_type priv_size() const + BOOST_CONTAINER_FORCEINLINE size_type priv_size() const { return this->is_short() ? this->priv_short_size() : this->priv_long_size(); } - size_type priv_short_size() const - { return this->members_.m_repr.short_repr().h.length; } + BOOST_CONTAINER_FORCEINLINE size_type priv_short_size() const + { return this->members_.pshort_repr()->h.length; } - size_type priv_long_size() const - { return this->members_.m_repr.long_repr().length; } + BOOST_CONTAINER_FORCEINLINE size_type priv_long_size() const + { return this->members_.plong_repr()->length; } - void priv_size(size_type sz) + BOOST_CONTAINER_FORCEINLINE void priv_size(size_type sz) { if(this->is_short()) this->priv_short_size(sz); @@ -417,15 +462,25 @@ class basic_string_base this->priv_long_size(sz); } - void priv_short_size(size_type sz) + BOOST_CONTAINER_FORCEINLINE void priv_short_size(size_type sz) { - this->members_.m_repr.s.h.length = (unsigned char)sz; + typedef unsigned char uchar_type; + static const uchar_type mask = uchar_type(uchar_type(-1) >> 1U); + BOOST_ASSERT( sz <= mask ); + //Make -Wconversion happy + this->members_.pshort_repr()->h.length = uchar_type(uchar_type(sz) & mask); } - void priv_long_size(size_type sz) + BOOST_CONTAINER_FORCEINLINE void priv_long_size(size_type sz) { - this->members_.m_repr.long_repr().length = sz; + static const size_type mask = size_type(-1) >> 1U; + BOOST_ASSERT( sz <= mask ); + //Make -Wconversion happy + this->members_.plong_repr()->length = sz & mask; } + #if defined(BOOST_GCC) && (BOOST_GCC >= 40700) + #pragma GCC diagnostic pop + #endif void swap_data(basic_string_base& other) { @@ -436,23 +491,23 @@ class basic_string_base other.members_.m_repr = tmp; } else{ - short_t short_backup(this->members_.m_repr.short_repr()); - this->members_.m_repr.short_repr().~short_t(); - ::new(&this->members_.m_repr.long_repr()) long_t(other.members_.m_repr.long_repr()); - other.members_.m_repr.long_repr().~long_t(); - ::new(&other.members_.m_repr.short_repr()) short_t(short_backup); + short_t short_backup(*this->members_.pshort_repr()); + this->members_.pshort_repr()->~short_t(); + ::new(this->members_.plong_repr()) long_t(*other.members_.plong_repr()); + other.members_.plong_repr()->~long_t(); + ::new(other.members_.pshort_repr()) short_t(short_backup); } } else{ if(other.is_short()){ - short_t short_backup(other.members_.m_repr.short_repr()); - other.members_.m_repr.short_repr().~short_t(); - ::new(&other.members_.m_repr.long_repr()) long_t(this->members_.m_repr.long_repr()); - this->members_.m_repr.long_repr().~long_t(); - ::new(&this->members_.m_repr.short_repr()) short_t(short_backup); + short_t short_backup(*other.members_.pshort_repr()); + other.members_.pshort_repr()->~short_t(); + ::new(other.members_.plong_repr()) long_t(*this->members_.plong_repr()); + this->members_.plong_repr()->~long_t(); + ::new(this->members_.pshort_repr()) short_t(short_backup); } else{ - boost::adl_move_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr()); + boost::adl_move_swap(*this->members_.plong_repr(), *other.members_.plong_repr()); } } } @@ -495,18 +550,18 @@ class basic_string_base //! \tparam Traits The Character Traits type, which encapsulates basic character operations //! \tparam Allocator The allocator, used for internal memory management. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED -template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = new_allocator<CharT> > +template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = void > #else template <class CharT, class Traits, class Allocator> #endif class basic_string - : private dtl::basic_string_base<Allocator> + : private dtl::basic_string_base<typename real_allocator<CharT, Allocator>::type> { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: - typedef allocator_traits<Allocator> allocator_traits_type; BOOST_COPYABLE_AND_MOVABLE(basic_string) - typedef dtl::basic_string_base<Allocator> base_t; + typedef dtl::basic_string_base<typename real_allocator<CharT, Allocator>::type> base_t; + typedef typename base_t::allocator_traits_type allocator_traits_type; static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars; protected: @@ -553,13 +608,13 @@ class basic_string ////////////////////////////////////////////// typedef Traits traits_type; typedef CharT value_type; - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits<Allocator>::reference reference; - typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference; - typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type; - typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type; - typedef Allocator allocator_type; + typedef typename real_allocator<CharT, Allocator>::type allocator_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer; + typedef typename ::boost::container::allocator_traits<allocator_type>::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits<allocator_type>::reference reference; + typedef typename ::boost::container::allocator_traits<allocator_type>::const_reference const_reference; + typedef typename ::boost::container::allocator_traits<allocator_type>::size_type size_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::difference_type difference_type; typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; typedef BOOST_CONTAINER_IMPDEF(pointer) iterator; typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator; @@ -569,7 +624,7 @@ class basic_string #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: - typedef constant_iterator<CharT, difference_type> cvalue_iterator; + typedef constant_iterator<CharT> cvalue_iterator; typedef typename base_t::alloc_version alloc_version; typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -596,7 +651,7 @@ class basic_string //! <b>Effects</b>: Default constructs a basic_string. //! //! <b>Throws</b>: If allocator_type's default constructor throws. - basic_string() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value) + basic_string() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value) : base_t() { this->priv_terminate_string(); } @@ -624,7 +679,7 @@ class basic_string //! //! <b>Throws</b>: If allocator_type's default constructor or allocation throws. template<template <class, class> class BasicStringView> - explicit basic_string(BasicStringView<CharT, Traits> sv, const Allocator& a = Allocator()) + explicit basic_string(BasicStringView<CharT, Traits> sv, const allocator_type& a = allocator_type()) : base_t(allocator_traits_type::select_on_container_copy_construction(a)) { this->priv_terminate_string(); @@ -669,7 +724,7 @@ class basic_string : base_t(a) { this->priv_terminate_string(); - if(a == this->alloc()){ + if(s.alloc() == this->alloc()){ this->swap_data(s); } else{ @@ -709,7 +764,7 @@ class basic_string : base_t() { this->priv_terminate_string(); - this->assign(s, s + n); + this->assign(s, s + difference_type(n)); } //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter, @@ -718,7 +773,7 @@ class basic_string : base_t(a) { this->priv_terminate_string(); - this->assign(s, s + n); + this->assign(s, s + difference_type(n)); } //! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator, @@ -822,7 +877,7 @@ class basic_string //! <b>Complexity</b>: Linear to the elements x contains. basic_string& operator=(BOOST_COPY_ASSIGN_REF(basic_string) x) { - if (&x != this){ + if (BOOST_LIKELY(this != &x)) { allocator_type &this_alloc = this->alloc(); const allocator_type &x_alloc = x.alloc(); dtl::bool_<allocator_traits_type:: @@ -830,7 +885,7 @@ class basic_string if(flag && this_alloc != x_alloc){ if(!this->is_short()){ this->deallocate_block(); - this->is_short(true); + this->assure_short(); Traits::assign(*this->priv_addr(), CharT(0)); this->priv_short_size(0); } @@ -853,27 +908,27 @@ class basic_string BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value || allocator_traits_type::is_always_equal::value) { - //for move constructor, no aliasing (&x != this) is assummed. - BOOST_ASSERT(this != &x); - allocator_type &this_alloc = this->alloc(); - allocator_type &x_alloc = x.alloc(); - const bool propagate_alloc = allocator_traits_type:: - propagate_on_container_move_assignment::value; - dtl::bool_<propagate_alloc> flag; - const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; - //Resources can be transferred if both allocators are - //going to be equal after this function (either propagated or already equal) - if(propagate_alloc || allocators_equal){ - //Destroy objects but retain memory in case x reuses it in the future - this->clear(); - //Move allocator if needed - dtl::move_alloc(this_alloc, x_alloc, flag); - //Nothrow swap - this->swap_data(x); - } - //Else do a one by one move - else{ - this->assign( x.begin(), x.end()); + if (BOOST_LIKELY(this != &x)) { + allocator_type &this_alloc = this->alloc(); + allocator_type &x_alloc = x.alloc(); + const bool propagate_alloc = allocator_traits_type:: + propagate_on_container_move_assignment::value; + dtl::bool_<propagate_alloc> flag; + const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; + //Resources can be transferred if both allocators are + //going to be equal after this function (either propagated or already equal) + if(propagate_alloc || allocators_equal){ + //Destroy objects but retain memory in case x reuses it in the future + this->clear(); + //Move allocator if needed + dtl::move_alloc(this_alloc, x_alloc, flag); + //Nothrow swap + this->swap_data(x); + } + //Else do a one by one move + else{ + this->assign( x.begin(), x.end()); + } } return *this; } @@ -908,7 +963,8 @@ class basic_string //! <b>Throws</b>: If allocator's copy constructor throws. //! //! <b>Complexity</b>: Constant. - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW { return this->alloc(); } //! <b>Effects</b>: Returns a reference to the internal allocator. @@ -918,7 +974,8 @@ class basic_string //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Non-standard extension. - stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW { return this->alloc(); } //! <b>Effects</b>: Returns a reference to the internal allocator. @@ -928,7 +985,8 @@ class basic_string //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW { return this->alloc(); } ////////////////////////////////////////////// @@ -942,7 +1000,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - iterator begin() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + iterator begin() BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_addr(); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector. @@ -950,7 +1009,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_addr(); } //! <b>Effects</b>: Returns an iterator to the end of the vector. @@ -958,7 +1018,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - iterator end() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + iterator end() BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_end_addr(); } //! <b>Effects</b>: Returns a const_iterator to the end of the vector. @@ -966,7 +1027,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_end_addr(); } //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning @@ -975,7 +1037,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW { return reverse_iterator(this->priv_end_addr()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning @@ -984,7 +1047,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW { return this->crbegin(); } //! <b>Effects</b>: Returns a reverse_iterator pointing to the end @@ -993,7 +1057,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW { return reverse_iterator(this->priv_addr()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end @@ -1002,7 +1067,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW { return this->crend(); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector. @@ -1010,7 +1076,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_addr(); } //! <b>Effects</b>: Returns a const_iterator to the end of the vector. @@ -1018,7 +1085,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_end_addr(); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning @@ -1027,7 +1095,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW { return const_reverse_iterator(this->priv_end_addr()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end @@ -1036,7 +1105,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW { return const_reverse_iterator(this->priv_addr()); } ////////////////////////////////////////////// @@ -1050,7 +1120,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - bool empty() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + bool empty() const BOOST_NOEXCEPT_OR_NOTHROW { return !this->priv_size(); } //! <b>Effects</b>: Returns the number of the elements contained in the vector. @@ -1058,7 +1129,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - size_type size() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type size() const BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_size(); } //! <b>Effects</b>: Returns the number of the elements contained in the vector. @@ -1066,15 +1138,17 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - size_type length() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type length() const BOOST_NOEXCEPT_OR_NOTHROW { return this->size(); } //! <b>Effects</b>: Returns the largest possible size of the vector. //! //! <b>Throws</b>: Nothing. //! - //! <b>Complexity</b>: Constant. - size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + //! <b>Complexity</b>: Constant + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW { return base_t::max_size(); } //! <b>Effects</b>: Inserts or erases elements at the end such that @@ -1086,7 +1160,7 @@ class basic_string void resize(size_type n, CharT c) { if (n <= this->size()) - this->erase(this->begin() + n, this->end()); + this->erase(this->begin() + difference_type(n), this->end()); else this->append(n - this->size(), c); } @@ -1100,7 +1174,6 @@ class basic_string void resize(size_type n) { resize(n, CharT()); } - //! <b>Effects</b>: Inserts or erases elements at the end such that //! the size becomes n. New elements are uninitialized. //! @@ -1112,7 +1185,7 @@ class basic_string void resize(size_type n, default_init_t) { if (n <= this->size()) - this->erase(this->begin() + n, this->end()); + this->erase(this->begin() + difference_type(n), this->end()); else{ this->priv_reserve(n, false); this->priv_size(n); @@ -1126,7 +1199,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_capacity(); } //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no @@ -1159,7 +1233,9 @@ class basic_string Traits::copy( boost::movelib::to_raw_pointer(this->priv_short_addr()) , boost::movelib::to_raw_pointer(long_addr) , long_size+1); - this->is_short(true); + BOOST_ASSERT(!this->is_short()); + this->destroy_long(); + this->construct_short(); this->alloc().deallocate(long_addr, long_storage); } else{ @@ -1183,7 +1259,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference front() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reference front() BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); return *this->priv_addr(); @@ -1197,7 +1274,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); return *this->priv_addr(); @@ -1211,7 +1289,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference back() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reference back() BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); return *(this->priv_addr() + (this->size() - 1u) ); @@ -1225,7 +1304,8 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); return *(this->priv_addr() + (this->size() - 1u) ); @@ -1239,10 +1319,11 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(this->size() > n); - return *(this->priv_addr() + n); + return *(this->priv_addr() + difference_type(n)); } //! <b>Requires</b>: size() > n. @@ -1253,10 +1334,11 @@ class basic_string //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(this->size() > n); - return *(this->priv_addr() + n); + return *(this->priv_addr() + difference_type(n)); } //! <b>Requires</b>: size() > n. @@ -1264,14 +1346,15 @@ class basic_string //! <b>Effects</b>: Returns a reference to the nth element //! from the beginning of the container. //! - //! <b>Throws</b>: std::range_error if n >= size() + //! <b>Throws</b>: range_error if n >= size() //! //! <b>Complexity</b>: Constant. - reference at(size_type n) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reference at(size_type n) { if (n >= this->size()) throw_out_of_range("basic_string::at invalid subscript"); - return *(this->priv_addr() + n); + return *(this->priv_addr() + difference_type(n)); } //! <b>Requires</b>: size() > n. @@ -1279,13 +1362,14 @@ class basic_string //! <b>Effects</b>: Returns a const reference to the nth element //! from the beginning of the container. //! - //! <b>Throws</b>: std::range_error if n >= size() + //! <b>Throws</b>: range_error if n >= size() //! //! <b>Complexity</b>: Constant. - const_reference at(size_type n) const { + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reference at(size_type n) const { if (n >= this->size()) throw_out_of_range("basic_string::at invalid subscript"); - return *(this->priv_addr() + n); + return *(this->priv_addr() + difference_type(n)); } ////////////////////////////////////////////// @@ -1368,7 +1452,7 @@ class basic_string //! //! <b>Returns</b>: *this basic_string& append(const CharT* s, size_type n) - { return this->append(s, s + n); } + { return this->append(s, s + difference_type(n)); } //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT. //! @@ -1409,9 +1493,9 @@ class basic_string const size_type old_size = this->priv_size(); if (old_size < this->capacity()){ const pointer addr = this->priv_addr(); - this->priv_construct_null(addr + old_size + 1); - Traits::assign(addr[old_size], c); - this->priv_size(old_size+1); + this->priv_construct_null(addr + difference_type(old_size + 1u)); + Traits::assign(addr[difference_type(old_size)], c); + this->priv_size(old_size+1u); } else{ //No enough memory, insert a new object at the end @@ -1467,7 +1551,7 @@ class basic_string //! //! <b>Returns</b>: *this basic_string& assign(const CharT* s, size_type n) - { return this->assign(s, s + n); } + { return this->assign(s, s + difference_type(n)); } //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT. //! @@ -1492,7 +1576,7 @@ class basic_string this->reserve(n); CharT* ptr = boost::movelib::to_raw_pointer(this->priv_addr()); Traits::copy(ptr, first, n); - this->priv_construct_null(ptr + n); + this->priv_construct_null(ptr + difference_type(n)); this->priv_size(n); return *this; } @@ -1518,7 +1602,7 @@ class basic_string ++ptr; } if (first == last) - this->erase(addr + cur, addr + old_size); + this->erase(addr + difference_type(cur), addr + difference_type(old_size)); else this->append(first, last); return *this; @@ -1591,7 +1675,7 @@ class basic_string throw_out_of_range("basic_string::insert out of range position"); if (this->size() > this->max_size() - n) throw_length_error("basic_string::insert max_size() exceeded"); - this->insert(this->priv_addr() + pos, s, s + n); + this->insert(this->priv_addr() + pos, s, s + difference_type(n)); return *this; } @@ -1643,7 +1727,7 @@ class basic_string //! <b>Returns</b>: An iterator which refers to the copy of the inserted character. iterator insert(const_iterator p, CharT c) { - size_type new_offset = p - this->priv_addr(); + size_type new_offset = size_type(p - this->priv_addr()); this->insert(p, cvalue_iterator(c, 1), cvalue_iterator()); return this->priv_addr() + new_offset; } @@ -1676,7 +1760,7 @@ class basic_string for ( ; first != last; ++first, ++p) { p = this->insert(p, *first); } - return this->begin() + n_pos; + return this->begin() + difference_type(n_pos); } #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1689,9 +1773,9 @@ class basic_string >::type * = 0 ) { - const size_type n_pos = p - this->cbegin(); + const size_type n_pos = size_type(p - this->cbegin()); if (first != last) { - const size_type n = boost::container::iterator_distance(first, last); + const size_type n = boost::container::iterator_udistance(first, last); const size_type old_size = this->priv_size(); const size_type remaining = this->capacity() - old_size; const pointer old_start = this->priv_addr(); @@ -1709,7 +1793,7 @@ class basic_string new_cap = this->next_capacity(n); hint = old_start; allocation_ret = this->allocation_command - (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint); + (allocate_new | expand_fwd | expand_bwd, old_size + n + 1u, new_cap, hint); //Check forward expansion if(old_start == allocation_ret){ @@ -1720,32 +1804,35 @@ class basic_string //Reuse same buffer if(enough_capacity){ - const size_type elems_after = old_size - (p - old_start); + const size_type elems_after = old_size - size_type(p - old_start); const size_type old_length = old_size; + size_type new_size = 0; if (elems_after >= n) { - const pointer pointer_past_last = old_start + old_size + 1; - priv_uninitialized_copy(old_start + (old_size - n + 1), + const pointer pointer_past_last = old_start + difference_type(old_size + 1u); + priv_uninitialized_copy(old_start + difference_type(old_size - n + 1u), pointer_past_last, pointer_past_last); - this->priv_size(old_size+n); - Traits::move(const_cast<CharT*>(boost::movelib::to_raw_pointer(p + n)), + Traits::move(const_cast<CharT*>(boost::movelib::to_raw_pointer(p + difference_type(n))), boost::movelib::to_raw_pointer(p), - (elems_after - n) + 1); - this->priv_copy(first, last, const_cast<CharT*>(boost::movelib::to_raw_pointer(p))); + (elems_after - n) + 1u); + (priv_copy)(first, last, const_cast<CharT*>(boost::movelib::to_raw_pointer(p))); + new_size = old_size + n; } else { ForwardIter mid = first; - boost::container::iterator_advance(mid, elems_after + 1); + boost::container::iterator_uadvance(mid, elems_after + 1u); - priv_uninitialized_copy(mid, last, old_start + old_size + 1); + priv_uninitialized_copy(mid, last, old_start + difference_type(old_size + 1u)); const size_type newer_size = old_size + (n - elems_after); this->priv_size(newer_size); priv_uninitialized_copy - (p, const_iterator(old_start + old_length + 1), - old_start + newer_size); - this->priv_size(newer_size + elems_after); - this->priv_copy(first, mid, const_cast<CharT*>(boost::movelib::to_raw_pointer(p))); + (p, const_iterator(old_start + difference_type(old_length + 1u)), + old_start + difference_type(newer_size)); + (priv_copy)(first, mid, const_cast<CharT*>(boost::movelib::to_raw_pointer(p))); + new_size = newer_size + elems_after; } + this->priv_size(new_size); + this->priv_construct_null(old_start + difference_type(new_size)); } else{ pointer new_start = allocation_ret; @@ -1756,14 +1843,14 @@ class basic_string new_length += priv_uninitialized_copy (const_iterator(old_start), p, new_start); new_length += priv_uninitialized_copy - (first, last, new_start + new_length); + (first, last, new_start + difference_type(new_length)); new_length += priv_uninitialized_copy - (p, const_iterator(old_start + old_size), - new_start + new_length); - this->priv_construct_null(new_start + new_length); + (p, const_iterator(old_start + difference_type(old_size)), + new_start + difference_type(new_length)); + this->priv_construct_null(new_start + difference_type(new_length)); this->deallocate_block(); - this->is_short(false); + this->assure_long(); this->priv_long_addr(new_start); this->priv_long_size(new_length); this->priv_long_storage(new_cap); @@ -1774,22 +1861,22 @@ class basic_string value_type * const oldbuf = boost::movelib::to_raw_pointer(old_start); value_type * const newbuf = boost::movelib::to_raw_pointer(new_start); const value_type *const pos = boost::movelib::to_raw_pointer(p); - const size_type before = pos - oldbuf; + const size_type before = size_type(pos - oldbuf); //First move old data Traits::move(newbuf, oldbuf, before); - Traits::move(newbuf + before + n, pos, old_size - before); + Traits::move(newbuf + difference_type(before + n), pos, old_size - before); //Now initialize the new data - priv_uninitialized_copy(first, last, new_start + before); - this->priv_construct_null(new_start + (old_size + n)); - this->is_short(false); + priv_uninitialized_copy(first, last, new_start + difference_type(before)); + this->priv_construct_null(new_start + difference_type(old_size + n)); + this->assure_long(); this->priv_long_addr(new_start); this->priv_long_size(old_size + n); this->priv_long_storage(new_cap); } } } - return this->begin() + n_pos; + return this->begin() + difference_type(n_pos); } #endif @@ -1798,7 +1885,7 @@ class basic_string //! //! <b>Returns</b>: An iterator which refers to the copy of the first inserted //! character, or p if i1 is empty. - iterator insert(const_iterator p, std::initializer_list<CharT> il) + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, std::initializer_list<CharT> il) { return this->insert(p, il.begin(), il.end()); } @@ -1832,7 +1919,7 @@ class basic_string if (pos > this->size()) throw_out_of_range("basic_string::erase out of range position"); const pointer addr = this->priv_addr(); - erase(addr + pos, addr + pos + dtl::min_value(n, this->size() - pos)); + erase(addr + difference_type(pos), addr + difference_type(pos) + dtl::min_value(n, this->size() - pos)); return *this; } @@ -1849,8 +1936,8 @@ class basic_string const size_type old_size = this->priv_size(); Traits::move(ptr, boost::movelib::to_raw_pointer(p + 1), - old_size - (p - this->priv_addr())); - this->priv_size(old_size-1); + old_size - size_type(p - this->priv_addr())); + this->priv_size(old_size-1u); return iterator(ptr); } @@ -1866,11 +1953,11 @@ class basic_string { CharT * f = const_cast<CharT*>(boost::movelib::to_raw_pointer(first)); if (first != last) { // The move includes the terminating null. - const size_type num_erased = last - first; + const size_type num_erased = size_type(last - first); const size_type old_size = this->priv_size(); Traits::move(f, boost::movelib::to_raw_pointer(last), - (old_size + 1)-(last - this->priv_addr())); + old_size + 1u - size_type(last - this->priv_addr())); const size_type new_length = old_size - num_erased; this->priv_size(new_length); } @@ -1884,10 +1971,14 @@ class basic_string //! <b>Complexity</b>: Linear to the number of elements in the vector. void clear() BOOST_NOEXCEPT_OR_NOTHROW { - if (!this->empty()) { - Traits::assign(*this->priv_addr(), CharT(0)); - this->priv_size(0); - } + if(this->is_short()) { + Traits::assign(*this->priv_short_addr(), CharT(0)); + this->priv_short_size(0); + } + else { + Traits::assign(*this->priv_long_addr(), CharT(0)); + this->priv_long_size(0); + } } //! <b>Requires</b>: pos1 <= size(). @@ -1905,15 +1996,15 @@ class basic_string if (this->size() - len >= this->max_size() - str.size()) throw_length_error("basic_string::replace max_size() exceeded"); const pointer addr = this->priv_addr(); - return this->replace( const_iterator(addr + pos1) - , const_iterator(addr + pos1 + len) + return this->replace( const_iterator(addr + difference_type(pos1)) + , const_iterator(addr + difference_type(pos1 + len)) , str.begin(), str.end()); } //! <b>Effects</b>: Calls `return replace(pos1, n1, sv.data(), sv.size());`. //! template<template<class, class> class BasicStringView> - basic_string& replace(size_type pos1, size_type n1, BasicStringView<CharT, Traits> sv) + BOOST_CONTAINER_FORCEINLINE basic_string& replace(size_type pos1, size_type n1, BasicStringView<CharT, Traits> sv) { return this->replace(pos1, n1, sv.data(), sv.size()); } @@ -1969,11 +2060,11 @@ class basic_string if (pos1 > this->size()) throw_out_of_range("basic_string::replace out of range position"); const size_type len = dtl::min_value(n1, this->size() - pos1); - const size_type max_size = this->max_size(); - if (n2 > max_size || (this->size() - len) >= (max_size - n2)) + const size_type max_sz = this->max_size(); + if (n2 > max_sz || (this->size() - len) >= (max_sz - n2)) throw_length_error("basic_string::replace max_size() exceeded"); const pointer addr = this->priv_addr() + pos1; - return this->replace(addr, addr + len, s, s + n2); + return this->replace(addr, addr + difference_type(len), s, s + difference_type(n2)); } //! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT. @@ -1990,7 +2081,7 @@ class basic_string //! if the length of the resulting string would exceed max_size() //! //! <b>Returns</b>: *this - basic_string& replace(size_type pos, size_type n1, const CharT* s) + BOOST_CONTAINER_FORCEINLINE basic_string& replace(size_type pos, size_type n1, const CharT* s) { return this->replace(pos, n1, s, Traits::length(s)); } @@ -2011,7 +2102,7 @@ class basic_string if (n2 > this->max_size() || this->size() - len >= this->max_size() - n2) throw_length_error("basic_string::replace max_size() exceeded"); const pointer addr = this->priv_addr(); - return this->replace(addr + pos1, addr + pos1 + len, n2, c); + return this->replace(addr + difference_type(pos1), addr + difference_type(pos1 + len), n2, c); } //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges. @@ -2021,7 +2112,7 @@ class basic_string //! <b>Throws</b>: if memory allocation throws //! //! <b>Returns</b>: *this - basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str) + BOOST_CONTAINER_FORCEINLINE basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str) { return this->replace(i1, i2, str.data(), str.data()+str.size()); } //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and @@ -2032,8 +2123,8 @@ class basic_string //! <b>Throws</b>: if memory allocation throws //! //! <b>Returns</b>: *this - basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s, size_type n) - { return this->replace(i1, i2, s, s + n); } + BOOST_CONTAINER_FORCEINLINE basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s, size_type n) + { return this->replace(i1, i2, s, s + difference_type(n)); } //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and s points to an //! array of at least traits::length(s) + 1 elements of CharT. @@ -2043,7 +2134,7 @@ class basic_string //! <b>Throws</b>: if memory allocation throws //! //! <b>Returns</b>: *this - basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s) + BOOST_CONTAINER_FORCEINLINE basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s) { return this->replace(i1, i2, s, s + Traits::length(s)); } //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges. @@ -2058,7 +2149,7 @@ class basic_string const size_type len = static_cast<size_type>(i2 - i1); if (len >= n) { Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), n, c); - erase(i1 + n, i2); + erase(i1 + difference_type(n), i2); } else { Traits::assign(const_cast<CharT*>(boost::movelib::to_raw_pointer(i1)), len, c); @@ -2110,7 +2201,7 @@ class basic_string const difference_type len = i2 - i1; if (len >= n) { this->priv_copy(j1, j2, const_cast<CharT*>(boost::movelib::to_raw_pointer(i1))); - this->erase(i1 + n, i2); + this->erase(i1 + difference_type(n), i2); } else { ForwardIter m = j1; @@ -2128,7 +2219,7 @@ class basic_string //! //! <b>Returns</b>: *this. template<template <class, class> class BasicStringView> - basic_string& replace(const_iterator i1, const_iterator i2, BasicStringView<CharT, Traits> sv) + BOOST_CONTAINER_FORCEINLINE basic_string& replace(const_iterator i1, const_iterator i2, BasicStringView<CharT, Traits> sv) { return this->replace( static_cast<size_type>(i1 - this->cbegin()) , static_cast<size_type>(i2 - i1), sv); @@ -2140,7 +2231,7 @@ class basic_string //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, il.begin(), il.size()). //! //! <b>Returns</b>: *this. - basic_string& replace(const_iterator i1, const_iterator i2, std::initializer_list<CharT> il) + BOOST_CONTAINER_FORCEINLINE basic_string& replace(const_iterator i1, const_iterator i2, std::initializer_list<CharT> il) { return this->replace( static_cast<size_type>(i1 - this->cbegin()) , static_cast<size_type>(i2 - i1) @@ -2192,7 +2283,8 @@ class basic_string //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()]. //! //! <b>Complexity</b>: constant time. - const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW { return boost::movelib::to_raw_pointer(this->priv_addr()); } //! <b>Requires</b>: The program shall not alter any of the values stored in the character array. @@ -2200,13 +2292,15 @@ class basic_string //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()]. //! //! <b>Complexity</b>: constant time. - const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW { return boost::movelib::to_raw_pointer(this->priv_addr()); } //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()]. //! //! <b>Complexity</b>: constant time. - CharT* data() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + CharT* data() BOOST_NOEXCEPT_OR_NOTHROW { return boost::movelib::to_raw_pointer(this->priv_addr()); } #ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN @@ -2214,7 +2308,7 @@ class basic_string //! //! <b>Complexity</b>: constant time. template<template <class, class> class BasicStringView> - operator BasicStringView<CharT, Traits>() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE operator BasicStringView<CharT, Traits>() const BOOST_NOEXCEPT_OR_NOTHROW { return this->to_view< BasicStringView<CharT, Traits> >(); } #endif @@ -2225,7 +2319,8 @@ class basic_string //! <b>Note</b>: This function is available to write portable code for compilers //! that don't support templated conversion operators. template<class BasicStringView> - BasicStringView to_view() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + BasicStringView to_view() const BOOST_NOEXCEPT_OR_NOTHROW { return BasicStringView(this->data(), this->size()); } ////////////////////////////////////////////// @@ -2242,7 +2337,8 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. - size_type find(const basic_string& s, size_type pos = 0) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find(const basic_string& s, size_type pos = 0) const { return find(s.c_str(), pos, s.size()); } //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both @@ -2254,26 +2350,28 @@ class basic_string //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. template<template <class, class> class BasicStringView> - size_type find(BasicStringView<CharT, Traits> sv, size_type pos = 0) const - { return find(sv.data(), pos, sv.size()); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find(BasicStringView<CharT, Traits> sv, size_type pos = 0) const + { return this->find(sv.data(), pos, sv.size()); } //! <b>Requires</b>: s points to an array of at least n elements of CharT. //! //! <b>Throws</b>: Nothing //! - //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(s,n),pos). - size_type find(const CharT* s, size_type pos, size_type n) const + //! <b>Returns</b>: find(basic_string<CharT,traits,allocator_type>(s,n),pos). + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find(const CharT* s, size_type pos, size_type n) const { if (pos + n > this->size()) return npos; else { const pointer addr = this->priv_addr(); - pointer finish = addr + this->priv_size(); + pointer finish = addr + difference_type(this->priv_size()); const const_iterator result = - boost::container::search(boost::movelib::to_raw_pointer(addr + pos), + boost::container::search(boost::movelib::to_raw_pointer(addr + difference_type(pos)), boost::movelib::to_raw_pointer(finish), - s, s + n, Eq_traits<Traits>()); - return result != finish ? result - begin() : npos; + s, s + difference_type(n), Eq_traits<Traits>()); + return result != finish ? size_type(result - begin()) : npos; } } @@ -2282,24 +2380,26 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find(basic_string(s), pos). - size_type find(const CharT* s, size_type pos = 0) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find(const CharT* s, size_type pos = 0) const { return this->find(s, pos, Traits::length(s)); } //! <b>Throws</b>: Nothing //! - //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(1,c), pos). - size_type find(CharT c, size_type pos = 0) const + //! <b>Returns</b>: find(basic_string<CharT,traits,allocator_type>(1,c), pos). + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find(CharT c, size_type pos = 0) const { const size_type sz = this->size(); if (pos >= sz) return npos; else { const pointer addr = this->priv_addr(); - pointer finish = addr + sz; + pointer finish = addr + difference_type(sz); const const_iterator result = - boost::container::find_if(addr + pos, finish, + boost::container::find_if(addr + difference_type(pos), finish, boost::container::bind2nd(Eq_traits<Traits>(), c)); - return result != finish ? result - begin() : npos; + return result != finish ? size_type(result - begin()) : npos; } } @@ -2311,8 +2411,9 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. - size_type rfind(const basic_string& str, size_type pos = npos) const - { return rfind(str.c_str(), pos, str.size()); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type rfind(const basic_string& str, size_type pos = npos) const + { return this->rfind(str.c_str(), pos, str.size()); } //! <b>Effects</b>: Determines the highest position xpos, if possible, such //! that both of the following conditions obtain: @@ -2323,15 +2424,17 @@ class basic_string //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. template<template <class, class> class BasicStringView> - size_type rfind(BasicStringView<CharT, Traits> sv, size_type pos = npos) const - { return rfind(sv.data(), pos, sv.size()); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type rfind(BasicStringView<CharT, Traits> sv, size_type pos = npos) const + { return this->rfind(sv.data(), pos, sv.size()); } //! <b>Requires</b>: s points to an array of at least n elements of CharT. //! //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: rfind(basic_string(s, n), pos). - size_type rfind(const CharT* s, size_type pos, size_type n) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type rfind(const CharT* s, size_type pos, size_type n) const { const size_type len = this->size(); @@ -2340,11 +2443,10 @@ class basic_string else if (n == 0) return dtl::min_value(len, pos); else { - const const_iterator last = begin() + dtl::min_value(len - n, pos) + n; - const const_iterator result = find_end(begin(), last, - s, s + n, - Eq_traits<Traits>()); - return result != last ? result - begin() : npos; + const const_iterator last = begin() + difference_type(dtl::min_value(len - n, pos + n)); + const const_iterator result = boost::container::find_end + (begin(), last, s, s + difference_type(n), Eq_traits<Traits>()); + return result != last ? size_type(result - begin()) : npos; } } @@ -2354,13 +2456,15 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: rfind(basic_string(s), pos). - size_type rfind(const CharT* s, size_type pos = npos) const - { return rfind(s, pos, Traits::length(s)); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type rfind(const CharT* s, size_type pos = npos) const + { return this->rfind(s, pos, Traits::length(s)); } //! <b>Throws</b>: Nothing //! - //! <b>Returns</b>: rfind(basic_string<CharT,traits,Allocator>(1,c),pos). - size_type rfind(CharT c, size_type pos = npos) const + //! <b>Returns</b>: rfind(basic_string<CharT,traits,allocator_type>(1,c),pos). + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type rfind(CharT c, size_type pos = npos) const { const size_type len = this->size(); @@ -2371,7 +2475,7 @@ class basic_string const_reverse_iterator rresult = boost::container::find_if(const_reverse_iterator(last), rend(), boost::container::bind2nd(Eq_traits<Traits>(), c)); - return rresult != rend() ? (rresult.base() - 1) - begin() : npos; + return rresult != rend() ? size_type((rresult.base() - 1) - begin()) : npos; } } @@ -2382,7 +2486,8 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. - size_type find_first_of(const basic_string& str, size_type pos = 0) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_of(const basic_string& str, size_type pos = 0) const { return this->find_first_of(str.c_str(), pos, str.size()); } //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both of the @@ -2393,7 +2498,8 @@ class basic_string //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. template<template <class, class> class BasicStringView> - size_type find_first_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const { return this->find_first_of(sv.data(), pos, sv.size()); } //! <b>Requires</b>: s points to an array of at least n elements of CharT. @@ -2401,17 +2507,18 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_first_of(basic_string(s, n), pos). - size_type find_first_of(const CharT* s, size_type pos, size_type n) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_of(const CharT* s, size_type pos, size_type n) const { const size_type sz = this->size(); if (pos >= sz) return npos; else { const pointer addr = this->priv_addr(); - pointer finish = addr + sz; + pointer finish = addr + difference_type(sz); const_iterator result = boost::container::find_first_of - (addr + pos, finish, s, s + n, Eq_traits<Traits>()); - return result != finish ? result - this->begin() : npos; + (addr + difference_type(pos), finish, s, s + difference_type(n), Eq_traits<Traits>()); + return result != finish ? size_type(result - this->begin()) : npos; } } @@ -2420,15 +2527,17 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_first_of(basic_string(s), pos). - size_type find_first_of(const CharT* s, size_type pos = 0) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_of(const CharT* s, size_type pos = 0) const { return this->find_first_of(s, pos, Traits::length(s)); } //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT. //! //! <b>Throws</b>: Nothing //! - //! <b>Returns</b>: find_first_of(basic_string<CharT,traits,Allocator>(1,c), pos). - size_type find_first_of(CharT c, size_type pos = 0) const + //! <b>Returns</b>: find_first_of(basic_string<CharT,traits,allocator_type>(1,c), pos). + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_of(CharT c, size_type pos = 0) const { return this->find(c, pos); } //! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of @@ -2438,7 +2547,8 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. - size_type find_last_of(const basic_string& str, size_type pos = npos) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_of(const basic_string& str, size_type pos = npos) const { return this->find_last_of(str.c_str(), pos, str.size()); } //! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of @@ -2449,7 +2559,8 @@ class basic_string //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. template<template <class, class> class BasicStringView> - size_type find_last_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const { return this->find_last_of(sv.data(), pos, sv.size()); } //! <b>Requires</b>: s points to an array of at least n elements of CharT. @@ -2457,7 +2568,8 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_last_of(basic_string(s, n), pos). - size_type find_last_of(const CharT* s, size_type pos, size_type n) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_of(const CharT* s, size_type pos, size_type n) const { const size_type len = this->size(); @@ -2465,11 +2577,11 @@ class basic_string return npos; else { const pointer addr = this->priv_addr(); - const const_iterator last = addr + dtl::min_value(len - 1, pos) + 1; + const const_iterator last = addr + difference_type(dtl::min_value(len - 1, pos) + 1); const const_reverse_iterator rresult = boost::container::find_first_of(const_reverse_iterator(last), rend(), - s, s + n, Eq_traits<Traits>()); - return rresult != rend() ? (rresult.base() - 1) - addr : npos; + s, s + difference_type(n), Eq_traits<Traits>()); + return rresult != rend() ? size_type((rresult.base() - 1) - addr) : npos; } } @@ -2477,15 +2589,17 @@ class basic_string //! //! <b>Throws</b>: Nothing //! - //! <b>Returns</b>: find_last_of(basic_string<CharT,traits,Allocator>(1,c),pos). - size_type find_last_of(const CharT* s, size_type pos = npos) const - { return find_last_of(s, pos, Traits::length(s)); } + //! <b>Returns</b>: find_last_of(basic_string<CharT,traits,allocator_type>(1,c),pos). + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_of(const CharT* s, size_type pos = npos) const + { return this->find_last_of(s, pos, Traits::length(s)); } //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_last_of(basic_string(s), pos). - size_type find_last_of(CharT c, size_type pos = npos) const - { return rfind(c, pos); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_of(CharT c, size_type pos = npos) const + { return this->rfind(c, pos); } //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that //! both of the following conditions obtain: @@ -2495,8 +2609,9 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. - size_type find_first_not_of(const basic_string& str, size_type pos = 0) const - { return find_first_not_of(str.c_str(), pos, str.size()); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_not_of(const basic_string& str, size_type pos = 0) const + { return this->find_first_not_of(str.c_str(), pos, str.size()); } //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that //! both of the following conditions obtain: @@ -2507,24 +2622,26 @@ class basic_string //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. template<template <class, class> class BasicStringView> - size_type find_first_not_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const - { return find_first_not_of(sv.data(), pos, sv.size()); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_not_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const + { return this->find_first_not_of(sv.data(), pos, sv.size()); } //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT. //! //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_first_not_of(basic_string(s, n), pos). - size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const { if (pos > this->size()) return npos; else { const pointer addr = this->priv_addr(); - const pointer finish = addr + this->priv_size(); + const pointer finish = addr + difference_type(this->priv_size()); const const_iterator result = boost::container::find_if - (addr + pos, finish, Not_within_traits<Traits>(s, s + n)); - return result != finish ? result - addr : npos; + (addr + difference_type(pos), finish, Not_within_traits<Traits>(s, s + difference_type(n))); + return result != finish ? size_type(result - addr) : npos; } } @@ -2533,23 +2650,25 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_first_not_of(basic_string(s), pos). - size_type find_first_not_of(const CharT* s, size_type pos = 0) const - { return find_first_not_of(s, pos, Traits::length(s)); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_not_of(const CharT* s, size_type pos = 0) const + { return this->find_first_not_of(s, pos, Traits::length(s)); } //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_first_not_of(basic_string(1, c), pos). - size_type find_first_not_of(CharT c, size_type pos = 0) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_first_not_of(CharT c, size_type pos = 0) const { if (pos > this->size()) return npos; else { const pointer addr = this->priv_addr(); - const pointer finish = addr + this->priv_size(); + const pointer finish = addr + difference_type(this->priv_size()); const const_iterator result - = boost::container::find_if(addr + pos, finish, + = boost::container::find_if(addr + difference_type(pos), finish, boost::container::not1(boost::container::bind2nd(Eq_traits<Traits>(), c))); - return result != finish ? result - begin() : npos; + return result != finish ? size_type(result - begin()) : npos; } } @@ -2560,8 +2679,9 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. - size_type find_last_not_of(const basic_string& str, size_type pos = npos) const - { return find_last_not_of(str.c_str(), pos, str.size()); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_not_of(const basic_string& str, size_type pos = npos) const + { return this->find_last_not_of(str.c_str(), pos, str.size()); } //! <b>Effects</b>: Determines the highest position xpos, if possible, such that //! both of the following conditions obtain: a) xpos <= pos and xpos < size(); @@ -2571,15 +2691,17 @@ class basic_string //! //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos. template<template <class, class> class BasicStringView> - size_type find_last_not_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const - { return find_last_not_of(sv.data(), pos, sv.size()); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_not_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const + { return this->find_last_not_of(sv.data(), pos, sv.size()); } //! <b>Requires</b>: s points to an array of at least n elements of CharT. //! //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_last_not_of(basic_string(s, n), pos). - size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const { const size_type len = this->size(); @@ -2589,8 +2711,8 @@ class basic_string const const_iterator last = begin() + dtl::min_value(len - 1, pos) + 1; const const_reverse_iterator rresult = boost::container::find_if(const_reverse_iterator(last), rend(), - Not_within_traits<Traits>(s, s + n)); - return rresult != rend() ? (rresult.base() - 1) - begin() : npos; + Not_within_traits<Traits>(s, s + difference_type(n))); + return rresult != rend() ? size_type((rresult.base() - 1) - begin()) : npos; } } @@ -2599,13 +2721,15 @@ class basic_string //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_last_not_of(basic_string(s), pos). - size_type find_last_not_of(const CharT* s, size_type pos = npos) const - { return find_last_not_of(s, pos, Traits::length(s)); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_not_of(const CharT* s, size_type pos = npos) const + { return this->find_last_not_of(s, pos, Traits::length(s)); } //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: find_last_not_of(basic_string(1, c), pos). - size_type find_last_not_of(CharT c, size_type pos = npos) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type find_last_not_of(CharT c, size_type pos = npos) const { const size_type len = this->size(); @@ -2616,7 +2740,7 @@ class basic_string const const_reverse_iterator rresult = boost::container::find_if(const_reverse_iterator(last), rend(), boost::container::not1(boost::container::bind2nd(Eq_traits<Traits>(), c))); - return rresult != rend() ? (rresult.base() - 1) - begin() : npos; + return rresult != rend() ? size_type((rresult.base() - 1) - begin()) : npos; } } @@ -2627,14 +2751,15 @@ class basic_string //! //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > size(). //! - //! <b>Returns</b>: basic_string<CharT,traits,Allocator>(data()+pos,rlen). - basic_string substr(size_type pos = 0, size_type n = npos) const + //! <b>Returns</b>: basic_string<CharT,traits,allocator_type>(data()+pos,rlen). + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + basic_string substr(size_type pos = 0, size_type n = npos) const { if (pos > this->size()) throw_out_of_range("basic_string::substr out of range position"); const pointer addr = this->priv_addr(); - return basic_string(addr + pos, - addr + pos + dtl::min_value(n, size() - pos), this->alloc()); + return basic_string(addr + difference_type(pos), + addr + difference_type(pos + dtl::min_value(n, size() - pos)), this->alloc()); } //! <b>Effects</b>: Determines the effective length rlen of the string to compare as @@ -2646,21 +2771,23 @@ class basic_string //! <b>Returns</b>: The nonzero result if the result of the comparison is nonzero. //! Otherwise, returns a value < 0 if size() < str.size(), a 0 value if size() == str.size(), //! and value > 0 if size() > str.size() - int compare(const basic_string& str) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(const basic_string& str) const { const pointer addr = this->priv_addr(); const pointer str_addr = str.priv_addr(); - return s_compare(addr, addr + this->priv_size(), str_addr, str_addr + str.priv_size()); + return this->s_compare(addr, addr + difference_type(this->priv_size()), str_addr, str_addr + difference_type(str.priv_size())); } //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: compare(basic_string(sv)). template<template <class, class> class BasicStringView> - int compare(BasicStringView<CharT,Traits> sv) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(BasicStringView<CharT,Traits> sv) const { const pointer addr = this->priv_addr(); - return s_compare(addr, addr + this->priv_size(), sv.data(), sv.data() + sv.size()); + return this->s_compare(addr, addr + difference_type(this->priv_size()), sv.data(), sv.data() + difference_type(sv.size())); } //! <b>Requires</b>: pos1 <= size() @@ -2672,15 +2799,16 @@ class basic_string //! <b>Throws</b>: out_of_range if pos1 > size() //! //! <b>Returns</b>:basic_string(*this,pos1,n1).compare(str). - int compare(size_type pos1, size_type n1, const basic_string& str) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(size_type pos1, size_type n1, const basic_string& str) const { if (pos1 > this->size()) throw_out_of_range("basic_string::compare out of range position"); const pointer addr = this->priv_addr(); const pointer str_addr = str.priv_addr(); - return s_compare(addr + pos1, - addr + pos1 + dtl::min_value(n1, this->size() - pos1), - str_addr, str_addr + str.priv_size()); + return this->s_compare(addr + difference_type(pos1), + addr + difference_type(pos1 + dtl::min_value(n1, this->size() - pos1)), + str_addr, str_addr + difference_type(str.priv_size())); } //! <b>Requires</b>: pos1 <= size() @@ -2689,13 +2817,14 @@ class basic_string //! //! <b>Returns</b>:basic_string(*this,pos1,n1).compare(sv). template<template <class, class> class BasicStringView> - int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv) const { if (pos1 > this->size()) throw_out_of_range("basic_string::compare out of range position"); const pointer addr = this->priv_addr() + pos1; const CharT* str_addr = sv.data(); - return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1), + return this->s_compare(addr, addr + difference_type(dtl::min_value(n1, this->size() - pos1)), str_addr, str_addr + sv.size()); } @@ -2707,14 +2836,15 @@ class basic_string //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > str.size() //! //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)). - int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const { if (pos1 > this->size() || pos2 > str.size()) throw_out_of_range("basic_string::compare out of range position"); const pointer addr = this->priv_addr() + pos1; const pointer str_addr = str.priv_addr() + pos2; - return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1), - str_addr, str_addr + dtl::min_value(n2, str.size() - pos2)); + return this->s_compare(addr, addr + difference_type(dtl::min_value(n1, this->size() - pos1)), + str_addr, str_addr + difference_type(dtl::min_value(n2, str.size() - pos2))); } //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size() @@ -2726,23 +2856,25 @@ class basic_string //! //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(BasicStringView<CharT, Traits>(sv, pos2, n2)). template<template <class, class> class BasicStringView> - int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv, size_type pos2, size_type n2) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv, size_type pos2, size_type n2) const { if (pos1 > this->size() || pos2 > sv.size()) throw_out_of_range("basic_string::compare out of range position"); const pointer addr = this->priv_addr() + pos1; const CharT * str_addr = sv.data() + pos2; - return s_compare(addr, addr + dtl::min_value(n1, this->size() - pos1), - str_addr, str_addr + dtl::min_value(n2, sv.size() - pos2)); + return this->s_compare(addr, addr + difference_type(dtl::min_value(n1, this->size() - pos1)), + str_addr, str_addr + difference_type(dtl::min_value(n2, sv.size() - pos2))); } //! <b>Throws</b>: Nothing //! //! <b>Returns</b>: compare(basic_string(s)). - int compare(const CharT* s) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(const CharT* s) const { const pointer addr = this->priv_addr(); - return s_compare(addr, addr + this->priv_size(), s, s + Traits::length(s)); + return this->s_compare(addr, addr + difference_type(this->priv_size()), s, s + Traits::length(s)); } //! <b>Requires</b>: pos1 > size() and s points to an array of at least n2 elements of CharT. @@ -2750,14 +2882,15 @@ class basic_string //! <b>Throws</b>: out_of_range if pos1 > size() //! //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)). - int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const { if (pos1 > this->size()) throw_out_of_range("basic_string::compare out of range position"); const pointer addr = this->priv_addr(); - return s_compare( addr + pos1, - addr + pos1 + dtl::min_value(n1, this->size() - pos1), - s, s + n2); + return this->s_compare( addr + difference_type(pos1), + addr + difference_type(pos1 + dtl::min_value(n1, this->size() - pos1)), + s, s + difference_type(n2)); } //! <b>Requires</b>: pos1 > size() and s points to an array of at least traits::length(s) + 1 elements of CharT. @@ -2765,7 +2898,8 @@ class basic_string //! <b>Throws</b>: out_of_range if pos1 > size() //! //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)). - int compare(size_type pos1, size_type n1, const CharT* s) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + int compare(size_type pos1, size_type n1, const CharT* s) const { return this->compare(pos1, n1, s, Traits::length(s)); } #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -2785,12 +2919,12 @@ class basic_string const pointer addr = this->priv_addr(); new_length += priv_uninitialized_copy - (addr, addr + this->priv_size(), new_start); + (addr, addr + difference_type(this->priv_size()), new_start); if(null_terminate){ - this->priv_construct_null(new_start + new_length); + this->priv_construct_null(new_start + difference_type(new_length)); } this->deallocate_block(); - this->is_short(false); + this->assure_long(); this->priv_long_addr(new_start); this->priv_long_size(new_length); this->priv_storage(new_cap); @@ -2800,8 +2934,8 @@ class basic_string template<class It1, class It2> static int s_compare(It1 f1, It1 l1, It2 f2, It2 l2) { - const difference_type n1 = l1 - f1; - const difference_type n2 = l2 - f2; + const std::size_t n1 = std::size_t(l1 - f1); + const std::size_t n2 = std::size_t(l2 - f2); const int cmp = Traits::compare(boost::movelib::to_raw_pointer(f1), boost::movelib::to_raw_pointer(f2), dtl::min_value(n1, n2)); @@ -2851,12 +2985,12 @@ class basic_string } } - void priv_construct_null(pointer p) + BOOST_CONTAINER_FORCEINLINE void priv_construct_null(pointer p) { this->construct(p, CharT(0)); } // Helper functions used by constructors. It is a severe error for // any of them to be called anywhere except from within constructors. - void priv_terminate_string() + BOOST_CONTAINER_FORCEINLINE void priv_terminate_string() { this->priv_construct_null(this->priv_end_addr()); } template<class FwdIt, class Count> inline @@ -2906,23 +3040,23 @@ class basic_string } template <class InputIterator, class OutIterator> - void priv_copy(InputIterator first, InputIterator last, OutIterator result) + static void priv_copy(InputIterator first, InputIterator last, OutIterator result) { for ( ; first != last; ++first, ++result) Traits::assign(*result, *first); } - void priv_copy(const CharT* first, const CharT* last, CharT* result) - { Traits::copy(result, first, last - first); } + static BOOST_CONTAINER_FORCEINLINE void priv_copy(const CharT* first, const CharT* last, CharT* result) + { Traits::copy(result, first, std::size_t(last - first)); } template <class Integer> - basic_string& priv_replace_dispatch(const_iterator first, const_iterator last, + BOOST_CONTAINER_FORCEINLINE basic_string& priv_replace_dispatch(const_iterator first, const_iterator last, Integer n, Integer x, dtl::true_) { return this->replace(first, last, (size_type) n, (CharT) x); } template <class InputIter> - basic_string& priv_replace_dispatch(const_iterator first, const_iterator last, + BOOST_CONTAINER_FORCEINLINE basic_string& priv_replace_dispatch(const_iterator first, const_iterator last, InputIter f, InputIter l, dtl::false_) { @@ -2933,6 +3067,18 @@ class basic_string #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template <typename InputIterator> +basic_string(InputIterator, InputIterator) -> + basic_string<typename iterator_traits<InputIterator>::value_type>; + +template <typename InputIterator, typename Allocator> +basic_string(InputIterator, InputIterator, Allocator const&) -> + basic_string<typename iterator_traits<InputIterator>::value_type, Allocator>; + +#endif + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //!Typedef for a basic_string of @@ -3271,6 +3417,7 @@ operator>=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT // Swap. template <class CharT, class Traits, class Allocator> inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y) + BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) { x.swap(y); } #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -3419,7 +3566,16 @@ getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocat template <class Ch, class Allocator> inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator> const& v) { - return hash_range(v.begin(), v.end()); + std::size_t seed = 0; + const Ch *first = v.data(); + + for(std::size_t i = 0, i_max = v.size(); i != i_max; ++i) + { + boost::intrusive::detail::hash_combine_size_t(seed, static_cast<std::size_t>(*first)); + ++first; + } + + return seed; } }} @@ -3433,8 +3589,9 @@ namespace boost { template <class C, class T, class Allocator> struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> > { - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && + typedef typename boost::container::basic_string<C, T, Allocator>::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value && ::boost::has_trivial_destructor_after_move<pointer>::value; }; diff --git a/contrib/restricted/boost/container/include/boost/container/throw_exception.hpp b/contrib/restricted/boost/container/include/boost/container/throw_exception.hpp index 1b6eec1179..f80c905b12 100644 --- a/contrib/restricted/boost/container/include/boost/container/throw_exception.hpp +++ b/contrib/restricted/boost/container/include/boost/container/throw_exception.hpp @@ -21,11 +21,110 @@ #include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/workaround.hpp> +#include <boost/core/ignore_unused.hpp> #ifndef BOOST_NO_EXCEPTIONS - #include <stdexcept> //for std exception types +#include <exception> //for std exception base + +# if defined(BOOST_CONTAINER_USE_STD_EXCEPTIONS) + #include <stdexcept> //for std::out_of_range, std::length_error, std::logic_error, std::runtime_error #include <string> //for implicit std::string conversion #include <new> //for std::bad_alloc + +namespace boost { +namespace container { + +typedef std::bad_alloc bad_alloc_t; +typedef std::out_of_range out_of_range_t; +typedef std::length_error length_error_t; +typedef std::logic_error logic_error_t; +typedef std::runtime_error runtime_error_t; + +}} //namespace boost::container + +# else //!BOOST_CONTAINER_USE_STD_EXCEPTIONS + +namespace boost { +namespace container { + +class BOOST_SYMBOL_VISIBLE exception + : public ::std::exception +{ + typedef ::std::exception std_exception_t; + + public: + + //msg must be a static string (guaranteed by callers) + explicit exception(const char *msg) + : std_exception_t(), m_msg(msg) + {} + + virtual const char *what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE + { return m_msg ? m_msg : "unknown boost::container exception"; } + + private: + const char *m_msg; +}; + +class BOOST_SYMBOL_VISIBLE bad_alloc + : public exception +{ + public: + bad_alloc() + : exception("boost::container::bad_alloc thrown") + {} +}; + +typedef bad_alloc bad_alloc_t; + +class BOOST_SYMBOL_VISIBLE out_of_range + : public exception +{ + public: + explicit out_of_range(const char *msg) + : exception(msg) + {} +}; + +typedef out_of_range out_of_range_t; + +class BOOST_SYMBOL_VISIBLE length_error + : public exception +{ + public: + explicit length_error(const char *msg) + : exception(msg) + {} +}; + +typedef length_error length_error_t; + +class BOOST_SYMBOL_VISIBLE logic_error + : public exception +{ + public: + explicit logic_error(const char *msg) + : exception(msg) + {} +}; + +typedef logic_error logic_error_t; + +class BOOST_SYMBOL_VISIBLE runtime_error + : public exception +{ + public: + explicit runtime_error(const char *msg) + : exception(msg) + {} +}; + +typedef runtime_error runtime_error_t; + +} // namespace boost { +} // namespace container { + +# endif #else #include <boost/assert.hpp> #include <cstdlib> //for std::abort @@ -37,55 +136,49 @@ namespace container { #if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) //The user must provide definitions for the following functions - void throw_bad_alloc(); + BOOST_NORETURN void throw_bad_alloc(); - void throw_out_of_range(const char* str); + BOOST_NORETURN void throw_out_of_range(const char* str); - void throw_length_error(const char* str); + BOOST_NORETURN void throw_length_error(const char* str); - void throw_logic_error(const char* str); + BOOST_NORETURN void throw_logic_error(const char* str); - void throw_runtime_error(const char* str); + BOOST_NORETURN void throw_runtime_error(const char* str); #elif defined(BOOST_NO_EXCEPTIONS) - inline void throw_bad_alloc() + BOOST_NORETURN inline void throw_bad_alloc() { - const char msg[] = "boost::container bad_alloc thrown"; - (void)msg; - BOOST_ASSERT(!msg); + BOOST_ASSERT(!"boost::container bad_alloc thrown"); std::abort(); } - inline void throw_out_of_range(const char* str) + BOOST_NORETURN inline void throw_out_of_range(const char* str) { - const char msg[] = "boost::container out_of_range thrown"; - (void)msg; (void)str; - BOOST_ASSERT_MSG(!msg, str); + boost::ignore_unused(str); + BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str); std::abort(); } - inline void throw_length_error(const char* str) + BOOST_NORETURN inline void throw_length_error(const char* str) { - const char msg[] = "boost::container length_error thrown"; - (void)msg; (void)str; - BOOST_ASSERT_MSG(!msg, str); + boost::ignore_unused(str); + BOOST_ASSERT_MSG(!"boost::container length_error thrown", str); std::abort(); } - inline void throw_logic_error(const char* str) + BOOST_NORETURN inline void throw_logic_error(const char* str) { - const char msg[] = "boost::container logic_error thrown"; - (void)msg; (void)str; - BOOST_ASSERT_MSG(!msg, str); + boost::ignore_unused(str); + BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str); std::abort(); } - inline void throw_runtime_error(const char* str) + BOOST_NORETURN inline void throw_runtime_error(const char* str) { - const char msg[] = "boost::container runtime_error thrown"; - (void)msg; (void)str; - BOOST_ASSERT_MSG(!msg, str); + boost::ignore_unused(str); + BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str); std::abort(); } @@ -93,7 +186,11 @@ namespace container { //! Exception callback called by Boost.Container when fails to allocate the requested storage space. //! <ul> - //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::bad_alloc()</code> is thrown.</li> + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined + //! <code>boost::container::bad_alloc(str)</code> is thrown.</li> + //! + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined + //! <code>std::bad_alloc(str)</code> is thrown.</li> //! //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS //! is NOT defined <code>BOOST_ASSERT(!"boost::container bad_alloc thrown")</code> is called @@ -102,14 +199,18 @@ namespace container { //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined //! the user must provide an implementation and the function should not return.</li> //! </ul> - inline void throw_bad_alloc() + BOOST_NORETURN inline void throw_bad_alloc() { - throw std::bad_alloc(); + throw bad_alloc_t(); } //! Exception callback called by Boost.Container to signal arguments out of range. //! <ul> - //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::out_of_range(str)</code> is thrown.</li> + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined + //! <code>boost::container::out_of_range(str)</code> is thrown.</li> + //! + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined + //! <code>std::out_of_range(str)</code> is thrown.</li> //! //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS //! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str)</code> is called @@ -118,14 +219,19 @@ namespace container { //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined //! the user must provide an implementation and the function should not return.</li> //! </ul> - inline void throw_out_of_range(const char* str) + BOOST_NORETURN inline void throw_out_of_range(const char* str) { - throw std::out_of_range(str); + throw out_of_range_t(str); } //! Exception callback called by Boost.Container to signal errors resizing. //! <ul> - //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::length_error(str)</code> is thrown.</li> + //! + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined + //! <code>boost::container::length_error(str)</code> is thrown.</li> + //! + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined + //! <code>std::length_error(str)</code> is thrown.</li> //! //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS //! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container length_error thrown", str)</code> is called @@ -134,15 +240,20 @@ namespace container { //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined //! the user must provide an implementation and the function should not return.</li> //! </ul> - inline void throw_length_error(const char* str) + BOOST_NORETURN inline void throw_length_error(const char* str) { - throw std::length_error(str); + throw length_error_t(str); } //! Exception callback called by Boost.Container to report errors in the internal logical //! of the program, such as violation of logical preconditions or class invariants. //! <ul> - //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::logic_error(str)</code> is thrown.</li> + //! + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined + //! <code>boost::container::logic_error(str)</code> is thrown.</li> + //! + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined + //! <code>std::logic_error(str)</code> is thrown.</li> //! //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS //! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str)</code> is called @@ -151,14 +262,18 @@ namespace container { //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined //! the user must provide an implementation and the function should not return.</li> //! </ul> - inline void throw_logic_error(const char* str) + BOOST_NORETURN inline void throw_logic_error(const char* str) { - throw std::logic_error(str); + throw logic_error_t(str); } //! Exception callback called by Boost.Container to report errors that can only be detected during runtime. //! <ul> - //! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::runtime_error(str)</code> is thrown.</li> + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined + //! <code>boost::container::runtime_error(str)</code> is thrown.</li> + //! + //! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined + //! <code>std::runtime_error(str)</code> is thrown.</li> //! //! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS //! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str)</code> is called @@ -167,9 +282,9 @@ namespace container { //! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined //! the user must provide an implementation and the function should not return.</li> //! </ul> - inline void throw_runtime_error(const char* str) + BOOST_NORETURN inline void throw_runtime_error(const char* str) { - throw std::runtime_error(str); + throw runtime_error_t(str); } #endif diff --git a/contrib/restricted/boost/container/include/boost/container/vector.hpp b/contrib/restricted/boost/container/include/boost/container/vector.hpp index 52e3c2391a..80df0ce518 100644 --- a/contrib/restricted/boost/container/include/boost/container/vector.hpp +++ b/contrib/restricted/boost/container/include/boost/container/vector.hpp @@ -82,8 +82,21 @@ class vec_iterator { public: typedef std::random_access_iterator_tag iterator_category; + #ifdef BOOST_MOVE_CONTIGUOUS_ITERATOR_TAG + typedef std::contiguous_iterator_tag iterator_concept; + #endif typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type; + + //Defining element_type to make libstdc++'s std::pointer_traits well-formed leads to ambiguity + //due to LWG3446. So we need to specialize std::pointer_traits. See + //https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96416 for details. Many thanks to Jonathan Wakely + //for explaining the issue. + #ifndef BOOST_GNU_STDLIB + //Define element_ + typedef typename boost::intrusive::pointer_traits<Pointer>::element_type element_type; + #endif typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type; + typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type; typedef typename dtl::if_c < IsConst , typename boost::intrusive::pointer_traits<Pointer>::template @@ -96,16 +109,24 @@ class vec_iterator #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: Pointer m_ptr; - class nat; + + class nat + { + public: + Pointer get_ptr() const + { return Pointer(); } + }; typedef typename dtl::if_c< IsConst , vec_iterator<Pointer, false> , nat>::type nonconst_iterator; public: - BOOST_CONTAINER_FORCEINLINE const Pointer &get_ptr() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE + const Pointer &get_ptr() const BOOST_NOEXCEPT_OR_NOTHROW { return m_ptr; } - BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE + Pointer &get_ptr() BOOST_NOEXCEPT_OR_NOTHROW { return m_ptr; } BOOST_CONTAINER_FORCEINLINE explicit vec_iterator(Pointer ptr) BOOST_NOEXCEPT_OR_NOTHROW @@ -132,64 +153,78 @@ class vec_iterator { m_ptr = other.get_ptr(); return *this; } //Pointer like operators - BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW - { return *m_ptr; } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(!!m_ptr); return *m_ptr; } - BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW - { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_ptr; } - BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW - { return m_ptr[off]; } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(!!m_ptr); return m_ptr[off]; } //Increment / Decrement BOOST_CONTAINER_FORCEINLINE vec_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW - { ++m_ptr; return *this; } + { BOOST_ASSERT(!!m_ptr); ++m_ptr; return *this; } BOOST_CONTAINER_FORCEINLINE vec_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW - { return vec_iterator(m_ptr++); } + { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr++); } BOOST_CONTAINER_FORCEINLINE vec_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW - { --m_ptr; return *this; } + { BOOST_ASSERT(!!m_ptr); --m_ptr; return *this; } BOOST_CONTAINER_FORCEINLINE vec_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW - { return vec_iterator(m_ptr--); } + { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr--); } //Arithmetic BOOST_CONTAINER_FORCEINLINE vec_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW - { m_ptr += off; return *this; } + { BOOST_ASSERT(m_ptr || !off); m_ptr += off; return *this; } BOOST_CONTAINER_FORCEINLINE vec_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW - { m_ptr -= off; return *this; } + { BOOST_ASSERT(m_ptr || !off); m_ptr -= off; return *this; } - BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW - { return vec_iterator(x.m_ptr+off); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(x.m_ptr || !off); return vec_iterator(x.m_ptr+off); } - BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW - { right.m_ptr += off; return right; } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(right.m_ptr || !off); right.m_ptr += off; return right; } - BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW - { left.m_ptr -= off; return left; } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(left.m_ptr || !off); left.m_ptr -= off; return left; } - BOOST_CONTAINER_FORCEINLINE friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW + //Difference + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW { return left.m_ptr - right.m_ptr; } //Comparison operators - BOOST_CONTAINER_FORCEINLINE friend bool operator== (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator== (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW { return l.m_ptr == r.m_ptr; } - BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator!= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW { return l.m_ptr != r.m_ptr; } - BOOST_CONTAINER_FORCEINLINE friend bool operator< (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator< (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW { return l.m_ptr < r.m_ptr; } - BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator<= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW { return l.m_ptr <= r.m_ptr; } - BOOST_CONTAINER_FORCEINLINE friend bool operator> (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator> (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW { return l.m_ptr > r.m_ptr; } - BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + friend bool operator>= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW { return l.m_ptr >= r.m_ptr; } }; @@ -241,13 +276,8 @@ struct vector_value_traits_base { static const bool trivial_dctr = dtl::is_trivially_destructible<T>::value; static const bool trivial_dctr_after_move = has_trivial_destructor_after_move<T>::value; - static const bool trivial_copy = dtl::is_trivially_copy_constructible<T>::value; - static const bool nothrow_copy = dtl::is_nothrow_copy_constructible<T>::value || trivial_copy; - static const bool trivial_assign = dtl::is_trivially_copy_assignable<T>::value; - static const bool nothrow_assign = dtl::is_nothrow_copy_assignable<T>::value || trivial_assign; }; - template <class Allocator> struct vector_value_traits : public vector_value_traits_base<typename Allocator::value_type> @@ -276,22 +306,25 @@ struct vector_alloc_holder BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) public: - typedef Allocator allocator_type; - typedef StoredSizeType stored_size_type; - typedef boost::container::allocator_traits<Allocator> allocator_traits_type; - typedef typename allocator_traits_type::pointer pointer; - typedef typename allocator_traits_type::size_type size_type; - typedef typename allocator_traits_type::value_type value_type; + typedef Allocator allocator_type; + typedef StoredSizeType stored_size_type; + typedef boost::container::allocator_traits<allocator_type> allocator_traits_type; + typedef typename allocator_traits_type::pointer pointer; + typedef typename allocator_traits_type::size_type size_type; + typedef typename allocator_traits_type::value_type value_type; - static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator) + BOOST_CONTAINER_FORCEINLINE + static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator) { (void)propagate_allocator; (void)p; (void)to_alloc; (void)from_alloc; const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value || !allocator_traits_type::storage_is_unpropagable(from_alloc, p); - return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(from_alloc, to_alloc)); + return all_storage_propagable && + (propagate_allocator || allocator_traits_type::is_always_equal::value || allocator_traits_type::equal(from_alloc, to_alloc)); } - static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p, bool const propagate_allocator) + BOOST_CONTAINER_FORCEINLINE + static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p, bool const propagate_allocator) { (void)propagate_allocator; (void)l_p; (void)r_p; (void)l_a; (void)r_a; const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value || @@ -301,51 +334,58 @@ struct vector_alloc_holder //Constructor, does not throw vector_alloc_holder() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value) - : Allocator(), m_start(), m_size(), m_capacity() + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value) + : allocator_type(), m_start(), m_size(), m_capacity() {} //Constructor, does not throw template<class AllocConvertible> explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW - : Allocator(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity() + : allocator_type(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity() {} //Constructor, does not throw - template<class AllocConvertible> - vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) - : Allocator(boost::forward<AllocConvertible>(a)) + template<class AllocConvertible, class SizeType> + vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, SizeType initial_size) + : allocator_type(boost::forward<AllocConvertible>(a)) , m_start() //Size is initialized here so vector should only call uninitialized_xxx after this , m_size(static_cast<stored_size_type>(initial_size)) , m_capacity() { - if(initial_size){ + if (initial_size > size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + else if(initial_size){ pointer reuse = pointer(); - size_type final_cap = initial_size; - m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse); - m_capacity = static_cast<stored_size_type>(final_cap); + size_type final_cap = static_cast<size_type>(initial_size); + m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse); + this->set_stored_capacity(final_cap); } } //Constructor, does not throw - vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size) - : Allocator() + template<class SizeType> + vector_alloc_holder(vector_uninitialized_size_t, SizeType initial_size) + : allocator_type() , m_start() //Size is initialized here so vector should only call uninitialized_xxx after this , m_size(static_cast<stored_size_type>(initial_size)) , m_capacity() { - if(initial_size){ + if (initial_size > size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + else if(initial_size){ pointer reuse = pointer(); size_type final_cap = initial_size; - m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse); - m_capacity = static_cast<stored_size_type>(final_cap); + m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse); + this->set_stored_capacity(final_cap); } } vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW - : Allocator(BOOST_MOVE_BASE(Allocator, holder)) + : allocator_type(BOOST_MOVE_BASE(allocator_type, holder)) , m_start(holder.m_start) , m_size(holder.m_size) , m_capacity(holder.m_capacity) @@ -354,38 +394,9 @@ struct vector_alloc_holder holder.m_size = holder.m_capacity = 0; } - vector_alloc_holder(initial_capacity_t, pointer p, size_type capacity, BOOST_RV_REF(vector_alloc_holder) holder) - : Allocator(BOOST_MOVE_BASE(Allocator, holder)) - , m_start(p) - , m_size(holder.m_size) - , m_capacity(static_cast<stored_size_type>(capacity)) - { - allocator_type &this_alloc = this->alloc(); - allocator_type &x_alloc = holder.alloc(); - if(this->is_propagable_from(x_alloc, holder.start(), this_alloc, true)){ - if(this->m_capacity){ - this->deallocate(this->m_start, this->m_capacity); - } - m_start = holder.m_start; - m_capacity = holder.m_capacity; - holder.m_start = pointer(); - holder.m_capacity = holder.m_size = 0; - } - else if(this->m_capacity < holder.m_size){ - size_type const n = holder.m_size; - pointer reuse = pointer(); - size_type final_cap = n; - m_start = this->allocation_command(allocate_new, n, final_cap, reuse); - m_capacity = static_cast<stored_size_type>(final_cap); - #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS - this->num_alloc += n != 0; - #endif - } - } - vector_alloc_holder(initial_capacity_t, pointer p, size_type n) - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value) - : Allocator() + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value) + : allocator_type() , m_start(p) , m_size() //n is guaranteed to fit into stored_size_type @@ -394,7 +405,7 @@ struct vector_alloc_holder template<class AllocFwd> vector_alloc_holder(initial_capacity_t, pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a) - : Allocator(::boost::forward<AllocFwd>(a)) + : allocator_type(::boost::forward<AllocFwd>(a)) , m_start(p) , m_size() , m_capacity(n) @@ -407,14 +418,26 @@ struct vector_alloc_holder } } + BOOST_CONTAINER_FORCEINLINE void set_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size = static_cast<stored_size_type>(s); } + + BOOST_CONTAINER_FORCEINLINE void dec_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size = static_cast<stored_size_type>(this->m_size - s); } + + BOOST_CONTAINER_FORCEINLINE void inc_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size = static_cast<stored_size_type>(this->m_size + s); } + + BOOST_CONTAINER_FORCEINLINE void set_stored_capacity(size_type c) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_capacity = static_cast<stored_size_type>(c); } + BOOST_CONTAINER_FORCEINLINE pointer allocation_command(boost::container::allocation_type command, - size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) + size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) { - typedef typename dtl::version<Allocator>::type alloc_version; + typedef typename dtl::version<allocator_type>::type alloc_version; return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse); } - BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n) + pointer allocate(size_type n) { const size_type max_alloc = allocator_traits_type::max_size(this->alloc()); const size_type max = max_alloc <= stored_size_type(-1) ? max_alloc : stored_size_type(-1); @@ -432,7 +455,7 @@ struct vector_alloc_holder bool try_expand_fwd(size_type at_least) { //There is not enough memory, try to expand the old one - const size_type new_cap = this->capacity() + at_least; + const size_type new_cap = size_type(this->capacity() + at_least); size_type real_cap = new_cap; pointer reuse = this->start(); bool const success = !!this->allocation_command(expand_fwd, new_cap, real_cap, reuse); @@ -451,9 +474,9 @@ struct vector_alloc_holder { BOOST_ASSERT(additional_objects > size_type(this->m_capacity - this->m_size)); size_type max = allocator_traits_type::max_size(this->alloc()); - (clamp_by_stored_size_type)(max, stored_size_type()); - const size_type remaining_cap = max - size_type(this->m_capacity); - const size_type min_additional_cap = additional_objects - size_type(this->m_capacity - this->m_size); + (clamp_by_stored_size_type<size_type>)(max, stored_size_type()); + const size_type remaining_cap = size_type(max - size_type(this->m_capacity)); + const size_type min_additional_cap = size_type(additional_objects - size_type(this->m_capacity - this->m_size)); if ( remaining_cap < min_additional_cap ) boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); @@ -481,10 +504,10 @@ struct vector_alloc_holder x.m_size = x.m_capacity = 0; } - BOOST_CONTAINER_FORCEINLINE Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW { return *this; } - BOOST_CONTAINER_FORCEINLINE const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW { return *this; } BOOST_CONTAINER_FORCEINLINE const pointer &start() const BOOST_NOEXCEPT_OR_NOTHROW @@ -494,7 +517,10 @@ struct vector_alloc_holder BOOST_CONTAINER_FORCEINLINE void start(const pointer &p) BOOST_NOEXCEPT_OR_NOTHROW { m_start = p; } BOOST_CONTAINER_FORCEINLINE void capacity(const size_type &c) BOOST_NOEXCEPT_OR_NOTHROW - { BOOST_ASSERT( c <= stored_size_type(-1)); m_capacity = c; } + { BOOST_ASSERT( c <= stored_size_type(-1)); this->set_stored_capacity(c); } + + static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow() + { } private: void priv_first_allocation(size_type cap) @@ -509,17 +535,7 @@ struct vector_alloc_holder } } - BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &, size_type) - {} - - template<class SomeStoredSizeType> - BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &s, SomeStoredSizeType) - { - if (s >= SomeStoredSizeType(-1) ) - s = SomeStoredSizeType(-1); - } - - BOOST_CONTAINER_FORCEINLINE pointer priv_allocation_command(version_1, boost::container::allocation_type command, + pointer priv_allocation_command(version_1, boost::container::allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) @@ -531,7 +547,7 @@ struct vector_alloc_holder if (limit_size > stored_size_type(-1)){ boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); } - (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + (clamp_by_stored_size_type<size_type>)(prefer_in_recvd_out_size, stored_size_type()); pointer const p = this->allocate(prefer_in_recvd_out_size); reuse = pointer(); return p; @@ -546,11 +562,11 @@ struct vector_alloc_holder if (limit_size > stored_size_type(-1)){ boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); } - (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + (clamp_by_stored_size_type<size_type>)(prefer_in_recvd_out_size, stored_size_type()); //Allocate memory pointer p = this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); //If after allocation prefer_in_recvd_out_size is not representable by stored_size_type, truncate it. - (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + (clamp_by_stored_size_type<size_type>)(prefer_in_recvd_out_size, stored_size_type()); return p; } }; @@ -564,31 +580,33 @@ struct vector_alloc_holder<Allocator, StoredSizeType, version_0> BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) public: - typedef boost::container::allocator_traits<Allocator> allocator_traits_type; + typedef Allocator allocator_type; + typedef boost::container:: + allocator_traits<allocator_type> allocator_traits_type; typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::size_type size_type; typedef typename allocator_traits_type::value_type value_type; typedef StoredSizeType stored_size_type; - + template <class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion> friend struct vector_alloc_holder; //Constructor, does not throw vector_alloc_holder() - BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value) - : Allocator(), m_size() + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value) + : allocator_type(), m_size() {} //Constructor, does not throw template<class AllocConvertible> explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW - : Allocator(boost::forward<AllocConvertible>(a)), m_size() + : allocator_type(boost::forward<AllocConvertible>(a)), m_size() {} //Constructor, does not throw template<class AllocConvertible> vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) - : Allocator(boost::forward<AllocConvertible>(a)) + : allocator_type(boost::forward<AllocConvertible>(a)) , m_size(initial_size) //Size is initialized here... { //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor @@ -597,7 +615,7 @@ struct vector_alloc_holder<Allocator, StoredSizeType, version_0> //Constructor, does not throw vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size) - : Allocator() + : allocator_type() , m_size(initial_size) //Size is initialized here... { //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor @@ -605,16 +623,19 @@ struct vector_alloc_holder<Allocator, StoredSizeType, version_0> } vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) - : Allocator(BOOST_MOVE_BASE(Allocator, holder)) + : allocator_type(BOOST_MOVE_BASE(allocator_type, holder)) , m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this { ::boost::container::uninitialized_move_alloc_n (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start())); + ::boost::container::destroy_alloc_n + (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size); + holder.m_size = 0; } template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion> vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> BOOST_RV_REF_END holder) - : Allocator() + : allocator_type() , m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort { //Different allocator type so we must check we have enough storage @@ -624,49 +645,63 @@ struct vector_alloc_holder<Allocator, StoredSizeType, version_0> (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), n, boost::movelib::to_raw_pointer(this->start())); } + static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow() + { allocator_type::on_capacity_overflow(); } + + BOOST_CONTAINER_FORCEINLINE void set_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size = static_cast<stored_size_type>(s); } + + BOOST_CONTAINER_FORCEINLINE void dec_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size = static_cast<stored_size_type>(this->m_size - s); } + + BOOST_CONTAINER_FORCEINLINE void inc_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size = static_cast<stored_size_type>(this->m_size + s); } + BOOST_CONTAINER_FORCEINLINE void priv_first_allocation(size_type cap) { - if(cap > Allocator::internal_capacity){ - throw_bad_alloc(); + if(cap > allocator_type::internal_capacity){ + on_capacity_overflow(); } } BOOST_CONTAINER_FORCEINLINE void deep_swap(vector_alloc_holder &x) - { - this->priv_deep_swap(x); - } + { this->priv_deep_swap(x); } template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion> void deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x) { - if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){ - throw_bad_alloc(); + typedef typename real_allocator<value_type, OtherAllocator>::type other_allocator_type; + if(this->m_size > other_allocator_type::internal_capacity || x.m_size > allocator_type::internal_capacity){ + on_capacity_overflow(); } this->priv_deep_swap(x); } BOOST_CONTAINER_FORCEINLINE void swap_resources(vector_alloc_holder &) BOOST_NOEXCEPT_OR_NOTHROW { //Containers with version 0 allocators can't be moved without moving elements one by one - throw_bad_alloc(); + on_capacity_overflow(); } - BOOST_CONTAINER_FORCEINLINE void steal_resources(vector_alloc_holder &) { //Containers with version 0 allocators can't be moved without moving elements one by one - throw_bad_alloc(); + on_capacity_overflow(); } - BOOST_CONTAINER_FORCEINLINE Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW { return *this; } - BOOST_CONTAINER_FORCEINLINE const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW { return *this; } BOOST_CONTAINER_FORCEINLINE bool try_expand_fwd(size_type at_least) { return !at_least; } - BOOST_CONTAINER_FORCEINLINE pointer start() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_storage(); } - BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_capacity; } + BOOST_CONTAINER_FORCEINLINE pointer start() const BOOST_NOEXCEPT_OR_NOTHROW + { return allocator_type::internal_storage(); } + + BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + { return allocator_type::internal_capacity; } + stored_size_type m_size; private: @@ -674,7 +709,7 @@ struct vector_alloc_holder<Allocator, StoredSizeType, version_0> template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion> void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x) { - const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity; + const size_type MaxTmpStorage = sizeof(value_type)*allocator_type::internal_capacity; value_type *const first_this = boost::movelib::to_raw_pointer(this->start()); value_type *const first_x = boost::movelib::to_raw_pointer(x.start()); @@ -690,18 +725,6 @@ struct vector_alloc_holder<Allocator, StoredSizeType, version_0> struct growth_factor_60; -template<class T, class Default> -struct default_if_void -{ - typedef T type; -}; - -template<class Default> -struct default_if_void<void, Default> -{ - typedef Default type; -}; - template<class Options, class AllocatorSizeType> struct get_vector_opt { @@ -716,7 +739,6 @@ struct get_vector_opt<void, AllocatorSizeType> typedef vector_opt<growth_factor_60, AllocatorSizeType> type; }; - #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! A vector is a sequence that supports random access to elements, constant @@ -725,14 +747,39 @@ struct get_vector_opt<void, AllocatorSizeType> //! elements in a vector may vary dynamically; memory management is automatic. //! //! \tparam T The type of object that is stored in the vector -//! \tparam Allocator The allocator used for all internal memory management +//! \tparam A The allocator used for all internal memory management, use void +//! for the default allocator //! \tparam Options A type produced from \c boost::container::vector_options. -template <class T, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>), class Options BOOST_CONTAINER_DOCONLY(= void) > +template <class T, class A BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void) > class vector { - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +public: + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef T value_type; + typedef BOOST_CONTAINER_IMPDEF + (typename real_allocator<T BOOST_MOVE_I A>::type) allocator_type; + typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_t; + typedef typename allocator_traits<allocator_type>::pointer pointer; + typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; + typedef typename allocator_traits<allocator_type>::reference reference; + typedef typename allocator_traits<allocator_type>::const_reference const_reference; + typedef typename allocator_traits<allocator_type>::size_type size_type; + typedef typename allocator_traits<allocator_type>::difference_type difference_type; + typedef allocator_type stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(vec_iterator<pointer BOOST_MOVE_I false>) iterator; + typedef BOOST_CONTAINER_IMPDEF(vec_iterator<pointer BOOST_MOVE_I true >) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator; - typedef typename boost::container::allocator_traits<Allocator>::size_type alloc_size_type; +private: + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + typedef typename boost::container:: + allocator_traits<allocator_type>::size_type alloc_size_type; typedef typename get_vector_opt<Options, alloc_size_type>::type options_type; typedef typename options_type::growth_factor_type growth_factor_type; typedef typename options_type::stored_size_type stored_size_type; @@ -742,52 +789,33 @@ class vector BOOST_STATIC_ASSERT( (sizeof(stored_size_type) < sizeof(alloc_size_type) || dtl::is_same<stored_size_type, alloc_size_type>::value) ); - typedef typename dtl::version<Allocator>::type alloc_version; - typedef boost::container::vector_alloc_holder<Allocator, stored_size_type> alloc_holder_t; + typedef typename dtl::version<allocator_type>::type alloc_version; + typedef boost::container::vector_alloc_holder + <allocator_type, stored_size_type> alloc_holder_t; + alloc_holder_t m_holder; - typedef allocator_traits<Allocator> allocator_traits_type; - template <class U, class UAllocator, class UOptions> + + typedef allocator_traits<allocator_type> allocator_traits_type; + template <class U, class UA, class UOptions> friend class vector; - typedef typename allocator_traits_type::pointer pointer_impl; - typedef vec_iterator<pointer_impl, false> iterator_impl; - typedef vec_iterator<pointer_impl, true > const_iterator_impl; protected: - static bool is_propagable_from(const Allocator &from_alloc, pointer_impl p, const Allocator &to_alloc, bool const propagate_allocator) + BOOST_CONTAINER_FORCEINLINE + static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator) { return alloc_holder_t::is_propagable_from(from_alloc, p, to_alloc, propagate_allocator); } - static bool are_swap_propagable( const Allocator &l_a, pointer_impl l_p - , const Allocator &r_a, pointer_impl r_p, bool const propagate_allocator) + BOOST_CONTAINER_FORCEINLINE + static bool are_swap_propagable( const allocator_type &l_a, pointer l_p + , const allocator_type &r_a, pointer r_p, bool const propagate_allocator) { return alloc_holder_t::are_swap_propagable(l_a, l_p, r_a, r_p, propagate_allocator); } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - public: - ////////////////////////////////////////////// - // - // types - // - ////////////////////////////////////////////// - - typedef T value_type; - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer; - typedef typename ::boost::container::allocator_traits<Allocator>::reference reference; - typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference; - typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type; - typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type; - typedef Allocator allocator_type; - typedef Allocator stored_allocator_type; - typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; - typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator; - typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator; - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(vector) - typedef vector_value_traits<Allocator> value_traits; - typedef constant_iterator<T, difference_type> cvalue_iterator; + typedef vector_value_traits<allocator_type> value_traits; + typedef constant_iterator<T> cvalue_iterator; protected: @@ -795,12 +823,12 @@ class vector { return this->m_holder.steal_resources(x.m_holder); } template<class AllocFwd> - BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity, BOOST_FWD_REF(AllocFwd) a) - : m_holder(initial_capacity_t(), initial_memory, capacity, ::boost::forward<AllocFwd>(a)) + BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type cap, BOOST_FWD_REF(AllocFwd) a) + : m_holder(initial_capacity_t(), initial_memory, cap, ::boost::forward<AllocFwd>(a)) {} - BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity) - : m_holder(initial_capacity_t(), initial_memory, capacity) + BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type cap) + : m_holder(initial_capacity_t(), initial_memory, cap) {} #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -817,7 +845,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value) + vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value) : m_holder() {} @@ -942,6 +970,12 @@ class vector //! throws or T's constructor taking a dereferenced InIt throws. //! //! <b>Complexity</b>: Linear to the range [first, last). +// template <class InIt> +// vector(InIt first, InIt last +// BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c +// < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value +// BOOST_MOVE_I dtl::nat >::type * = 0) +// ) -> vector<typename iterator_traits<InIt>::value_type, new_allocator<typename iterator_traits<InIt>::value_type>>; template <class InIt> vector(InIt first, InIt last BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c @@ -1005,9 +1039,14 @@ class vector //! //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()). vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type()) - : m_holder(a) + : m_holder(vector_uninitialized_size, a, il.size()) { - this->assign(il.begin(), il.end()); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += il.size() != 0; + #endif + ::boost::container::uninitialized_copy_alloc_n_source + ( this->m_holder.alloc(), il.begin() + , static_cast<size_type>(il.size()), this->priv_raw_begin()); } #endif @@ -1020,15 +1059,15 @@ class vector //! <b>Complexity</b>: Linear. //! //! <b>Note</b>: Non-standard extension to support static_vector - template<class OtherAllocator> - vector(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x + template<class OtherA> + vector(BOOST_RV_REF_BEG vector<T, OtherA, Options> BOOST_RV_REF_END x , typename dtl::enable_if_c - < dtl::is_version<OtherAllocator, 0>::value>::type * = 0 + < dtl::is_version<typename real_allocator<T, OtherA>::type, 0>::value>::type * = 0 ) : m_holder(boost::move(x.m_holder)) {} - #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #endif // defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! <b>Effects</b>: Copy constructs a vector using the specified allocator. //! @@ -1058,10 +1097,12 @@ class vector //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise. vector(BOOST_RV_REF(vector) x, const allocator_type &a) : m_holder( vector_uninitialized_size, a - , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true) ? 0 : x.size() + //In this allocator move constructor the allocator won't be propagated --v + , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, false) ? 0 : x.size() ) { - if(is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true)){ + //In this allocator move constructor the allocator won't be propagated ---v + if(is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, false)){ this->m_holder.steal_resources(x.m_holder); } else{ @@ -1098,7 +1139,7 @@ class vector //! <b>Complexity</b>: Linear to the number of elements in x. BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x) { - if (&x != this){ + if (BOOST_LIKELY(&x != this)){ this->priv_copy_assign(x); } return *this; @@ -1130,8 +1171,9 @@ class vector BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value || allocator_traits_type::is_always_equal::value) { - BOOST_ASSERT(&x != this); - this->priv_move_assign(boost::move(x)); + if (BOOST_LIKELY(&x != this)){ + this->priv_move_assign(boost::move(x)); + } return *this; } @@ -1147,13 +1189,13 @@ class vector //! <b>Complexity</b>: Linear. //! //! <b>Note</b>: Non-standard extension to support static_vector - template<class OtherAllocator> + template<class OtherA> BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and < vector& - , dtl::is_version<OtherAllocator, 0> - , dtl::is_different<OtherAllocator, allocator_type> + , dtl::is_version<typename real_allocator<T, OtherA>::type, 0> + , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type> >::type - operator=(BOOST_RV_REF_BEG vector<value_type, OtherAllocator> BOOST_RV_REF_END x) + operator=(BOOST_RV_REF_BEG vector<value_type, OtherA, Options> BOOST_RV_REF_END x) { this->priv_move_assign(boost::move(x)); return *this; @@ -1169,13 +1211,13 @@ class vector //! <b>Complexity</b>: Linear. //! //! <b>Note</b>: Non-standard extension to support static_vector - template<class OtherAllocator> + template<class OtherA> BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and < vector& - , dtl::is_version<OtherAllocator, 0> - , dtl::is_different<OtherAllocator, allocator_type> + , dtl::is_version<typename real_allocator<T, OtherA>::type, 0> + , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type> >::type - operator=(const vector<value_type, OtherAllocator> &x) + operator=(const vector<value_type, OtherA, Options> &x) { this->priv_copy_assign(x); return *this; @@ -1191,6 +1233,7 @@ class vector //! <b>Complexity</b>: Linear to n. template <class InIt> void assign(InIt first, InIt last + //Input iterators or version 0 allocator BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or < void BOOST_MOVE_I dtl::is_convertible<InIt BOOST_MOVE_I size_type> @@ -1240,6 +1283,7 @@ class vector //! <b>Complexity</b>: Linear to n. template <class FwdIt> void assign(FwdIt first, FwdIt last + //Forward iterators and version > 0 allocator BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or < void BOOST_MOVE_I dtl::is_same<alloc_version BOOST_MOVE_I version_0> @@ -1248,9 +1292,15 @@ class vector >::type * = 0) ) { + typedef typename iter_size<FwdIt>::type it_size_type; //For Fwd iterators the standard only requires EmplaceConstructible and assignable from *first //so we can't do any backwards allocation - const size_type input_sz = static_cast<size_type>(boost::container::iterator_distance(first, last)); + const it_size_type sz = boost::container::iterator_udistance(first, last); + if (sz > size_type(-1)){ + boost::container::throw_length_error("vector::assign, FwdIt's max length reached"); + } + + const size_type input_sz = static_cast<size_type>(sz); const size_type old_capacity = this->capacity(); if(input_sz > old_capacity){ //If input range is too big, we need to reallocate size_type real_cap = 0; @@ -1279,21 +1329,9 @@ class vector //Forward expansion, use assignment + back deletion/construction that comes later } } - //Overwrite all elements we can from [first, last) - iterator cur = this->begin(); - const iterator end_it = this->end(); - for ( ; first != last && cur != end_it; ++cur, ++first){ - *cur = *first; - } - if (first == last){ - //There are no more elements in the sequence, erase remaining - this->priv_destroy_last_n(this->size() - input_sz); - } - else{ - //Uninitialized construct at end the remaining range - this->priv_uninitialized_construct_at_end(first, last); - } + boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), first, input_sz, this->priv_raw_begin(), this->size()); + m_holder.set_stored_size(input_sz); } //! <b>Effects</b>: Assigns the n copies of val to *this. @@ -1310,7 +1348,7 @@ class vector //! <b>Throws</b>: If allocator's copy constructor throws. //! //! <b>Complexity</b>: Constant. - allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW { return this->m_holder.alloc(); } //! <b>Effects</b>: Returns a reference to the internal allocator. @@ -1320,7 +1358,8 @@ class vector //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW { return this->m_holder.alloc(); } //! <b>Effects</b>: Returns a reference to the internal allocator. @@ -1330,7 +1369,8 @@ class vector //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Non-standard extension. - BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW { return this->m_holder.alloc(); } ////////////////////////////////////////////// @@ -1344,7 +1384,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW { return iterator(this->m_holder.start()); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector. @@ -1352,7 +1392,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW { return const_iterator(this->m_holder.start()); } //! <b>Effects</b>: Returns an iterator to the end of the vector. @@ -1360,15 +1400,19 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW - { return iterator(this->m_holder.start() + this->m_holder.m_size); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW + { + iterator it (this->m_holder.start()); + it += difference_type(this->m_holder.m_size); + return it; //Adding zero to null pointer is allowed (non-UB) + } //! <b>Effects</b>: Returns a const_iterator to the end of the vector. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW { return this->cend(); } //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning @@ -1377,7 +1421,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW { return reverse_iterator(this->end()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning @@ -1386,7 +1430,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW { return this->crbegin(); } //! <b>Effects</b>: Returns a reverse_iterator pointing to the end @@ -1395,7 +1439,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW { return reverse_iterator(this->begin()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end @@ -1404,7 +1448,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW { return this->crend(); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector. @@ -1412,7 +1456,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW { return const_iterator(this->m_holder.start()); } //! <b>Effects</b>: Returns a const_iterator to the end of the vector. @@ -1420,8 +1464,12 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW - { return const_iterator(this->m_holder.start() + this->m_holder.m_size); } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW + { + const_iterator it (this->m_holder.start()); + it += difference_type(this->m_holder.m_size); + return it; //Adding zero to null pointer is allowed (non-UB) + } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning //! of the reversed vector. @@ -1429,7 +1477,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW { return const_reverse_iterator(this->end());} //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end @@ -1438,7 +1486,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW { return const_reverse_iterator(this->begin()); } ////////////////////////////////////////////// @@ -1452,7 +1500,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW { return !this->m_holder.m_size; } //! <b>Effects</b>: Returns the number of the elements contained in the vector. @@ -1460,7 +1508,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW { return this->m_holder.m_size; } //! <b>Effects</b>: Returns the largest possible size of the vector. @@ -1468,7 +1516,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW { return allocator_traits_type::max_size(this->m_holder.alloc()); } //! <b>Effects</b>: Inserts or erases elements at the end such that @@ -1477,8 +1525,8 @@ class vector //! <b>Throws</b>: If memory allocation throws, or T's copy/move or value initialization throws. //! //! <b>Complexity</b>: Linear to the difference between size() and new_size. - void resize(size_type new_size) - { this->priv_resize(new_size, value_init); } + BOOST_CONTAINER_FORCEINLINE void resize(size_type new_size) + { this->priv_resize(new_size, value_init, alloc_version()); } //! <b>Effects</b>: Inserts or erases elements at the end such that //! the size becomes n. New elements are default initialized. @@ -1488,8 +1536,8 @@ class vector //! <b>Complexity</b>: Linear to the difference between size() and new_size. //! //! <b>Note</b>: Non-standard extension - void resize(size_type new_size, default_init_t) - { this->priv_resize(new_size, default_init); } + BOOST_CONTAINER_FORCEINLINE void resize(size_type new_size, default_init_t) + { this->priv_resize(new_size, default_init, alloc_version()); } //! <b>Effects</b>: Inserts or erases elements at the end such that //! the size becomes n. New elements are copy constructed from x. @@ -1497,8 +1545,8 @@ class vector //! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws. //! //! <b>Complexity</b>: Linear to the difference between size() and new_size. - void resize(size_type new_size, const T& x) - { this->priv_resize(new_size, x); } + BOOST_CONTAINER_FORCEINLINE void resize(size_type new_size, const T& x) + { this->priv_resize(new_size, x, alloc_version()); } //! <b>Effects</b>: Number of elements for which memory has been allocated. //! capacity() is always greater than or equal to size(). @@ -1506,7 +1554,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return this->m_holder.capacity(); } //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no @@ -1518,7 +1566,7 @@ class vector BOOST_CONTAINER_FORCEINLINE void reserve(size_type new_cap) { if (this->capacity() < new_cap){ - this->priv_reserve_no_capacity(new_cap, alloc_version()); + this->priv_move_to_new_buffer(new_cap, alloc_version()); } } @@ -1545,7 +1593,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference front() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE reference front() BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); return *this->m_holder.start(); @@ -1559,7 +1607,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); return *this->m_holder.start(); @@ -1573,10 +1621,10 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference back() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE reference back() BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); - return this->m_holder.start()[this->m_holder.m_size - 1]; + return this->m_holder.start()[difference_type(this->m_holder.m_size - 1u)]; } //! <b>Requires</b>: !empty() @@ -1587,7 +1635,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); return this->m_holder.start()[this->m_holder.m_size - 1]; @@ -1601,10 +1649,10 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(this->m_holder.m_size > n); - return this->m_holder.start()[n]; + return this->m_holder.start()[difference_type(n)]; } //! <b>Requires</b>: size() > n. @@ -1615,7 +1663,8 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(this->m_holder.m_size > n); return this->m_holder.start()[n]; @@ -1632,10 +1681,11 @@ class vector //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Non-standard extension - iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(this->m_holder.m_size >= n); - return iterator(this->m_holder.start()+n); + return iterator(this->m_holder.start()+difference_type(n)); } //! <b>Requires</b>: size() >= n. @@ -1649,10 +1699,11 @@ class vector //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Non-standard extension - const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(this->m_holder.m_size >= n); - return const_iterator(this->m_holder.start()+n); + return const_iterator(this->m_holder.start()+difference_type(n)); } //! <b>Requires</b>: begin() <= p <= end(). @@ -1665,7 +1716,8 @@ class vector //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Non-standard extension - size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW { //Range check assert done in priv_index_of return this->priv_index_of(vector_iterator_get_ptr(p)); @@ -1681,7 +1733,8 @@ class vector //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Non-standard extension - size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW { //Range check assert done in priv_index_of return this->priv_index_of(vector_iterator_get_ptr(p)); @@ -1692,13 +1745,13 @@ class vector //! <b>Effects</b>: Returns a reference to the nth element //! from the beginning of the container. //! - //! <b>Throws</b>: std::range_error if n >= size() + //! <b>Throws</b>: range_error if n >= size() //! //! <b>Complexity</b>: Constant. - reference at(size_type n) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE reference at(size_type n) { this->priv_throw_if_out_of_range(n); - return this->m_holder.start()[n]; + return this->m_holder.start()[difference_type(n)]; } //! <b>Requires</b>: size() > n. @@ -1706,10 +1759,10 @@ class vector //! <b>Effects</b>: Returns a const reference to the nth element //! from the beginning of the container. //! - //! <b>Throws</b>: std::range_error if n >= size() + //! <b>Throws</b>: range_error if n >= size() //! //! <b>Complexity</b>: Constant. - const_reference at(size_type n) const + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_reference at(size_type n) const { this->priv_throw_if_out_of_range(n); return this->m_holder.start()[n]; @@ -1727,7 +1780,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - T* data() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE T* data() BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_raw_begin(); } //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range. @@ -1736,7 +1789,7 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const T * data() const BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const T * data() const BOOST_NOEXCEPT_OR_NOTHROW { return this->priv_raw_begin(); } ////////////////////////////////////////////// @@ -1758,17 +1811,17 @@ class vector template<class ...Args> BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_FWD_REF(Args)...args) { + T* const p = this->priv_raw_end(); if (BOOST_LIKELY(this->room_enough())){ //There is more memory, just construct a new object at the end - T* const p = this->priv_raw_end(); allocator_traits_type::construct(this->m_holder.alloc(), p, ::boost::forward<Args>(args)...); ++this->m_holder.m_size; return *p; } else{ - typedef dtl::insert_emplace_proxy<Allocator, T*, Args...> type; - return *this->priv_forward_range_insert_no_capacity - (this->back_ptr(), 1, type(::boost::forward<Args>(args)...), alloc_version()); + typedef dtl::insert_emplace_proxy<allocator_type, T*, Args...> proxy_t; + return *this->priv_insert_forward_range_no_capacity + (p, 1, proxy_t(::boost::forward<Args>(args)...), alloc_version()); } } @@ -1803,13 +1856,13 @@ class vector //! <b>Complexity</b>: If position is end(), amortized constant time //! Linear time otherwise. template<class ...Args> - iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args) + BOOST_CONTAINER_FORCEINLINE iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args) { BOOST_ASSERT(this->priv_in_range_or_end(position)); //Just call more general insert(pos, size, value) and return iterator - typedef dtl::insert_emplace_proxy<Allocator, T*, Args...> type; - return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1 - , type(::boost::forward<Args>(args)...)); + typedef dtl::insert_emplace_proxy<allocator_type, T*, Args...> proxy_t; + return this->priv_insert_forward_range( vector_iterator_get_ptr(position), 1 + , proxy_t(::boost::forward<Args>(args)...)); } #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -1818,17 +1871,17 @@ class vector BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_MOVE_UREF##N)\ {\ + T* const p = this->priv_raw_end();\ if (BOOST_LIKELY(this->room_enough())){\ - T* const p = this->priv_raw_end();\ allocator_traits_type::construct (this->m_holder.alloc()\ , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ ++this->m_holder.m_size;\ return *p;\ }\ else{\ - typedef dtl::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\ - return *this->priv_forward_range_insert_no_capacity\ - ( this->back_ptr(), 1, type(BOOST_MOVE_FWD##N), alloc_version());\ + typedef dtl::insert_emplace_proxy_arg##N<allocator_type, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\ + return *this->priv_insert_forward_range_no_capacity\ + ( p, 1, proxy_t(BOOST_MOVE_FWD##N), alloc_version());\ }\ }\ \ @@ -1845,11 +1898,11 @@ class vector }\ \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ - iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + BOOST_CONTAINER_FORCEINLINE iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ {\ BOOST_ASSERT(this->priv_in_range_or_end(pos));\ - typedef dtl::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\ - return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), 1, type(BOOST_MOVE_FWD##N));\ + typedef dtl::insert_emplace_proxy_arg##N<allocator_type, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\ + return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), 1, proxy_t(BOOST_MOVE_FWD##N));\ }\ // BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VECTOR_EMPLACE_CODE) @@ -1911,11 +1964,11 @@ class vector //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor throws. //! //! <b>Complexity</b>: Linear to n. - iterator insert(const_iterator p, size_type n, const T& x) + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, size_type n, const T& x) { BOOST_ASSERT(this->priv_in_range_or_end(p)); - dtl::insert_n_copies_proxy<Allocator, T*> proxy(x); - return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy); + dtl::insert_n_copies_proxy<allocator_type, T*> proxy(x); + return this->priv_insert_forward_range(vector_iterator_get_ptr(p), n, proxy); } //! <b>Requires</b>: p must be a valid iterator of *this. @@ -1940,18 +1993,18 @@ class vector ) { BOOST_ASSERT(this->priv_in_range_or_end(pos)); - const size_type n_pos = pos - this->cbegin(); + const size_type n_pos = size_type(pos - this->cbegin()); iterator it(vector_iterator_get_ptr(pos)); for(;first != last; ++first){ it = this->emplace(it, *first); ++it; } - return iterator(this->m_holder.start() + n_pos); + return iterator(this->m_holder.start() + difference_type(n_pos)); } #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) template <class FwdIt> - iterator insert(const_iterator pos, FwdIt first, FwdIt last + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator pos, FwdIt first, FwdIt last , typename dtl::disable_if_or < void , dtl::is_convertible<FwdIt, size_type> @@ -1959,9 +2012,15 @@ class vector >::type * = 0 ) { + typedef typename iter_size<FwdIt>::type it_size_type; BOOST_ASSERT(this->priv_in_range_or_end(pos)); - dtl::insert_range_proxy<Allocator, FwdIt, T*> proxy(first); - return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), boost::container::iterator_distance(first, last), proxy); + const it_size_type sz = boost::container::iterator_udistance(first, last); + if (sz > size_type(-1)){ + boost::container::throw_length_error("vector::insert, FwdIt's max length reached"); + } + + dtl::insert_range_proxy<allocator_type, FwdIt, T*> proxy(first); + return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), static_cast<size_type>(sz), proxy); } #endif @@ -1982,14 +2041,14 @@ class vector //! a non-standard extension. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) template <class InIt> - iterator insert(const_iterator pos, size_type num, InIt first, InIt last) + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator pos, size_type num, InIt first, InIt last) { BOOST_ASSERT(this->priv_in_range_or_end(pos)); BOOST_ASSERT(dtl::is_input_iterator<InIt>::value || - num == static_cast<size_type>(boost::container::iterator_distance(first, last))); + num == boost::container::iterator_udistance(first, last)); (void)last; - dtl::insert_range_proxy<Allocator, InIt, T*> proxy(first); - return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy); + dtl::insert_range_proxy<allocator_type, InIt, T*> proxy(first); + return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), num, proxy); } #endif @@ -2001,7 +2060,7 @@ class vector //! <b>Returns</b>: an iterator to the first inserted element or position if first == last. //! //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()). - iterator insert(const_iterator position, std::initializer_list<value_type> il) + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, std::initializer_list<value_type> il) { //Assertion done in insert() return this->insert(position, il.begin(), il.end()); @@ -2013,11 +2072,12 @@ class vector //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant time. - void pop_back() BOOST_NOEXCEPT_OR_NOTHROW + BOOST_CONTAINER_FORCEINLINE void pop_back() BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(!this->empty()); //Destroy last element - this->priv_destroy_last(); + allocator_traits_type::destroy(this->get_stored_allocator(), this->priv_raw_end() - 1); + --this->m_holder.m_size; } //! <b>Effects</b>: Erases the element at position pos. @@ -2031,10 +2091,16 @@ class vector BOOST_ASSERT(this->priv_in_range(position)); const pointer p = vector_iterator_get_ptr(position); T *const pos_ptr = boost::movelib::to_raw_pointer(p); - T *const beg_ptr = this->priv_raw_begin(); - T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr); + T *const end_ptr = this->priv_raw_end(); + //Move elements forward and destroy last - this->priv_destroy_last(pos_ptr != new_end_ptr); + (void)::boost::container::move(pos_ptr + 1, end_ptr, pos_ptr); + + T *const last_ptr = end_ptr-1; + if(!value_traits::trivial_dctr_after_move || pos_ptr == last_ptr){ + allocator_traits_type::destroy(this->get_stored_allocator(), last_ptr); + } + --this->m_holder.m_size; return iterator(p); } @@ -2046,14 +2112,19 @@ class vector //! plus linear to the elements between pos and the last element. iterator erase(const_iterator first, const_iterator last) { - BOOST_ASSERT(first == last || - (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last))); - if (first != last){ + BOOST_ASSERT(this->priv_in_range_or_end(first)); + BOOST_ASSERT(this->priv_in_range_or_end(last)); + BOOST_ASSERT(first <= last); + if(first != last){ T* const old_end_ptr = this->priv_raw_end(); T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first)); T* const last_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last)); - T* const ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr)); - this->priv_destroy_last_n(old_end_ptr - ptr); + T* const new_last_ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr)); + const size_type n = static_cast<size_type>(old_end_ptr - new_last_ptr); + if(!value_traits::trivial_dctr_after_move || old_end_ptr == last_ptr){ + boost::container::destroy_alloc_n(this->get_stored_allocator(), new_last_ptr, n); + } + this->m_holder.dec_stored_size(n); } return iterator(vector_iterator_get_ptr(first)); } @@ -2066,9 +2137,9 @@ class vector BOOST_CONTAINER_FORCEINLINE void swap(vector& x) BOOST_NOEXCEPT_IF( ((allocator_traits_type::propagate_on_container_swap::value || allocator_traits_type::is_always_equal::value) && - !dtl::is_version<Allocator, 0>::value)) + !dtl::is_version<allocator_type, 0>::value)) { - this->priv_swap(x, dtl::bool_<dtl::is_version<Allocator, 0>::value>()); + this->priv_swap(x, dtl::bool_<dtl::is_version<allocator_type, 0>::value>()); } #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -2080,12 +2151,12 @@ class vector //! <b>Complexity</b>: Linear //! //! <b>Note</b>: Non-standard extension to support static_vector - template<class OtherAllocator> - BOOST_CONTAINER_FORCEINLINE void swap(vector<T, OtherAllocator> & x + template<class OtherA> + BOOST_CONTAINER_FORCEINLINE void swap(vector<T, OtherA, Options> & x , typename dtl::enable_if_and < void - , dtl::is_version<OtherAllocator, 0> - , dtl::is_different<OtherAllocator, allocator_type> + , dtl::is_version<typename real_allocator<T, OtherA>::type, 0> + , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type> >::type * = 0 ) { this->m_holder.deep_swap(x.m_holder); } @@ -2103,51 +2174,44 @@ class vector //! <b>Effects</b>: Returns true if x and y are equal //! //! <b>Complexity</b>: Linear to the number of elements in the container. - BOOST_CONTAINER_FORCEINLINE friend bool operator==(const vector& x, const vector& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE friend bool operator==(const vector& x, const vector& y) { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } //! <b>Effects</b>: Returns true if x and y are unequal //! //! <b>Complexity</b>: Linear to the number of elements in the container. - BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const vector& x, const vector& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const vector& x, const vector& y) { return !(x == y); } //! <b>Effects</b>: Returns true if x is less than y //! //! <b>Complexity</b>: Linear to the number of elements in the container. - friend bool operator<(const vector& x, const vector& y) - { - const_iterator first1(x.cbegin()), first2(y.cbegin()); - const const_iterator last1(x.cend()), last2(y.cend()); - for ( ; (first1 != last1) && (first2 != last2); ++first1, ++first2 ) { - if (*first1 < *first2) return true; - if (*first2 < *first1) return false; - } - return (first1 == last1) && (first2 != last2); - } + BOOST_CONTAINER_ATTRIBUTE_NODISCARD friend bool operator<(const vector& x, const vector& y) + { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } //! <b>Effects</b>: Returns true if x is greater than y //! //! <b>Complexity</b>: Linear to the number of elements in the container. - BOOST_CONTAINER_FORCEINLINE friend bool operator>(const vector& x, const vector& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE friend bool operator>(const vector& x, const vector& y) { return y < x; } //! <b>Effects</b>: Returns true if x is equal or less than y //! //! <b>Complexity</b>: Linear to the number of elements in the container. - BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const vector& x, const vector& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const vector& x, const vector& y) { return !(y < x); } //! <b>Effects</b>: Returns true if x is equal or greater than y //! //! <b>Complexity</b>: Linear to the number of elements in the container. - BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const vector& x, const vector& y) + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const vector& x, const vector& y) { return !(x < y); } //! <b>Effects</b>: x.swap(y) //! //! <b>Complexity</b>: Constant. BOOST_CONTAINER_FORCEINLINE friend void swap(vector& x, vector& y) + BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) { x.swap(y); } #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -2163,7 +2227,7 @@ class vector bool stable_reserve(size_type new_cap) { const size_type cp = this->capacity(); - return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(new_cap - cp)); + return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(size_type(new_cap - cp))); } //Absolutely experimental. This function might change, disappear or simply crash! @@ -2187,11 +2251,11 @@ class vector size_type const free_cap = c - s; //If not input iterator and new elements don't fit in the remaining capacity, merge in new buffer if(!dtl::is_input_iterator<InputIt>::value && - free_cap < (n = static_cast<size_type>(boost::container::iterator_distance(first, last)))){ + free_cap < (n = boost::container::iterator_udistance(first, last))){ this->priv_merge_in_new_buffer(first, n, comp, alloc_version()); } else{ - iterator pos(this->insert(this->cend(), first, last)); + this->insert(this->cend(), first, last); T *const raw_beg = this->priv_raw_begin(); T *const raw_end = this->priv_raw_end(); T *const raw_pos = raw_beg + s; @@ -2206,11 +2270,11 @@ class vector template<class InputIt, class Compare> BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last, Compare comp) { - size_type const s = this->size(); + size_type const old_size = this->size(); this->priv_set_difference_back(first, last, comp); T *const raw_beg = this->priv_raw_begin(); T *const raw_end = this->priv_raw_end(); - T *raw_pos = raw_beg + s; + T *raw_pos = raw_beg + old_size; boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size()); } @@ -2254,14 +2318,14 @@ class vector else{ //Hole was just filled, disable exception rollback and change vector size past_hole_values_destroyer.release(); - this->m_holder.m_size += element_count; + this->m_holder.inc_stored_size(element_count); } } else{ if(old_hole_size){ //Hole was just filled by priv_insert_ordered_at_shift_range, disable exception rollback and change vector size past_hole_values_destroyer.release(); - this->m_holder.m_size += element_count; + this->m_holder.inc_stored_size(element_count); } //Insert the new value in the already constructed range begin_ptr[pos + insertions_left - 1] = position_value.get_val(); @@ -2287,14 +2351,14 @@ class vector if (comp(*first1, *first2)) { this->emplace_back(*first1); - //Reallocation happened, update range T * const raw_begin = this->priv_raw_begin(); - if(old_first2 != raw_begin){ + if(old_first2 != raw_begin) + { + //Reallocation happened, update range first2 = raw_begin + (first2 - old_first2); - last2 = first2 + (last2 - old_first2); + last2 = raw_begin + (last2 - old_first2); old_first2 = raw_begin; } - ++first1; } else { @@ -2309,7 +2373,7 @@ class vector template<class FwdIt, class Compare> BOOST_CONTAINER_FORCEINLINE void priv_merge_in_new_buffer(FwdIt, size_type, Compare, version_0) { - throw_bad_alloc(); + alloc_holder_t::on_capacity_overflow(); } template<class FwdIt, class Compare, class Version> @@ -2359,8 +2423,10 @@ class vector pointer const old_p = this->m_holder.start(); size_type const old_cap = this->m_holder.capacity(); boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size); - this->m_holder.deallocate(old_p, old_cap); - this->m_holder.m_size = old_size + added; + if (old_cap > 0) { + this->m_holder.deallocate(old_p, old_cap); + } + m_holder.set_stored_size(old_size + added); this->m_holder.start(new_storage); this->m_holder.capacity(new_cap); new_buffer_deallocator.release(); @@ -2368,99 +2434,100 @@ class vector } BOOST_CONTAINER_FORCEINLINE bool room_enough() const - { return this->m_holder.m_size < this->m_holder.capacity(); } + { return this->m_holder.m_size != this->m_holder.capacity(); } BOOST_CONTAINER_FORCEINLINE pointer back_ptr() const - { return this->m_holder.start() + this->m_holder.m_size; } + { return this->m_holder.start() + difference_type(this->m_holder.m_size); } - size_type priv_index_of(pointer p) const + BOOST_CONTAINER_FORCEINLINE size_type priv_index_of(pointer p) const { BOOST_ASSERT(this->m_holder.start() <= p); - BOOST_ASSERT(p <= (this->m_holder.start()+this->size())); + BOOST_ASSERT(p <= (this->m_holder.start()+difference_type(this->size()))); return static_cast<size_type>(p - this->m_holder.start()); } - template<class OtherAllocator> - void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x + template<class OtherA> + void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherA, Options> BOOST_RV_REF_END x , typename dtl::enable_if_c - < dtl::is_version<OtherAllocator, 0>::value >::type * = 0) + < dtl::is_version<typename real_allocator<T, OtherA>::type, 0>::value >::type * = 0) { - if(!dtl::is_same<OtherAllocator, allocator_type>::value && + if(!dtl::is_same<typename real_allocator<T, OtherA>::type, allocator_type>::value && this->capacity() < x.size()){ - throw_bad_alloc(); + alloc_holder_t::on_capacity_overflow(); } T* const this_start = this->priv_raw_begin(); T* const other_start = x.priv_raw_begin(); const size_type this_sz = m_holder.m_size; const size_type other_sz = static_cast<size_type>(x.m_holder.m_size); boost::container::move_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz); - this->m_holder.m_size = other_sz; + m_holder.set_stored_size(other_sz); + //Not emptying the source container seems to be confusing for users as drop-in + //replacement for non-static vectors, so clear it. + x.clear(); } - template<class OtherAllocator> - void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x + template<class OtherA> + void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherA, Options> BOOST_RV_REF_END x , typename dtl::disable_if_or < void - , dtl::is_version<OtherAllocator, 0> - , dtl::is_different<OtherAllocator, allocator_type> + , dtl::is_version<typename real_allocator<T, OtherA>::type, 0> + , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type> >::type * = 0) { - //for move assignment, no aliasing (&x != this) is assummed. - BOOST_ASSERT(this != &x); + //for move assignment, no aliasing (&x != this) is assumed. + //x.size() == 0 is allowed for buggy std libraries. + BOOST_ASSERT(this != &x || x.size() == 0); allocator_type &this_alloc = this->m_holder.alloc(); allocator_type &x_alloc = x.m_holder.alloc(); const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value; + //In this allocator move constructor the allocator maybe will be propagated -----------------------v const bool is_propagable_from_x = is_propagable_from(x_alloc, x.m_holder.start(), this_alloc, propagate_alloc); - const bool is_propagable_from_t = is_propagable_from(this_alloc, m_holder.start(), x_alloc, propagate_alloc); - const bool are_both_propagable = is_propagable_from_x && is_propagable_from_t; //Resources can be transferred if both allocators are //going to be equal after this function (either propagated or already equal) - if(are_both_propagable){ - //Destroy objects but retain memory in case x reuses it in the future + if(is_propagable_from_x){ this->clear(); - this->m_holder.swap_resources(x.m_holder); - } - else if(is_propagable_from_x){ - this->clear(); - this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity); + if(BOOST_LIKELY(!!this->m_holder.m_start)) + this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity); this->m_holder.steal_resources(x.m_holder); } - //Else do a one by one move + //Else do a one by one move. Also, clear the source as users find confusing + //elements are still alive in the source container. else{ this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin())) , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end() )) ); + x.clear(); } //Move allocator if needed dtl::move_alloc(this_alloc, x_alloc, dtl::bool_<propagate_alloc>()); } - template<class OtherAllocator> - void priv_copy_assign(const vector<T, OtherAllocator> &x + template<class OtherA> + void priv_copy_assign(const vector<T, OtherA, Options> &x , typename dtl::enable_if_c - < dtl::is_version<OtherAllocator, 0>::value >::type * = 0) + < dtl::is_version<typename real_allocator<T, OtherA>::type, 0>::value >::type * = 0) { - if(!dtl::is_same<OtherAllocator, allocator_type>::value && + if(!dtl::is_same<typename real_allocator<T, OtherA>::type, allocator_type>::value && this->capacity() < x.size()){ - throw_bad_alloc(); + alloc_holder_t::on_capacity_overflow(); } T* const this_start = this->priv_raw_begin(); T* const other_start = x.priv_raw_begin(); const size_type this_sz = m_holder.m_size; const size_type other_sz = static_cast<size_type>(x.m_holder.m_size); boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz); - this->m_holder.m_size = other_sz; + m_holder.set_stored_size(other_sz); } - template<class OtherAllocator> + template<class OtherA> typename dtl::disable_if_or < void - , dtl::is_version<OtherAllocator, 0> - , dtl::is_different<OtherAllocator, allocator_type> + , dtl::is_version<typename real_allocator<T, OtherA>::type, 0> + , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type> >::type - priv_copy_assign(const vector<T, OtherAllocator> &x) + priv_copy_assign(const vector<T, OtherA, Options> &x) { allocator_type &this_alloc = this->m_holder.alloc(); const allocator_type &x_alloc = x.m_holder.alloc(); @@ -2475,15 +2542,18 @@ class vector } template<class Vector> //Template it to avoid it in explicit instantiations - void priv_swap(Vector &x, dtl::true_type) //version_0 + BOOST_CONTAINER_FORCEINLINE void priv_swap(Vector &x, dtl::true_type) //version_0 { this->m_holder.deep_swap(x.m_holder); } template<class Vector> //Template it to avoid it in explicit instantiations void priv_swap(Vector &x, dtl::false_type) //version_N { const bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value; - if(are_swap_propagable( this->get_stored_allocator(), this->m_holder.start() - , x.get_stored_allocator(), x.m_holder.start(), propagate_alloc)){ + if (BOOST_UNLIKELY(&x == this)){ + return; + } + else if(are_swap_propagable( this->get_stored_allocator(), this->m_holder.start() + , x.get_stored_allocator(), x.m_holder.start(), propagate_alloc)){ //Just swap internals this->m_holder.swap_resources(x.m_holder); } @@ -2493,42 +2563,54 @@ class vector vector &sml = t_smaller ? *this : x; vector &big = t_smaller ? x : *this; - size_type const common_elements = sml.size(); - for(size_type i = 0; i != common_elements; ++i){ - boost::adl_move_swap(sml[i], big[i]); + //For empty containers, maybe storage can be moved from the other (just like in the move constructor) + if(sml.empty() && is_propagable_from(big.get_stored_allocator(), big.data(), sml.get_allocator(), propagate_alloc)){ + if(BOOST_LIKELY(0u != sml.capacity())) + sml.m_holder.deallocate(sml.m_holder.m_start, sml.m_holder.m_capacity); + sml.steal_resources(big); + } + else { + //Else swap element by element... + size_type const common_elements = sml.size(); + for(size_type i = 0; i != common_elements; ++i){ + boost::adl_move_swap(sml[i], big[i]); + } + //... and move-insert the remaining range + sml.insert( sml.cend() + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.nth(common_elements))) + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end())) + ); + //Destroy remaining elements + big.erase(big.nth(common_elements), big.cend()); } - //... and move-insert the remaining range - sml.insert( sml.cend() - , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.nth(common_elements))) - , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end())) - ); - //Destroy remaining elements - big.erase(big.nth(common_elements), big.cend()); } //And now swap the allocator dtl::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), dtl::bool_<propagate_alloc>()); } - void priv_reserve_no_capacity(size_type, version_0) - { throw_bad_alloc(); } + BOOST_CONTAINER_FORCEINLINE void priv_move_to_new_buffer(size_type, version_0) + { alloc_holder_t::on_capacity_overflow(); } - dtl::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*> priv_dummy_empty_proxy() + BOOST_CONTAINER_FORCEINLINE dtl::insert_range_proxy<allocator_type, boost::move_iterator<T*>, T*> priv_dummy_empty_proxy() { - return dtl::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*> + return dtl::insert_range_proxy<allocator_type, boost::move_iterator<T*>, T*> (::boost::make_move_iterator((T *)0)); } - void priv_reserve_no_capacity(size_type new_cap, version_1) + BOOST_CONTAINER_FORCEINLINE void priv_move_to_new_buffer(size_type new_cap, version_1) { //There is not enough memory, allocate a new buffer //Pass the hint so that allocators can take advantage of this. pointer const p = this->m_holder.allocate(new_cap); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif //We will reuse insert code, so create a dummy input iterator - this->priv_forward_range_insert_new_allocation + this->priv_insert_forward_range_new_allocation ( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy()); } - void priv_reserve_no_capacity(size_type new_cap, version_2) + void priv_move_to_new_buffer(size_type new_cap, version_2) { //There is not enough memory, allocate a new //buffer or expand the old one. @@ -2552,38 +2634,24 @@ class vector #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_expand_bwd; #endif - this->priv_forward_range_insert_expand_backwards - ( new_mem , real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); + this->priv_insert_forward_range_expand_backwards + ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); } else{ //New buffer #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_alloc; #endif - this->priv_forward_range_insert_new_allocation + this->priv_insert_forward_range_new_allocation ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); } } } - void priv_destroy_last(const bool moved = false) BOOST_NOEXCEPT_OR_NOTHROW - { - (void)moved; - const bool skip_destructor = value_traits::trivial_dctr || (value_traits::trivial_dctr_after_move && moved); - if(!skip_destructor){ - value_type* const p = this->priv_raw_end() - 1; - allocator_traits_type::destroy(this->get_stored_allocator(), p); - } - --this->m_holder.m_size; - } - void priv_destroy_last_n(const size_type n) BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT(n <= this->m_holder.m_size); - if(!value_traits::trivial_dctr){ - T* const destroy_pos = this->priv_raw_begin() + (this->m_holder.m_size-n); - boost::container::destroy_alloc_n(this->get_stored_allocator(), destroy_pos, n); - } - this->m_holder.m_size -= n; + boost::container::destroy_alloc_n(this->get_stored_allocator(), this->priv_raw_end() - n, n); + this->m_holder.dec_stored_size(n); } template<class InpIt> @@ -2591,7 +2659,7 @@ class vector { T* const old_end_pos = this->priv_raw_end(); T* const new_end_pos = boost::container::uninitialized_copy_alloc(this->m_holder.alloc(), first, last, old_end_pos); - this->m_holder.m_size += new_end_pos - old_end_pos; + this->m_holder.inc_stored_size(static_cast<size_type>(new_end_pos - old_end_pos)); } void priv_destroy_all() BOOST_NOEXCEPT_OR_NOTHROW @@ -2602,57 +2670,32 @@ class vector } template<class U> - iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x) + BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) u) { - BOOST_ASSERT(this->priv_in_range_or_end(p)); - return this->priv_forward_range_insert - ( vector_iterator_get_ptr(p), 1, dtl::get_insert_value_proxy<T*, Allocator>(::boost::forward<U>(x))); + return this->emplace(p, ::boost::forward<U>(u)); } - dtl::insert_copy_proxy<Allocator, T*> priv_single_insert_proxy(const T &x) - { return dtl::insert_copy_proxy<Allocator, T*> (x); } - - dtl::insert_move_proxy<Allocator, T*> priv_single_insert_proxy(BOOST_RV_REF(T) x) - { return dtl::insert_move_proxy<Allocator, T*> (x); } - template <class U> - void priv_push_back(BOOST_FWD_REF(U) u) + BOOST_CONTAINER_FORCEINLINE void priv_push_back(BOOST_FWD_REF(U) u) { - if (BOOST_LIKELY(this->room_enough())){ - //There is more memory, just construct a new object at the end - allocator_traits_type::construct - ( this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward<U>(u) ); - ++this->m_holder.m_size; - } - else{ - this->priv_forward_range_insert_no_capacity - ( this->back_ptr(), 1 - , this->priv_single_insert_proxy(::boost::forward<U>(u)), alloc_version()); - } + this->emplace_back(::boost::forward<U>(u)); } - BOOST_CONTAINER_FORCEINLINE dtl::insert_n_copies_proxy<Allocator, T*> priv_resize_proxy(const T &x) - { return dtl::insert_n_copies_proxy<Allocator, T*>(x); } + //Overload to support compiler errors that instantiate too much + BOOST_CONTAINER_FORCEINLINE void priv_push_back(::boost::move_detail::nat) + {} - BOOST_CONTAINER_FORCEINLINE dtl::insert_default_initialized_n_proxy<Allocator, T*> priv_resize_proxy(default_init_t) - { return dtl::insert_default_initialized_n_proxy<Allocator, T*>(); } + BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator, ::boost::move_detail::nat) + { return iterator(); } - BOOST_CONTAINER_FORCEINLINE dtl::insert_value_initialized_n_proxy<Allocator, T*> priv_resize_proxy(value_init_t) - { return dtl::insert_value_initialized_n_proxy<Allocator, T*>(); } + BOOST_CONTAINER_FORCEINLINE dtl::insert_n_copies_proxy<allocator_type, T*> priv_resize_proxy(const T &x) + { return dtl::insert_n_copies_proxy<allocator_type, T*>(x); } - template <class U> - void priv_resize(size_type new_size, const U& u) - { - const size_type sz = this->size(); - if (new_size < sz){ - //Destroy last elements - this->priv_destroy_last_n(sz - new_size); - } - else{ - const size_type n = new_size - this->size(); - this->priv_forward_range_insert_at_end(n, this->priv_resize_proxy(u), alloc_version()); - } - } + BOOST_CONTAINER_FORCEINLINE dtl::insert_default_initialized_n_proxy<allocator_type, T*> priv_resize_proxy(default_init_t) + { return dtl::insert_default_initialized_n_proxy<allocator_type, T*>(); } + + BOOST_CONTAINER_FORCEINLINE dtl::insert_value_initialized_n_proxy<allocator_type, T*> priv_resize_proxy(value_init_t) + { return dtl::insert_value_initialized_n_proxy<allocator_type, T*>(); } BOOST_CONTAINER_FORCEINLINE void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW {} @@ -2663,22 +2706,13 @@ class vector if(cp){ const size_type sz = this->size(); if(!sz){ - this->m_holder.deallocate(this->m_holder.m_start, cp); + if(BOOST_LIKELY(!!this->m_holder.m_start)) + this->m_holder.deallocate(this->m_holder.m_start, cp); this->m_holder.m_start = pointer(); this->m_holder.m_capacity = 0; } else if(sz < cp){ - //Allocate a new buffer. - //Pass the hint so that allocators can take advantage of this. - pointer const p = this->m_holder.allocate(sz); - - //We will reuse insert code, so create a dummy input iterator - #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS - ++this->num_alloc; - #endif - this->priv_forward_range_insert_new_allocation - ( boost::movelib::to_raw_pointer(p), sz - , this->priv_raw_begin(), 0, this->priv_dummy_empty_proxy()); + this->priv_move_to_new_buffer(sz, alloc_version()); } } } @@ -2689,7 +2723,8 @@ class vector if(cp){ const size_type sz = this->size(); if(!sz){ - this->m_holder.deallocate(this->m_holder.m_start, cp); + if(BOOST_LIKELY(!!this->m_holder.m_start)) + this->m_holder.deallocate(this->m_holder.m_start, cp); this->m_holder.m_start = pointer(); this->m_holder.m_capacity = 0; } @@ -2708,20 +2743,18 @@ class vector } template <class InsertionProxy> - iterator priv_forward_range_insert_no_capacity - (const pointer &pos, const size_type, const InsertionProxy , version_0) + BOOST_CONTAINER_FORCEINLINE iterator priv_insert_forward_range_no_capacity + (T * const, const size_type, const InsertionProxy , version_0) { - throw_bad_alloc(); - return iterator(pos); + return alloc_holder_t::on_capacity_overflow(), iterator(); } template <class InsertionProxy> - iterator priv_forward_range_insert_no_capacity - (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_1) + BOOST_CONTAINER_NOINLINE iterator priv_insert_forward_range_no_capacity + (T *const raw_pos, const size_type n, const InsertionProxy insert_range_proxy, version_1) { //Check if we have enough memory or try to expand current memory - const size_type n_pos = pos - this->m_holder.start(); - T *const raw_pos = boost::movelib::to_raw_pointer(pos); + const size_type n_pos = static_cast<size_type>(raw_pos - this->priv_raw_begin()); const size_type new_cap = this->m_holder.template next_capacity<growth_factor_type>(n); //Pass the hint so that allocators can take advantage of this. @@ -2729,25 +2762,23 @@ class vector #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_alloc; #endif - this->priv_forward_range_insert_new_allocation - ( new_buf, new_cap, raw_pos, n, insert_range_proxy); - return iterator(this->m_holder.start() + n_pos); + this->priv_insert_forward_range_new_allocation(new_buf, new_cap, raw_pos, n, insert_range_proxy); + return iterator(this->m_holder.start() + difference_type(n_pos)); } template <class InsertionProxy> - iterator priv_forward_range_insert_no_capacity - (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_2) + BOOST_CONTAINER_NOINLINE iterator priv_insert_forward_range_no_capacity + (T *const raw_pos, const size_type n, const InsertionProxy insert_range_proxy, version_2) { //Check if we have enough memory or try to expand current memory - T *const raw_pos = boost::movelib::to_raw_pointer(pos); - const size_type n_pos = raw_pos - this->priv_raw_begin(); + const size_type n_pos = size_type(raw_pos - this->priv_raw_begin()); //There is not enough memory, allocate a new //buffer or expand the old one. size_type real_cap = this->m_holder.template next_capacity<growth_factor_type>(n); pointer reuse(this->m_holder.start()); pointer const ret (this->m_holder.allocation_command - (allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse)); + (allocate_new | expand_fwd | expand_bwd, size_type(this->m_holder.m_size + n), real_cap, reuse)); //Buffer reallocated if(reuse){ @@ -2758,14 +2789,15 @@ class vector #endif this->m_holder.capacity(real_cap); //Expand forward - this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy); + this->priv_insert_forward_range_expand_forward + (raw_pos, n, insert_range_proxy, dtl::bool_<dtl::is_single_value_proxy<InsertionProxy>::value>()); } //Backwards (and possibly forward) expansion else{ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_expand_bwd; #endif - this->priv_forward_range_insert_expand_backwards + this->priv_insert_forward_range_expand_backwards (boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy); } } @@ -2774,54 +2806,61 @@ class vector #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_alloc; #endif - this->priv_forward_range_insert_new_allocation + this->priv_insert_forward_range_new_allocation ( boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy); } - return iterator(this->m_holder.start() + n_pos); + return iterator(this->m_holder.start() + (difference_type)(n_pos)); } template <class InsertionProxy> - iterator priv_forward_range_insert + BOOST_CONTAINER_FORCEINLINE iterator priv_insert_forward_range (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy) { BOOST_ASSERT(this->m_holder.capacity() >= this->m_holder.m_size); + T *const p = boost::movelib::to_raw_pointer(pos); //Check if we have enough memory or try to expand current memory - const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size; - - bool same_buffer_start = n <= remaining; - if (!same_buffer_start){ - return priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version()); + if (BOOST_LIKELY(n <= (this->m_holder.capacity() - this->m_holder.m_size))){ + //Expand forward + this->priv_insert_forward_range_expand_forward + (p, n, insert_range_proxy, dtl::bool_<dtl::is_single_value_proxy<InsertionProxy>::value>()); + return iterator(pos); } else{ - //Expand forward - T *const raw_pos = boost::movelib::to_raw_pointer(pos); - const size_type n_pos = raw_pos - this->priv_raw_begin(); - this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy); - return iterator(this->m_holder.start() + n_pos); + return this->priv_insert_forward_range_no_capacity(p, n, insert_range_proxy, alloc_version()); } } - template <class InsertionProxy> - iterator priv_forward_range_insert_at_end - (const size_type n, const InsertionProxy insert_range_proxy, version_0) + template <class U> + void priv_resize(const size_type new_size, const U &u, version_0) { - //Check if we have enough memory or try to expand current memory - const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size; - - if (n > remaining){ + const size_type sz = this->m_holder.m_size; + if (new_size > this->capacity()){ //This will trigger an error - throw_bad_alloc(); + alloc_holder_t::on_capacity_overflow(); + } + else if (new_size < sz){ + //Destroy last elements + this->priv_destroy_last_n(sz - new_size); + } + else{ + T* const old_finish = this->priv_raw_end(); + this->priv_resize_proxy(u).uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, new_size - sz); + this->m_holder.set_stored_size(new_size); } - this->priv_forward_range_insert_at_end_expand_forward(n, insert_range_proxy); - return this->end(); } - template <class InsertionProxy, class AllocVersion> - BOOST_CONTAINER_FORCEINLINE iterator priv_forward_range_insert_at_end - (const size_type n, const InsertionProxy insert_range_proxy, AllocVersion) + template <class U, class AllocVersion> + void priv_resize(const size_type new_size, const U &u, AllocVersion) { - return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy); + const size_type sz = this->m_holder.m_size; + if (new_size < sz){ + //Destroy last elements + this->priv_destroy_last_n(size_type(sz - new_size)); + } + else { + this->priv_insert_forward_range(this->back_ptr(), size_type(new_size - sz), this->priv_resize_proxy(u)); + } } //Takes the range pointed by [first_pos, last_pos) and shifts it to the right @@ -2896,7 +2935,9 @@ class vector //All uninitialized_moved ::boost::container::uninitialized_move_alloc (this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count); - hole_size = first_pos + shift_count - limit_pos; + //Cast in case size_type is narrower than int, promotions are applied + //and Wconversion is in place + hole_size = static_cast<size_type>(first_pos + shift_count - limit_pos); } //Case C: else{ @@ -2917,103 +2958,69 @@ class vector BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() const { return this->priv_raw_begin() + this->m_holder.m_size; } - template <class InsertionProxy> - void priv_forward_range_insert_at_end_expand_forward(const size_type n, InsertionProxy insert_range_proxy) + template <class InsertionProxy> //inline single-element version as it is significantly smaller + BOOST_CONTAINER_FORCEINLINE void priv_insert_forward_range_expand_forward + (T* const raw_pos, const size_type, InsertionProxy insert_range_proxy, dtl::true_type) { - T* const old_finish = this->priv_raw_end(); - insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); - this->m_holder.m_size += n; - } - - template <class InsertionProxy> - void priv_forward_range_insert_expand_forward(T* const pos, const size_type n, InsertionProxy insert_range_proxy) - { - //n can't be 0, because there is nothing to do in that case - if(BOOST_UNLIKELY(!n)) return; + BOOST_ASSERT(this->room_enough()); //There is enough memory T* const old_finish = this->priv_raw_end(); - const size_type elems_after = old_finish - pos; + allocator_type & a = this->m_holder.alloc(); - if (!elems_after){ - insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); - this->m_holder.m_size += n; + if (old_finish == raw_pos){ + insert_range_proxy.uninitialized_copy_n_and_update(a, old_finish, 1); + ++this->m_holder.m_size; } - else if (elems_after >= n){ + else{ //New elements can be just copied. //Move to uninitialized memory last objects - ::boost::container::uninitialized_move_alloc - (this->m_holder.alloc(), old_finish - n, old_finish, old_finish); - this->m_holder.m_size += n; + T * const before_old_finish = old_finish-1; + + allocator_traits_type::construct(a, old_finish, ::boost::move(*before_old_finish)); + ++this->m_holder.m_size; //Copy previous to last objects to the initialized end - boost::container::move_backward(pos, old_finish - n, old_finish); - //Insert new objects in the pos - insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n); - } - else { - //The new elements don't fit in the [pos, end()) range. - - //Copy old [pos, end()) elements to the uninitialized memory (a gap is created) - ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pos, old_finish, pos + n); - BOOST_TRY{ - //Copy first new elements in pos (gap is still there) - insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elems_after); - //Copy to the beginning of the unallocated zone the last new elements (the gap is closed). - insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n - elems_after); - this->m_holder.m_size += n; - } - BOOST_CATCH(...){ - boost::container::destroy_alloc_n(this->get_stored_allocator(), pos + n, elems_after); - BOOST_RETHROW - } - BOOST_CATCH_END + boost::container::move_backward(raw_pos, before_old_finish, old_finish); + //Insert new objects in the raw_pos + insert_range_proxy.copy_n_and_update(a, raw_pos, 1); } } template <class InsertionProxy> - void priv_forward_range_insert_new_allocation + BOOST_CONTAINER_FORCEINLINE void priv_insert_forward_range_expand_forward(T* const raw_pos, const size_type n, InsertionProxy insert_range_proxy, dtl::false_type) + { + //There is enough memory + boost::container::expand_forward_and_insert_alloc + ( this->m_holder.alloc(), raw_pos, this->priv_raw_end(), n, insert_range_proxy); + this->m_holder.inc_stored_size(n); + } + + template <class InsertionProxy> + void priv_insert_forward_range_new_allocation (T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy) { //n can be zero, if we want to reallocate! - T *new_finish = new_start; - T *old_finish; - //Anti-exception rollbacks - typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, this->m_holder.alloc(), new_cap); - typename value_traits::ArrayDestructor new_values_destroyer(new_start, this->m_holder.alloc(), 0u); - - //Initialize with [begin(), pos) old buffer - //the start of the new buffer - T * const old_buffer = this->priv_raw_begin(); - if(old_buffer){ - new_finish = ::boost::container::uninitialized_move_alloc - (this->m_holder.alloc(), this->priv_raw_begin(), pos, old_finish = new_finish); - new_values_destroyer.increment_size(new_finish - old_finish); - } - //Initialize new objects, starting from previous point - old_finish = new_finish; - insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); - new_finish += n; - new_values_destroyer.increment_size(new_finish - old_finish); - //Initialize from the rest of the old buffer, - //starting from previous point - if(old_buffer){ - new_finish = ::boost::container::uninitialized_move_alloc - (this->m_holder.alloc(), pos, old_buffer + this->m_holder.m_size, new_finish); - //Destroy and deallocate old elements - //If there is allocated memory, destroy and deallocate - if(!value_traits::trivial_dctr_after_move) - boost::container::destroy_alloc_n(this->get_stored_allocator(), old_buffer, this->m_holder.m_size); + allocator_type &a = this->m_holder.alloc(); + T * const raw_old_buffer = this->priv_raw_begin(); + + typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, a, new_cap); + boost::container::uninitialized_move_and_insert_alloc + (a, raw_old_buffer, pos, this->priv_raw_end(), new_start, n, insert_range_proxy); + new_buffer_deallocator.release(); + + //Destroy and deallocate old elements + if(raw_old_buffer){ + BOOST_IF_CONSTEXPR(!has_trivial_destructor_after_move<value_type>::value) + boost::container::destroy_alloc_n(a, raw_old_buffer, this->m_holder.m_size); this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity()); } + this->m_holder.start(new_start); - this->m_holder.m_size = size_type(new_finish - new_start); + this->m_holder.inc_stored_size(n); this->m_holder.capacity(new_cap); - //All construction successful, disable rollbacks - new_values_destroyer.release(); - new_buffer_deallocator.release(); } template <class InsertionProxy> - void priv_forward_range_insert_expand_backwards + void priv_insert_forward_range_expand_backwards (T* const new_start, const size_type new_capacity, T* const pos, const size_type n, InsertionProxy insert_range_proxy) { @@ -3022,29 +3029,32 @@ class vector T* const old_start = this->priv_raw_begin(); const size_type old_size = this->m_holder.m_size; T* const old_finish = old_start + old_size; - - //We can have 8 possibilities: - const size_type elemsbefore = static_cast<size_type>(pos - old_start); - const size_type s_before = static_cast<size_type>(old_start - new_start); - const size_type before_plus_new = elemsbefore + n; + allocator_type &a = this->m_holder.alloc(); //Update the vector buffer information to a safe state this->m_holder.start(new_start); this->m_holder.capacity(new_capacity); this->m_holder.m_size = 0; + //We can have 8 possibilities: + const size_type elemsbefore = static_cast<size_type>(pos - old_start); + const size_type s_before = static_cast<size_type>(old_start - new_start); + const size_type before_plus_new = size_type(elemsbefore + n); + + typedef typename value_traits::ArrayDestructor array_destructor_t; + //If anything goes wrong, this object will destroy //all the old objects to fulfill previous vector state - typename value_traits::ArrayDestructor old_values_destroyer(old_start, this->m_holder.alloc(), old_size); + array_destructor_t old_values_destroyer(old_start, a, old_size); //Check if s_before is big enough to hold the beginning of old data + new data if(s_before >= before_plus_new){ //Copy first old values before pos, after that the new objects T *const new_elem_pos = - ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), old_start, pos, new_start); - this->m_holder.m_size = elemsbefore; - insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_elem_pos, n); - this->m_holder.m_size = before_plus_new; - const size_type new_size = old_size + n; + ::boost::container::uninitialized_move_alloc(a, old_start, pos, new_start); + this->m_holder.set_stored_size(elemsbefore); + insert_range_proxy.uninitialized_copy_n_and_update(a, new_elem_pos, n); + this->m_holder.set_stored_size(before_plus_new); + const size_type new_size = size_type(old_size + n); //Check if s_before is so big that even copying the old data + new data //there is a gap between the new data and the old data if(s_before >= new_size){ @@ -3060,15 +3070,14 @@ class vector // //Now initialize the rest of memory with the last old values if(before_plus_new != new_size){ //Special case to avoid operations in back insertion - ::boost::container::uninitialized_move_alloc - (this->m_holder.alloc(), pos, old_finish, new_start + before_plus_new); + ::boost::container::uninitialized_move_alloc(a, pos, old_finish, new_start + before_plus_new); //All new elements correctly constructed, avoid new element destruction - this->m_holder.m_size = new_size; + this->m_holder.set_stored_size(new_size); } //Old values destroyed automatically with "old_values_destroyer" //when "old_values_destroyer" goes out of scope unless the have trivial //destructor after move. - if(value_traits::trivial_dctr_after_move) + BOOST_IF_CONSTEXPR(value_traits::trivial_dctr_after_move) old_values_destroyer.release(); } //s_before is so big that divides old_end @@ -3085,30 +3094,29 @@ class vector // //Now initialize the rest of memory with the last old values //All new elements correctly constructed, avoid new element destruction - const size_type raw_gap = s_before - before_plus_new; - if(!value_traits::trivial_dctr){ + BOOST_IF_CONSTEXPR(!value_traits::trivial_dctr){ + const size_type raw_gap = s_before - before_plus_new; //Now initialize the rest of s_before memory with the //first of elements after new values - ::boost::container::uninitialized_move_alloc_n - (this->m_holder.alloc(), pos, raw_gap, new_start + before_plus_new); + ::boost::container::uninitialized_move_alloc_n(a, pos, raw_gap, new_start + before_plus_new); //Now we have a contiguous buffer so program trailing element destruction //and update size to the final size. old_values_destroyer.shrink_forward(new_size-s_before); - this->m_holder.m_size = new_size; + this->m_holder.set_stored_size(new_size); //Now move remaining last objects in the old buffer begin T * const remaining_pos = pos + raw_gap; if(remaining_pos != old_start){ //Make sure data has to be moved ::boost::container::move(remaining_pos, old_finish, old_start); } //Once moved, avoid calling the destructors if trivial after move - if(value_traits::trivial_dctr_after_move){ + BOOST_IF_CONSTEXPR(value_traits::trivial_dctr_after_move){ old_values_destroyer.release(); } } else{ //If trivial destructor, we can uninitialized copy + copy in a single uninitialized copy ::boost::container::uninitialized_move_alloc_n - (this->m_holder.alloc(), pos, static_cast<size_type>(old_finish - pos), new_start + before_plus_new); - this->m_holder.m_size = new_size; + (a, pos, static_cast<size_type>(old_finish - pos), new_start + before_plus_new); + this->m_holder.set_stored_size(new_size); old_values_destroyer.release(); } } @@ -3162,8 +3170,7 @@ class vector //|___________|_____|_________|_____________________| // //Copy the first part of old_begin to raw_mem - ::boost::container::uninitialized_move_alloc_n - (this->m_holder.alloc(), old_start, s_before, new_start); + ::boost::container::uninitialized_move_alloc_n(a, old_start, s_before, new_start); //The buffer is all constructed until old_end, //so program trailing destruction and assign final size //if !do_after, s_before+n otherwise. @@ -3175,17 +3182,18 @@ class vector } else{ new_1st_range = n; - if(value_traits::trivial_dctr_after_move) + BOOST_IF_CONSTEXPR(value_traits::trivial_dctr_after_move){ old_values_destroyer.release(); + } else{ old_values_destroyer.shrink_forward(old_size - (s_before - n)); } } - this->m_holder.m_size = old_size + new_1st_range; + this->m_holder.set_stored_size(size_type(old_size + new_1st_range)); //Now copy the second part of old_begin overwriting itself T *const next = ::boost::container::move(old_start + s_before, pos, old_start); //Now copy the new_beg elements - insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, new_1st_range); + insert_range_proxy.copy_n_and_update(a, next, new_1st_range); //If there is no after work and the last old part needs to be moved to front, do it if(!do_after && (n != s_before)){ @@ -3221,33 +3229,37 @@ class vector // //First copy whole old_begin and part of new to raw_mem T * const new_pos = ::boost::container::uninitialized_move_alloc - (this->m_holder.alloc(), old_start, pos, new_start); - this->m_holder.m_size = elemsbefore; - const size_type mid_n = s_before - elemsbefore; - insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_pos, mid_n); + (a, old_start, pos, new_start); + this->m_holder.set_stored_size(elemsbefore); + const size_type mid_n = size_type(s_before - elemsbefore); + insert_range_proxy.uninitialized_copy_n_and_update(a, new_pos, mid_n); //The buffer is all constructed until old_end, //release destroyer - this->m_holder.m_size = old_size + s_before; + this->m_holder.set_stored_size(size_type(old_size + s_before)); old_values_destroyer.release(); if(do_after){ //Copy new_beg part - insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, elemsbefore); + insert_range_proxy.copy_n_and_update(a, old_start, elemsbefore); } else{ //Copy all new elements - const size_type rest_new = n - mid_n; - insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, rest_new); + const size_type rest_new = size_type(n - mid_n); + insert_range_proxy.copy_n_and_update(a, old_start, rest_new); + T* const move_start = old_start + rest_new; //Displace old_end, but make sure data has to be moved T* const move_end = move_start != pos ? ::boost::container::move(pos, old_finish, move_start) : old_finish; + (void)move_end; //To avoid warnings of unused initialization for move_end in case + //trivial_dctr_after_move is true //Destroy remaining moved elements from old_end except if they //have trivial destructor after being moved - size_type n_destroy = s_before - n; - if(!value_traits::trivial_dctr_after_move) - boost::container::destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy); - this->m_holder.m_size -= n_destroy; + const size_type n_destroy = size_type(s_before - n); + BOOST_IF_CONSTEXPR(!value_traits::trivial_dctr_after_move){ + boost::container::destroy_alloc_n(a, move_end, n_destroy); + } + this->m_holder.dec_stored_size(n_destroy); } } @@ -3270,8 +3282,8 @@ class vector //| old_begin + new | old_end |raw | //|_______________________________________|_________|____| // - const size_type n_after = n - s_before; - const size_type elemsafter = old_size - elemsbefore; + const size_type n_after = size_type(n - s_before); + const size_type elemsafter = size_type(old_size - elemsbefore); //We can have two situations: if (elemsafter >= n_after){ @@ -3289,14 +3301,13 @@ class vector // //First copy the part of old_end raw_mem T* finish_n = old_finish - n_after; - ::boost::container::uninitialized_move_alloc - (this->m_holder.alloc(), finish_n, old_finish, old_finish); - this->m_holder.m_size += n_after; + ::boost::container::uninitialized_move_alloc(a, finish_n, old_finish, old_finish); + this->m_holder.inc_stored_size(n_after); //Displace the rest of old_end to the new position boost::container::move_backward(pos, finish_n, old_finish); //Now overwrite with new_end //The new_end part is [first + (n - n_after), last) - insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n_after); + insert_range_proxy.copy_n_and_update(a, pos, n_after); } else { //The raw_mem from end will divide new_end part @@ -3310,23 +3321,20 @@ class vector // _____________________________________________________________ //| old_begin + new_beg | new_end |old_end | raw_mem | //|__________________________|_______________|________|_________| - // - const size_type mid_last_dist = n_after - elemsafter; //First initialize data in raw memory + const size_type mid_last_dist = size_type(n_after - elemsafter); //Copy to the old_end part to the uninitialized zone leaving a gap. - ::boost::container::uninitialized_move_alloc - (this->m_holder.alloc(), pos, old_finish, old_finish + mid_last_dist); + ::boost::container::uninitialized_move_alloc(a, pos, old_finish, old_finish + mid_last_dist); - typename value_traits::ArrayDestructor old_end_destroyer - (old_finish + mid_last_dist, this->m_holder.alloc(), old_finish - pos); + array_destructor_t old_end_destroyer(old_finish + mid_last_dist, a, static_cast<size_type>(old_finish - pos)); //Copy the first part to the already constructed old_end zone - insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elemsafter); + insert_range_proxy.copy_n_and_update(a, pos, elemsafter); //Copy the rest to the uninitialized zone filling the gap - insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, mid_last_dist); - this->m_holder.m_size += n_after; + insert_range_proxy.uninitialized_copy_n_and_update(a, old_finish, mid_last_dist); + this->m_holder.inc_stored_size(n_after); old_end_destroyer.release(); } } @@ -3363,6 +3371,19 @@ class vector #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template <typename InputIterator> +vector(InputIterator, InputIterator) -> + vector<typename iter_value<InputIterator>::type>; + +template <typename InputIterator, typename Allocator> +vector(InputIterator, InputIterator, Allocator const&) -> + vector<typename iter_value<InputIterator>::type, Allocator>; + +#endif + + }} //namespace boost::container #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -3371,16 +3392,31 @@ namespace boost { //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations -template <class T, class Allocator> -struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> > +template <class T, class Allocator, class Options> +struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator, Options> > { - typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer; - static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value && + typedef typename boost::container::vector<T, Allocator, Options>::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value && ::boost::has_trivial_destructor_after_move<pointer>::value; }; } +//See comments on vec_iterator::element_type to know why is this needed +#ifdef BOOST_GNU_STDLIB + +BOOST_MOVE_STD_NS_BEG + +template <class Pointer, bool IsConst> +struct pointer_traits< boost::container::vec_iterator<Pointer, IsConst> > + : public boost::intrusive::pointer_traits< boost::container::vec_iterator<Pointer, IsConst> > +{}; + +BOOST_MOVE_STD_NS_END + +#endif //BOOST_GNU_STDLIB + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #include <boost/container/detail/config_end.hpp> diff --git a/contrib/restricted/boost/container/src/dlmalloc_2_8_6.c b/contrib/restricted/boost/container/src/dlmalloc_2_8_6.c index bb105b63fb..3424f59b17 100644 --- a/contrib/restricted/boost/container/src/dlmalloc_2_8_6.c +++ b/contrib/restricted/boost/container/src/dlmalloc_2_8_6.c @@ -1515,7 +1515,7 @@ LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); #pragma intrinsic (_InterlockedExchange) #define interlockedcompareexchange _InterlockedCompareExchange #define interlockedexchange _InterlockedExchange -#elif defined(WIN32) && defined(__GNUC__) +#elif defined(WIN32) && (defined(__GNUC__) || defined(__clang__)) #define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b) #define interlockedexchange __sync_lock_test_and_set #endif /* Win32 */ @@ -1762,7 +1762,7 @@ static FORCEINLINE int win32munmap(void* ptr, size_t size) { #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL #endif /* HAVE_MMAP && HAVE_MREMAP */ -/* mstate bit set if continguous morecore disabled or failed */ +/* mstate bit set if contiguous morecore disabled or failed */ #define USE_NONCONTIGUOUS_BIT (4U) /* segment bit set in create_mspace_with_base */ @@ -2726,7 +2726,7 @@ static int has_segment_link(mstate m, msegmentptr ss) { noncontiguous segments are added. */ #define TOP_FOOT_SIZE\ - (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) + (align_offset(TWO_SIZE_T_SIZES)+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) /* ------------------------------- Hooks -------------------------------- */ @@ -4676,7 +4676,7 @@ void* dlmalloc(size_t bytes) { void dlfree(void* mem) { /* - Consolidate freed chunks with preceeding or succeeding bordering + Consolidate freed chunks with preceding or succeeding bordering free chunks, if they exist, and then place in a bin. Intermixed with special cases for top, dv, mmapped chunks, and usage errors. */ @@ -6210,10 +6210,10 @@ History: Wolfram Gloger (Gloger@lrz.uni-muenchen.de). * Use last_remainder in more cases. * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold + * Use ordered bins instead of best-fit threshold * Eliminate block-local decls to simplify tracing and debugging. * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. + * Fix error occurring when initial sbrk_base not word-aligned. * Rely on page size for units instead of SBRK_UNIT to avoid surprises about sbrk alignment conventions. * Add mallinfo, mallopt. Thanks to Raymond Nijssen diff --git a/contrib/restricted/boost/container/src/dlmalloc_ext_2_8_6.c b/contrib/restricted/boost/container/src/dlmalloc_ext_2_8_6.c index 3328d72975..2bdd3afdf7 100644 --- a/contrib/restricted/boost/container/src/dlmalloc_ext_2_8_6.c +++ b/contrib/restricted/boost/container/src/dlmalloc_ext_2_8_6.c @@ -19,6 +19,8 @@ #define MSPACES 1 #define NO_MALLINFO 1 #define NO_MALLOC_STATS 1 +//disable sbrk as it's deprecated in some systems and weakens ASLR +#define HAVE_MORECORE 0 #if !defined(NDEBUG) @@ -33,7 +35,6 @@ #ifdef __GNUC__ #define FORCEINLINE inline #endif -#include "dlmalloc_2_8_6.c" #ifdef _MSC_VER #pragma warning (push) @@ -43,8 +44,13 @@ #pragma warning (disable : 4702) #pragma warning (disable : 4390) /*empty controlled statement found; is this the intent?*/ #pragma warning (disable : 4251 4231 4660) /*dll warnings*/ +#pragma warning (disable : 4057) /*differs in indirection to slightly different base types from*/ +#pragma warning (disable : 4702) /*unreachable code*/ +#pragma warning (disable : 4127) /*conditional expression is constant*/ #endif +#include "dlmalloc_2_8_6.c" + #define DL_SIZE_IMPL(p) (chunksize(mem2chunk(p)) - overhead_for(mem2chunk(p))) static size_t s_allocated_memory; @@ -80,7 +86,6 @@ static void mspace_free_lockless(mspace msp, void* mem) if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { size_t psize = chunksize(p); mchunkptr next = chunk_plus_offset(p, psize); - s_allocated_memory -= psize; if (!pinuse(p)) { size_t prevsize = p->prev_foot; if (is_mmapped(p)) { @@ -368,89 +373,6 @@ static mchunkptr try_realloc_chunk_with_min(mstate m, mchunkptr p, size_t min_nb return newp; } -#define BOOST_ALLOC_PLUS_MEMCHAIN_MEM_JUMP_NEXT(THISMEM, NEXTMEM) \ - *((void**)(THISMEM)) = *((void**)((NEXTMEM))) - -//This function is based on internal_bulk_free -//replacing iteration over array[] with boost_cont_memchain. -//Instead of returning the unallocated nodes, returns a chain of non-deallocated nodes. -//After forward merging, backwards merging is also tried -static void internal_multialloc_free(mstate m, boost_cont_memchain *pchain) -{ -#if FOOTERS - boost_cont_memchain ret_chain; - BOOST_CONTAINER_MEMCHAIN_INIT(&ret_chain); -#endif - if (!PREACTION(m)) { - boost_cont_memchain_it a_it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(pchain); - while(!BOOST_CONTAINER_MEMCHAIN_IS_END_IT(pchain, a_it)) { /* Iterate though all memory holded by the chain */ - void* a_mem = BOOST_CONTAINER_MEMIT_ADDR(a_it); - mchunkptr a_p = mem2chunk(a_mem); - size_t psize = chunksize(a_p); -#if FOOTERS - if (get_mstate_for(a_p) != m) { - BOOST_CONTAINER_MEMIT_NEXT(a_it); - BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(&ret_chain, a_mem); - continue; - } -#endif - check_inuse_chunk(m, a_p); - if (RTCHECK(ok_address(m, a_p) && ok_inuse(a_p))) { - while(1) { /* Internal loop to speed up forward and backward merging (avoids some redundant checks) */ - boost_cont_memchain_it b_it = a_it; - BOOST_CONTAINER_MEMIT_NEXT(b_it); - if(!BOOST_CONTAINER_MEMCHAIN_IS_END_IT(pchain, b_it)){ - void *b_mem = BOOST_CONTAINER_MEMIT_ADDR(b_it); - mchunkptr b_p = mem2chunk(b_mem); - if (b_p == next_chunk(a_p)) { /* b chunk is contiguous and next so b's size can be added to a */ - psize += chunksize(b_p); - set_inuse(m, a_p, psize); - BOOST_ALLOC_PLUS_MEMCHAIN_MEM_JUMP_NEXT(a_mem, b_mem); - continue; - } - if(RTCHECK(ok_address(m, b_p) && ok_inuse(b_p))){ - /* b chunk is contiguous and previous so a's size can be added to b */ - if(a_p == next_chunk(b_p)) { - psize += chunksize(b_p); - set_inuse(m, b_p, psize); - a_it = b_it; - a_p = b_p; - a_mem = b_mem; - continue; - } - } - } - /* Normal deallocation starts again in the outer loop */ - a_it = b_it; - s_allocated_memory -= psize; - dispose_chunk(m, a_p, psize); - break; - } - } - else { - CORRUPTION_ERROR_ACTION(m); - break; - } - } - if (should_trim(m, m->topsize)) - sys_trim(m, 0); - POSTACTION(m); - } -#if FOOTERS - { - boost_cont_memchain_it last_pchain = BOOST_CONTAINER_MEMCHAIN_LAST_IT(pchain); - BOOST_CONTAINER_MEMCHAIN_INIT(pchain); - BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER - (pchain - , last_pchain - , BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ret_chain) - , BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ret_chain) - , BOOST_CONTAINER_MEMCHAIN_SIZE(&ret_chain) - ); - } -#endif -} - /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// @@ -840,129 +762,233 @@ static int internal_shrink(mstate m, void* oldmem, size_t minbytes, size_t maxby mchunkptr remainder = chunk_plus_offset(oldp, nb); set_inuse(m, oldp, nb); set_inuse(m, remainder, rsize); + s_allocated_memory -= rsize; extra = chunk2mem(remainder); + mspace_free_lockless(m, extra); + check_inuse_chunk(m, oldp); } *received_size = nb - overhead_for(oldp); - if(!do_commit) - return 1; + return 1; } } } else { USAGE_ERROR_ACTION(m, oldmem); - return 0; - } - - if (extra != 0 && do_commit) { - mspace_free_lockless(m, extra); - check_inuse_chunk(m, oldp); - return 1; - } - else { - return 0; } + return 0; } } - #define INTERNAL_MULTIALLOC_DEFAULT_CONTIGUOUS_MEM 4096 - #define SQRT_MAX_SIZE_T (((size_t)-1)>>(sizeof(size_t)*CHAR_BIT/2)) static int internal_node_multialloc - (mstate m, size_t n_elements, size_t element_size, size_t contiguous_elements, boost_cont_memchain *pchain) { - void* mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size; /* remaining bytes while splitting */ - flag_t was_enabled; /* to disable mmap */ - size_t elements_per_segment = 0; - size_t element_req_size = request2size(element_size); - boost_cont_memchain_it prev_last_it = BOOST_CONTAINER_MEMCHAIN_LAST_IT(pchain); - - /*Error if wrong element_size parameter */ - if( !element_size || - /*OR Error if n_elements less thatn contiguous_elements */ - ((contiguous_elements + 1) > (DL_MULTIALLOC_DEFAULT_CONTIGUOUS + 1) && n_elements < contiguous_elements) || - /* OR Error if integer overflow */ - (SQRT_MAX_SIZE_T < (element_req_size | contiguous_elements) && - (MAX_SIZE_T/element_req_size) < contiguous_elements)){ - return 0; - } - switch(contiguous_elements){ - case DL_MULTIALLOC_DEFAULT_CONTIGUOUS: - { - /* Default contiguous, just check that we can store at least one element */ - elements_per_segment = INTERNAL_MULTIALLOC_DEFAULT_CONTIGUOUS_MEM/element_req_size; - elements_per_segment += (size_t)(!elements_per_segment); - } - break; - case DL_MULTIALLOC_ALL_CONTIGUOUS: - /* All elements should be allocated in a single call */ - elements_per_segment = n_elements; - break; - default: - /* Allocate in chunks of "contiguous_elements" */ - elements_per_segment = contiguous_elements; - } +(mstate m, size_t n_elements, size_t element_size, size_t contiguous_elements, boost_cont_memchain *pchain) { + void* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + size_t remainder_size; /* remaining bytes while splitting */ + flag_t was_enabled; /* to disable mmap */ + size_t elements_per_segment = 0; + size_t element_req_size = request2size(element_size); + boost_cont_memchain_it prev_last_it = BOOST_CONTAINER_MEMCHAIN_LAST_IT(pchain); + + /*Error if wrong element_size parameter */ + if (!element_size || + /*OR Error if n_elements less than contiguous_elements */ + ((contiguous_elements + 1) > (BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS + 1) && n_elements < contiguous_elements) || + /* OR Error if integer overflow */ + (SQRT_MAX_SIZE_T < (element_req_size | contiguous_elements) && + (MAX_SIZE_T / element_req_size) < contiguous_elements)) { + return 0; + } + switch (contiguous_elements) { + case BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS: + { + /* Default contiguous, just check that we can store at least one element */ + elements_per_segment = INTERNAL_MULTIALLOC_DEFAULT_CONTIGUOUS_MEM / element_req_size; + elements_per_segment += (size_t)(!elements_per_segment); + } + break; + case BOOST_CONTAINER_DL_MULTIALLOC_ALL_CONTIGUOUS: + /* All elements should be allocated in a single call */ + elements_per_segment = n_elements; + break; + default: + /* Allocate in chunks of "contiguous_elements" */ + elements_per_segment = contiguous_elements; + } + + { + size_t i; + size_t next_i; + /* + Allocate the aggregate chunk. First disable direct-mmapping so + malloc won't use it, since we would not be able to later + free/realloc space internal to a segregated mmap region. + */ + was_enabled = use_mmap(m); + disable_mmap(m); + for (i = 0; i != n_elements; i = next_i) + { + size_t accum_size; + size_t n_elements_left = n_elements - i; + next_i = i + ((n_elements_left < elements_per_segment) ? n_elements_left : elements_per_segment); + accum_size = element_req_size * (next_i - i); + + mem = mspace_malloc_lockless(m, accum_size - CHUNK_OVERHEAD); + if (mem == 0) { + BOOST_CONTAINER_MEMIT_NEXT(prev_last_it); + while (i) { + void *addr = BOOST_CONTAINER_MEMIT_ADDR(prev_last_it); + --i; + BOOST_CONTAINER_MEMIT_NEXT(prev_last_it); + s_allocated_memory -= chunksize(mem2chunk(addr)); + mspace_free_lockless(m, addr); + } + if (was_enabled) + enable_mmap(m); + return 0; + } + p = mem2chunk(mem); + remainder_size = chunksize(p); + s_allocated_memory += remainder_size; + + assert(!is_mmapped(p)); + { /* split out elements */ + //void *mem_orig = mem; + //boost_cont_memchain_it last_it = BOOST_CONTAINER_MEMCHAIN_LAST_IT(pchain); + size_t num_elements = next_i - i; + + size_t num_loops = num_elements - 1; + remainder_size -= element_req_size * num_loops; + while (num_loops) { + --num_loops; + //void **mem_prev = ((void**)mem); + set_size_and_pinuse_of_inuse_chunk(m, p, element_req_size); + BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(pchain, mem); + p = chunk_plus_offset(p, element_req_size); + mem = chunk2mem(p); + //*mem_prev = mem; + } + set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); + BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(pchain, mem); + //BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER(pchain, last_it, mem_orig, mem, num_elements); + } + } + if (was_enabled) + enable_mmap(m); + } + return 1; +} - { - size_t i; - size_t next_i; - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - for(i = 0; i != n_elements; i = next_i) - { - size_t accum_size; - size_t n_elements_left = n_elements - i; - next_i = i + ((n_elements_left < elements_per_segment) ? n_elements_left : elements_per_segment); - accum_size = element_req_size*(next_i - i); +#define BOOST_CONTAINER_DLMALLOC_SIMPLE_MULTIDEALLOC +#ifndef BOOST_CONTAINER_DLMALLOC_SIMPLE_MULTIDEALLOC - mem = mspace_malloc_lockless(m, accum_size - CHUNK_OVERHEAD); - if (mem == 0){ - BOOST_CONTAINER_MEMIT_NEXT(prev_last_it); - while(i--){ - void *addr = BOOST_CONTAINER_MEMIT_ADDR(prev_last_it); - BOOST_CONTAINER_MEMIT_NEXT(prev_last_it); - mspace_free_lockless(m, addr); - } - if (was_enabled) - enable_mmap(m); - return 0; - } - p = mem2chunk(mem); - remainder_size = chunksize(p); - s_allocated_memory += remainder_size; +#define BOOST_ALLOC_PLUS_MEMCHAIN_MEM_JUMP_NEXT(THISMEM, NEXTMEM) \ + *((void**)(THISMEM)) = *((void**)((NEXTMEM))) - assert(!is_mmapped(p)); - { /* split out elements */ - void *mem_orig = mem; - boost_cont_memchain_it last_it = BOOST_CONTAINER_MEMCHAIN_LAST_IT(pchain); - size_t num_elements = next_i-i; +//This function is based on internal_bulk_free +//replacing iteration over array[] with boost_cont_memchain. +//Instead of returning the unallocated nodes, returns a chain of non-deallocated nodes. +//After forward merging, backwards merging is also tried +static void internal_multialloc_free(mstate m, boost_cont_memchain *pchain) +{ +#if FOOTERS + boost_cont_memchain ret_chain; + BOOST_CONTAINER_MEMCHAIN_INIT(&ret_chain); +#endif + if (!PREACTION(m)) { + boost_cont_memchain_it a_it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(pchain); + while (!BOOST_CONTAINER_MEMCHAIN_IS_END_IT(pchain, a_it)) { /* Iterate though all memory holded by the chain */ + void* a_mem = BOOST_CONTAINER_MEMIT_ADDR(a_it); + mchunkptr a_p = mem2chunk(a_mem); + size_t psize = chunksize(a_p); +#if FOOTERS + if (get_mstate_for(a_p) != m) { + BOOST_CONTAINER_MEMIT_NEXT(a_it); + BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(&ret_chain, a_mem); + continue; + } +#endif + check_inuse_chunk(m, a_p); + if (RTCHECK(ok_address(m, a_p) && ok_inuse(a_p))) { + while (1) { /* Internal loop to speed up forward and backward merging (avoids some redundant checks) */ + boost_cont_memchain_it b_it = a_it; + BOOST_CONTAINER_MEMIT_NEXT(b_it); + if (!BOOST_CONTAINER_MEMCHAIN_IS_END_IT(pchain, b_it)) { + void *b_mem = BOOST_CONTAINER_MEMIT_ADDR(b_it); + mchunkptr b_p = mem2chunk(b_mem); + if (b_p == next_chunk(a_p)) { /* b chunk is contiguous and next so b's size can be added to a */ + psize += chunksize(b_p); + set_inuse(m, a_p, psize); + BOOST_ALLOC_PLUS_MEMCHAIN_MEM_JUMP_NEXT(a_mem, b_mem); + continue; + } + if (RTCHECK(ok_address(m, b_p) && ok_inuse(b_p))) { + /* b chunk is contiguous and previous so a's size can be added to b */ + if (a_p == next_chunk(b_p)) { + psize += chunksize(b_p); + set_inuse(m, b_p, psize); + a_it = b_it; + a_p = b_p; + a_mem = b_mem; + continue; + } + } + } + /* Normal deallocation starts again in the outer loop */ + a_it = b_it; + s_allocated_memory -= psize; + dispose_chunk(m, a_p, psize); + break; + } + } + else { + CORRUPTION_ERROR_ACTION(m); + break; + } + } + if (should_trim(m, m->topsize)) + sys_trim(m, 0); + POSTACTION(m); + } +#if FOOTERS + { + boost_cont_memchain_it last_pchain = BOOST_CONTAINER_MEMCHAIN_LAST_IT(pchain); + BOOST_CONTAINER_MEMCHAIN_INIT(pchain); + BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER + (pchain + , last_pchain + , BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ret_chain) + , BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ret_chain) + , BOOST_CONTAINER_MEMCHAIN_SIZE(&ret_chain) + ); + } +#endif +} - size_t num_loops = num_elements - 1; - remainder_size -= element_req_size*num_loops; - while(num_loops--){ - void **mem_prev = ((void**)mem); - set_size_and_pinuse_of_inuse_chunk(m, p, element_req_size); - p = chunk_plus_offset(p, element_req_size); - mem = chunk2mem(p); - *mem_prev = mem; - } - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER(pchain, last_it, mem_orig, mem, num_elements); - } - } - if (was_enabled) - enable_mmap(m); - } - return 1; +#else //BOOST_CONTAINER_DLMALLOC_SIMPLE_MULTIDEALLOC + +//This function is based on internal_bulk_free +//replacing iteration over array[] with boost_cont_memchain. +//Instead of returning the unallocated nodes, returns a chain of non-deallocated nodes. +//After forward merging, backwards merging is also tried +static void internal_multialloc_free(mstate m, boost_cont_memchain *pchain) +{ + if (!PREACTION(m)) { + boost_cont_memchain_it a_it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(pchain); + while (!BOOST_CONTAINER_MEMCHAIN_IS_END_IT(pchain, a_it)) { /* Iterate though all memory holded by the chain */ + void* a_mem = BOOST_CONTAINER_MEMIT_ADDR(a_it); + BOOST_CONTAINER_MEMIT_NEXT(a_it); + s_allocated_memory -= chunksize(mem2chunk(a_mem)); + mspace_free_lockless(m, a_mem); + } + POSTACTION(m); + } } +#endif //BOOST_CONTAINER_DLMALLOC_SIMPLE_MULTIDEALLOC + static int internal_multialloc_arrays (mstate m, size_t n_elements, const size_t* sizes, size_t element_size, size_t contiguous_elements, boost_cont_memchain *pchain) { void* mem; /* malloced aggregate space */ @@ -980,11 +1006,11 @@ static int internal_multialloc_arrays max_size = MAX_REQUEST/element_size; /* Different sizes*/ switch(contiguous_elements){ - case DL_MULTIALLOC_DEFAULT_CONTIGUOUS: + case BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS: /* Use default contiguous mem */ boost_cont_multialloc_segmented_malloc_size = INTERNAL_MULTIALLOC_DEFAULT_CONTIGUOUS_MEM; break; - case DL_MULTIALLOC_ALL_CONTIGUOUS: + case BOOST_CONTAINER_DL_MULTIALLOC_ALL_CONTIGUOUS: boost_cont_multialloc_segmented_malloc_size = MAX_REQUEST + CHUNK_OVERHEAD; break; default: @@ -1036,6 +1062,7 @@ static int internal_multialloc_arrays while(i--){ void *addr = BOOST_CONTAINER_MEMIT_ADDR(it); BOOST_CONTAINER_MEMIT_NEXT(it); + s_allocated_memory -= chunksize(mem2chunk(addr)); mspace_free_lockless(m, addr); } if (was_enabled) @@ -1143,6 +1170,8 @@ void boost_cont_free(void* mem) USAGE_ERROR_ACTION(ms,ms); } else if (!PREACTION(ms)) { + if(mem) + s_allocated_memory -= chunksize(mem2chunk(mem)); mspace_free_lockless(ms, mem); POSTACTION(ms); } diff --git a/contrib/restricted/boost/container/src/global_resource.cpp b/contrib/restricted/boost/container/src/global_resource.cpp index 15f4fe404c..69a91c3cf0 100644 --- a/contrib/restricted/boost/container/src/global_resource.cpp +++ b/contrib/restricted/boost/container/src/global_resource.cpp @@ -10,10 +10,11 @@ #define BOOST_CONTAINER_SOURCE #include <boost/container/pmr/memory_resource.hpp> - +#include <boost/container/pmr/global_resource.hpp> #include <boost/core/no_exceptions_support.hpp> #include <boost/container/throw_exception.hpp> #include <boost/container/detail/dlmalloc.hpp> //For global lock +#include <boost/container/detail/singleton.hpp> #include <cstddef> #include <new> @@ -27,58 +28,68 @@ class new_delete_resource_imp { public: - virtual ~new_delete_resource_imp() + ~new_delete_resource_imp() BOOST_OVERRIDE {} - virtual void* do_allocate(std::size_t bytes, std::size_t alignment) + void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE { (void)bytes; (void)alignment; return new char[bytes]; } - virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) + void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE { (void)bytes; (void)alignment; delete[]((char*)p); } - virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT + bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE { return &other == this; } -} new_delete_resource_instance; +}; struct null_memory_resource_imp : public memory_resource { public: - virtual ~null_memory_resource_imp() + ~null_memory_resource_imp() BOOST_OVERRIDE {} - virtual void* do_allocate(std::size_t bytes, std::size_t alignment) + void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE { (void)bytes; (void)alignment; + #if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) || defined(BOOST_NO_EXCEPTIONS) throw_bad_alloc(); return 0; + #else + throw std::bad_alloc(); + #endif } - virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) + void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE { (void)p; (void)bytes; (void)alignment; } - virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT + bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE { return &other == this; } -} null_memory_resource_instance; +}; BOOST_CONTAINER_DECL memory_resource* new_delete_resource() BOOST_NOEXCEPT { - return &new_delete_resource_instance; + return &boost::container::dtl::singleton_default<new_delete_resource_imp>::instance(); } BOOST_CONTAINER_DECL memory_resource* null_memory_resource() BOOST_NOEXCEPT { - return &null_memory_resource_instance; + return &boost::container::dtl::singleton_default<null_memory_resource_imp>::instance(); } -static memory_resource *default_memory_resource = &new_delete_resource_instance; +#if 1 + +static memory_resource *default_memory_resource = + &boost::container::dtl::singleton_default<new_delete_resource_imp>::instance(); BOOST_CONTAINER_DECL memory_resource* set_default_resource(memory_resource* r) BOOST_NOEXCEPT { - //TO-DO: synchronizes-with part using atomics if(dlmalloc_global_sync_lock()){ memory_resource *previous = default_memory_resource; + if(!previous){ + //function called before main, default_memory_resource is not initialized yet + previous = new_delete_resource(); + } default_memory_resource = r ? r : new_delete_resource(); dlmalloc_global_sync_unlock(); return previous; @@ -90,9 +101,12 @@ BOOST_CONTAINER_DECL memory_resource* set_default_resource(memory_resource* r) B BOOST_CONTAINER_DECL memory_resource* get_default_resource() BOOST_NOEXCEPT { - //TO-DO: synchronizes-with part using atomics if(dlmalloc_global_sync_lock()){ memory_resource *current = default_memory_resource; + if(!current){ + //function called before main, default_memory_resource is not initialized yet + current = new_delete_resource(); + } dlmalloc_global_sync_unlock(); return current; } @@ -101,6 +115,32 @@ BOOST_CONTAINER_DECL memory_resource* get_default_resource() BOOST_NOEXCEPT } } +#else // #if defined(BOOST_NO_CXX11_HDR_ATOMIC) + +} //namespace pmr { +} //namespace container { +} //namespace boost { + +#include <atomic> + +namespace boost { +namespace container { +namespace pmr { + +static std::atomic<memory_resource*> default_memory_resource = + ATOMIC_VAR_INIT(&boost::container::dtl::singleton_default<new_delete_resource_imp>::instance()); + +BOOST_CONTAINER_DECL memory_resource* set_default_resource(memory_resource* r) BOOST_NOEXCEPT +{ + memory_resource *const res = r ? r : new_delete_resource(); + return default_memory_resource.exchange(res, std::memory_order_acq_rel); +} + +BOOST_CONTAINER_DECL memory_resource* get_default_resource() BOOST_NOEXCEPT +{ return default_memory_resource.load(std::memory_order_acquire); } + +#endif + } //namespace pmr { } //namespace container { } //namespace boost { diff --git a/contrib/restricted/boost/container/src/monotonic_buffer_resource.cpp b/contrib/restricted/boost/container/src/monotonic_buffer_resource.cpp index f9f6f4cbe5..5507ef2d56 100644 --- a/contrib/restricted/boost/container/src/monotonic_buffer_resource.cpp +++ b/contrib/restricted/boost/container/src/monotonic_buffer_resource.cpp @@ -18,6 +18,7 @@ #include <boost/container/detail/min_max.hpp> #include <boost/intrusive/detail/math.hpp> #include <boost/container/throw_exception.hpp> +#include <new> #include <cstddef> @@ -63,6 +64,8 @@ monotonic_buffer_resource::monotonic_buffer_resource(memory_resource* upstream) , m_current_buffer(0) , m_current_buffer_size(0u) , m_next_buffer_size(initial_next_buffer_size) + , m_initial_buffer(0) + , m_initial_buffer_size(0u) {} monotonic_buffer_resource::monotonic_buffer_resource(std::size_t initial_size, memory_resource* upstream) BOOST_NOEXCEPT @@ -70,6 +73,8 @@ monotonic_buffer_resource::monotonic_buffer_resource(std::size_t initial_size, m , m_current_buffer(0) , m_current_buffer_size(0u) , m_next_buffer_size(minimum_buffer_size) + , m_initial_buffer(0) + , m_initial_buffer_size(0u) { //In case initial_size is zero this->increase_next_buffer_at_least_to(initial_size + !initial_size); } @@ -81,6 +86,8 @@ monotonic_buffer_resource::monotonic_buffer_resource(void* buffer, std::size_t b , m_next_buffer_size (bi::detail::previous_or_equal_pow2 (boost::container::dtl::max_value(buffer_size, std::size_t(initial_next_buffer_size)))) + , m_initial_buffer(buffer) + , m_initial_buffer_size(buffer_size) { this->increase_next_buffer(); } monotonic_buffer_resource::~monotonic_buffer_resource() @@ -89,8 +96,8 @@ monotonic_buffer_resource::~monotonic_buffer_resource() void monotonic_buffer_resource::release() BOOST_NOEXCEPT { m_memory_blocks.release(); - m_current_buffer = 0u; - m_current_buffer_size = 0u; + m_current_buffer = m_initial_buffer; + m_current_buffer_size = m_initial_buffer_size; m_next_buffer_size = initial_next_buffer_size; } @@ -129,12 +136,21 @@ void *monotonic_buffer_resource::allocate_from_current(std::size_t aligner, std: void* monotonic_buffer_resource::do_allocate(std::size_t bytes, std::size_t alignment) { - if(alignment > memory_resource::max_align) + if(alignment > memory_resource::max_align){ + (void)bytes; (void)alignment; + #if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) || defined(BOOST_NO_EXCEPTIONS) throw_bad_alloc(); + #else + throw std::bad_alloc(); + #endif + } //See if there is room in current buffer std::size_t aligner = 0u; if(this->remaining_storage(alignment, aligner) < bytes){ + //The new buffer will be aligned to the strictest alignment so reset + //the aligner, which was needed for the old buffer. + aligner = 0u; //Update next_buffer_size to at least bytes this->increase_next_buffer_at_least_to(bytes); //Now allocate and update internal data @@ -150,7 +166,7 @@ void monotonic_buffer_resource::do_deallocate(void* p, std::size_t bytes, std::s { (void)p; (void)bytes; (void)alignment; } bool monotonic_buffer_resource::do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT -{ return this == dynamic_cast<const monotonic_buffer_resource*>(&other); } +{ return this == &other; } } //namespace pmr { } //namespace container { diff --git a/contrib/restricted/boost/container/src/pool_resource.cpp b/contrib/restricted/boost/container/src/pool_resource.cpp index e6829e28e7..82105a4520 100644 --- a/contrib/restricted/boost/container/src/pool_resource.cpp +++ b/contrib/restricted/boost/container/src/pool_resource.cpp @@ -176,7 +176,7 @@ pool_resource::pool_resource(const pool_options& opts) BOOST_NOEXCEPT : m_options(opts), m_upstream(*get_default_resource()), m_oversized_list(), m_pool_data(), m_pool_count() { this->priv_constructor_body(); } -pool_resource::~pool_resource() //virtual +pool_resource::~pool_resource() { this->release(); @@ -203,7 +203,7 @@ memory_resource* pool_resource::upstream_resource() const pool_options pool_resource::options() const { return m_options; } -void* pool_resource::do_allocate(std::size_t bytes, std::size_t alignment) //virtual +void* pool_resource::do_allocate(std::size_t bytes, std::size_t alignment) { if(!m_pool_data){ this->priv_init_pools(); @@ -224,7 +224,7 @@ void* pool_resource::do_allocate(std::size_t bytes, std::size_t alignment) //vir } } -void pool_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment) //virtual +void pool_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment) { (void)alignment; //alignment ignored here, max_align is used by pools if(bytes > m_options.largest_required_pool_block){ @@ -237,10 +237,6 @@ void pool_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignm } } -bool pool_resource::do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT //virtual -{ return this == dynamic_cast<const pool_resource*>(&other); } - - std::size_t pool_resource::pool_count() const { if(BOOST_LIKELY((0 != m_pool_data))){ diff --git a/contrib/restricted/boost/container/src/synchronized_pool_resource.cpp b/contrib/restricted/boost/container/src/synchronized_pool_resource.cpp index b98bed4f63..21c40a9e5b 100644 --- a/contrib/restricted/boost/container/src/synchronized_pool_resource.cpp +++ b/contrib/restricted/boost/container/src/synchronized_pool_resource.cpp @@ -11,31 +11,29 @@ #define BOOST_CONTAINER_SOURCE #include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/workaround.hpp> -#include <boost/container/detail/dlmalloc.hpp> +#include <boost/container/detail/thread_mutex.hpp> #include <boost/container/pmr/synchronized_pool_resource.hpp> #include <cstddef> namespace { -using namespace boost::container; +using namespace boost::container::dtl; -class dlmalloc_sync_scoped_lock +class thread_mutex_lock { - void *m_sync; + thread_mutex &m_mut; public: - explicit dlmalloc_sync_scoped_lock(void *sync) - : m_sync(sync) + explicit thread_mutex_lock(thread_mutex &m) + : m_mut(m) { - if(!dlmalloc_sync_lock(m_sync)){ - throw_bad_alloc(); - } + m_mut.lock(); } - ~dlmalloc_sync_scoped_lock() + ~thread_mutex_lock() { - dlmalloc_sync_unlock(m_sync); + m_mut.unlock(); } }; @@ -46,32 +44,28 @@ namespace container { namespace pmr { synchronized_pool_resource::synchronized_pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT - : m_pool_resource(opts, upstream), m_opaque_sync() + : m_mut(), m_pool_resource(opts, upstream) {} synchronized_pool_resource::synchronized_pool_resource() BOOST_NOEXCEPT - : m_pool_resource(), m_opaque_sync() + : m_mut(), m_pool_resource() {} synchronized_pool_resource::synchronized_pool_resource(memory_resource* upstream) BOOST_NOEXCEPT - : m_pool_resource(upstream), m_opaque_sync() + : m_mut(), m_pool_resource(upstream) {} synchronized_pool_resource::synchronized_pool_resource(const pool_options& opts) BOOST_NOEXCEPT - : m_pool_resource(opts), m_opaque_sync() + : m_mut(), m_pool_resource(opts) {} synchronized_pool_resource::~synchronized_pool_resource() //virtual -{ - if(m_opaque_sync) - dlmalloc_sync_destroy(m_opaque_sync); -} +{} void synchronized_pool_resource::release() { - if(m_opaque_sync){ //If there is no mutex, no allocation could be done - m_pool_resource.release(); - } + thread_mutex_lock lck(m_mut); (void)lck; + m_pool_resource.release(); } memory_resource* synchronized_pool_resource::upstream_resource() const @@ -82,24 +76,18 @@ pool_options synchronized_pool_resource::options() const void* synchronized_pool_resource::do_allocate(std::size_t bytes, std::size_t alignment) //virtual { - if(!m_opaque_sync){ //If there is no mutex, no allocation could be done - m_opaque_sync = dlmalloc_sync_create(); - if(!m_opaque_sync){ - throw_bad_alloc(); - } - } - dlmalloc_sync_scoped_lock lock(m_opaque_sync); (void)lock; + thread_mutex_lock lck(m_mut); (void)lck; return m_pool_resource.do_allocate(bytes, alignment); } void synchronized_pool_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment) //virtual { - dlmalloc_sync_scoped_lock lock(m_opaque_sync); (void)lock; + thread_mutex_lock lck(m_mut); (void)lck; return m_pool_resource.do_deallocate(p, bytes, alignment); } bool synchronized_pool_resource::do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT //virtual -{ return this == dynamic_cast<const synchronized_pool_resource*>(&other); } +{ return this == &other; } std::size_t synchronized_pool_resource::pool_count() const { return m_pool_resource.pool_count(); } diff --git a/contrib/restricted/boost/container/src/unsynchronized_pool_resource.cpp b/contrib/restricted/boost/container/src/unsynchronized_pool_resource.cpp index 0c84f694a3..9ce7fef9b6 100644 --- a/contrib/restricted/boost/container/src/unsynchronized_pool_resource.cpp +++ b/contrib/restricted/boost/container/src/unsynchronized_pool_resource.cpp @@ -55,7 +55,7 @@ void unsynchronized_pool_resource::do_deallocate(void* p, std::size_t bytes, std { return m_resource.do_deallocate(p, bytes, alignment); } bool unsynchronized_pool_resource::do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT //virtual -{ return this == dynamic_cast<const unsynchronized_pool_resource*>(&other); } +{ return this == &other; } std::size_t unsynchronized_pool_resource::pool_count() const { return m_resource.pool_count(); } diff --git a/contrib/restricted/boost/core/include/boost/detail/no_exceptions_support.hpp b/contrib/restricted/boost/core/include/boost/detail/no_exceptions_support.hpp deleted file mode 100644 index 2cf0938327..0000000000 --- a/contrib/restricted/boost/core/include/boost/detail/no_exceptions_support.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2014 Glen Fernandes - * - * 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_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP -#define BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP - -// The header file at this path is deprecated; -// use boost/core/no_exceptions_support.hpp instead. - -#include <boost/config/header_deprecated.hpp> - -BOOST_HEADER_DEPRECATED("<boost/core/no_exceptions_support.hpp>") - -#include <boost/core/no_exceptions_support.hpp> - -#endif diff --git a/contrib/restricted/boost/intrusive/README.md b/contrib/restricted/boost/intrusive/README.md new file mode 100644 index 0000000000..e14bd38c87 --- /dev/null +++ b/contrib/restricted/boost/intrusive/README.md @@ -0,0 +1,40 @@ +Boost.Intrusive +========== + +Boost.Intrusive, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), is a library presenting intrusive containers to the world of C++. Intrusive containers are special containers that offer better performance and exception safety guarantees than non-intrusive containers (like STL containers). The performance benefits of intrusive containers makes them ideal as a building block to efficiently construct complex data structures like multi-index containers or to design high performance code like memory allocation algorithms. + +While intrusive containers were and are widely used in C, they became more and more forgotten in C++ due to the presence of the standard containers which don't support intrusive techniques.Boost.Intrusive wants to push intrusive containers usage encapsulating the implementation in STL-like interfaces. Hence anyone familiar with standard containers can easily use Boost.Intrusive. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +### Properties + +* C++03 +* Header-Only + +### Build Status + +Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | +:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | +[`master`](https://github.com/boostorg/intrusive/tree/master) | [![Build Status](https://travis-ci.org/boostorg/intrusive.svg?branch=master)](https://travis-ci.org/boostorg/intrusive) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/intrusive-0k1xg/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-intrusive) | [![codecov](https://codecov.io/gh/boostorg/intrusive/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/intrusive/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/intrusive.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/intrusive.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/intrusive.html) +[`develop`](https://github.com/boostorg/intrusive/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/intrusive.svg?branch=develop)](https://travis-ci.org/boostorg/intrusive) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/intrusive-0k1xg/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-intrusive) | [![codecov](https://codecov.io/gh/boostorg/intrusive/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/intrusive/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/intrusive.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/intrusive.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/intrusive.html) + +### Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `doc` | documentation | +| `example` | examples | +| `include` | headers | +| `proj` | ide projects | +| `test` | unit tests | + +### More information + +* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-intrusive) +* [Report bugs](https://github.com/boostorg/intrusive/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). +* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[intrusive]` tag at the beginning of the subject line. + diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/avltree.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/avltree.hpp index cdc9b75d60..747d41cc38 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/avltree.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/avltree.hpp @@ -154,61 +154,61 @@ class avltree_impl ~avltree_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static avltree_impl &container_from_end_iterator(iterator end_iterator); + static avltree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const avltree_impl &container_from_end_iterator(const_iterator end_iterator); + static const avltree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static avltree_impl &container_from_iterator(iterator it); + static avltree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const avltree_impl &container_from_iterator(const_iterator it); + static const avltree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -217,10 +217,10 @@ class avltree_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::swap void swap(avltree_impl& other); @@ -278,26 +278,26 @@ class avltree_impl (const_iterator hint, const key_type &key, insert_commit_data &commit_data); //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator) template<class Iterator> void insert_unique(Iterator b, Iterator e); //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const key_type &) size_type erase(const key_type &key); @@ -308,11 +308,11 @@ class avltree_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) template<class Disposer> @@ -323,11 +323,11 @@ class avltree_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::bstree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template<class Disposer> - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::count(const key_type &ke)const size_type count(const key_type &key) const; @@ -413,28 +413,28 @@ class avltree_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::merge_unique(bstree<T, Options2...>&) template<class T, class ...Options2> @@ -535,46 +535,46 @@ class avltree //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value)); - avltree() + BOOST_INTRUSIVE_FORCEINLINE avltree() : Base() {} - explicit avltree( const key_compare &cmp, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE explicit avltree( const key_compare &cmp, const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} template<class Iterator> - avltree( bool unique, Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE avltree( bool unique, Iterator b, Iterator e , const key_compare &cmp = key_compare() , const value_traits &v_traits = value_traits()) : Base(unique, b, e, cmp, v_traits) {} - avltree(BOOST_RV_REF(avltree) x) + BOOST_INTRUSIVE_FORCEINLINE avltree(BOOST_RV_REF(avltree) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - avltree& operator=(BOOST_RV_REF(avltree) x) + BOOST_INTRUSIVE_FORCEINLINE avltree& operator=(BOOST_RV_REF(avltree) x) { return static_cast<avltree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const avltree &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const avltree &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(avltree) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(avltree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static avltree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static avltree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<avltree &>(Base::container_from_end_iterator(end_iterator)); } - static const avltree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const avltree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const avltree &>(Base::container_from_end_iterator(end_iterator)); } - static avltree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static avltree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast<avltree &>(Base::container_from_iterator(it)); } - static const avltree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const avltree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast<const avltree &>(Base::container_from_iterator(it)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/avltree_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/avltree_algorithms.hpp index 1459851fb4..48b028c978 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/avltree_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/avltree_algorithms.hpp @@ -42,18 +42,18 @@ struct avltree_node_cloner typedef typename NodeTraits::node_ptr node_ptr; typedef detail::ebo_functor_holder<F> base_t; - avltree_node_cloner(F f) + BOOST_INTRUSIVE_FORCEINLINE avltree_node_cloner(F f) : base_t(f) {} - node_ptr operator()(const node_ptr & p) + node_ptr operator()(node_ptr p) { node_ptr n = base_t::get()(p); NodeTraits::set_balance(n, NodeTraits::get_balance(p)); return n; } - node_ptr operator()(const node_ptr & p) const + node_ptr operator()(node_ptr p) const { node_ptr n = base_t::get()(p); NodeTraits::set_balance(n, NodeTraits::get_balance(p)); @@ -83,7 +83,7 @@ struct avltree_node_checker : base_checker_t(comp, extra_checker) {} - void operator () (const const_node_ptr& p, + void operator () (const_node_ptr p, const return_type& check_return_left, const return_type& check_return_right, return_type& check_return) { @@ -166,22 +166,22 @@ class avltree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const const_node_ptr & n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const const_node_ptr & header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const const_node_ptr & header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(const node_ptr & header1, const node_ptr & header2); + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&) - static void swap_nodes(const node_ptr & node1, const node_ptr & node2) + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -190,8 +190,8 @@ class avltree_algorithms swap_nodes(node1, header1, node2, header2); } - //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&) - static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2) + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -202,23 +202,23 @@ class avltree_algorithms NodeTraits::set_balance(node2, c); } - //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&) - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node) + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT { if(node_to_be_replaced == new_node) return; replace_node(node_to_be_replaced, bstree_algo::get_header(node_to_be_replaced), new_node); } - //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&) - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node) + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::replace_node(node_to_be_replaced, header, new_node); NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced)); } - //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(const node_ptr&) - static void unlink(const node_ptr & node) + //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr) + static void unlink(node_ptr node) BOOST_NOEXCEPT { node_ptr x = NodeTraits::get_parent(node); if(x){ @@ -230,22 +230,22 @@ class avltree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const const_node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const const_node_ptr & header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr) + static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr) + static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&) - static void init(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) + static void init(node_ptr node) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! <b>Requires</b>: node must not be part of any tree. @@ -258,14 +258,14 @@ class avltree_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree. - static void init_header(const node_ptr & header) + static void init_header(node_ptr header) BOOST_NOEXCEPT { bstree_algo::init_header(header); NodeTraits::set_balance(header, NodeTraits::zero()); } - //! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&) - static node_ptr erase(const node_ptr & header, const node_ptr & z) + //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) + static node_ptr erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT { typename bstree_algo::data_for_rebalance info; bstree_algo::erase(header, z, info); @@ -276,7 +276,7 @@ class avltree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique template<class NodePtrCompare> static bool transfer_unique - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) { typename bstree_algo::data_for_rebalance info; bool const transferred = bstree_algo::transfer_unique(header1, comp, header2, z, info); @@ -290,7 +290,7 @@ class avltree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal template<class NodePtrCompare> static void transfer_equal - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) { typename bstree_algo::data_for_rebalance info; bstree_algo::transfer_equal(header1, comp, header2, z, info); @@ -298,134 +298,134 @@ class avltree_algorithms rebalance_after_insertion(header1, z); } - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template <class Cloner, class Disposer> static void clone - (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer) + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) { avltree_node_cloner<NodeTraits, Cloner> new_cloner(cloner); bstree_algo::clone(source_header, target_header, new_cloner, disposer); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer) template<class Disposer> - static void clear_and_dispose(const node_ptr & header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> bounded_range - (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed); - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> - static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare> static node_ptr insert_equal_upper_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr h, node_ptr new_node, NodePtrCompare comp) { bstree_algo::insert_equal_upper_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare> static node_ptr insert_equal_lower_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr h, node_ptr new_node, NodePtrCompare comp) { bstree_algo::insert_equal_lower_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare> static node_ptr insert_equal - (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp) { bstree_algo::insert_equal(header, hint, new_node, comp); rebalance_after_insertion(header, new_node); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr) static node_ptr insert_before - (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node) + (node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::insert_before(header, pos, new_node); rebalance_after_insertion(header, new_node); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&) - static void push_back(const node_ptr & header, const node_ptr & new_node) + //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) + static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_back(header, new_node); rebalance_after_insertion(header, new_node); } - //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&) - static void push_front(const node_ptr & header, const node_ptr & new_node) + //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr) + static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_front(header, new_node); rebalance_after_insertion(header, new_node); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const const_node_ptr & header, const KeyType &key + (const_node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data); - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const const_node_ptr & header, const node_ptr &hint, const KeyType &key + (const_node_ptr header, node_ptr hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data); #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data &) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data &) static void insert_unique_commit - (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { bstree_algo::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(header, new_value); } //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const const_node_ptr & p) + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT { return NodeTraits::get_balance(p) == NodeTraits::zero() && bstree_algo::is_header(p); } /// @cond - static bool verify(const node_ptr &header) + static bool verify(node_ptr header) { std::size_t height; std::size_t count; @@ -483,7 +483,7 @@ class avltree_algorithms } static void rebalance_after_erasure - ( const node_ptr & header, const node_ptr &z, const typename bstree_algo::data_for_rebalance &info) + ( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) BOOST_NOEXCEPT { if(info.y != z){ NodeTraits::set_balance(info.y, NodeTraits::get_balance(z)); @@ -492,7 +492,7 @@ class avltree_algorithms rebalance_after_erasure_restore_invariants(header, info.x, info.x_parent); } - static void rebalance_after_erasure_restore_invariants(const node_ptr & header, node_ptr x, node_ptr x_parent) + static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) BOOST_NOEXCEPT { for ( node_ptr root = NodeTraits::get_parent(header) ; x != root @@ -560,7 +560,7 @@ class avltree_algorithms } } - static void rebalance_after_insertion(const node_ptr & header, node_ptr x) + static void rebalance_after_insertion(node_ptr header, node_ptr x) BOOST_NOEXCEPT { NodeTraits::set_balance(x, NodeTraits::zero()); // Rebalance. @@ -605,7 +605,7 @@ class avltree_algorithms } } - static void left_right_balancing(const node_ptr & a, const node_ptr & b, const node_ptr & c) + static void left_right_balancing(node_ptr a, node_ptr b, node_ptr c) BOOST_NOEXCEPT { // balancing... const balance c_balance = NodeTraits::get_balance(c); @@ -630,7 +630,7 @@ class avltree_algorithms } } - static node_ptr avl_rotate_left_right(const node_ptr a, const node_ptr a_oldleft, const node_ptr & hdr) + static node_ptr avl_rotate_left_right(const node_ptr a, const node_ptr a_oldleft, node_ptr hdr) BOOST_NOEXCEPT { // [note: 'a_oldleft' is 'b'] // | | // // a(-2) c // @@ -650,7 +650,7 @@ class avltree_algorithms return c; } - static node_ptr avl_rotate_right_left(const node_ptr a, const node_ptr a_oldright, const node_ptr & hdr) + static node_ptr avl_rotate_right_left(const node_ptr a, const node_ptr a_oldright, node_ptr hdr) BOOST_NOEXCEPT { // [note: 'a_oldright' is 'b'] // | | // // a(pos) c // @@ -670,7 +670,7 @@ class avltree_algorithms return c; } - static void avl_rotate_left(const node_ptr &x, const node_ptr &x_oldright, const node_ptr & hdr) + static void avl_rotate_left(node_ptr x, node_ptr x_oldright, node_ptr hdr) BOOST_NOEXCEPT { bstree_algo::rotate_left(x, x_oldright, NodeTraits::get_parent(x), hdr); @@ -685,7 +685,7 @@ class avltree_algorithms } } - static void avl_rotate_right(const node_ptr &x, const node_ptr &x_oldleft, const node_ptr & hdr) + static void avl_rotate_right(node_ptr x, node_ptr x_oldleft, node_ptr hdr) BOOST_NOEXCEPT { bstree_algo::rotate_right(x, x_oldleft, NodeTraits::get_parent(x), hdr); diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/bstree.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/bstree.hpp index 410eedf930..51687ebd27 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/bstree.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/bstree.hpp @@ -145,22 +145,22 @@ struct bstbase3 BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const { return pointer_traits<const_value_traits_ptr>::pointer_to(this->get_value_traits()); } - iterator begin() + BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT { return iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT { return cbegin(); } - const_iterator cbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT { return const_iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); } - iterator end() + BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT { return iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT { return cend(); } - BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT { return const_iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr()); } BOOST_INTRUSIVE_FORCEINLINE iterator root() @@ -195,32 +195,32 @@ struct bstbase3 node_algorithms::replace_node( get_value_traits().to_node_ptr(*replace_this) , this->header_ptr() , get_value_traits().to_node_ptr(with_this)); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(replace_this.pointed_node()); } - BOOST_INTRUSIVE_FORCEINLINE void rebalance() + BOOST_INTRUSIVE_FORCEINLINE void rebalance() BOOST_NOEXCEPT { node_algorithms::rebalance(this->header_ptr()); } - iterator rebalance_subtree(iterator root) - { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this->priv_value_traits_ptr()); } + iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT + { return iterator(node_algorithms::rebalance_subtree(r.pointed_node()), this->priv_value_traits_ptr()); } - static iterator s_iterator_to(reference value) + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr()); } - static const_iterator s_iterator_to(const_reference value) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); return const_iterator (value_traits::to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), const_value_traits_ptr()); } - iterator iterator_to(reference value) + iterator iterator_to(reference value) BOOST_NOEXCEPT { return iterator (this->get_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); } - const_iterator iterator_to(const_reference value) const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT { return const_iterator (this->get_value_traits().to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), this->priv_value_traits_ptr()); } BOOST_INTRUSIVE_FORCEINLINE static void init_node(reference value) @@ -301,10 +301,10 @@ struct bstbase2 : detail::ebo_functor_holder<value_compare>(value_compare(comp)), treeheader_t(vtraits) {} - const value_compare &comp() const + const value_compare &get_comp() const { return this->get(); } - value_compare &comp() + value_compare &get_comp() { return this->get(); } typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer; @@ -315,10 +315,10 @@ struct bstbase2 typedef typename node_algorithms::insert_commit_data insert_commit_data; BOOST_INTRUSIVE_FORCEINLINE value_compare value_comp() const - { return this->comp(); } + { return this->get_comp(); } BOOST_INTRUSIVE_FORCEINLINE key_compare key_comp() const - { return this->comp().key_comp(); } + { return this->get_comp().key_comp(); } //lower_bound BOOST_INTRUSIVE_FORCEINLINE iterator lower_bound(const key_type &key) @@ -400,8 +400,8 @@ struct bstbase2 template<class KeyType, class KeyTypeKeyCompare> std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp) { - std::pair<node_ptr, node_ptr> ret - (node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp))); + std::pair<node_ptr, node_ptr> ret = + node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp)); return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr()) , iterator(ret.second, this->priv_value_traits_ptr())); } @@ -414,8 +414,8 @@ struct bstbase2 std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp) const { - std::pair<node_ptr, node_ptr> ret - (node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp))); + std::pair<node_ptr, node_ptr> ret = + node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp)); return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr()) , const_iterator(ret.second, this->priv_value_traits_ptr())); } @@ -427,8 +427,8 @@ struct bstbase2 template<class KeyType, class KeyTypeKeyCompare> std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp) { - std::pair<node_ptr, node_ptr> ret - (node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp))); + std::pair<node_ptr, node_ptr> ret = + node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp)); return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr()) , iterator(ret.second, this->priv_value_traits_ptr())); } @@ -441,8 +441,8 @@ struct bstbase2 std::pair<const_iterator, const_iterator> lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp) const { - std::pair<node_ptr, node_ptr> ret - (node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp))); + std::pair<node_ptr, node_ptr> ret = + node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp)); return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr()) , const_iterator(ret.second, this->priv_value_traits_ptr())); } @@ -456,9 +456,9 @@ struct bstbase2 std::pair<iterator,iterator> bounded_range (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) { - std::pair<node_ptr, node_ptr> ret - (node_algorithms::bounded_range - (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed)); + std::pair<node_ptr, node_ptr> ret = + node_algorithms::bounded_range + (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed); return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr()) , iterator(ret.second, this->priv_value_traits_ptr())); } @@ -471,9 +471,9 @@ struct bstbase2 std::pair<const_iterator,const_iterator> bounded_range (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const { - std::pair<node_ptr, node_ptr> ret - (node_algorithms::bounded_range - (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed)); + std::pair<node_ptr, node_ptr> ret = + node_algorithms::bounded_range + (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed); return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr()) , const_iterator(ret.second, this->priv_value_traits_ptr())); } @@ -735,7 +735,7 @@ class bstree_impl //! move constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or the move constructor of the comparison objet throws. bstree_impl(BOOST_RV_REF(bstree_impl) x) - : data_type(::boost::move(x.comp()), ::boost::move(x.get_value_traits())) + : data_type(::boost::move(x.get_comp()), ::boost::move(x.get_value_traits())) { this->swap(x); } @@ -761,42 +761,42 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the container. //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the container. //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns an iterator pointing to the end of the container. //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - iterator end(); + iterator end() BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_iterator pointing to the end of the container. //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_iterator pointing to the end of the container. //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the //! reversed container. @@ -804,7 +804,7 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. @@ -812,7 +812,7 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. @@ -820,7 +820,7 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a reverse_iterator pointing to the end //! of the reversed container. @@ -828,7 +828,7 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -836,7 +836,7 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -844,28 +844,28 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a iterator pointing to the root node of the container or end() if not present. //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - iterator root(); + iterator root() BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_iterator pointing to the root node of the container or cend() if not present. //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! <b>Effects</b>: Returns a const_iterator pointing to the root node of the container or cend() if not present. //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -877,7 +877,7 @@ class bstree_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - static bstree_impl &container_from_end_iterator(iterator end_iterator) + static bstree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<bstree_impl&> (data_type::get_tree_base_from_end_iterator(end_iterator)); @@ -891,7 +891,7 @@ class bstree_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) + static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<bstree_impl&> (data_type::get_tree_base_from_end_iterator(end_iterator)); @@ -905,7 +905,7 @@ class bstree_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Logarithmic. - static bstree_impl &container_from_iterator(iterator it) + static bstree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT { return container_from_end_iterator(it.end_iterator_from_it()); } //! <b>Precondition</b>: it must be a valid end const_iterator @@ -916,7 +916,7 @@ class bstree_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Logarithmic. - static const bstree_impl &container_from_iterator(const_iterator it) + static const bstree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return container_from_end_iterator(it.end_iterator_from_it()); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -942,7 +942,7 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - bool empty() const + bool empty() const BOOST_NOEXCEPT { if(ConstantTimeSize){ return !this->data_type::sz_traits().get_size(); @@ -958,9 +958,9 @@ class bstree_impl //! if constant-time size option is disabled. Constant time otherwise. //! //! <b>Throws</b>: Nothing. - size_type size() const + size_type size() const BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) return this->sz_traits().get_size(); else{ return (size_type)node_algorithms::size(this->header_ptr()); @@ -975,7 +975,7 @@ class bstree_impl void swap(bstree_impl& other) { //This can throw - ::boost::adl_move_swap(this->comp(), other.comp()); + ::boost::adl_move_swap(this->get_comp(), other.get_comp()); //These can't throw node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr())); this->sz_traits().swap(other.sz_traits()); @@ -1008,7 +1008,7 @@ class bstree_impl ,detail::node_cloner <Cloner, value_traits, AlgoType>(cloner, &this->get_value_traits()) ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits())); this->sz_traits().set_size(src.sz_traits().get_size()); - this->comp() = src.comp(); + this->get_comp() = src.get_comp(); rollback.release(); } } @@ -1043,7 +1043,7 @@ class bstree_impl ,detail::node_cloner <Cloner, value_traits, AlgoType, false>(cloner, &this->get_value_traits()) ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits())); this->sz_traits().set_size(src.sz_traits().get_size()); - this->comp() = src.comp(); + this->get_comp() = src.get_comp(); rollback.release(); } } @@ -1062,8 +1062,7 @@ class bstree_impl iterator insert_equal(reference value) { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); iterator ret(node_algorithms::insert_equal_upper_bound (this->header_ptr(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr()); this->sz_traits().increment(); @@ -1087,8 +1086,7 @@ class bstree_impl iterator insert_equal(const_iterator hint, reference value) { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); iterator ret(node_algorithms::insert_equal (this->header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr()); this->sz_traits().increment(); @@ -1105,7 +1103,7 @@ class bstree_impl //! size of the range. However, it is linear in N if the range is already sorted //! by value_comp(). //! - //! <b>Throws</b>: Nothing. + //! <b>Throws</b>: If the comparison functor call throws. //! //! <b>Note</b>: Does not affect the validity of iterators and references. //! No copy-constructors are called. @@ -1125,7 +1123,7 @@ class bstree_impl //! <b>Complexity</b>: Average complexity for insert element is at //! most logarithmic. //! - //! <b>Throws</b>: Nothing. + //! <b>Throws</b>: If the comparison functor call throws. //! //! <b>Note</b>: Does not affect the validity of iterators and references. //! No copy-constructors are called. @@ -1151,7 +1149,7 @@ class bstree_impl //! constant time (two comparisons in the worst case) //! if t is inserted immediately before hint. //! - //! <b>Throws</b>: Nothing. + //! <b>Throws</b>: If the comparison functor call throws. //! //! <b>Note</b>: Does not affect the validity of iterators and references. //! No copy-constructors are called. @@ -1174,7 +1172,7 @@ class bstree_impl //! size of the range. However, it is linear in N if the range is already sorted //! by value_comp(). //! - //! <b>Throws</b>: Nothing. + //! <b>Throws</b>: If the comparison functor call throws. //! //! <b>Note</b>: Does not affect the validity of iterators and references. //! No copy-constructors are called. @@ -1314,11 +1312,10 @@ class bstree_impl //! <b>Notes</b>: This function has only sense if a "insert_check" has been //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); #if !(defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) )) //Test insertion position is correct @@ -1328,8 +1325,8 @@ class bstree_impl } //Check if the insertion point is correct to detect wrong //uses insert_unique_check - BOOST_ASSERT(( p == this->end() || !this->comp()(*p, value) )); - BOOST_ASSERT(( p == this->begin() || !this->comp()(value, *--p) )); + BOOST_ASSERT(( p == this->end() || !this->get_comp()(*p, value) )); + BOOST_ASSERT(( p == this->begin() || !this->get_comp()(value, *--p) )); #endif node_algorithms::insert_unique_commit @@ -1352,11 +1349,10 @@ class bstree_impl //! the successor of "value" container ordering invariant will be broken. //! This is a low-level function to be used only for performance reasons //! by advanced users. - iterator insert_before(const_iterator pos, reference value) + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); this->sz_traits().increment(); return iterator(node_algorithms::insert_before (this->header_ptr(), pos.pointed_node(), to_insert), this->priv_value_traits_ptr()); @@ -1376,11 +1372,10 @@ class bstree_impl //! This function is slightly more efficient than using "insert_before". //! This is a low-level function to be used only for performance reasons //! by advanced users. - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); this->sz_traits().increment(); node_algorithms::push_back(this->header_ptr(), to_insert); } @@ -1399,11 +1394,10 @@ class bstree_impl //! This function is slightly more efficient than using "insert_before". //! This is a low-level function to be used only for performance reasons //! by advanced users. - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); this->sz_traits().increment(); node_algorithms::push_front(this->header_ptr(), to_insert); } @@ -1416,16 +1410,15 @@ class bstree_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator i) + iterator erase(const_iterator i) BOOST_NOEXCEPT { const_iterator ret(i); ++ret; node_ptr to_erase(i.pointed_node()); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase)); node_algorithms::erase(this->header_ptr(), to_erase); this->sz_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); return ret.unconst(); } @@ -1439,7 +1432,7 @@ class bstree_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, const_iterator e) + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT { size_type n; return this->private_erase(b, e, n); } //! <b>Effects</b>: Erases all the elements with the given value. @@ -1452,7 +1445,7 @@ class bstree_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - size_type erase(const key_type &key) + size_type erase(const key_type &key) BOOST_NOEXCEPT { return this->erase(key, this->key_comp()); } //! <b>Requires</b>: key is a value such that `*this` is partitioned with respect to @@ -1493,7 +1486,7 @@ class bstree_impl //! <b>Note</b>: Invalidates the iterators //! to the erased elements. template<class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase(i.pointed_node()); iterator ret(this->erase(i)); @@ -1536,7 +1529,7 @@ class bstree_impl //! <b>Note</b>: Invalidates the iterators //! to the erased elements. template<class Disposer> - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT { size_type n; return this->private_erase(b, e, n, disposer); } //! <b>Requires</b>: key is a value such that `*this` is partitioned with respect to @@ -1577,9 +1570,9 @@ class bstree_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - void clear() + void clear() BOOST_NOEXCEPT { - if(safemode_or_autounlink){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ this->clear_and_dispose(detail::null_disposer()); } else{ @@ -1598,7 +1591,7 @@ class bstree_impl //! <b>Note</b>: Invalidates the iterators (but not the references) //! to the erased elements. Calls N times to disposer functor. template<class Disposer> - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_algorithms::clear_and_dispose(this->header_ptr() , detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits())); @@ -1841,7 +1834,7 @@ class bstree_impl //! //! <b>Note</b>: This static function is available only if the <i>value traits</i> //! is stateless. - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! <b>Requires</b>: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. @@ -1855,7 +1848,7 @@ class bstree_impl //! //! <b>Note</b>: This static function is available only if the <i>value traits</i> //! is stateless. - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! <b>Requires</b>: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. @@ -1866,7 +1859,7 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! <b>Requires</b>: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. @@ -1877,7 +1870,7 @@ class bstree_impl //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! <b>Requires</b>: value shall not be in a container. //! @@ -1890,7 +1883,7 @@ class bstree_impl //! //! <b>Note</b>: This function puts the hook in the well-known default state //! used by auto_unlink and safe hooks. - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -1904,14 +1897,14 @@ class bstree_impl //! only be used for more unlink_leftmost_without_rebalance calls. //! This function is normally used to achieve a step by step //! controlled destruction of the container. - pointer unlink_leftmost_without_rebalance() + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT { node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance (this->header_ptr())); if(!to_be_disposed) return 0; this->sz_traits().decrement(); - if(safemode_or_autounlink)//If this is commented does not work with normal_link + BOOST_IF_CONSTEXPR(safemode_or_autounlink)//If this is commented does not work with normal_link node_algorithms::init(to_be_disposed); return this->get_value_traits().to_value_ptr(to_be_disposed); } @@ -1932,14 +1925,14 @@ class bstree_impl //! with_this is not equivalent to *replace_this according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing or comparison is needed. - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! <b>Effects</b>: Rebalances the tree. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear. - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! <b>Requires</b>: old_root is a node of a tree. //! @@ -1950,7 +1943,7 @@ class bstree_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the elements in the subtree. - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -1966,12 +1959,12 @@ class bstree_impl //! If the user calls //! this function with a constant time size container or stateful comparison //! functor a compilation error will be issued. - static void remove_node(reference value) + static void remove_node(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!constant_time_size)); node_ptr to_remove(value_traits::to_node_ptr(value)); node_algorithms::unlink(to_remove); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_remove); } @@ -2061,8 +2054,7 @@ class bstree_impl typedef typename get_node_checker<AlgoType, ValueTraits, nodeptr_comp_t, ExtraChecker>::type node_checker_t; typename node_checker_t::return_type checker_return; node_algorithms::check(this->header_ptr(), node_checker_t(nodeptr_comp, extra_checker), checker_return); - if (constant_time_size) - BOOST_INTRUSIVE_INVARIANT_ASSERT(this->sz_traits().get_size() == checker_return.node_count); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!constant_time_size || this->sz_traits().get_size() == checker_return.node_count); } //! <b>Effects</b>: Asserts the integrity of the container. @@ -2194,46 +2186,46 @@ class bstree //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value)); - bstree() + BOOST_INTRUSIVE_FORCEINLINE bstree() : Base() {} - explicit bstree( const key_compare &cmp, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE explicit bstree( const key_compare &cmp, const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} template<class Iterator> - bstree( bool unique, Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE bstree( bool unique, Iterator b, Iterator e , const key_compare &cmp = key_compare() , const value_traits &v_traits = value_traits()) : Base(unique, b, e, cmp, v_traits) {} - bstree(BOOST_RV_REF(bstree) x) + BOOST_INTRUSIVE_FORCEINLINE bstree(BOOST_RV_REF(bstree) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - bstree& operator=(BOOST_RV_REF(bstree) x) + BOOST_INTRUSIVE_FORCEINLINE bstree& operator=(BOOST_RV_REF(bstree) x) { return static_cast<bstree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const bstree &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const bstree &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static bstree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static bstree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<bstree &>(Base::container_from_end_iterator(end_iterator)); } - static const bstree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const bstree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const bstree &>(Base::container_from_end_iterator(end_iterator)); } - static bstree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static bstree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast<bstree &>(Base::container_from_iterator(it)); } - static const bstree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const bstree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast<const bstree &>(Base::container_from_iterator(it)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/bstree_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/bstree_algorithms.hpp index e449ebac08..ac8a088926 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/bstree_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/bstree_algorithms.hpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2014 +// (C) Copyright Ion Gaztanaga 2007-2021 +// (C) Copyright Daniel Steck 2021 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -79,14 +80,12 @@ struct bstree_node_checker : base_checker_t(extra_checker), comp_(comp) {} - void operator () (const const_node_ptr& p, + void operator () (const_node_ptr p, const return_type& check_return_left, const return_type& check_return_right, return_type& check_return) { - if (check_return_left.max_key_node_ptr) - BOOST_INTRUSIVE_INVARIANT_ASSERT(!comp_(p, check_return_left.max_key_node_ptr)); - if (check_return_right.min_key_node_ptr) - BOOST_INTRUSIVE_INVARIANT_ASSERT(!comp_(check_return_right.min_key_node_ptr, p)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!check_return_left.max_key_node_ptr || !comp_(p, check_return_left.max_key_node_ptr)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!check_return_right.min_key_node_ptr || !comp_(check_return_right.min_key_node_ptr, p)); check_return.min_key_node_ptr = node_traits::get_left(p)? check_return_left.min_key_node_ptr : p; check_return.max_key_node_ptr = node_traits::get_right(p)? check_return_right.max_key_node_ptr : p; check_return.node_count = check_return_left.node_count + check_return_right.node_count + 1; @@ -187,7 +186,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> template<class Disposer> struct dispose_subtree_disposer { - BOOST_INTRUSIVE_FORCEINLINE dispose_subtree_disposer(Disposer &disp, const node_ptr & subtree) + BOOST_INTRUSIVE_FORCEINLINE dispose_subtree_disposer(Disposer &disp, node_ptr subtree) : disposer_(&disp), subtree_(subtree) {} @@ -214,7 +213,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Constant time. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr begin_node(const const_node_ptr & header) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT { return node_traits::get_left(header); } //! <b>Requires</b>: 'header' is the header node of a tree. @@ -224,7 +223,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Constant time. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr end_node(const const_node_ptr & header) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT { return detail::uncast(header); } //! <b>Requires</b>: 'header' is the header node of a tree. @@ -234,7 +233,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Constant time. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr root_node(const const_node_ptr & header) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr root_node(const_node_ptr header) BOOST_NOEXCEPT { node_ptr p = node_traits::get_parent(header); return p ? p : detail::uncast(header); @@ -248,7 +247,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Constant time. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool unique(const const_node_ptr & node) + BOOST_INTRUSIVE_FORCEINLINE static bool unique(const_node_ptr node) BOOST_NOEXCEPT { return !NodeTraits::get_parent(node); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -259,7 +258,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Logarithmic. //! //! <b>Throws</b>: Nothing. - static node_ptr get_header(const const_node_ptr & node); + static node_ptr get_header(const_node_ptr node); #endif //! <b>Requires</b>: node1 and node2 can't be header nodes @@ -277,7 +276,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function - static void swap_nodes(const node_ptr & node1, const node_ptr & node2) + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -301,7 +300,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function - static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2) + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -398,38 +397,47 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> NodeTraits::set_parent(node1, NodeTraits::get_parent(node2)); NodeTraits::set_parent(node2, temp); - //Now adjust adjacent nodes for newly inserted node 1 + //Now adjust child nodes for newly inserted node 1 if((temp = NodeTraits::get_left(node1))){ NodeTraits::set_parent(temp, node1); } if((temp = NodeTraits::get_right(node1))){ NodeTraits::set_parent(temp, node1); } - if((temp = NodeTraits::get_parent(node1)) && - //The header has been already updated so avoid it - temp != header2){ - if(NodeTraits::get_left(temp) == node2){ - NodeTraits::set_left(temp, node1); - } - if(NodeTraits::get_right(temp) == node2){ - NodeTraits::set_right(temp, node1); - } - } - //Now adjust adjacent nodes for newly inserted node 2 + //Now adjust child nodes for newly inserted node 2 if((temp = NodeTraits::get_left(node2))){ NodeTraits::set_parent(temp, node2); } if((temp = NodeTraits::get_right(node2))){ NodeTraits::set_parent(temp, node2); } - if((temp = NodeTraits::get_parent(node2)) && - //The header has been already updated so avoid it - temp != header1){ - if(NodeTraits::get_left(temp) == node1){ - NodeTraits::set_left(temp, node2); + + //Finally adjust parent nodes + if ((temp = NodeTraits::get_parent(node1)) == NodeTraits::get_parent(node2)) { + // special logic for the case where the nodes are siblings + const node_ptr left = NodeTraits::get_left(temp); + NodeTraits::set_left(temp, NodeTraits::get_right(temp)); + NodeTraits::set_right(temp, left); + } else { + if ((temp = NodeTraits::get_parent(node1)) && + //The header has been already updated so avoid it + temp != header2) { + if (NodeTraits::get_left(temp) == node2) { + NodeTraits::set_left(temp, node1); + } + if (NodeTraits::get_right(temp) == node2) { + NodeTraits::set_right(temp, node1); + } } - if(NodeTraits::get_right(temp) == node1){ - NodeTraits::set_right(temp, node2); + if ((temp = NodeTraits::get_parent(node2)) && + //The header has been already updated so avoid it + temp != header1) { + if (NodeTraits::get_left(temp) == node1) { + NodeTraits::set_left(temp, node2); + } + if (NodeTraits::get_right(temp) == node1) { + NodeTraits::set_right(temp, node2); + } } } } @@ -448,10 +456,8 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing and comparison is needed. Experimental function - BOOST_INTRUSIVE_FORCEINLINE static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node) + BOOST_INTRUSIVE_FORCEINLINE static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT { - if(node_to_be_replaced == new_node) - return; replace_node(node_to_be_replaced, base_type::get_header(node_to_be_replaced), new_node); } @@ -469,10 +475,9 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting //! the node, since no rebalancing or comparison is needed. Experimental function - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node) + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { - if(node_to_be_replaced == new_node) - return; + BOOST_ASSERT(node_to_be_replaced != new_node); //Update header if necessary if(node_to_be_replaced == NodeTraits::get_left(header)){ @@ -520,7 +525,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Average constant time. //! //! <b>Throws</b>: Nothing. - static node_ptr next_node(const node_ptr & node); + static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT; //! <b>Requires</b>: 'node' is a node from the tree except the leftmost node. //! @@ -529,7 +534,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Average constant time. //! //! <b>Throws</b>: Nothing. - static node_ptr prev_node(const node_ptr & node); + static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT; //! <b>Requires</b>: 'node' is a node of a tree but not the header. //! @@ -559,24 +564,24 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: Nothing. //! //! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree. - BOOST_INTRUSIVE_FORCEINLINE static void init(const node_ptr & node) + static void init(node_ptr node) BOOST_NOEXCEPT { NodeTraits::set_parent(node, node_ptr()); NodeTraits::set_left(node, node_ptr()); NodeTraits::set_right(node, node_ptr()); - }; + } //! <b>Effects</b>: Returns true if node is in the same state as if called init(node) //! //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool inited(const const_node_ptr & node) + static bool inited(const_node_ptr node) { return !NodeTraits::get_parent(node) && !NodeTraits::get_left(node) && !NodeTraits::get_right(node) ; - }; + } //! <b>Requires</b>: node must not be part of any tree. //! @@ -588,7 +593,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: Nothing. //! //! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree. - BOOST_INTRUSIVE_FORCEINLINE static void init_header(const node_ptr & header) + static void init_header(node_ptr header) BOOST_NOEXCEPT { NodeTraits::set_parent(header, node_ptr()); NodeTraits::set_left(header, header); @@ -599,15 +604,15 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! taking a node_ptr parameter and shouldn't throw. //! //! <b>Effects</b>: Empties the target tree calling - //! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree + //! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree //! except the header. //! //! <b>Complexity</b>: Linear to the number of element of the source tree plus the. //! number of elements of tree target tree when calling this function. //! - //! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed. + //! <b>Throws</b>: Nothing. template<class Disposer> - static void clear_and_dispose(const node_ptr & header, Disposer disposer) + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT { node_ptr source_root = NodeTraits::get_parent(header); if(!source_root) @@ -629,7 +634,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! only be used for more unlink_leftmost_without_rebalance calls. //! This function is normally used to achieve a step by step //! controlled destruction of the tree. - static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header) + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT { node_ptr leftmost = NodeTraits::get_left(header); if (leftmost == header) @@ -666,7 +671,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Linear time. //! //! <b>Throws</b>: Nothing. - static std::size_t size(const const_node_ptr & header) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT { node_ptr beg(begin_node(header)); node_ptr end(end_node(header)); @@ -684,7 +689,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - static void swap_tree(const node_ptr & header1, const node_ptr & header2) + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT { if(header1 == header2) return; @@ -732,7 +737,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - static bool is_header(const const_node_ptr & p); + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT; #endif //! <b>Requires</b>: "header" must be the header node of a tree. @@ -748,7 +753,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class KeyType, class KeyNodePtrCompare> static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { node_ptr end = detail::uncast(header); node_ptr y = lower_bound(header, key, comp); @@ -778,7 +783,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Note</b>: Experimental function, the interface might change. template< class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> bounded_range - ( const const_node_ptr & header + ( const_node_ptr header , const KeyType &lower_key , const KeyType &upper_key , KeyNodePtrCompare comp @@ -845,7 +850,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class KeyType, class KeyNodePtrCompare> static std::size_t count - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { std::pair<node_ptr, node_ptr> ret = equal_range(header, key, comp); std::size_t n = 0; @@ -871,7 +876,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class KeyType, class KeyNodePtrCompare> BOOST_INTRUSIVE_FORCEINLINE static std::pair<node_ptr, node_ptr> equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bounded_range(header, key, key, comp, true, true); } @@ -891,7 +896,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> lower_bound_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { node_ptr const lb(lower_bound(header, key, comp)); std::pair<node_ptr, node_ptr> ret_ii(lb, lb); @@ -915,7 +920,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class KeyType, class KeyNodePtrCompare> BOOST_INTRUSIVE_FORCEINLINE static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return lower_bound_loop(NodeTraits::get_parent(header), detail::uncast(header), key, comp); } @@ -933,7 +938,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class KeyType, class KeyNodePtrCompare> BOOST_INTRUSIVE_FORCEINLINE static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return upper_bound_loop(NodeTraits::get_parent(header), detail::uncast(header), key, comp); } @@ -956,7 +961,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. BOOST_INTRUSIVE_FORCEINLINE static void insert_unique_commit - (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return insert_commit(header, new_value, commit_data); } //! <b>Requires</b>: "header" must be the header node of a tree. @@ -995,7 +1000,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! if no more objects are inserted or erased from the set. template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const const_node_ptr & header, const KeyType &key + (const_node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 @@ -1014,7 +1019,8 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> while(x){ ++depth; y = x; - x = (left_child = comp(key, x)) ? + left_child = comp(key, x); + x = left_child ? NodeTraits::get_left(x) : (prev = y, NodeTraits::get_right(x)); } @@ -1072,7 +1078,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! if no more objects are inserted or erased from the set. template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const const_node_ptr & header, const node_ptr &hint, const KeyType &key + (const_node_ptr header, node_ptr hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 @@ -1112,7 +1118,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class NodePtrCompare> static node_ptr insert_equal - (const node_ptr & h, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp + (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif @@ -1138,7 +1144,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class NodePtrCompare> static node_ptr insert_equal_upper_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp + (node_ptr h, node_ptr new_node, NodePtrCompare comp #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif @@ -1164,7 +1170,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If "comp" throws. template<class NodePtrCompare> static node_ptr insert_equal_lower_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp + (node_ptr h, node_ptr new_node, NodePtrCompare comp #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif @@ -1191,11 +1197,11 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node" //! tree invariants might be broken. static node_ptr insert_before - (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node + (node_ptr header, node_ptr pos, node_ptr new_node #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { insert_commit_data commit_data; insert_before_check(header, pos, commit_data, pdepth); @@ -1217,11 +1223,11 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! tree invariants are broken. This function is slightly faster than //! using "insert_before". static void push_back - (const node_ptr & header, const node_ptr & new_node + (node_ptr header, node_ptr new_node #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { insert_commit_data commit_data; push_back_check(header, commit_data, pdepth); @@ -1242,11 +1248,11 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! tree invariants are broken. This function is slightly faster than //! using "insert_before". static void push_front - (const node_ptr & header, const node_ptr & new_node + (node_ptr header, node_ptr new_node #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { insert_commit_data commit_data; push_front_check(header, commit_data, pdepth); @@ -1262,7 +1268,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Logarithmic to the number of nodes in the tree. //! //! <b>Throws</b>: Nothing. - static std::size_t depth(const_node_ptr node) + static std::size_t depth(const_node_ptr node) BOOST_NOEXCEPT { std::size_t depth = 0; node_ptr p_parent; @@ -1278,13 +1284,13 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! take a node_ptr and shouldn't throw. //! //! <b>Effects</b>: First empties target tree calling - //! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree + //! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree //! except the header. //! //! Then, duplicates the entire tree pointed by "source_header" cloning each - //! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain + //! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain //! the nodes of the target tree. If "cloner" throws, the cloned target nodes - //! are disposed using <tt>void disposer(const node_ptr &)</tt>. + //! are disposed using <tt>void disposer(node_ptr )</tt>. //! //! <b>Complexity</b>: Linear to the number of element of the source tree plus the //! number of elements of tree target tree when calling this function. @@ -1292,7 +1298,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed. template <class Cloner, class Disposer> static void clone - (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer) + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) { if(!unique(target_header)){ clear_and_dispose(target_header, disposer); @@ -1316,7 +1322,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Amortized constant time. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void erase(const node_ptr & header, const node_ptr & z) + BOOST_INTRUSIVE_FORCEINLINE static void erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT { data_for_rebalance ignored; erase(header, z, ignored); @@ -1336,7 +1342,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If the comparison throws. template<class NodePtrCompare> BOOST_INTRUSIVE_FORCEINLINE static bool transfer_unique - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) { data_for_rebalance ignored; return transfer_unique(header1, comp, header2, z, ignored); @@ -1353,7 +1359,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: If the comparison throws. template<class NodePtrCompare> BOOST_INTRUSIVE_FORCEINLINE static void transfer_equal - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) { data_for_rebalance ignored; transfer_equal(header1, comp, header2, z, ignored); @@ -1366,7 +1372,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Average complexity is constant time. //! //! <b>Throws</b>: Nothing. - static void unlink(const node_ptr & node) + static void unlink(node_ptr node) BOOST_NOEXCEPT { node_ptr x = NodeTraits::get_parent(node); if(x){ @@ -1383,7 +1389,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear. - static void rebalance(const node_ptr & header) + static void rebalance(node_ptr header) BOOST_NOEXCEPT { node_ptr root = NodeTraits::get_parent(header); if(root){ @@ -1400,7 +1406,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear. - static node_ptr rebalance_subtree(const node_ptr & old_root) + static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT { //Taken from: //"Tree rebalancing in optimal time and space" @@ -1449,7 +1455,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Note</b>: The method might not have effect when asserts are turned off (e.g., with NDEBUG). //! Experimental function, interface might change in future versions. template<class Checker> - static void check(const const_node_ptr& header, Checker checker, typename Checker::return_type& checker_return) + static void check(const_node_ptr header, Checker checker, typename Checker::return_type& checker_return) { const_node_ptr root_node_ptr = NodeTraits::get_parent(header); if (!root_node_ptr){ @@ -1476,7 +1482,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> template<class NodePtrCompare> static bool transfer_unique - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z, data_for_rebalance &info) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z, data_for_rebalance &info) { insert_commit_data commit_data; bool const transferable = insert_unique_check(header1, z, comp, commit_data).second; @@ -1489,7 +1495,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> template<class NodePtrCompare> static void transfer_equal - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z, data_for_rebalance &info) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z, data_for_rebalance &info) { insert_commit_data commit_data; insert_equal_upper_bound_check(header1, z, comp, commit_data); @@ -1497,7 +1503,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> insert_commit(header1, z, commit_data); } - static void erase(const node_ptr & header, const node_ptr & z, data_for_rebalance &info) + static void erase(node_ptr header, node_ptr z, data_for_rebalance &info) { node_ptr y(z); node_ptr x; @@ -1586,7 +1592,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Linear time. //! //! <b>Throws</b>: Nothing. - static std::size_t subtree_size(const const_node_ptr & subtree) + static std::size_t subtree_size(const_node_ptr subtree) BOOST_NOEXCEPT { std::size_t count = 0; if (subtree){ @@ -1629,7 +1635,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool is_left_child(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static bool is_left_child(node_ptr p) BOOST_NOEXCEPT { return NodeTraits::get_left(NodeTraits::get_parent(p)) == p; } //! <b>Requires</b>: p is a node of a tree. @@ -1639,11 +1645,11 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool is_right_child(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static bool is_right_child(node_ptr p) BOOST_NOEXCEPT { return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; } static void insert_before_check - (const node_ptr &header, const node_ptr & pos + (node_ptr header, node_ptr pos , insert_commit_data &commit_data #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 @@ -1662,11 +1668,11 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } static void push_back_check - (const node_ptr & header, insert_commit_data &commit_data + (node_ptr header, insert_commit_data &commit_data #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { node_ptr prev(NodeTraits::get_right(header)); if(pdepth){ @@ -1677,11 +1683,11 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } static void push_front_check - (const node_ptr & header, insert_commit_data &commit_data + (node_ptr header, insert_commit_data &commit_data #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED , std::size_t *pdepth = 0 #endif - ) + ) BOOST_NOEXCEPT { node_ptr pos(NodeTraits::get_left(header)); if(pdepth){ @@ -1693,7 +1699,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> template<class NodePtrCompare> static void insert_equal_check - (const node_ptr &header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp , insert_commit_data &commit_data /// @cond , std::size_t *pdepth = 0 @@ -1722,7 +1728,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> template<class NodePtrCompare> static void insert_equal_upper_bound_check - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) + (node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) { std::size_t depth = 0; node_ptr y(h); @@ -1741,7 +1747,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> template<class NodePtrCompare> static void insert_equal_lower_bound_check - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) + (node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) { std::size_t depth = 0; node_ptr y(h); @@ -1759,7 +1765,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } static void insert_commit - (const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data) BOOST_NOEXCEPT { //Check if commit_data has not been initialized by a insert_unique_check call. BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != node_ptr()); @@ -1785,7 +1791,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } //Fix header and own's parent data when replacing x with own, providing own's old data with parent - static void set_child(const node_ptr & header, const node_ptr & new_child, const node_ptr & new_parent, const bool link_left) + static void set_child(node_ptr header, node_ptr new_child, node_ptr new_parent, const bool link_left) BOOST_NOEXCEPT { if(new_parent == header) NodeTraits::set_parent(header, new_child); @@ -1796,7 +1802,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } // rotate p to left (no header and p's parent fixup) - static void rotate_left_no_parent_fix(const node_ptr & p, const node_ptr &p_right) + static void rotate_left_no_parent_fix(node_ptr p, node_ptr p_right) BOOST_NOEXCEPT { node_ptr p_right_left(NodeTraits::get_left(p_right)); NodeTraits::set_right(p, p_right_left); @@ -1808,7 +1814,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } // rotate p to left (with header and p's parent fixup) - static void rotate_left(const node_ptr & p, const node_ptr & p_right, const node_ptr & p_parent, const node_ptr & header) + static void rotate_left(node_ptr p, node_ptr p_right, node_ptr p_parent, node_ptr header) BOOST_NOEXCEPT { const bool p_was_left(NodeTraits::get_left(p_parent) == p); rotate_left_no_parent_fix(p, p_right); @@ -1817,7 +1823,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } // rotate p to right (no header and p's parent fixup) - static void rotate_right_no_parent_fix(const node_ptr & p, const node_ptr &p_left) + static void rotate_right_no_parent_fix(node_ptr p, node_ptr p_left) BOOST_NOEXCEPT { node_ptr p_left_right(NodeTraits::get_right(p_left)); NodeTraits::set_left(p, p_left_right); @@ -1829,7 +1835,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } // rotate p to right (with header and p's parent fixup) - static void rotate_right(const node_ptr & p, const node_ptr & p_left, const node_ptr & p_parent, const node_ptr & header) + static void rotate_right(node_ptr p, node_ptr p_left, node_ptr p_parent, node_ptr header) BOOST_NOEXCEPT { const bool p_was_left(NodeTraits::get_left(p_parent) == p); rotate_right_no_parent_fix(p, p_left); @@ -1839,7 +1845,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> private: - static void subtree_to_vine(node_ptr vine_tail, std::size_t &size) + static void subtree_to_vine(node_ptr vine_tail, std::size_t &size) BOOST_NOEXCEPT { //Inspired by LibAVL: //It uses a clever optimization for trees with parent pointers. @@ -1866,7 +1872,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> size = len; } - static void compress_subtree(node_ptr scanner, std::size_t count) + static void compress_subtree(node_ptr scanner, std::size_t count) BOOST_NOEXCEPT { while(count--){ //compress "count" spine nodes in the tree with pseudo-root scanner node_ptr child = NodeTraits::get_right(scanner); @@ -1883,7 +1889,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } } - static void vine_to_subtree(const node_ptr & super_root, std::size_t count) + static void vine_to_subtree(node_ptr super_root, std::size_t count) BOOST_NOEXCEPT { const std::size_t one_szt = 1u; std::size_t leaf_nodes = count + one_szt - std::size_t(one_szt << detail::floor_log2(count + one_szt)); @@ -1910,7 +1916,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> //! <b>Complexity</b>: Logarithmic. //! //! <b>Throws</b>: Nothing. - static node_ptr get_root(const node_ptr & node) + static node_ptr get_root(node_ptr node) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(node))); node_ptr x = NodeTraits::get_parent(node); @@ -1927,7 +1933,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> template <class Cloner, class Disposer> static node_ptr clone_subtree - (const const_node_ptr &source_parent, const node_ptr &target_parent + (const_node_ptr source_parent, node_ptr target_parent , Cloner cloner, Disposer disposer , node_ptr &leftmost_out, node_ptr &rightmost_out ) @@ -2002,7 +2008,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } template<class Disposer> - static void dispose_subtree(node_ptr x, Disposer disposer) + static void dispose_subtree(node_ptr x, Disposer disposer) BOOST_NOEXCEPT { while (x){ node_ptr save(NodeTraits::get_left(x)); @@ -2053,7 +2059,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits> } template<class Checker> - static void check_subtree(const const_node_ptr& node, Checker checker, typename Checker::return_type& check_return) + static void check_subtree(const_node_ptr node, Checker checker, typename Checker::return_type& check_return) { const_node_ptr left = NodeTraits::get_left(node); const_node_ptr right = NodeTraits::get_right(node); diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/circular_list_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/circular_list_algorithms.hpp index 0bc4d9de90..a4efc0237a 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/circular_list_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/circular_list_algorithms.hpp @@ -67,7 +67,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void init(const node_ptr &this_node) + static void init(node_ptr this_node) BOOST_NOEXCEPT { const node_ptr null_node = node_ptr(); NodeTraits::set_next(this_node, null_node); @@ -80,7 +80,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool inited(const const_node_ptr &this_node) + BOOST_INTRUSIVE_FORCEINLINE static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT { return !NodeTraits::get_next(this_node); } //! <b>Effects</b>: Constructs an empty list, making this_node the only @@ -91,12 +91,21 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void init_header(const node_ptr &this_node) + static void init_header(node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, this_node); NodeTraits::set_previous(this_node, this_node); } + //! <b>Effects</b>: Returns true if this_node_points to an empty list. + //! + //! <b>Complexity</b>: Constant + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_empty(const_node_ptr this_node) BOOST_NOEXCEPT + { + return NodeTraits::get_next(this_node) == this_node; + } //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list. //! @@ -106,7 +115,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static bool unique(const const_node_ptr &this_node) + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT { node_ptr next = NodeTraits::get_next(this_node); return !next || next == this_node; @@ -120,7 +129,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Linear //! //! <b>Throws</b>: Nothing. - static std::size_t count(const const_node_ptr &this_node) + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT { std::size_t result = 0; const_node_ptr p = this_node; @@ -138,7 +147,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr unlink(const node_ptr &this_node) + static node_ptr unlink(node_ptr this_node) BOOST_NOEXCEPT { node_ptr next(NodeTraits::get_next(this_node)); node_ptr prev(NodeTraits::get_previous(this_node)); @@ -154,7 +163,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void unlink(const node_ptr &b, const node_ptr &e) + static void unlink(node_ptr b, node_ptr e) BOOST_NOEXCEPT { if (b != e) { node_ptr prevb(NodeTraits::get_previous(b)); @@ -170,7 +179,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void link_before(const node_ptr &nxt_node, const node_ptr &this_node) + static void link_before(node_ptr nxt_node, node_ptr this_node) BOOST_NOEXCEPT { node_ptr prev(NodeTraits::get_previous(nxt_node)); NodeTraits::set_previous(this_node, prev); @@ -189,7 +198,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void link_after(const node_ptr &prev_node, const node_ptr &this_node) + static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT { node_ptr next(NodeTraits::get_next(prev_node)); NodeTraits::set_previous(this_node, prev_node); @@ -211,7 +220,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node) + static void swap_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { if (other_node == this_node) return; @@ -252,9 +261,9 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void transfer(const node_ptr &p, const node_ptr &b, const node_ptr &e) + static void transfer(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT { - if (b != e) { + if (b != e && p != b && p != e) { node_ptr prev_p(NodeTraits::get_previous(p)); node_ptr prev_b(NodeTraits::get_previous(b)); node_ptr prev_e(NodeTraits::get_previous(e)); @@ -277,7 +286,7 @@ class circular_list_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void transfer(const node_ptr &p, const node_ptr &i) + static void transfer(node_ptr p, node_ptr i) BOOST_NOEXCEPT { node_ptr n(NodeTraits::get_next(i)); if(n != p && i != p){ @@ -298,7 +307,7 @@ class circular_list_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: This function is linear time. - static void reverse(const node_ptr &p) + static void reverse(node_ptr p) BOOST_NOEXCEPT { node_ptr f(NodeTraits::get_next(p)); node_ptr i(NodeTraits::get_next(f)), e(p); @@ -316,7 +325,7 @@ class circular_list_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of moved positions. - static void move_backwards(const node_ptr &p, std::size_t n) + static void move_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT { //Null shift, nothing to do if(!n) return; @@ -336,7 +345,7 @@ class circular_list_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of moved positions. - static void move_forward(const node_ptr &p, std::size_t n) + static void move_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT { //Null shift, nothing to do if(!n) return; @@ -359,12 +368,11 @@ class circular_list_algorithms //! <b>Complexity</b>: Linear //! //! <b>Throws</b>: Nothing. - static std::size_t distance(const const_node_ptr &f, const const_node_ptr &l) + static std::size_t distance(const_node_ptr f, const_node_ptr l) BOOST_NOEXCEPT { - const_node_ptr i(f); std::size_t result = 0; - while(i != l){ - i = NodeTraits::get_next(i); + while(f != l){ + f = NodeTraits::get_next(f); ++result; } return result; @@ -378,7 +386,7 @@ class circular_list_algorithms }; template<class Pred> - static void stable_partition(node_ptr beg, const node_ptr &end, Pred pred, stable_partition_info &info) + static void stable_partition(node_ptr beg, node_ptr end, Pred pred, stable_partition_info &info) { node_ptr bcur = node_traits::get_previous(beg); node_ptr cur = beg; @@ -435,14 +443,14 @@ class circular_list_algorithms } private: - BOOST_INTRUSIVE_FORCEINLINE static void swap_prev(const node_ptr &this_node, const node_ptr &other_node) + static void swap_prev(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { node_ptr temp(NodeTraits::get_previous(this_node)); NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node)); NodeTraits::set_previous(other_node, temp); } - BOOST_INTRUSIVE_FORCEINLINE static void swap_next(const node_ptr &this_node, const node_ptr &other_node) + static void swap_next(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { node_ptr temp(NodeTraits::get_next(this_node)); NodeTraits::set_next(this_node, NodeTraits::get_next(other_node)); diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/circular_slist_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/circular_slist_algorithms.hpp index da840ef0c1..5ce4e8cdba 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/circular_slist_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/circular_slist_algorithms.hpp @@ -18,6 +18,7 @@ #include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/detail/common_slist_algorithms.hpp> +#include <boost/intrusive/detail/uncast.hpp> #include <boost/intrusive/detail/algo_type.hpp> #if defined(BOOST_HAS_PRAGMA_ONCE) @@ -72,7 +73,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void init(node_ptr this_node); + static void init(node_ptr this_node) BOOST_NOEXCEPT; //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list. //! @@ -83,7 +84,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static bool unique(const_node_ptr this_node); + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT; //! <b>Effects</b>: Returns true is "this_node" has the same state as //! if it was inited using "init(node_ptr)" @@ -91,7 +92,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static bool inited(const_node_ptr this_node); + static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT; //! <b>Requires</b>: prev_node must be in a circular list or be an empty circular list. //! @@ -100,7 +101,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void unlink_after(node_ptr prev_node); + static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT; //! <b>Requires</b>: prev_node and last_node must be in a circular list //! or be an empty circular list. @@ -110,7 +111,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void unlink_after(node_ptr prev_node, node_ptr last_node); + static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT; //! <b>Requires</b>: prev_node must be a node of a circular list. //! @@ -119,7 +120,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void link_after(node_ptr prev_node, node_ptr this_node); + static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT; //! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range. //! and p must be a node of a different circular list. @@ -130,7 +131,11 @@ class circular_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void transfer_after(node_ptr p, node_ptr b, node_ptr e); + static void transfer_after(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT; + + #else + + using base_t::transfer_after; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -141,9 +146,44 @@ class circular_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void init_header(const node_ptr &this_node) + BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, this_node); } + //! <b>Requires</b>: 'p' is the first node of a list. + //! + //! <b>Effects</b>: Returns a pointer to a node that represents the "end" (one past end) node + //! + //! <b>Complexity</b>: Constant time. + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static node_ptr end_node(const_node_ptr p) BOOST_NOEXCEPT + { return detail::uncast(p); } + + //! <b>Effects</b>: Returns true if this_node_points to an empty list. + //! + //! <b>Complexity</b>: Constant + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_empty(const_node_ptr this_node) BOOST_NOEXCEPT + { return NodeTraits::get_next(this_node) == this_node; } + + //! <b>Effects</b>: Returns true if this_node points to a sentinel node. + //! + //! <b>Complexity</b>: Constant + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_sentinel(const_node_ptr this_node) BOOST_NOEXCEPT + { return NodeTraits::get_next(this_node) == node_ptr(); } + + //! <b>Effects</b>: Marks this node as a "sentinel" node, a special state that is different from "empty", + //! that can be used to mark a special state of the list + //! + //! <b>Complexity</b>: Constant + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void set_sentinel(node_ptr this_node) BOOST_NOEXCEPT + { NodeTraits::set_next(this_node, node_ptr()); } + //! <b>Requires</b>: this_node and prev_init_node must be in the same circular list. //! //! <b>Effects</b>: Returns the previous node of this_node in the circular list starting. @@ -153,7 +193,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Linear to the number of elements between prev_init_node and this_node. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr &prev_init_node, const node_ptr &this_node) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node) BOOST_NOEXCEPT { return base_t::get_previous_node(prev_init_node, this_node); } //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list. @@ -163,7 +203,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Linear to the number of elements in the circular list. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(node_ptr this_node) BOOST_NOEXCEPT { return base_t::get_previous_node(this_node, this_node); } //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list. @@ -173,7 +213,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Linear to the number of elements in the circular list. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_previous_node(const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_previous_node(node_ptr this_node) BOOST_NOEXCEPT { return get_previous_previous_node(this_node, this_node); } //! <b>Requires</b>: this_node and p must be in the same circular list. @@ -185,7 +225,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Linear to the number of elements in the circular list. //! //! <b>Throws</b>: Nothing. - static node_ptr get_previous_previous_node(node_ptr p, const node_ptr & this_node) + static node_ptr get_previous_previous_node(node_ptr p, node_ptr this_node) BOOST_NOEXCEPT { node_ptr p_next = NodeTraits::get_next(p); node_ptr p_next_next = NodeTraits::get_next(p_next); @@ -205,7 +245,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Linear //! //! <b>Throws</b>: Nothing. - static std::size_t count(const const_node_ptr & this_node) + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT { std::size_t result = 0; const_node_ptr p = this_node; @@ -223,7 +263,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Linear to the number of elements in the circular list //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void unlink(const node_ptr & this_node) + static void unlink(node_ptr this_node) BOOST_NOEXCEPT { if(NodeTraits::get_next(this_node)) base_t::unlink_after(get_previous_node(this_node)); @@ -236,7 +276,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Linear to the number of elements in the circular list. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void link_before (const node_ptr & nxt_node, const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static void link_before (node_ptr nxt_node, node_ptr this_node) BOOST_NOEXCEPT { base_t::link_after(get_previous_node(nxt_node), this_node); } //! <b>Requires</b>: this_node and other_node must be nodes inserted @@ -249,7 +289,7 @@ class circular_slist_algorithms //! <b>Complexity</b>: Linear to number of elements of both lists //! //! <b>Throws</b>: Nothing. - static void swap_nodes(const node_ptr & this_node, const node_ptr & other_node) + static void swap_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { if (other_node == this_node) return; @@ -275,7 +315,7 @@ class circular_slist_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: This function is linear to the contained elements. - static void reverse(const node_ptr & p) + static void reverse(node_ptr p) BOOST_NOEXCEPT { node_ptr i = NodeTraits::get_next(p), e(p); for (;;) { @@ -294,7 +334,7 @@ class circular_slist_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. - static node_ptr move_backwards(const node_ptr & p, std::size_t n) + static node_ptr move_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT { //Null shift, nothing to do if(!n) return node_ptr(); @@ -346,7 +386,7 @@ class circular_slist_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. - static node_ptr move_forward(const node_ptr & p, std::size_t n) + static node_ptr move_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT { //Null shift, nothing to do if(!n) return node_ptr(); @@ -386,6 +426,35 @@ class circular_slist_algorithms base_t::link_after(new_last, p); return new_last; } + + //! <b>Requires</b>: other must be a list and p must be a node of a different list. + //! + //! <b>Effects</b>: Transfers all nodes from other after p in p's list. + //! + //! <b>Complexity</b>: Linear + //! + //! <b>Throws</b>: Nothing. + static void transfer_after(node_ptr p, node_ptr other) BOOST_NOEXCEPT + { + node_ptr other_last((get_previous_node)(other)); + base_t::transfer_after(p, other, other_last); + } + + //! <b>Requires</b>: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! <b>Effects</b>: Unlinks all nodes reachable from p (but not p) and calls + //! <tt>void disposer::operator()(node_ptr)</tt> for every node of the list + //! where p is linked. + //! + //! <b>Returns</b>: The number of disposed nodes + //! + //! <b>Complexity</b>: Linear to the number of element of the list. + //! + //! <b>Throws</b>: Nothing. + template<class Disposer> + BOOST_INTRUSIVE_FORCEINLINE static std::size_t detach_and_dispose(node_ptr p, Disposer disposer) BOOST_NOEXCEPT + { return base_t::unlink_after_and_dispose(p, p, disposer); } }; /// @cond diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/derivation_value_traits.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/derivation_value_traits.hpp index 06991983f3..626031257c 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/derivation_value_traits.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/derivation_value_traits.hpp @@ -52,20 +52,20 @@ struct derivation_value_traits pointer_traits<const_pointer>::reference const_reference; static const link_mode_type link_mode = LinkMode; - static node_ptr to_node_ptr(reference value) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) BOOST_NOEXCEPT { return node_ptr(&value); } - static const_node_ptr to_node_ptr(const_reference value) + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) BOOST_NOEXCEPT { return node_ptr(&value); } - static pointer to_value_ptr(const node_ptr &n) + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) BOOST_NOEXCEPT { return pointer_traits<pointer>::pointer_to(static_cast<reference>(*n)); } - static const_pointer to_value_ptr(const const_node_ptr &n) + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) BOOST_NOEXCEPT { - return pointer_traits<pointer>::pointer_to(static_cast<const_reference>(*n)); + return pointer_traits<const_pointer>::pointer_to(static_cast<const_reference>(*n)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/array_initializer.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/array_initializer.hpp index 126a253afb..1b6a933294 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/array_initializer.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/array_initializer.hpp @@ -23,6 +23,8 @@ #include <boost/config.hpp> #include <boost/core/no_exceptions_support.hpp> +#include <boost/move/detail/placement_new.hpp> +#include <boost/move/detail/force_ptr.hpp> namespace boost { namespace intrusive { @@ -55,14 +57,14 @@ class array_initializer std::size_t i = 0; BOOST_TRY{ for(; i != N; ++i){ - new(init_buf)T(init); + ::new(init_buf, boost_move_new_t()) T(init); init_buf += sizeof(T); } } BOOST_CATCH(...){ while(i--){ init_buf -= sizeof(T); - ((T*)init_buf)->~T(); + move_detail::force_ptr<T*>(init_buf)->~T(); } BOOST_RETHROW; } @@ -80,7 +82,7 @@ class array_initializer char *init_buf = (char*)rawbuf + N*sizeof(T); for(std::size_t i = 0; i != N; ++i){ init_buf -= sizeof(T); - ((T*)init_buf)->~T(); + move_detail::force_ptr<T*>(init_buf)->~T(); } } diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/avltree_node.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/avltree_node.hpp index 16d1c1d291..b9c52dcaab 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/avltree_node.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/avltree_node.hpp @@ -63,46 +63,46 @@ struct avltree_node template<class VoidPointer> struct default_avltree_node_traits_impl { - typedef avltree_node<VoidPointer> node; + typedef avltree_node<VoidPointer> node; typedef typename node::node_ptr node_ptr; typedef typename node::const_node_ptr const_node_ptr; typedef typename node::balance balance; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_parent(const node_ptr & n, const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->parent_ = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_left(const node_ptr & n, const node_ptr & l) + BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_right(const node_ptr & n, const node_ptr & r) + BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } - BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const_node_ptr n) { return n->balance_; } - BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(node_ptr n) { return n->balance_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_balance(const node_ptr & n, balance b) + BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b) { n->balance_ = b; } BOOST_INTRUSIVE_FORCEINLINE static balance negative() @@ -121,34 +121,34 @@ template<class VoidPointer> struct compact_avltree_node_traits_impl { typedef compact_avltree_node<VoidPointer> node; - typedef typename node::node_ptr node_ptr; - typedef typename node::const_node_ptr const_node_ptr; + typedef typename node::node_ptr node_ptr; + typedef typename node::const_node_ptr const_node_ptr; typedef typename node::balance balance; typedef pointer_plus_bits<node_ptr, 2> ptr_bit; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return ptr_bit::get_pointer(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static void set_parent(const node_ptr & n, const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { ptr_bit::set_pointer(n->parent_, p); } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_left(const node_ptr & n, const node_ptr & l) + BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_right(const node_ptr & n, const node_ptr & r) + BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } - BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static balance get_balance(const_node_ptr n) { return (balance)ptr_bit::get_bits(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static void set_balance(const node_ptr & n, balance b) + BOOST_INTRUSIVE_FORCEINLINE static void set_balance(node_ptr n, balance b) { ptr_bit::set_bits(n->parent_, (std::size_t)b); } BOOST_INTRUSIVE_FORCEINLINE static balance negative() diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/bstree_algorithms_base.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/bstree_algorithms_base.hpp index 8404010565..023d870794 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/bstree_algorithms_base.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/bstree_algorithms_base.hpp @@ -42,7 +42,7 @@ class bstree_algorithms_base //! <b>Complexity</b>: Average constant time. //! //! <b>Throws</b>: Nothing. - static node_ptr next_node(const node_ptr & node) + static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT { node_ptr const n_right(NodeTraits::get_right(node)); if(n_right){ @@ -66,11 +66,10 @@ class bstree_algorithms_base //! <b>Complexity</b>: Average constant time. //! //! <b>Throws</b>: Nothing. - static node_ptr prev_node(const node_ptr & node) + static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT { if(is_header(node)){ - //return NodeTraits::get_right(node); - return maximum(NodeTraits::get_parent(node)); + return NodeTraits::get_right(node); } else if(NodeTraits::get_left(node)){ return maximum(NodeTraits::get_left(node)); @@ -127,7 +126,7 @@ class bstree_algorithms_base //! <b>Complexity</b>: Constant. //! //! <b>Throws</b>: Nothing. - static bool is_header(const const_node_ptr & p) + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT { node_ptr p_left (NodeTraits::get_left(p)); node_ptr p_right(NodeTraits::get_right(p)); @@ -151,7 +150,7 @@ class bstree_algorithms_base //! <b>Complexity</b>: Logarithmic. //! //! <b>Throws</b>: Nothing. - static node_ptr get_header(const const_node_ptr & node) + static node_ptr get_header(const_node_ptr node) { node_ptr n(detail::uncast(node)); node_ptr p(NodeTraits::get_parent(node)); diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/common_slist_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/common_slist_algorithms.hpp index 5e6ff4d1aa..e7aba10dca 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/common_slist_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/common_slist_algorithms.hpp @@ -40,7 +40,7 @@ class common_slist_algorithms typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef NodeTraits node_traits; - static node_ptr get_previous_node(node_ptr p, const node_ptr & this_node) + static node_ptr get_previous_node(node_ptr p, node_ptr this_node) { for( node_ptr p_next ; this_node != (p_next = NodeTraits::get_next(p)) @@ -52,41 +52,41 @@ class common_slist_algorithms return p; } - BOOST_INTRUSIVE_FORCEINLINE static void init(const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, node_ptr()); } - BOOST_INTRUSIVE_FORCEINLINE static bool unique(const const_node_ptr & this_node) + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT { node_ptr next = NodeTraits::get_next(this_node); return !next || next == this_node; } - BOOST_INTRUSIVE_FORCEINLINE static bool inited(const const_node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT { return !NodeTraits::get_next(this_node); } - BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(const node_ptr & prev_node) + BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT { const_node_ptr this_node(NodeTraits::get_next(prev_node)); NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node)); } - BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node) + BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT { NodeTraits::set_next(prev_node, last_node); } - BOOST_INTRUSIVE_FORCEINLINE static void link_after(const node_ptr & prev_node, const node_ptr & this_node) + static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node)); NodeTraits::set_next(prev_node, this_node); } - BOOST_INTRUSIVE_FORCEINLINE static void incorporate_after(const node_ptr & bp, const node_ptr & b, const node_ptr & be) + static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be) BOOST_NOEXCEPT { node_ptr p(NodeTraits::get_next(bp)); NodeTraits::set_next(bp, b); NodeTraits::set_next(be, p); } - static void transfer_after(const node_ptr & bp, const node_ptr & bb, const node_ptr & be) + static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be) BOOST_NOEXCEPT { if (bp != bb && bp != be && bb != be) { node_ptr next_b = NodeTraits::get_next(bb); @@ -107,7 +107,7 @@ class common_slist_algorithms }; template<class Pred> - static void stable_partition(node_ptr before_beg, const node_ptr &end, Pred pred, stable_partition_info &info) + static void stable_partition(node_ptr before_beg, node_ptr end, Pred pred, stable_partition_info &info) { node_ptr bcur = before_beg; node_ptr cur = node_traits::get_next(bcur); @@ -167,7 +167,7 @@ class common_slist_algorithms //! <b>Complexity</b>: Linear //! //! <b>Throws</b>: Nothing. - static std::size_t distance(const const_node_ptr &f, const const_node_ptr &l) + static std::size_t distance(const_node_ptr f, const_node_ptr l) BOOST_NOEXCEPT { const_node_ptr i(f); std::size_t result = 0; @@ -177,6 +177,75 @@ class common_slist_algorithms } return result; } + + //! <b>Requires</b>: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! <b>Effects</b>: Calls + //! <tt>void disposer::operator()(node_ptr)</tt> for every node of the list + //! [p, e). + //! + //! <b>Returns</b>: The number of unlinked/disposed nodes + //! + //! <b>Complexity</b>: Linear to the number of element of the list. + //! + //! <b>Throws</b>: Nothing. + template<class Disposer> + static std::size_t unlink_after_and_dispose(node_ptr bb, node_ptr e, Disposer disposer) BOOST_NOEXCEPT + { + std::size_t n = 0u; + node_ptr i = node_traits::get_next(bb); + while (i != e) { + node_ptr to_erase(i); + i = node_traits::get_next(i); + disposer(to_erase); + ++n; + } + node_traits::set_next(bb, e); + return n; + } + + //! <b>Requires</b>: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! <b>Effects</b>: Calls + //! <tt>void disposer::operator()(node_ptr)</tt> for every node of the list + //! after p (but not for p). Works for circular or linear lists + //! + //! <b>Complexity</b>: Linear to the number of element of the list. + //! + //! <b>Throws</b>: Nothing. + template<class Disposer> + BOOST_INTRUSIVE_FORCEINLINE static void unlink_after_and_dispose(node_ptr bb, Disposer disposer) BOOST_NOEXCEPT + { + node_ptr i = node_traits::get_next(bb); + node_traits::set_next(bb, node_traits::get_next(i)); + disposer(i); + } + + //! <b>Requires</b>: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! <b>Effects</b>: Unlinks all nodes reachable from p (but not p) and calls + //! <tt>void disposer::operator()(node_ptr)</tt> for every node of the list + //! where p is linked. + //! + //! <b>Complexity</b>: Linear to the number of element of the list. + //! + //! <b>Throws</b>: Nothing. + template<class Disposer> + static std::size_t detach_and_dispose(node_ptr p, Disposer disposer) BOOST_NOEXCEPT + { + std::size_t n = 0; + node_ptr i = node_traits::get_next(p); + while ( i != p || i != node_ptr() ) { + node_ptr to_erase(i); + i = node_traits::get_next(i); + disposer(to_erase); + } + node_traits::set_next(p, i); + return n; + } }; /// @endcond diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/config_begin.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/config_begin.hpp index 8bd57a3b51..b261ca91d3 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/config_begin.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/config_begin.hpp @@ -17,6 +17,7 @@ #ifdef BOOST_MSVC #pragma warning (push) + #pragma warning (disable : 4619) // there is no warning number 'XXXX' #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier" #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2" #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/default_header_holder.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/default_header_holder.hpp index ba561b5f5b..42f35d2be7 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/default_header_holder.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/default_header_holder.hpp @@ -47,7 +47,7 @@ struct default_header_holder : public NodeTraits::node { return pointer_traits< node_ptr >::pointer_to(*static_cast< node* >(this)); } // (unsafe) downcast used to implement container-from-iterator - BOOST_INTRUSIVE_FORCEINLINE static default_header_holder* get_holder(const node_ptr &p) + BOOST_INTRUSIVE_FORCEINLINE static default_header_holder* get_holder(node_ptr p) { return static_cast< default_header_holder* >(boost::movelib::to_raw_pointer(p)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/ebo_functor_holder.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/ebo_functor_holder.hpp index 27415c1170..8883166783 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/ebo_functor_holder.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/ebo_functor_holder.hpp @@ -158,7 +158,7 @@ template<typename T> struct is_unary_or_binary_function : is_unary_or_binary_function_impl<T> {}; -template<typename T, bool = is_unary_or_binary_function<T>::value> +template<typename T, typename Tag = void, bool = is_unary_or_binary_function<T>::value> class ebo_functor_holder { BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder) @@ -222,8 +222,8 @@ class ebo_functor_holder T t_; }; -template<typename T> -class ebo_functor_holder<T, false> +template<typename T, typename Tag> +class ebo_functor_holder<T, Tag, false> : public T { BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder) diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/empty_node_checker.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/empty_node_checker.hpp index 16aa5600e7..fbff4b6736 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/empty_node_checker.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/empty_node_checker.hpp @@ -34,7 +34,7 @@ struct empty_node_checker struct return_type {}; - void operator () (const const_node_ptr&, const return_type&, const return_type&, return_type&) {} + void operator () (const_node_ptr, const return_type&, const return_type&, return_type&) {} }; } //namespace detail{ diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/exception_disposer.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/exception_disposer.hpp index 91c5bf3b67..0e21faebaa 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/exception_disposer.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/exception_disposer.hpp @@ -52,37 +52,6 @@ class exception_disposer } }; -template<class Container, class Disposer, class SizeType> -class exception_array_disposer -{ - Container *cont_; - Disposer &disp_; - SizeType &constructed_; - - exception_array_disposer(const exception_array_disposer&); - exception_array_disposer &operator=(const exception_array_disposer&); - - public: - - exception_array_disposer - (Container &cont, Disposer &disp, SizeType &constructed) - : cont_(&cont), disp_(disp), constructed_(constructed) - {} - - BOOST_INTRUSIVE_FORCEINLINE void release() - { cont_ = 0; } - - ~exception_array_disposer() - { - SizeType n = constructed_; - if(cont_){ - while(n--){ - cont_[n].clear_and_dispose(disp_); - } - } - } -}; - } //namespace detail{ } //namespace intrusive{ } //namespace boost{ diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/generic_hook.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/generic_hook.hpp index 13421b8805..6e43f90d9c 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/generic_hook.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/generic_hook.hpp @@ -41,7 +41,7 @@ struct link_dispatch {}; template<class Hook> -void destructor_impl(Hook &hook, detail::link_dispatch<safe_link>) +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch<safe_link>) { //If this assertion raises, you might have destroyed an object //while it was still inserted in a container that is alive. //If so, remove the object from the container before destroying it. @@ -49,11 +49,11 @@ void destructor_impl(Hook &hook, detail::link_dispatch<safe_link>) } template<class Hook> -void destructor_impl(Hook &hook, detail::link_dispatch<auto_unlink>) +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch<auto_unlink>) { hook.unlink(); } template<class Hook> -void destructor_impl(Hook &, detail::link_dispatch<normal_link>) +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &, detail::link_dispatch<normal_link>) {} } //namespace detail { @@ -161,52 +161,52 @@ class generic_hook < NodeTraits , Tag, LinkMode, BaseHookType> hooktags; - node_ptr this_ptr() + BOOST_INTRUSIVE_FORCEINLINE node_ptr this_ptr() BOOST_NOEXCEPT { return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*this)); } - const_node_ptr this_ptr() const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr this_ptr() const BOOST_NOEXCEPT { return pointer_traits<const_node_ptr>::pointer_to(static_cast<const node&>(*this)); } public: /// @endcond - generic_hook() + BOOST_INTRUSIVE_FORCEINLINE generic_hook() BOOST_NOEXCEPT { if(hooktags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } - generic_hook(const generic_hook& ) + BOOST_INTRUSIVE_FORCEINLINE generic_hook(const generic_hook& ) BOOST_NOEXCEPT { if(hooktags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } - generic_hook& operator=(const generic_hook& ) + BOOST_INTRUSIVE_FORCEINLINE generic_hook& operator=(const generic_hook& ) BOOST_NOEXCEPT { return *this; } - ~generic_hook() + BOOST_INTRUSIVE_FORCEINLINE ~generic_hook() { destructor_impl (*this, detail::link_dispatch<hooktags::link_mode>()); } - void swap_nodes(generic_hook &other) + BOOST_INTRUSIVE_FORCEINLINE void swap_nodes(generic_hook &other) BOOST_NOEXCEPT { node_algorithms::swap_nodes (this->this_ptr(), other.this_ptr()); } - bool is_linked() const + BOOST_INTRUSIVE_FORCEINLINE bool is_linked() const BOOST_NOEXCEPT { //is_linked() can be only used in safe-mode or auto-unlink BOOST_STATIC_ASSERT(( hooktags::safemode_or_autounlink )); return !node_algorithms::unique(this->this_ptr()); } - void unlink() + BOOST_INTRUSIVE_FORCEINLINE void unlink() BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink )); node_ptr n(this->this_ptr()); diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/hash_combine.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/hash_combine.hpp new file mode 100644 index 0000000000..f089fb0cc0 --- /dev/null +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/hash_combine.hpp @@ -0,0 +1,92 @@ +// Copyright 2005-2014 Daniel James. +// 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) +// +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. +// +// This also contains public domain code from MurmurHash. From the +// MurmurHash header: +// +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. +// +// Copyright 2021 Ion Gaztanaga +// Refactored the original boost/container_hash/hash.hpp to avoid +// any heavy std header dependencies to just combine two hash +// values represented in a std::size_t type. + +#ifndef BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP +#define BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include <boost/cstdint.hpp> + +#if defined(_MSC_VER) +# include <stdlib.h> +# define BOOST_INTRUSIVE_HASH_ROTL32(x, r) _rotl(x,r) +#else +# define BOOST_INTRUSIVE_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r)) +#endif + +namespace boost { +namespace intrusive { +namespace detail { + +template <typename SizeT> +inline void hash_combine_size_t(SizeT& seed, SizeT value) +{ + seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); +} + +inline void hash_combine_size_t(boost::uint32_t& h1, boost::uint32_t k1) +{ + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + k1 *= c1; + k1 = BOOST_INTRUSIVE_HASH_ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = BOOST_INTRUSIVE_HASH_ROTL32(h1,13); + h1 = h1*5+0xe6546b64; +} + + + // Don't define 64-bit hash combine on platforms without 64 bit integers, + // and also not for 32-bit gcc as it warns about the 64-bit constant. + #if !defined(BOOST_NO_INT64_T) && \ + !(defined(__GNUC__) && ULONG_MAX == 0xffffffff) + inline void hash_combine_size_t(boost::uint64_t& h, boost::uint64_t k) + { + const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995); + const int r = 47; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + + // Completely arbitrary number, to prevent 0's + // from hashing to 0. + h += 0xe6546b64; + } + + #endif // BOOST_NO_INT64_T + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#endif //BOOST_INTRUSIVE_DETAIL_HASH_COMBINE_HPP diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/hook_traits.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/hook_traits.hpp index 7a6f206ca2..b7164365d6 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/hook_traits.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/hook_traits.hpp @@ -55,28 +55,36 @@ struct bhtraits_base typedef node& node_reference; typedef const node & const_node_reference; - BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) { - return pointer_traits<pointer>::pointer_to + pointer p = pointer_traits<pointer>::pointer_to (static_cast<reference>(static_cast<node_holder_reference>(*n))); + BOOST_ASSERT(!!p); + return p; } - BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) { - return pointer_traits<const_pointer>::pointer_to + const_pointer p = pointer_traits<const_pointer>::pointer_to (static_cast<const_reference>(static_cast<const_node_holder_reference>(*n))); + BOOST_ASSERT(!!p); + return p; } BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) { - return pointer_traits<node_ptr>::pointer_to + node_ptr p = pointer_traits<node_ptr>::pointer_to (static_cast<node_reference>(static_cast<node_holder_reference>(value))); + BOOST_ASSERT(!!p); + return p; } BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) { - return pointer_traits<const_node_ptr>::pointer_to + const_node_ptr p = pointer_traits<const_node_ptr>::pointer_to (static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value))); + BOOST_ASSERT(!!p); + return p; } }; @@ -124,14 +132,14 @@ struct mhtraits (static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P))); } - BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(node_ptr n) { return pointer_traits<pointer>::pointer_to (*detail::parent_from_member<T, Hook> (static_cast<Hook*>(boost::movelib::to_raw_pointer(n)), P)); } - BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const_node_ptr n) { return pointer_traits<const_pointer>::pointer_to (*detail::parent_from_member<T, Hook> @@ -166,17 +174,17 @@ struct fhtraits static const_node_ptr to_node_ptr(const_reference value) { return static_cast<const node*>(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); } - static pointer to_value_ptr(const node_ptr & n) + static pointer to_value_ptr(node_ptr n) { return Functor::to_value_ptr(to_hook_ptr(n)); } - static const_pointer to_value_ptr(const const_node_ptr & n) + static const_pointer to_value_ptr(const_node_ptr n) { return Functor::to_value_ptr(to_hook_ptr(n)); } private: - static hook_ptr to_hook_ptr(const node_ptr & n) + static hook_ptr to_hook_ptr(node_ptr n) { return hook_ptr(&*static_cast<hook_type*>(&*n)); } - static const_hook_ptr to_hook_ptr(const const_node_ptr & n) + static const_hook_ptr to_hook_ptr(const_node_ptr n) { return const_hook_ptr(&*static_cast<const hook_type*>(&*n)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/iterator.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/iterator.hpp index c25be430a2..9421cc4d59 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/iterator.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/iterator.hpp @@ -49,6 +49,11 @@ namespace boost { namespace intrusive { using boost::movelib::iterator_traits; +using boost::movelib::iter_difference; +using boost::movelib::iter_value; +using boost::movelib::iter_category; +using boost::movelib::iter_size; + //////////////////// // iterator @@ -63,26 +68,59 @@ struct iterator typedef Reference reference; }; -//////////////////////////////////////// -// iterator_[dis|en]able_if_boost_iterator -//////////////////////////////////////// -template<class I> -struct is_boost_iterator +//////////////////////////////////////////////////////////////////////////////// +// Conversion from boost::iterator traversals to std tags +//////////////////////////////////////////////////////////////////////////////// + +template<class Tag> +struct get_std_category_from_tag { - static const bool value = false; + typedef Tag type; }; -template<class Category, class Traversal> -struct is_boost_iterator< boost::iterators::detail::iterator_category_with_traversal<Category, Traversal> > +template <class Category> +struct get_std_category_from_tag + <boost::iterators::detail::iterator_category_with_traversal + <Category, boost::iterators::incrementable_traversal_tag> > { - static const bool value = true; + typedef std::input_iterator_tag type; }; -template<class I, class R = void> -struct iterator_enable_if_boost_iterator - : ::boost::move_detail::enable_if_c - < is_boost_iterator<typename boost::intrusive::iterator_traits<I>::iterator_category >::value - , R> +template <class Category> +struct get_std_category_from_tag + <boost::iterators::detail::iterator_category_with_traversal + <Category, boost::iterators::single_pass_traversal_tag> > +{ + typedef std::input_iterator_tag type; +}; + +template <class Category> +struct get_std_category_from_tag + <boost::iterators::detail::iterator_category_with_traversal + <Category, boost::iterators::forward_traversal_tag> > +{ + typedef std::input_iterator_tag type; +}; + +template <class Category> +struct get_std_category_from_tag + <boost::iterators::detail::iterator_category_with_traversal + <Category, boost::iterators::bidirectional_traversal_tag> > +{ + typedef std::bidirectional_iterator_tag type; +}; + +template <class Category> +struct get_std_category_from_tag + <boost::iterators::detail::iterator_category_with_traversal + <Category, boost::iterators::random_access_traversal_tag> > +{ + typedef std::random_access_iterator_tag type; +}; + +template<class It> +struct get_std_category_from_it + : get_std_category_from_tag< typename boost::intrusive::iter_category<It>::type > {}; //////////////////////////////////////// @@ -92,7 +130,7 @@ template<class I, class Tag, class R = void> struct iterator_enable_if_tag : ::boost::move_detail::enable_if_c < ::boost::move_detail::is_same - < typename boost::intrusive::iterator_traits<I>::iterator_category + < typename get_std_category_from_it<I>::type , Tag >::value , R> @@ -102,7 +140,7 @@ template<class I, class Tag, class R = void> struct iterator_disable_if_tag : ::boost::move_detail::enable_if_c < !::boost::move_detail::is_same - < typename boost::intrusive::iterator_traits<I>::iterator_category + < typename get_std_category_from_it<I>::type , Tag >::value , R> @@ -115,11 +153,11 @@ template<class I, class Tag, class Tag2, class R = void> struct iterator_enable_if_convertible_tag : ::boost::move_detail::enable_if_c < ::boost::move_detail::is_same_or_convertible - < typename boost::intrusive::iterator_traits<I>::iterator_category + < typename get_std_category_from_it<I>::type , Tag >::value && !::boost::move_detail::is_same_or_convertible - < typename boost::intrusive::iterator_traits<I>::iterator_category + < typename get_std_category_from_it<I>::type , Tag2 >::value , R> @@ -130,42 +168,42 @@ struct iterator_enable_if_convertible_tag //////////////////////////////////////// template<class I, class Tag> struct iterator_enable_if_tag_difference_type - : iterator_enable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type> + : iterator_enable_if_tag<I, Tag, typename boost::intrusive::iter_difference<I>::type> {}; template<class I, class Tag> struct iterator_disable_if_tag_difference_type - : iterator_disable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type> + : iterator_disable_if_tag<I, Tag, typename boost::intrusive::iter_difference<I>::type> {}; //////////////////// // advance //////////////////// -template<class InputIt, class Distance> +template<class InputIt> BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type - iterator_advance(InputIt& it, Distance n) + iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n) { while(n--) - ++it; + ++it; } -template<class InputIt, class Distance> +template<class InputIt> typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type - iterator_advance(InputIt& it, Distance n) + iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n) { while(n--) - ++it; + ++it; } -template<class InputIt, class Distance> +template<class InputIt> BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type - iterator_advance(InputIt& it, Distance n) + iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n) { for (; 0 < n; --n) - ++it; + ++it; for (; n < 0; ++n) - --it; + --it; } template<class InputIt, class Distance> @@ -175,65 +213,24 @@ BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::random it += n; } -template<class InputIt, class Distance> -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - <InputIt, const boost::iterators::incrementable_traversal_tag&, const boost::iterators::single_pass_traversal_tag&>::type - iterator_advance(InputIt& it, Distance n) -{ - while(n--) - ++it; -} - -template<class InputIt, class Distance> -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - <InputIt, const boost::iterators::single_pass_traversal_tag &, const boost::iterators::forward_traversal_tag&>::type - iterator_advance(InputIt& it, Distance n) -{ - while(n--) - ++it; -} - -template<class InputIt, class Distance> -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - <InputIt, const boost::iterators::forward_traversal_tag&, const boost::iterators::bidirectional_traversal_tag&>::type - iterator_advance(InputIt& it, Distance n) -{ - while(n--) - ++it; -} - -template<class InputIt, class Distance> -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - <InputIt, const boost::iterators::bidirectional_traversal_tag&, const boost::iterators::random_access_traversal_tag&>::type - iterator_advance(InputIt& it, Distance n) -{ - for (; 0 < n; --n) - ++it; - for (; n < 0; ++n) - --it; -} - -class fake{}; - -template<class InputIt, class Distance> -BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag - <InputIt, const boost::iterators::random_access_traversal_tag&, const fake&>::type - iterator_advance(InputIt& it, Distance n) +template<class It> +BOOST_INTRUSIVE_FORCEINLINE + void iterator_uadvance(It& it, typename iter_size<It>::type n) { - it += n; + (iterator_advance)(it, (typename iterator_traits<It>::difference_type)n); } -//////////////////// -// distance -//////////////////// +//////////////////////////////////////// +// iterator_distance +//////////////////////////////////////// template<class InputIt> inline typename iterator_disable_if_tag_difference_type <InputIt, std::random_access_iterator_tag>::type iterator_distance(InputIt first, InputIt last) { - typename iterator_traits<InputIt>::difference_type off = 0; + typename iter_difference<InputIt>::type off = 0; while(first != last){ - ++off; + ++off; ++first; } return off; @@ -244,10 +241,43 @@ BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag_difference_type <InputIt, std::random_access_iterator_tag>::type iterator_distance(InputIt first, InputIt last) { - typename iterator_traits<InputIt>::difference_type off = last - first; + typename iter_difference<InputIt>::type off = last - first; return off; } +//////////////////////////////////////// +// iterator_udistance +//////////////////////////////////////// + +template<class It> +BOOST_INTRUSIVE_FORCEINLINE typename iter_size<It>::type + iterator_udistance(It first, It last) +{ + return (typename iter_size<It>::type)(iterator_distance)(first, last); +} + +//////////////////////////////////////// +// iterator_next +//////////////////////////////////////// + +template<class InputIt> +BOOST_INTRUSIVE_FORCEINLINE InputIt iterator_next(InputIt it, typename iter_difference<InputIt>::type n) +{ + (iterator_advance)(it, n); + return it; +} + +template<class InputIt> +BOOST_INTRUSIVE_FORCEINLINE InputIt iterator_unext(InputIt it, typename iterator_traits<InputIt>::size_type n) +{ + (iterator_uadvance)(it, n); + return it; +} + +//////////////////////////////////////// +// iterator_arrow_result +//////////////////////////////////////// + template<class I> BOOST_INTRUSIVE_FORCEINLINE typename iterator_traits<I>::pointer iterator_arrow_result(const I &i) { return i.operator->(); } diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/key_nodeptr_comp.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/key_nodeptr_comp.hpp index bdc025e5ab..1029a3404a 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/key_nodeptr_comp.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/key_nodeptr_comp.hpp @@ -78,7 +78,7 @@ public: static const bool value = same_type || is_convertible<P1, const_node_ptr>::value; }; - base_t base() const + BOOST_INTRUSIVE_FORCEINLINE base_t base() const { return static_cast<const base_t&>(*this); } BOOST_INTRUSIVE_FORCEINLINE key_nodeptr_comp(KeyTypeKeyCompare kcomp, const ValueTraits *traits) diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/list_iterator.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/list_iterator.hpp index 08ba8a3775..f301a4b8e7 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/list_iterator.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/list_iterator.hpp @@ -63,7 +63,7 @@ class list_iterator BOOST_INTRUSIVE_FORCEINLINE list_iterator() {} - BOOST_INTRUSIVE_FORCEINLINE explicit list_iterator(const node_ptr & nodeptr, const const_value_traits_ptr &traits_ptr) + BOOST_INTRUSIVE_FORCEINLINE explicit list_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr) : members_(nodeptr, traits_ptr) {} @@ -78,11 +78,11 @@ class list_iterator BOOST_INTRUSIVE_FORCEINLINE list_iterator &operator=(const list_iterator &other) { members_.nodeptr_ = other.members_.nodeptr_; return *this; } - BOOST_INTRUSIVE_FORCEINLINE const node_ptr &pointed_node() const + BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const { return members_.nodeptr_; } - BOOST_INTRUSIVE_FORCEINLINE list_iterator &operator=(const node_ptr &node) - { members_.nodeptr_ = node; return *this; } + BOOST_INTRUSIVE_FORCEINLINE list_iterator &operator=(node_ptr nodeptr) + { members_.nodeptr_ = nodeptr; return *this; } BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const { return members_.get_ptr(); } diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/list_node.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/list_node.hpp index c3b4847011..eac56f6d4a 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/list_node.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/list_node.hpp @@ -47,22 +47,22 @@ struct list_node_traits typedef typename node::node_ptr node_ptr; typedef typename pointer_rebind<VoidPointer, const node>::type const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const_node_ptr n) { return n->prev_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous(node_ptr n) { return n->prev_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_previous(const node_ptr & n, const node_ptr & prev) + BOOST_INTRUSIVE_FORCEINLINE static void set_previous(node_ptr n, node_ptr prev) { n->prev_ = prev; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) { return n->next_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(node_ptr n) { return n->next_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_next(const node_ptr & n, const node_ptr & next) + BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) { n->next_ = next; } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/math.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/math.hpp index 4901053cb3..ff379f6589 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/math.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/math.hpp @@ -24,6 +24,7 @@ #include <cstddef> #include <climits> #include <boost/intrusive/detail/mpl.hpp> +#include <cstring> namespace boost { namespace intrusive { @@ -75,8 +76,8 @@ namespace detail { inline std::size_t floor_log2 (std::size_t x) { unsigned long log2; - BOOST_INTRUSIVE_BSR_INTRINSIC( &log2, (unsigned long)x ); - return log2; + BOOST_INTRUSIVE_BSR_INTRINSIC( &log2, x ); + return static_cast<std::size_t>(log2); } #undef BOOST_INTRUSIVE_BSR_INTRINSIC @@ -92,7 +93,7 @@ namespace detail { struct builtin_clz_dispatch< ::boost::ulong_long_type > { static ::boost::ulong_long_type call(::boost::ulong_long_type n) - { return __builtin_clzll(n); } + { return (::boost::ulong_long_type)__builtin_clzll(n); } }; #endif @@ -100,14 +101,14 @@ namespace detail { struct builtin_clz_dispatch<unsigned long> { static unsigned long call(unsigned long n) - { return __builtin_clzl(n); } + { return (unsigned long)__builtin_clzl(n); } }; template<> struct builtin_clz_dispatch<unsigned int> { static unsigned int call(unsigned int n) - { return __builtin_clz(n); } + { return (unsigned int)__builtin_clz(n); } }; inline std::size_t floor_log2(std::size_t n) @@ -149,53 +150,6 @@ namespace detail { return log2; } - //////////////////////////// - // DeBruijn method - //////////////////////////// - - //Taken from: - //http://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers - //Thanks to Desmond Hume - - inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 32>) - { - static const int MultiplyDeBruijnBitPosition[32] = - { - 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, - 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 - }; - - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - - return MultiplyDeBruijnBitPosition[(std::size_t)(v * 0x07C4ACDDU) >> 27]; - } - - inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 64>) - { - static const std::size_t MultiplyDeBruijnBitPosition[64] = { - 63, 0, 58, 1, 59, 47, 53, 2, - 60, 39, 48, 27, 54, 33, 42, 3, - 61, 51, 37, 40, 49, 18, 28, 20, - 55, 30, 34, 11, 43, 14, 22, 4, - 62, 57, 46, 52, 38, 26, 32, 41, - 50, 36, 17, 19, 29, 10, 13, 21, - 56, 45, 25, 31, 35, 16, 9, 12, - 44, 24, 15, 8, 23, 7, 6, 5}; - - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - return MultiplyDeBruijnBitPosition[((std::size_t)((v - (v >> 1))*0x07EDD5E59A4E28C2ULL)) >> 58]; - } - - inline std::size_t floor_log2 (std::size_t x) { const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT; @@ -208,19 +162,12 @@ namespace detail { //http://www.flipcode.com/archives/Fast_log_Function.shtml inline float fast_log2 (float val) { - union caster_t - { - unsigned x; - float val; - } caster; - - caster.val = val; - unsigned x = caster.x; + unsigned x; + std::memcpy(&x, &val, sizeof(float)); const int log_2 = int((x >> 23) & 255) - 128; x &= ~(unsigned(255u) << 23u); x += unsigned(127) << 23u; - caster.x = x; - val = caster.val; + std::memcpy(&val, &x, sizeof(float)); //1+log2(m), m ranging from 1 to 2 //3rd degree polynomial keeping first derivate continuity. //For less precision the line can be commented out @@ -262,7 +209,7 @@ template<class SizeType, class Enabler = void > struct sqrt2_pow_max; template <class SizeType> -struct sqrt2_pow_max<SizeType, typename enable_if< numbits_eq<SizeType, 32> >::type> +struct sqrt2_pow_max<SizeType, typename voider<typename enable_if< numbits_eq<SizeType, 32> >::type>::type> { static const SizeType value = 0xb504f334; static const std::size_t pow = 31; @@ -271,7 +218,7 @@ struct sqrt2_pow_max<SizeType, typename enable_if< numbits_eq<SizeType, 32> >::t #ifndef BOOST_NO_INT64_T template <class SizeType> -struct sqrt2_pow_max<SizeType, typename enable_if< numbits_eq<SizeType, 64> >::type> +struct sqrt2_pow_max<SizeType, typename voider<typename enable_if< numbits_eq<SizeType, 64> >::type>::type> { static const SizeType value = 0xb504f333f9de6484ull; static const std::size_t pow = 63; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/mpl.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/mpl.hpp index 1523088161..d86fa4f3c9 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/mpl.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/mpl.hpp @@ -40,6 +40,7 @@ using boost::move_detail::remove_pointer; using boost::move_detail::add_pointer; using boost::move_detail::true_type; using boost::move_detail::false_type; +using boost::move_detail::voider; using boost::move_detail::enable_if_c; using boost::move_detail::enable_if; using boost::move_detail::disable_if_c; @@ -154,7 +155,7 @@ template <class T>\ struct TRAITS_PREFIX##_bool\ {\ template<bool Add>\ - struct two_or_three {yes_type _[2 + Add];};\ + struct two_or_three {yes_type _[2u + (unsigned)Add];};\ template <class U> static yes_type test(...);\ template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\ static const std::size_t value = sizeof(test<T>(0));\ diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/node_cloner_disposer.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/node_cloner_disposer.hpp index 3fe2954347..97e8d15326 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/node_cloner_disposer.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/node_cloner_disposer.hpp @@ -59,7 +59,7 @@ struct node_cloner {} // tree-based containers use this method, which is proxy-reference friendly - node_ptr operator()(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE node_ptr operator()(node_ptr p) { reference_type v = *traits_->to_value_ptr(p); node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); @@ -85,13 +85,13 @@ struct node_disposer static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value; - node_disposer(F f, const ValueTraits *cont) + BOOST_INTRUSIVE_FORCEINLINE node_disposer(F f, const ValueTraits *cont) : base_t(f), traits_(cont) {} - void operator()(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE void operator()(node_ptr p) { - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(p); base_t::get()(traits_->to_value_ptr(p)); } diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/rbtree_node.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/rbtree_node.hpp index 68f4bdf8e2..07811991cb 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/rbtree_node.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/rbtree_node.hpp @@ -74,40 +74,40 @@ struct default_rbtree_node_traits_impl typedef typename node::color color; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_parent(const node_ptr & n, const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->parent_ = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_left(const node_ptr & n, const node_ptr & l) + BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_right(const node_ptr & n, const node_ptr & r) + BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(const_node_ptr n) { return n->color_; } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(node_ptr n) { return n->color_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_color(const node_ptr & n, color c) + BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c) { n->color_ = c; } BOOST_INTRUSIVE_FORCEINLINE static color black() @@ -130,40 +130,40 @@ struct compact_rbtree_node_traits_impl typedef typename node::color color; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return ptr_bit::get_pointer(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n) { return ptr_bit::get_pointer(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static void set_parent(const node_ptr & n, const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { ptr_bit::set_pointer(n->parent_, p); } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_left(const node_ptr & n, const node_ptr & l) + BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_right(const node_ptr & n, const node_ptr & r) + BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(const_node_ptr n) { return (color)ptr_bit::get_bits(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static color get_color(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static color get_color(node_ptr n) { return (color)ptr_bit::get_bits(n->parent_); } - BOOST_INTRUSIVE_FORCEINLINE static void set_color(const node_ptr & n, color c) + BOOST_INTRUSIVE_FORCEINLINE static void set_color(node_ptr n, color c) { ptr_bit::set_bits(n->parent_, c != 0); } BOOST_INTRUSIVE_FORCEINLINE static color black() diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/reverse_iterator.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/reverse_iterator.hpp index 57631feb5d..00b0e5f353 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/reverse_iterator.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/reverse_iterator.hpp @@ -13,153 +13,16 @@ #ifndef BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP #define BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP -#ifndef BOOST_CONFIG_HPP -# include <boost/config.hpp> -#endif - -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include <boost/intrusive/detail/config_begin.hpp> -#include <boost/intrusive/detail/iterator.hpp> -#include <boost/intrusive/detail/mpl.hpp> +#include <boost/move/detail/reverse_iterator.hpp> namespace boost { namespace intrusive { -template<class It> -class reverse_iterator -{ - public: - typedef typename boost::intrusive::iterator_traits<It>::pointer pointer; - typedef typename boost::intrusive::iterator_traits<It>::reference reference; - typedef typename boost::intrusive::iterator_traits<It>::difference_type difference_type; - typedef typename boost::intrusive::iterator_traits<It>::iterator_category iterator_category; - typedef typename boost::intrusive::iterator_traits<It>::value_type value_type; - - - typedef It iterator_type; - - reverse_iterator() - : m_current() //Value initialization to achieve "null iterators" (N3644) - {} - - explicit reverse_iterator(It r) - : m_current(r) - {} - - reverse_iterator(const reverse_iterator& r) - : m_current(r.base()) - {} - - template<class OtherIt> - reverse_iterator( const reverse_iterator<OtherIt>& r - , typename boost::intrusive::detail::enable_if_convertible<OtherIt, It>::type* =0 - ) - : m_current(r.base()) - {} - - reverse_iterator & operator=( const reverse_iterator& r) - { m_current = r.base(); return *this; } - - template<class OtherIt> - typename boost::intrusive::detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type - operator=( const reverse_iterator<OtherIt>& r) - { m_current = r.base(); return *this; } - - It base() const - { return m_current; } - - reference operator*() const - { - It temp(m_current); - --temp; - reference r = *temp; - return r; - } - - pointer operator->() const - { - It temp(m_current); - --temp; - return iterator_arrow_result(temp); - } - - reference operator[](difference_type off) const - { - return this->m_current[-off - 1]; - } - - reverse_iterator& operator++() - { - --m_current; - return *this; - } - - reverse_iterator operator++(int) - { - reverse_iterator temp((*this)); - --m_current; - return temp; - } - - reverse_iterator& operator--() - { - ++m_current; - return *this; - } - - reverse_iterator operator--(int) - { - reverse_iterator temp((*this)); - ++m_current; - return temp; - } - - friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current == r.m_current; } - - friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current != r.m_current; } - - friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current > r.m_current; } - - friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current >= r.m_current; } - - friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current < r.m_current; } - - friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) - { return l.m_current <= r.m_current; } - - reverse_iterator& operator+=(difference_type off) - { m_current -= off; return *this; } - - reverse_iterator& operator-=(difference_type off) - { m_current += off; return *this; } - - friend reverse_iterator operator+(reverse_iterator l, difference_type off) - { return (l += off); } - - friend reverse_iterator operator+(difference_type off, reverse_iterator r) - { return (r += off); } - - friend reverse_iterator operator-(reverse_iterator l, difference_type off) - { return (l-= off); } - - friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) - { return r.m_current - l.m_current; } - - private: - It m_current; // the wrapped iterator -}; +using boost::movelib::reverse_iterator; +using boost::movelib::make_reverse_iterator; } //namespace intrusive { } //namespace boost { -#include <boost/intrusive/detail/config_end.hpp> #endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/simple_disposers.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/simple_disposers.hpp index 1420b281b0..6b9bd4bc63 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/simple_disposers.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/simple_disposers.hpp @@ -13,6 +13,8 @@ #ifndef BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP #define BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP +#include <boost/intrusive/detail/workaround.hpp> + #ifndef BOOST_CONFIG_HPP # include <boost/config.hpp> #endif @@ -39,7 +41,7 @@ class init_disposer typedef typename NodeAlgorithms::node_ptr node_ptr; public: - void operator()(const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE void operator()(node_ptr p) { NodeAlgorithms::init(p); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/slist_iterator.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/slist_iterator.hpp index a78e63f074..d6ef336afc 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/slist_iterator.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/slist_iterator.hpp @@ -65,10 +65,14 @@ class slist_iterator BOOST_INTRUSIVE_FORCEINLINE slist_iterator() {} - BOOST_INTRUSIVE_FORCEINLINE explicit slist_iterator(const node_ptr & nodeptr, const const_value_traits_ptr &traits_ptr) + BOOST_INTRUSIVE_FORCEINLINE slist_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr) : members_(nodeptr, traits_ptr) {} + BOOST_INTRUSIVE_FORCEINLINE explicit slist_iterator(node_ptr nodeptr) + : members_(nodeptr, const_value_traits_ptr()) + { BOOST_STATIC_ASSERT((stateful_value_traits == false)); } + BOOST_INTRUSIVE_FORCEINLINE slist_iterator(const slist_iterator &other) : members_(other.pointed_node(), other.get_value_traits()) {} @@ -80,15 +84,18 @@ class slist_iterator BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(const slist_iterator &other) { members_.nodeptr_ = other.members_.nodeptr_; return *this; } - BOOST_INTRUSIVE_FORCEINLINE const node_ptr &pointed_node() const + BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const { return members_.nodeptr_; } - BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(const node_ptr &node) - { members_.nodeptr_ = node; return static_cast<slist_iterator&>(*this); } + BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(node_ptr n) + { members_.nodeptr_ = n; return static_cast<slist_iterator&>(*this); } BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const { return members_.get_ptr(); } + BOOST_INTRUSIVE_FORCEINLINE bool operator!() const + { return !members_.nodeptr_; } + public: BOOST_INTRUSIVE_FORCEINLINE slist_iterator& operator++() { @@ -107,7 +114,7 @@ class slist_iterator { return l.pointed_node() == r.pointed_node(); } BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const slist_iterator& l, const slist_iterator& r) - { return !(l == r); } + { return l.pointed_node() != r.pointed_node(); } BOOST_INTRUSIVE_FORCEINLINE reference operator*() const { return *operator->(); } diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/slist_node.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/slist_node.hpp index 848764e571..d209f76ade 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/slist_node.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/slist_node.hpp @@ -46,13 +46,13 @@ struct slist_node_traits typedef typename node::node_ptr node_ptr; typedef typename pointer_rebind<VoidPointer, const node>::type const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const_node_ptr n) { return n->next_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(node_ptr n) { return n->next_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_next(const node_ptr & n, const node_ptr & next) + BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) { n->next_ = next; } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_iterator.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_iterator.hpp index 41988cf180..ba1375f8c8 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_iterator.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_iterator.hpp @@ -71,7 +71,7 @@ class tree_iterator BOOST_INTRUSIVE_FORCEINLINE tree_iterator() {} - BOOST_INTRUSIVE_FORCEINLINE explicit tree_iterator(const node_ptr & nodeptr, const const_value_traits_ptr &traits_ptr) + BOOST_INTRUSIVE_FORCEINLINE explicit tree_iterator(node_ptr nodeptr, const_value_traits_ptr traits_ptr) : members_(nodeptr, traits_ptr) {} @@ -86,7 +86,7 @@ class tree_iterator BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(const tree_iterator &other) { members_.nodeptr_ = other.members_.nodeptr_; return *this; } - BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(const node_ptr &nodeptr) + BOOST_INTRUSIVE_FORCEINLINE tree_iterator &operator=(node_ptr nodeptr) { members_.nodeptr_ = nodeptr; return *this; } BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_node.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_node.hpp index 606fbc865e..949d2d913b 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_node.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_node.hpp @@ -44,31 +44,31 @@ struct tree_node_traits typedef typename node::node_ptr node_ptr; typedef typename pointer_rebind<VoidPointer, const node>::type const_node_ptr; - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const_node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_parent(node_ptr n) { return n->parent_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_parent(const node_ptr & n, const node_ptr & p) + BOOST_INTRUSIVE_FORCEINLINE static void set_parent(node_ptr n, node_ptr p) { n->parent_ = p; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const_node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_left(node_ptr n) { return n->left_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_left(const node_ptr & n, const node_ptr & l) + BOOST_INTRUSIVE_FORCEINLINE static void set_left(node_ptr n, node_ptr l) { n->left_ = l; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const const_node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const_node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(const node_ptr & n) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_right(node_ptr n) { return n->right_; } - BOOST_INTRUSIVE_FORCEINLINE static void set_right(const node_ptr & n, const node_ptr & r) + BOOST_INTRUSIVE_FORCEINLINE static void set_right(node_ptr n, node_ptr r) { n->right_ = r; } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_value_compare.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_value_compare.hpp index f6dd01dc25..c78da0acd6 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_value_compare.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/tree_value_compare.hpp @@ -45,7 +45,7 @@ struct disable_if_smartref_to //This function object takes a KeyCompare function object //and compares values that contains keys using KeyOfValue -template< class ValuePtr, class KeyCompare, class KeyOfValue +template< class ValuePtr, class KeyCompare, class KeyOfValue, class Ret = bool , bool = boost::intrusive::detail::is_same <typename boost::movelib::pointer_element<ValuePtr>::type, typename KeyOfValue::type>::value > struct tree_value_compare @@ -80,41 +80,52 @@ struct tree_value_compare BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const { return static_cast<const key_compare &>(*this); } - BOOST_INTRUSIVE_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key) const + { return this->key_comp()(key); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value) const + { return this->key_comp()(KeyOfValue()(value)); } + + template<class U> + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey + , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const + { return this->key_comp()(nonkey); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const key_type &key2) const { return this->key_comp()(key1, key2); } - BOOST_INTRUSIVE_FORCEINLINE bool operator()(const value_type &value1, const value_type &value2) const + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value1, const value_type &value2) const { return this->key_comp()(KeyOfValue()(value1), KeyOfValue()(value2)); } - BOOST_INTRUSIVE_FORCEINLINE bool operator()(const key_type &key1, const value_type &value2) const + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const value_type &value2) const { return this->key_comp()(key1, KeyOfValue()(value2)); } - BOOST_INTRUSIVE_FORCEINLINE bool operator()(const value_type &value1, const key_type &key2) const + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value1, const key_type &key2) const { return this->key_comp()(KeyOfValue()(value1), key2); } template<class U> - BOOST_INTRUSIVE_FORCEINLINE bool operator()( const key_type &key1, const U &nonkey2 + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const key_type &key1, const U &nonkey2 , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const { return this->key_comp()(key1, nonkey2); } template<class U> - BOOST_INTRUSIVE_FORCEINLINE bool operator()( const U &nonkey1, const key_type &key2 + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey1, const key_type &key2 , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const { return this->key_comp()(nonkey1, key2); } template<class U> - BOOST_INTRUSIVE_FORCEINLINE bool operator()( const value_type &value1, const U &nonvalue2 + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const value_type &value1, const U &nonvalue2 , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const { return this->key_comp()(KeyOfValue()(value1), nonvalue2); } template<class U> - BOOST_INTRUSIVE_FORCEINLINE bool operator()( const U &nonvalue1, const value_type &value2 + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonvalue1, const value_type &value2 , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const { return this->key_comp()(nonvalue1, KeyOfValue()(value2)); } }; -template<class ValuePtr, class KeyCompare, class KeyOfValue> -struct tree_value_compare<ValuePtr, KeyCompare, KeyOfValue, true> +template<class ValuePtr, class KeyCompare, class KeyOfValue, class Ret> +struct tree_value_compare<ValuePtr, KeyCompare, KeyOfValue, Ret, true> : public boost::intrusive::detail::ebo_functor_holder<KeyCompare> { typedef typename @@ -147,16 +158,24 @@ struct tree_value_compare<ValuePtr, KeyCompare, KeyOfValue, true> BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const { return static_cast<const key_compare &>(*this); } - BOOST_INTRUSIVE_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key) const + { return this->key_comp()(key); } + + template<class U> + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey + , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const + { return this->key_comp()(nonkey); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const key_type &key2) const { return this->key_comp()(key1, key2); } template<class U> - BOOST_INTRUSIVE_FORCEINLINE bool operator()( const key_type &key1, const U &nonkey2 + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const key_type &key1, const U &nonkey2 , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const { return this->key_comp()(key1, nonkey2); } template<class U> - BOOST_INTRUSIVE_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2 + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const U &nonkey1, const key_type &key2 , typename disable_if_smartref_to<U, ValuePtr>::type* = 0) const { return this->key_comp()(nonkey1, key2); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/twin.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/twin.hpp new file mode 100644 index 0000000000..b778732f4e --- /dev/null +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/twin.hpp @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_TWIN_HPP +#define BOOST_INTRUSIVE_DETAIL_TWIN_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//A tiny utility to avoid pulling std::pair / utility for +//very simple algorithms/types + +namespace boost { +namespace intrusive { + +template <class T> +struct twin +{ + typedef T type; + twin() + : first(), second() + {} + + twin(const type &f, const type &s) + : first(f), second(s) + {} + + T first; + T second; +}; + +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_TWIN_HPP diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/value_functors.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/value_functors.hpp new file mode 100644 index 0000000000..7e220ebefb --- /dev/null +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/value_functors.hpp @@ -0,0 +1,52 @@ +#ifndef BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP +#define BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-2021. 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/intrusive for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include <cstddef> + +namespace boost { +namespace intrusive { + +//Functors for member algorithm defaults +template<class ValueType> +struct value_less +{ + bool operator()(const ValueType &a, const ValueType &b) const + { return a < b; } +}; + +//Functors for member algorithm defaults +template<class T> +struct value_less<T*> +{ + bool operator()(const T *a, const T* b) const + { return std::size_t(a) < std::size_t(b); } +}; + +template<class ValueType> +struct value_equal +{ + bool operator()(const ValueType &a, const ValueType &b) const + { return a == b; } +}; + +} //namespace intrusive { +} //namespace boost { + +#endif //BOOST_INTRUSIVE_DETAIL_VALUE_FUNCTORS_HPP diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/workaround.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/workaround.hpp index 594ac0b2e5..40db395cbb 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/workaround.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/detail/workaround.hpp @@ -23,6 +23,11 @@ #include <boost/config.hpp> #endif +// MSVC-12 ICEs when variadic templates are enabled. +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && (!defined(BOOST_MSVC) || BOOST_MSVC >= 1900) + #define BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#endif + #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #define BOOST_INTRUSIVE_PERFECT_FORWARDING #endif @@ -34,16 +39,16 @@ #define BOOST_INTRUSIVE_I , #define BOOST_INTRUSIVE_DOCIGN(T1) T1 -#define BOOST_INTRUSIVE_DISABLE_FORCEINLINE +//#define BOOST_INTRUSIVE_DISABLE_FORCEINLINE #if defined(BOOST_INTRUSIVE_DISABLE_FORCEINLINE) #define BOOST_INTRUSIVE_FORCEINLINE inline #elif defined(BOOST_INTRUSIVE_FORCEINLINE_IS_BOOST_FORCELINE) #define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE -#elif defined(BOOST_MSVC) && defined(_DEBUG) - //"__forceinline" and MSVC seems to have some bugs in debug mode +#elif defined(BOOST_MSVC) && (_MSC_VER < 1900 || defined(_DEBUG)) + //"__forceinline" and MSVC seems to have some bugs in old versions and in debug mode #define BOOST_INTRUSIVE_FORCEINLINE inline -#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) +#elif defined(BOOST_GCC) && (__GNUC__ <= 5) //Older GCCs have problems with forceinline #define BOOST_INTRUSIVE_FORCEINLINE inline #else diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/intrusive_fwd.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/intrusive_fwd.hpp index f51276d636..127dbc9e8e 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/intrusive_fwd.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/intrusive_fwd.hpp @@ -384,6 +384,7 @@ template , class O4 = void , class O5 = void , class O6 = void + , class O7 = void > #else template<class T, class ...Options> @@ -399,6 +400,7 @@ template , class O4 = void , class O5 = void , class O6 = void + , class O7 = void > #else template<class T, class ...Options> @@ -414,6 +416,7 @@ template , class O4 = void , class O5 = void , class O6 = void + , class O7 = void > #else template<class T, class ...Options> @@ -567,6 +570,7 @@ template , class O8 = void , class O9 = void , class O10 = void + , class O11 = void > #else template<class T, class ...Options> @@ -586,6 +590,7 @@ template , class O8 = void , class O9 = void , class O10 = void + , class O11 = void > #else template<class T, class ...Options> diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/linear_slist_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/linear_slist_algorithms.hpp index 6c8e9b797c..a616d7ed71 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/linear_slist_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/linear_slist_algorithms.hpp @@ -19,7 +19,7 @@ #include <boost/intrusive/detail/common_slist_algorithms.hpp> #include <boost/intrusive/detail/algo_type.hpp> #include <cstddef> -#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair +#include <boost/intrusive/detail/twin.hpp> //for node_pair #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once @@ -62,6 +62,12 @@ class linear_slist_algorithms typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef NodeTraits node_traits; + //A simple struct containing: + // + // typedef node_ptr type; + // node_ptr first; + // node_ptr second; + typedef twin<node_ptr> node_pair; #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -72,7 +78,7 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void init(const node_ptr & this_node); + static void init(node_ptr this_node) BOOST_NOEXCEPT; //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list. //! @@ -83,7 +89,7 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static bool unique(const_node_ptr this_node); + static bool unique(const_node_ptr this_node) BOOST_NOEXCEPT; //! <b>Effects</b>: Returns true is "this_node" has the same state as if //! it was inited using "init(node_ptr)" @@ -91,7 +97,7 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static bool inited(const_node_ptr this_node); + static bool inited(const_node_ptr this_node) BOOST_NOEXCEPT; //! <b>Requires</b>: prev_node must be in a circular list or be an empty circular list. //! @@ -100,7 +106,7 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void unlink_after(const node_ptr & prev_node); + static void unlink_after(node_ptr prev_node) BOOST_NOEXCEPT; //! <b>Requires</b>: prev_node and last_node must be in a circular list //! or be an empty circular list. @@ -110,7 +116,7 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node); + static void unlink_after(node_ptr prev_node, node_ptr last_node) BOOST_NOEXCEPT; //! <b>Requires</b>: prev_node must be a node of a linear list. //! @@ -119,7 +125,7 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void link_after(const node_ptr & prev_node, const node_ptr & this_node); + static void link_after(node_ptr prev_node, node_ptr this_node) BOOST_NOEXCEPT; //! <b>Requires</b>: b and e must be nodes of the same linear list or an empty range. //! and p must be a node of a different linear list. @@ -130,7 +136,11 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void transfer_after(const node_ptr & p, const node_ptr & b, const node_ptr & e); + static void transfer_after(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT; + + #else + + using base_t::transfer_after; #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) @@ -141,9 +151,44 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static void init_header(const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) BOOST_NOEXCEPT { NodeTraits::set_next(this_node, node_ptr ()); } + //! <b>Requires</b>: 'p' is the first node of a list. + //! + //! <b>Effects</b>: Returns a pointer to a node that represents the "end" (one past end) node + //! + //! <b>Complexity</b>: Constant time. + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static node_ptr end_node(const_node_ptr) BOOST_NOEXCEPT + { return node_ptr(); } + + //! <b>Effects</b>: Returns true if this_node_points to an empty list. + //! + //! <b>Complexity</b>: Constant + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_empty(const_node_ptr this_node) BOOST_NOEXCEPT + { return !NodeTraits::get_next(this_node); } + + //! <b>Effects</b>: Returns true if this_node points to a sentinel node. + //! + //! <b>Complexity</b>: Constant + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static bool is_sentinel(const_node_ptr this_node) BOOST_NOEXCEPT + { return NodeTraits::get_next(this_node) == this_node; } + + //! <b>Effects</b>: Marks this node as a "sentinel" node, a special state that is different from "empty", + //! that can be used to mark a special state of the list + //! + //! <b>Complexity</b>: Constant + //! + //! <b>Throws</b>: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void set_sentinel(node_ptr this_node) BOOST_NOEXCEPT + { NodeTraits::set_next(this_node, this_node); } + //! <b>Requires</b>: this_node and prev_init_node must be in the same linear list. //! //! <b>Effects</b>: Returns the previous node of this_node in the linear list starting. @@ -153,7 +198,8 @@ class linear_slist_algorithms //! <b>Complexity</b>: Linear to the number of elements between prev_init_node and this_node. //! //! <b>Throws</b>: Nothing. - BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr & prev_init_node, const node_ptr & this_node) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr + get_previous_node(node_ptr prev_init_node, node_ptr this_node) BOOST_NOEXCEPT { return base_t::get_previous_node(prev_init_node, this_node); } //! <b>Requires</b>: this_node must be in a linear list or be an empty linear list. @@ -164,7 +210,7 @@ class linear_slist_algorithms //! <b>Complexity</b>: Linear //! //! <b>Throws</b>: Nothing. - static std::size_t count(const const_node_ptr & this_node) + static std::size_t count(const_node_ptr this_node) BOOST_NOEXCEPT { std::size_t result = 0; const_node_ptr p = this_node; @@ -184,7 +230,7 @@ class linear_slist_algorithms //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - static void swap_trailing_nodes(const node_ptr & this_node, const node_ptr & other_node) + BOOST_INTRUSIVE_FORCEINLINE static void swap_trailing_nodes(node_ptr this_node, node_ptr other_node) BOOST_NOEXCEPT { node_ptr this_nxt = NodeTraits::get_next(this_node); node_ptr other_nxt = NodeTraits::get_next(other_node); @@ -199,7 +245,7 @@ class linear_slist_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: This function is linear to the contained elements. - static node_ptr reverse(const node_ptr & p) + static node_ptr reverse(node_ptr p) BOOST_NOEXCEPT { if(!p) return node_ptr(); node_ptr i = NodeTraits::get_next(p); @@ -222,9 +268,9 @@ class linear_slist_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. - static std::pair<node_ptr, node_ptr> move_first_n_backwards(const node_ptr & p, std::size_t n) + static node_pair move_first_n_backwards(node_ptr p, std::size_t n) BOOST_NOEXCEPT { - std::pair<node_ptr, node_ptr> ret; + node_pair ret; //Null shift, or count() == 0 or 1, nothing to do if(!n || !p || !NodeTraits::get_next(p)){ return ret; @@ -277,9 +323,9 @@ class linear_slist_algorithms //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. - static std::pair<node_ptr, node_ptr> move_first_n_forward(const node_ptr & p, std::size_t n) + static node_pair move_first_n_forward(node_ptr p, std::size_t n) BOOST_NOEXCEPT { - std::pair<node_ptr, node_ptr> ret; + node_pair ret; //Null shift, or count() == 0 or 1, nothing to do if(!n || !p || !NodeTraits::get_next(p)) return ret; @@ -322,6 +368,40 @@ class linear_slist_algorithms ret.second = new_last; return ret; } + + //! <b>Requires</b>: other must be a list and p must be a node of a different linear list. + //! + //! <b>Effects</b>: Transfers all nodes from other after p in p's linear list. + //! + //! <b>Complexity</b>: Linear + //! + //! <b>Throws</b>: Nothing. + static void transfer_after(node_ptr p, node_ptr other) BOOST_NOEXCEPT + { + if ((is_empty)(p)) { + (swap_trailing_nodes)(p, other); + } + else { + node_ptr other_last((get_previous_node)(other, node_ptr())); + base_t::transfer_after(p, other, other_last); + } + } + + //! <b>Requires</b>: "disposer" must be an object function + //! taking a node_ptr parameter and shouldn't throw. + //! + //! <b>Effects</b>: Unlinks all nodes reachable from p (but not p) and calls + //! <tt>void disposer::operator()(node_ptr)</tt> for every node of the list + //! where p is linked. + //! + //! <b>Returns</b>: The number of disposed nodes + //! + //! <b>Complexity</b>: Linear to the number of element of the list. + //! + //! <b>Throws</b>: Nothing. + template<class Disposer> + BOOST_INTRUSIVE_FORCEINLINE static std::size_t detach_and_dispose(node_ptr p, Disposer disposer) BOOST_NOEXCEPT + { return base_t::unlink_after_and_dispose(p, node_ptr(), disposer); } }; /// @cond diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/list.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/list.hpp index 71eac5c42e..23b3c10070 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/list.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/list.hpp @@ -39,7 +39,7 @@ #include <boost/move/utility_core.hpp> #include <boost/static_assert.hpp> -#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//std::less +#include <boost/intrusive/detail/value_functors.hpp> #include <cstddef> //std::size_t, etc. #if defined(BOOST_HAS_PRAGMA_ONCE) @@ -127,10 +127,10 @@ class list_impl ((int)value_traits::link_mode == (int)auto_unlink) )); - node_ptr get_root_node() + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_root_node() { return data_.root_plus_size_.m_header.get_node(); } - const_node_ptr get_root_node() const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_root_node() const { return data_.root_plus_size_.m_header.get_node(); } struct root_plus_size : public size_traits @@ -141,29 +141,29 @@ class list_impl struct data_t : public value_traits { typedef typename list_impl::value_traits value_traits; - explicit data_t(const value_traits &val_traits) + BOOST_INTRUSIVE_FORCEINLINE explicit data_t(const value_traits &val_traits) : value_traits(val_traits) {} root_plus_size root_plus_size_; } data_; - size_traits &priv_size_traits() + BOOST_INTRUSIVE_FORCEINLINE size_traits &priv_size_traits() BOOST_NOEXCEPT { return data_.root_plus_size_; } - const size_traits &priv_size_traits() const + BOOST_INTRUSIVE_FORCEINLINE const size_traits &priv_size_traits() const BOOST_NOEXCEPT { return data_.root_plus_size_; } - const value_traits &priv_value_traits() const + BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const BOOST_NOEXCEPT { return data_; } - value_traits &priv_value_traits() + BOOST_INTRUSIVE_FORCEINLINE value_traits &priv_value_traits() BOOST_NOEXCEPT { return data_; } typedef typename boost::intrusive::value_traits_pointers <ValueTraits>::const_value_traits_ptr const_value_traits_ptr; - const_value_traits_ptr priv_value_traits_ptr() const + BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const BOOST_NOEXCEPT { return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); } /// @endcond @@ -245,11 +245,13 @@ class list_impl //! are called), but the hooks according to the ValueTraits template parameter //! are set to their default value. //! + //! <b>Throws</b>: Nothing. + //! //! <b>Complexity</b>: Linear to the number of elements in the list, if //! it's a safe-mode or auto-unlink value . Otherwise constant. ~list_impl() { - if(is_safe_autounlink<ValueTraits::link_mode>::value){ + BOOST_IF_CONSTEXPR(is_safe_autounlink<ValueTraits::link_mode>::value){ this->clear(); node_algorithms::init(this->get_root_node()); } @@ -265,7 +267,7 @@ class list_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { node_ptr to_insert = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert)); @@ -283,7 +285,7 @@ class list_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert)); @@ -299,7 +301,7 @@ class list_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element. - void pop_back() + void pop_back() BOOST_NOEXCEPT { return this->pop_back_and_dispose(detail::null_disposer()); } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. @@ -314,12 +316,12 @@ class list_impl //! //! <b>Note</b>: Invalidates the iterators to the erased element. template<class Disposer> - void pop_back_and_dispose(Disposer disposer) + void pop_back_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase = node_traits::get_previous(this->get_root_node()); node_algorithms::unlink(to_erase); this->priv_size_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); } @@ -332,7 +334,7 @@ class list_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element. - void pop_front() + void pop_front() BOOST_NOEXCEPT { return this->pop_front_and_dispose(detail::null_disposer()); } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. @@ -347,12 +349,12 @@ class list_impl //! //! <b>Note</b>: Invalidates the iterators to the erased element. template<class Disposer> - void pop_front_and_dispose(Disposer disposer) + void pop_front_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase = node_traits::get_next(this->get_root_node()); node_algorithms::unlink(to_erase); this->priv_size_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); } @@ -362,7 +364,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference front() + BOOST_INTRUSIVE_FORCEINLINE reference front() BOOST_NOEXCEPT { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! <b>Effects</b>: Returns a const_reference to the first element of the list. @@ -370,7 +372,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference front() const + BOOST_INTRUSIVE_FORCEINLINE const_reference front() const BOOST_NOEXCEPT { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! <b>Effects</b>: Returns a reference to the last element of the list. @@ -378,7 +380,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference back() + BOOST_INTRUSIVE_FORCEINLINE reference back() BOOST_NOEXCEPT { return *priv_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); } //! <b>Effects</b>: Returns a const_reference to the last element of the list. @@ -386,7 +388,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference back() const + BOOST_INTRUSIVE_FORCEINLINE const_reference back() const BOOST_NOEXCEPT { return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); } //! <b>Effects</b>: Returns an iterator to the first element contained in the list. @@ -394,7 +396,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - iterator begin() + BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT { return iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. @@ -402,7 +404,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT { return this->cbegin(); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. @@ -410,7 +412,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator cbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT { return const_iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns an iterator to the end of the list. @@ -418,7 +420,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - iterator end() + BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT { return iterator(this->get_root_node(), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a const_iterator to the end of the list. @@ -426,7 +428,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator end() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT { return this->cend(); } //! <b>Effects</b>: Returns a constant iterator to the end of the list. @@ -434,7 +436,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator cend() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT { return const_iterator(detail::uncast(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning @@ -443,7 +445,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reverse_iterator rbegin() + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(this->end()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning @@ -452,7 +454,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reverse_iterator rbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return this->crbegin(); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning @@ -461,7 +463,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reverse_iterator crbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } //! <b>Effects</b>: Returns a reverse_iterator pointing to the end @@ -470,7 +472,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reverse_iterator rend() + BOOST_INTRUSIVE_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end @@ -479,7 +481,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reverse_iterator rend() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT { return this->crend(); } //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end @@ -488,7 +490,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reverse_iterator crend() const + BOOST_INTRUSIVE_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(this->begin()); } //! <b>Precondition</b>: end_iterator must be a valid end iterator @@ -499,7 +501,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - static list_impl &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static list_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return list_impl::priv_container_from_end_iterator(end_iterator); } //! <b>Precondition</b>: end_iterator must be a valid end const_iterator @@ -510,7 +512,7 @@ class list_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - static const list_impl &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const list_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return list_impl::priv_container_from_end_iterator(end_iterator); } //! <b>Effects</b>: Returns the number of the elements contained in the list. @@ -521,9 +523,9 @@ class list_impl //! if constant-time size option is disabled. Constant time otherwise. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - size_type size() const + BOOST_INTRUSIVE_FORCEINLINE size_type size() const BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) return this->priv_size_traits().get_size(); else return node_algorithms::count(this->get_root_node()) - 1; @@ -536,7 +538,7 @@ class list_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - bool empty() const + BOOST_INTRUSIVE_FORCEINLINE bool empty() const BOOST_NOEXCEPT { return node_algorithms::unique(this->get_root_node()); } //! <b>Effects</b>: Swaps the elements of x and *this. @@ -546,7 +548,7 @@ class list_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - void swap(list_impl& other) + void swap(list_impl& other) BOOST_NOEXCEPT { node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node()); this->priv_size_traits().swap(other.priv_size_traits()); @@ -561,7 +563,7 @@ class list_impl //! <b>Complexity</b>: Linear to the number of shifts. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - void shift_backwards(size_type n = 1) + BOOST_INTRUSIVE_FORCEINLINE void shift_backwards(size_type n = 1) BOOST_NOEXCEPT { node_algorithms::move_forward(this->get_root_node(), n); } //! <b>Effects</b>: Moves forward all the elements, so that the second @@ -573,7 +575,7 @@ class list_impl //! <b>Complexity</b>: Linear to the number of shifts. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - void shift_forward(size_type n = 1) + BOOST_INTRUSIVE_FORCEINLINE void shift_forward(size_type n = 1) BOOST_NOEXCEPT { node_algorithms::move_backwards(this->get_root_node(), n); } //! <b>Effects</b>: Erases the element pointed by i of the list. @@ -588,7 +590,7 @@ class list_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase(const_iterator i) + BOOST_INTRUSIVE_FORCEINLINE iterator erase(const_iterator i) BOOST_NOEXCEPT { return this->erase_and_dispose(i, detail::null_disposer()); } //! <b>Requires</b>: b and e must be valid iterators to elements in *this. @@ -606,9 +608,9 @@ class list_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased elements. - iterator erase(const_iterator b, const_iterator e) + BOOST_INTRUSIVE_FORCEINLINE iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT { - if(safemode_or_autounlink || constant_time_size){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink || constant_time_size){ return this->erase_and_dispose(b, e, detail::null_disposer()); } else{ @@ -633,14 +635,15 @@ class list_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased elements. - iterator erase(const_iterator b, const_iterator e, size_type n) + iterator erase(const_iterator b, const_iterator e, size_type n) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance(b.pointed_node(), e.pointed_node()) == n); - if(safemode_or_autounlink || constant_time_size){ + (void)n; + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ return this->erase_and_dispose(b, e, detail::null_disposer()); } else{ - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().decrease(n); } node_algorithms::unlink(b.pointed_node(), e.pointed_node()); @@ -663,13 +666,13 @@ class list_impl //! //! <b>Note</b>: Invalidates the iterators to the erased element. template <class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase(i.pointed_node()); ++i; node_algorithms::unlink(to_erase); this->priv_size_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(this->priv_value_traits().to_value_ptr(to_erase)); return i.unconst(); @@ -677,7 +680,7 @@ class list_impl #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template<class Disposer> - iterator erase_and_dispose(iterator i, Disposer disposer) + iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_and_dispose(const_iterator(i), disposer); } #endif @@ -696,14 +699,14 @@ class list_impl //! //! <b>Note</b>: Invalidates the iterators to the erased elements. template <class Disposer> - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT { node_ptr bp(b.pointed_node()), ep(e.pointed_node()); node_algorithms::unlink(bp, ep); while(bp != ep){ node_ptr to_erase(bp); bp = node_traits::get_next(bp); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); @@ -720,9 +723,9 @@ class list_impl //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased elements. - void clear() + void clear() BOOST_NOEXCEPT { - if(safemode_or_autounlink){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ this->clear_and_dispose(detail::null_disposer()); } else{ @@ -743,13 +746,13 @@ class list_impl //! //! <b>Note</b>: Invalidates the iterators to the erased elements. template <class Disposer> - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { const_iterator it(this->begin()), itend(this->end()); while(it != itend){ node_ptr to_erase(it.pointed_node()); ++it; - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); } @@ -822,7 +825,7 @@ class list_impl //! <b>Complexity</b>: Constant time. No copy constructors are called. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - iterator insert(const_iterator p, reference value) + iterator insert(const_iterator p, reference value) BOOST_NOEXCEPT { node_ptr to_insert = this->priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert)); @@ -843,7 +846,7 @@ class list_impl //! //! <b>Note</b>: Does not affect the validity of iterators and references. template<class Iterator> - void insert(const_iterator p, Iterator b, Iterator e) + void insert(const_iterator p, Iterator b, Iterator e) BOOST_NOEXCEPT { for (; b != e; ++b) this->insert(p, *b); @@ -865,7 +868,7 @@ class list_impl //! <b>Note</b>: Invalidates the iterators (but not the references) //! to the erased elements. template<class Iterator> - void assign(Iterator b, Iterator e) + void assign(Iterator b, Iterator e) BOOST_NOEXCEPT { this->clear(); this->insert(this->cend(), b, e); @@ -888,7 +891,7 @@ class list_impl //! <b>Note</b>: Invalidates the iterators (but not the references) //! to the erased elements. template<class Iterator, class Disposer> - void dispose_and_assign(Disposer disposer, Iterator b, Iterator e) + void dispose_and_assign(Disposer disposer, Iterator b, Iterator e) BOOST_NOEXCEPT { this->clear_and_dispose(disposer); this->insert(this->cend(), b, e); @@ -905,7 +908,7 @@ class list_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of //! this list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl& x) + void splice(const_iterator p, list_impl& x) BOOST_NOEXCEPT { if(!x.empty()){ node_algorithms::transfer @@ -930,7 +933,7 @@ class list_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl&x, const_iterator new_ele) + void splice(const_iterator p, list_impl&x, const_iterator new_ele) BOOST_NOEXCEPT { node_algorithms::transfer(p.pointed_node(), new_ele.pointed_node()); x.priv_size_traits().decrement(); @@ -950,9 +953,9 @@ class list_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e) + void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e) BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) this->splice(p, x, f, e, node_algorithms::distance(f.pointed_node(), e.pointed_node())); else this->splice(p, x, f, e, 1);//intrusive::iterator_distance is a dummy value @@ -971,10 +974,10 @@ class list_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, size_type n) + void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, size_type n) BOOST_NOEXCEPT { if(n){ - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ BOOST_INTRUSIVE_INVARIANT_ASSERT(n == node_algorithms::distance(f.pointed_node(), e.pointed_node())); node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node()); size_traits &thist = this->priv_size_traits(); @@ -988,19 +991,19 @@ class list_impl } } - //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. + //! <b>Effects</b>: This function sorts the list *this according to operator <. //! The sort is stable, that is, the relative order of equivalent elements is preserved. //! //! <b>Throws</b>: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or std::less<value_type> throws. Basic guarantee. + //! or operator < throws. Basic guarantee. //! //! <b>Notes</b>: Iterators and references are not invalidated. //! //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N //! is the list's size. void sort() - { this->sort(std::less<value_type>()); } + { this->sort(value_less<value_type>()); } //! <b>Requires</b>: p must be a comparison function that induces a strict weak ordering //! @@ -1043,18 +1046,18 @@ class list_impl } //! <b>Effects</b>: This function removes all of x's elements and inserts them - //! in order into *this according to std::less<value_type>. The merge is stable; + //! in order into *this according to operator <. The merge is stable; //! that is, if an element from *this is equivalent to one from x, then the element //! from *this will precede the one from x. //! - //! <b>Throws</b>: If std::less<value_type> throws. Basic guarantee. + //! <b>Throws</b>: If operator < throws. Basic guarantee. //! //! <b>Complexity</b>: This function is linear time: it performs at most //! size() + x.size() - 1 comparisons. //! //! <b>Note</b>: Iterators and references are not invalidated void merge(list_impl& x) - { this->merge(x, std::less<value_type>()); } + { this->merge(x, value_less<value_type>()); } //! <b>Requires</b>: p must be a comparison function that induces a strict weak //! ordering and both *this and x must be sorted according to that ordering @@ -1102,19 +1105,19 @@ class list_impl //! <b>Complexity</b>: This function is linear time. //! //! <b>Note</b>: Iterators and references are not invalidated - void reverse() + void reverse() BOOST_NOEXCEPT { node_algorithms::reverse(this->get_root_node()); } //! <b>Effects</b>: Removes all the elements that compare equal to value. //! No destructors are called. //! - //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. + //! <b>Throws</b>: If operator == throws. Basic guarantee. //! //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. //! //! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. - void remove(const_reference value) + void remove(const_reference value) BOOST_NOEXCEPT { this->remove_if(detail::equal_to_value<const_reference>(value)); } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. @@ -1122,14 +1125,14 @@ class list_impl //! <b>Effects</b>: Removes all the elements that compare equal to value. //! Disposer::operator()(pointer) is called for every removed element. //! - //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. + //! <b>Throws</b>: If operator == throws. Basic guarantee. //! //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. //! //! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. template<class Disposer> - void remove_and_dispose(const_reference value, Disposer disposer) + void remove_and_dispose(const_reference value, Disposer disposer) BOOST_NOEXCEPT { this->remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); } //! <b>Effects</b>: Removes all the elements for which a specified @@ -1267,7 +1270,7 @@ class list_impl //! <b>Note</b>: Iterators and references are not invalidated. //! This static function is available only if the <i>value traits</i> //! is stateless. - static iterator s_iterator_to(reference value) + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value))); @@ -1285,7 +1288,7 @@ class list_impl //! <b>Note</b>: Iterators and references are not invalidated. //! This static function is available only if the <i>value traits</i> //! is stateless. - static const_iterator s_iterator_to(const_reference value) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value)); @@ -1302,7 +1305,7 @@ class list_impl //! <b>Complexity</b>: Constant time. //! //! <b>Note</b>: Iterators and references are not invalidated. - iterator iterator_to(reference value) + iterator iterator_to(reference value) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value))); return iterator(this->priv_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); @@ -1317,7 +1320,7 @@ class list_impl //! <b>Complexity</b>: Constant time. //! //! <b>Note</b>: Iterators and references are not invalidated. - const_iterator iterator_to(const_reference value) const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT { reference r = *detail::uncast(pointer_traits<const_pointer>::pointer_to(value)); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(r))); @@ -1341,7 +1344,7 @@ class list_impl == (node_traits::get_previous(header_ptr) == header_ptr)); if (node_traits::get_next(header_ptr) == header_ptr) { - if (constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == 0); return; } @@ -1356,7 +1359,7 @@ class list_impl if (p == header_ptr) break; ++node_count; } - if (constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count); } @@ -1368,28 +1371,28 @@ class list_impl return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend()); } - friend bool operator!=(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!=(const list_impl &x, const list_impl &y) { return !(x == y); } - friend bool operator<(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator<(const list_impl &x, const list_impl &y) { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } - friend bool operator>(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator>(const list_impl &x, const list_impl &y) { return y < x; } - friend bool operator<=(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator<=(const list_impl &x, const list_impl &y) { return !(y < x); } - friend bool operator>=(const list_impl &x, const list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend bool operator>=(const list_impl &x, const list_impl &y) { return !(x < y); } - friend void swap(list_impl &x, list_impl &y) + BOOST_INTRUSIVE_FORCEINLINE friend void swap(list_impl &x, list_impl &y) BOOST_NOEXCEPT { x.swap(y); } /// @cond private: - static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((has_container_from_iterator)); node_ptr p = end_iterator.pointed_node(); @@ -1471,38 +1474,38 @@ class list typedef typename Base::iterator iterator; typedef typename Base::const_iterator const_iterator; - list() + BOOST_INTRUSIVE_FORCEINLINE list() : Base() {} - explicit list(const value_traits &v_traits) + BOOST_INTRUSIVE_FORCEINLINE explicit list(const value_traits &v_traits) : Base(v_traits) {} template<class Iterator> - list(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE list(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) : Base(b, e, v_traits) {} - list(BOOST_RV_REF(list) x) + BOOST_INTRUSIVE_FORCEINLINE list(BOOST_RV_REF(list) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - list& operator=(BOOST_RV_REF(list) x) + BOOST_INTRUSIVE_FORCEINLINE list& operator=(BOOST_RV_REF(list) x) { return static_cast<list &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const list &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const list &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static list &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static list &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<list &>(Base::container_from_end_iterator(end_iterator)); } - static const list &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const list &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const list &>(Base::container_from_end_iterator(end_iterator)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/list_hook.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/list_hook.hpp index 892e4e20d7..03cf9a563a 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/list_hook.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/list_hook.hpp @@ -96,7 +96,7 @@ class list_base_hook //! initializes the node to an unlinked state. //! //! <b>Throws</b>: Nothing. - list_base_hook(); + list_base_hook() BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -107,7 +107,7 @@ class list_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - list_base_hook(const list_base_hook& ); + list_base_hook(const list_base_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: Empty function. The argument is ignored. //! @@ -117,7 +117,7 @@ class list_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - list_base_hook& operator=(const list_base_hook& ); + list_base_hook& operator=(const list_base_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -139,7 +139,7 @@ class list_base_hook //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - void swap_nodes(list_base_hook &other); + void swap_nodes(list_base_hook &other) BOOST_NOEXCEPT; //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink. //! @@ -154,7 +154,7 @@ class list_base_hook //! This function is only allowed if link_mode is \c auto_unlink. //! //! <b>Throws</b>: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; @@ -219,7 +219,7 @@ class list_member_hook //! initializes the node to an unlinked state. //! //! <b>Throws</b>: Nothing. - list_member_hook(); + list_member_hook() BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -230,7 +230,7 @@ class list_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - list_member_hook(const list_member_hook& ); + list_member_hook(const list_member_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: Empty function. The argument is ignored. //! @@ -240,7 +240,7 @@ class list_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - list_member_hook& operator=(const list_member_hook& ); + list_member_hook& operator=(const list_member_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -262,7 +262,7 @@ class list_member_hook //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - void swap_nodes(list_member_hook &other); + void swap_nodes(list_member_hook &other) BOOST_NOEXCEPT; //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink. //! @@ -277,7 +277,7 @@ class list_member_hook //! This function is only allowed if link_mode is \c auto_unlink. //! //! <b>Throws</b>: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/options.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/options.hpp index 6523ffb574..ff6902e8f8 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/options.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/options.hpp @@ -17,7 +17,6 @@ #include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/link_mode.hpp> #include <boost/intrusive/pack_options.hpp> -#include <boost/intrusive/detail/mpl.hpp> #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once @@ -70,6 +69,15 @@ BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare) //!that will return the key from a value_type of an associative container BOOST_INTRUSIVE_OPTION_TYPE(key_of_value, KeyOfValue, KeyOfValue, key_of_value) +//!This option setter specifies a function object +//!that specifies the type of the priority of a treap +//!container and an operator to obtain it from a value type. +//! +//!This function object must the define a `type` member typedef and +//!a member with signature `type [const&] operator()(const value_type &) const` +//!that will return the priority from a value_type of a treap container +BOOST_INTRUSIVE_OPTION_TYPE(priority_of_value, PrioOfValue, PrioOfValue, priority_of_value) + //!This option setter for scapegoat containers specifies if //!the intrusive scapegoat container should use a non-variable //!alpha value that does not need floating-point operations. @@ -204,13 +212,22 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash) //!with the same key. BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey) -//!This option setter specifies if the bucket array will be always power of two. +//!This option setter specifies if the length of the bucket array provided by +//!the user will always be power of two. //!This allows using masks instead of the default modulo operation to determine //!the bucket number from the hash value, leading to better performance. -//!In debug mode, if power of two buckets mode is activated, the bucket length -//!will be checked with assertions. +//!In debug mode, the provided bucket array length will be checked with assertions. BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets) +//!WARNING: this option is EXPERIMENTAL, don't use it in production code +//!This option setter specifies if the length of the bucket array provided by +//!the user will always be a value specified by the +//!suggested_upper|lower_bucket_count call. This allows the use of some +//!precomputed values and speeds hash to bucket index operations, leading +//!to better performance. +//!In debug mode, the provided bucket array length will be checked with assertions. +BOOST_INTRUSIVE_OPTION_CONSTANT(fastmod_buckets, bool, Enabled, fastmod_buckets) + //!This option setter specifies if the container will cache a pointer to the first //!non-empty bucket so that begin() is always constant-time. //!This is specially helpful when we can have containers with a few elements @@ -233,6 +250,11 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash) //!(rehashing the whole bucket array) is not admisible. BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, incremental) +//!This option setter specifies if the buckets (which form a singly linked lists of nodes) +//!are linear (true) or circular (false, default value). Linear buckets can improve performance +//!in some cases, but the container loses some features like obtaining an iterator from a value. +BOOST_INTRUSIVE_OPTION_CONSTANT(linear_buckets, bool, Enabled, linear_buckets) + /// @cond struct hook_defaults diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/pack_options.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/pack_options.hpp index 944243f661..0ae349d282 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/pack_options.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/pack_options.hpp @@ -19,6 +19,8 @@ # pragma once #endif +#include <cstddef> + namespace boost { namespace intrusive { @@ -97,19 +99,19 @@ struct pack_options #else //index_tuple -template<int... Indexes> +template<std::size_t... Indexes> struct index_tuple{}; //build_number_seq template<std::size_t Num, typename Tuple = index_tuple<> > struct build_number_seq; -template<std::size_t Num, int... Indexes> +template<std::size_t Num, std::size_t... Indexes> struct build_number_seq<Num, index_tuple<Indexes...> > : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> > {}; -template<int... Indexes> +template<std::size_t... Indexes> struct build_number_seq<0, index_tuple<Indexes...> > { typedef index_tuple<Indexes...> type; }; @@ -121,10 +123,10 @@ struct typelist template<class T> struct invert_typelist; -template<int I, typename Tuple> +template<std::size_t I, typename Tuple> struct typelist_element; -template<int I, typename Head, typename... Tail> +template<std::size_t I, typename Head, typename... Tail> struct typelist_element<I, typelist<Head, Tail...> > { typedef typename typelist_element<I-1, typelist<Tail...> >::type type; @@ -136,7 +138,7 @@ struct typelist_element<0, typelist<Head, Tail...> > typedef Head type; }; -template<int ...Ints, class ...Types> +template<std::size_t ...Ints, class ...Types> typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...> inverted_typelist(index_tuple<Ints...>, typelist<Types...>) { @@ -158,7 +160,7 @@ template<class Typelist, class Indexes> struct invert_typelist_impl; -template<class Typelist, int ...Ints> +template<class Typelist, std::size_t ...Ints> struct invert_typelist_impl< Typelist, index_tuple<Ints...> > { static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1; @@ -166,7 +168,7 @@ struct invert_typelist_impl< Typelist, index_tuple<Ints...> > <typename typelist_element<last_idx - Ints, Typelist>::type...> type; }; -template<class Typelist, int Int> +template<class Typelist, std::size_t Int> struct invert_typelist_impl< Typelist, index_tuple<Int> > { typedef Typelist type; @@ -209,6 +211,12 @@ struct do_pack<typelist<Prev, Last> > typedef typename Prev::template pack<Last> type; }; +template<class ...Others> +struct do_pack<typelist<void, Others...> > +{ + typedef typename do_pack<typelist<Others...> >::type type; +}; + template<class Prev, class ...Others> struct do_pack<typelist<Prev, Others...> > { diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/parent_from_member.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/parent_from_member.hpp index a9a9293c7c..9c8f167dad 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/parent_from_member.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/parent_from_member.hpp @@ -30,7 +30,7 @@ namespace intrusive { //! Note: this function does not work with pointer to members that rely on //! virtual inheritance. template<class Parent, class Member> -BOOST_INTRUSIVE_FORCEINLINE Parent *get_parent_from_member(Member *member, const Member Parent::* ptr_to_member) +BOOST_INTRUSIVE_FORCEINLINE Parent *get_parent_from_member(Member *member, const Member Parent::* ptr_to_member) BOOST_NOEXCEPT { return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); } //! Given a const pointer to a member and its corresponding const pointer to data member, @@ -38,7 +38,7 @@ BOOST_INTRUSIVE_FORCEINLINE Parent *get_parent_from_member(Member *member, const //! Note: this function does not work with pointer to members that rely on //! virtual inheritance. template<class Parent, class Member> -BOOST_INTRUSIVE_FORCEINLINE const Parent *get_parent_from_member(const Member *member, const Member Parent::* ptr_to_member) +BOOST_INTRUSIVE_FORCEINLINE const Parent *get_parent_from_member(const Member *member, const Member Parent::* ptr_to_member) BOOST_NOEXCEPT { return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); } } //namespace intrusive { diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/pointer_plus_bits.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/pointer_plus_bits.hpp index a39da32443..b967bb636d 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/pointer_plus_bits.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/pointer_plus_bits.hpp @@ -30,6 +30,9 @@ # if (BOOST_GCC >= 40600) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wuninitialized" +# if (BOOST_GCC >= 40700) +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +# endif # endif #endif @@ -78,19 +81,19 @@ struct pointer_plus_bits<T*, NumBits> static const uintptr_t Mask = uintptr_t((uintptr_t(1u) << NumBits) - 1); typedef T* pointer; - BOOST_INTRUSIVE_FORCEINLINE static pointer get_pointer(pointer n) + BOOST_INTRUSIVE_FORCEINLINE static pointer get_pointer(pointer n) BOOST_NOEXCEPT { return pointer(uintptr_t(n) & uintptr_t(~Mask)); } - BOOST_INTRUSIVE_FORCEINLINE static void set_pointer(pointer &n, pointer p) + BOOST_INTRUSIVE_FORCEINLINE static void set_pointer(pointer &n, pointer p) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(0 == (uintptr_t(p) & Mask)); n = pointer(uintptr_t(p) | (uintptr_t(n) & Mask)); } - BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_bits(pointer n) + BOOST_INTRUSIVE_FORCEINLINE static std::size_t get_bits(pointer n) BOOST_NOEXCEPT { return std::size_t(uintptr_t(n) & Mask); } - BOOST_INTRUSIVE_FORCEINLINE static void set_bits(pointer &n, std::size_t c) + BOOST_INTRUSIVE_FORCEINLINE static void set_bits(pointer &n, std::size_t c) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(uintptr_t(c) <= Mask); n = pointer(uintptr_t((get_pointer)(n)) | uintptr_t(c)); diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/pointer_traits.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/pointer_traits.hpp index 4216c7ee9c..1b2ed05763 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/pointer_traits.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/pointer_traits.hpp @@ -46,6 +46,7 @@ BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(has_member_function_call BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(element_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_traits_ptr) @@ -103,7 +104,13 @@ struct pointer_traits (boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type; typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT - (boost::intrusive::detail::, Ptr, reference, typename boost::intrusive::detail::unvoid_ref<element_type>::type) reference; + ( boost::intrusive::detail::, Ptr, size_type + , typename boost::move_detail:: + make_unsigned<difference_type>::type) size_type; + + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + ( boost::intrusive::detail::, Ptr, reference + , typename boost::intrusive::detail::unvoid_ref<element_type>::type) reference; // template <class U> struct rebind_pointer { @@ -123,7 +130,7 @@ struct pointer_traits //! //! <b>Note</b>: For non-conforming compilers only the existence of a member function called //! <code>pointer_to</code> is checked. - static pointer pointer_to(reference r) + BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) BOOST_NOEXCEPT { //Non-standard extension, it does not require Ptr::pointer_to. If not present //tries to converts &r to pointer. @@ -143,7 +150,7 @@ struct pointer_traits //! <b>Note</b>: For non-conforming compilers only the existence of a member function called //! <code>static_cast_from</code> is checked. template<class UPtr> - static pointer static_cast_from(const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(const UPtr &uptr) BOOST_NOEXCEPT { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: @@ -164,7 +171,7 @@ struct pointer_traits //! <b>Note</b>: For non-conforming compilers only the existence of a member function called //! <code>const_cast_from</code> is checked. template<class UPtr> - static pointer const_cast_from(const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(const UPtr &uptr) BOOST_NOEXCEPT { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: @@ -185,7 +192,7 @@ struct pointer_traits //! <b>Note</b>: For non-conforming compilers only the existence of a member function called //! <code>dynamic_cast_from</code> is checked. template<class UPtr> - static pointer dynamic_cast_from(const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(const UPtr &uptr) BOOST_NOEXCEPT { typedef const UPtr &RefArg; const bool value = boost::intrusive::detail:: @@ -201,46 +208,46 @@ struct pointer_traits private: //priv_to_raw_pointer template <class T> - static T* to_raw_pointer(T* p) + BOOST_INTRUSIVE_FORCEINLINE static T* to_raw_pointer(T* p) BOOST_NOEXCEPT { return p; } template <class Pointer> - static typename pointer_traits<Pointer>::element_type* - to_raw_pointer(const Pointer &p) + BOOST_INTRUSIVE_FORCEINLINE static typename pointer_traits<Pointer>::element_type* + to_raw_pointer(const Pointer &p) BOOST_NOEXCEPT { return pointer_traits::to_raw_pointer(p.operator->()); } //priv_pointer_to - static pointer priv_pointer_to(boost::intrusive::detail::true_, reference r) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::true_, reference r) BOOST_NOEXCEPT { return Ptr::pointer_to(r); } - static pointer priv_pointer_to(boost::intrusive::detail::false_, reference r) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_pointer_to(boost::intrusive::detail::false_, reference r) BOOST_NOEXCEPT { return pointer(boost::intrusive::detail::addressof(r)); } //priv_static_cast_from template<class UPtr> - static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT { return Ptr::static_cast_from(uptr); } template<class UPtr> - static pointer priv_static_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_static_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT { return uptr ? pointer_to(*static_cast<element_type*>(to_raw_pointer(uptr))) : pointer(); } //priv_const_cast_from template<class UPtr> - static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT { return Ptr::const_cast_from(uptr); } template<class UPtr> - static pointer priv_const_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_const_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT { return uptr ? pointer_to(const_cast<element_type&>(*uptr)) : pointer(); } //priv_dynamic_cast_from template<class UPtr> - static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::true_, const UPtr &uptr) BOOST_NOEXCEPT { return Ptr::dynamic_cast_from(uptr); } template<class UPtr> - static pointer priv_dynamic_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer priv_dynamic_cast_from(boost::intrusive::detail::false_, const UPtr &uptr) BOOST_NOEXCEPT { return uptr ? pointer_to(dynamic_cast<element_type&>(*uptr)) : pointer(); } ///@endcond }; @@ -265,9 +272,10 @@ struct pointer_traits<Ptr&> : pointer_traits<Ptr> { }; template <typename T> struct pointer_traits<T*> { - typedef T element_type; - typedef T* pointer; - typedef std::ptrdiff_t difference_type; + typedef T element_type; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED typedef T & reference; @@ -288,25 +296,25 @@ struct pointer_traits<T*> //! <b>Returns</b>: addressof(r) //! - BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) + BOOST_INTRUSIVE_FORCEINLINE static pointer pointer_to(reference r) BOOST_NOEXCEPT { return boost::intrusive::detail::addressof(r); } //! <b>Returns</b>: static_cast<pointer>(uptr) //! template<class U> - BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(U *uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer static_cast_from(U *uptr) BOOST_NOEXCEPT { return static_cast<pointer>(uptr); } //! <b>Returns</b>: const_cast<pointer>(uptr) //! template<class U> - BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(U *uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer const_cast_from(U *uptr) BOOST_NOEXCEPT { return const_cast<pointer>(uptr); } //! <b>Returns</b>: dynamic_cast<pointer>(uptr) //! template<class U> - BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(U *uptr) + BOOST_INTRUSIVE_FORCEINLINE static pointer dynamic_cast_from(U *uptr) BOOST_NOEXCEPT { return dynamic_cast<pointer>(uptr); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/rbtree.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/rbtree.hpp index 4f5d86dd6a..922fce51b0 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/rbtree.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/rbtree.hpp @@ -153,61 +153,61 @@ class rbtree_impl ~rbtree_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static rbtree_impl &container_from_end_iterator(iterator end_iterator); + static rbtree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator); + static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static rbtree_impl &container_from_iterator(iterator it); + static rbtree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const rbtree_impl &container_from_iterator(const_iterator it); + static const rbtree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -216,10 +216,10 @@ class rbtree_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::swap void swap(rbtree_impl& other); @@ -281,26 +281,26 @@ class rbtree_impl (const_iterator hint, const key_type &key, insert_commit_data &commit_data); //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator) template<class Iterator> void insert_unique(Iterator b, Iterator e); //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const key_type &key) size_type erase(const key_type &key); @@ -311,11 +311,11 @@ class rbtree_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) template<class Disposer> @@ -326,11 +326,11 @@ class rbtree_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::bstree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template<class Disposer> - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const size_type count(const key_type &key) const; @@ -416,28 +416,28 @@ class rbtree_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::merge_unique(bstree<T, Options2...>&) template<class T, class ...Options2> @@ -538,46 +538,46 @@ class rbtree //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value)); - rbtree() + BOOST_INTRUSIVE_FORCEINLINE rbtree() : Base() {} - explicit rbtree( const key_compare &cmp, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE explicit rbtree( const key_compare &cmp, const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} template<class Iterator> - rbtree( bool unique, Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE rbtree( bool unique, Iterator b, Iterator e , const key_compare &cmp = key_compare() , const value_traits &v_traits = value_traits()) : Base(unique, b, e, cmp, v_traits) {} - rbtree(BOOST_RV_REF(rbtree) x) + BOOST_INTRUSIVE_FORCEINLINE rbtree(BOOST_RV_REF(rbtree) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - rbtree& operator=(BOOST_RV_REF(rbtree) x) + BOOST_INTRUSIVE_FORCEINLINE rbtree& operator=(BOOST_RV_REF(rbtree) x) { return static_cast<rbtree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const rbtree &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const rbtree &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(rbtree) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(rbtree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static rbtree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static rbtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<rbtree &>(Base::container_from_end_iterator(end_iterator)); } - static const rbtree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const rbtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const rbtree &>(Base::container_from_end_iterator(end_iterator)); } - static rbtree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static rbtree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast<rbtree &>(Base::container_from_iterator(it)); } - static const rbtree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const rbtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast<const rbtree &>(Base::container_from_iterator(it)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/rbtree_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/rbtree_algorithms.hpp index 6a7c563cf0..4457dc64cb 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/rbtree_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/rbtree_algorithms.hpp @@ -54,7 +54,7 @@ struct rbtree_node_cloner : base_t(f) {} - node_ptr operator()(const node_ptr & p) + node_ptr operator()(node_ptr p) { node_ptr n = base_t::get()(p); NodeTraits::set_color(n, NodeTraits::get_color(p)); @@ -85,7 +85,7 @@ struct rbtree_node_checker : base_checker_t(comp, extra_checker) {} - void operator () (const const_node_ptr& p, + void operator () (const_node_ptr p, const return_type& check_return_left, const return_type& check_return_right, return_type& check_return) { @@ -190,22 +190,22 @@ class rbtree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const const_node_ptr & n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const const_node_ptr & header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const const_node_ptr & header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(const node_ptr & header1, const node_ptr & header2); + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&) - static void swap_nodes(const node_ptr & node1, const node_ptr & node2) + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -214,8 +214,8 @@ class rbtree_algorithms swap_nodes(node1, header1, node2, header2); } - //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&) - static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2) + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT { if(node1 == node2) return; @@ -226,23 +226,23 @@ class rbtree_algorithms NodeTraits::set_color(node2, c); } - //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&) - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node) + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT { if(node_to_be_replaced == new_node) return; replace_node(node_to_be_replaced, bstree_algo::get_header(node_to_be_replaced), new_node); } - //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&) - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node) + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::replace_node(node_to_be_replaced, header, new_node); NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced)); } - //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(const node_ptr&) - static void unlink(const node_ptr& node) + //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr) + static void unlink(node_ptr node) BOOST_NOEXCEPT { node_ptr x = NodeTraits::get_parent(node); if(x){ @@ -254,33 +254,33 @@ class rbtree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const const_node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const const_node_ptr & header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const_node_ptr) + static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const_node_ptr) + static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&) - static void init(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) + static void init(node_ptr node) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(const node_ptr&) - static void init_header(const node_ptr & header) + //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr) + static void init_header(node_ptr header) BOOST_NOEXCEPT { bstree_algo::init_header(header); NodeTraits::set_color(header, NodeTraits::red()); } - //! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&) - static node_ptr erase(const node_ptr & header, const node_ptr & z) + //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) + static node_ptr erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT { typename bstree_algo::data_for_rebalance info; bstree_algo::erase(header, z, info); @@ -291,7 +291,7 @@ class rbtree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique template<class NodePtrCompare> static bool transfer_unique - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) { typename bstree_algo::data_for_rebalance info; bool const transferred = bstree_algo::transfer_unique(header1, comp, header2, z, info); @@ -305,7 +305,7 @@ class rbtree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal template<class NodePtrCompare> static void transfer_equal - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) { typename bstree_algo::data_for_rebalance info; bstree_algo::transfer_equal(header1, comp, header2, z, info); @@ -313,129 +313,129 @@ class rbtree_algorithms rebalance_after_insertion(header1, z); } - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template <class Cloner, class Disposer> static void clone - (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer) + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) { rbtree_node_cloner<NodeTraits, Cloner> new_cloner(cloner); bstree_algo::clone(source_header, target_header, new_cloner, disposer); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const_node_ptr,Disposer) template<class Disposer> - static void clear_and_dispose(const node_ptr & header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> bounded_range - (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + (const_node_ptr eader, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed); - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> - static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare> static node_ptr insert_equal_upper_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr h, node_ptr new_node, NodePtrCompare comp) { bstree_algo::insert_equal_upper_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare> static node_ptr insert_equal_lower_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr h, node_ptr new_node, NodePtrCompare comp) { bstree_algo::insert_equal_lower_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare> static node_ptr insert_equal - (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp) { bstree_algo::insert_equal(header, hint, new_node, comp); rebalance_after_insertion(header, new_node); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr) static node_ptr insert_before - (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node) + (node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::insert_before(header, pos, new_node); rebalance_after_insertion(header, new_node); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&) - static void push_back(const node_ptr & header, const node_ptr & new_node) + //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) + static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_back(header, new_node); rebalance_after_insertion(header, new_node); } - //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&) - static void push_front(const node_ptr & header, const node_ptr & new_node) + //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr) + static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_front(header, new_node); rebalance_after_insertion(header, new_node); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const const_node_ptr & header, const KeyType &key + (const_node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data); - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const const_node_ptr & header, const node_ptr &hint, const KeyType &key + (const_node_ptr header, node_ptr hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data); #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data&) static void insert_unique_commit - (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data) + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { bstree_algo::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(header, new_value); } //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const const_node_ptr & p) + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT { return NodeTraits::get_color(p) == NodeTraits::red() && bstree_algo::is_header(p); @@ -445,7 +445,7 @@ class rbtree_algorithms private: static void rebalance_after_erasure - ( const node_ptr & header, const node_ptr &z, const typename bstree_algo::data_for_rebalance &info) + ( node_ptr header, node_ptr z, const typename bstree_algo::data_for_rebalance &info) BOOST_NOEXCEPT { color new_z_color; if(info.y != z){ @@ -461,7 +461,7 @@ class rbtree_algorithms } } - static void rebalance_after_erasure_restore_invariants(const node_ptr & header, node_ptr x, node_ptr x_parent) + static void rebalance_after_erasure_restore_invariants(node_ptr header, node_ptr x, node_ptr x_parent) BOOST_NOEXCEPT { while(1){ if(x_parent == header || (x && NodeTraits::get_color(x) != NodeTraits::black())){ @@ -545,7 +545,7 @@ class rbtree_algorithms NodeTraits::set_color(x, NodeTraits::black()); } - static void rebalance_after_insertion(const node_ptr & header, node_ptr p) + static void rebalance_after_insertion(node_ptr header, node_ptr p) BOOST_NOEXCEPT { NodeTraits::set_color(p, NodeTraits::red()); while(1){ diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/set.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/set.hpp index 3cd9013d4b..30f0760d2f 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/set.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/set.hpp @@ -120,61 +120,61 @@ class set_impl ~set_impl(); //! @copydoc ::boost::intrusive::rbtree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(iterator) - static set_impl &container_from_end_iterator(iterator end_iterator); + static set_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(const_iterator) - static const set_impl &container_from_end_iterator(const_iterator end_iterator); + static const set_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(iterator) - static set_impl &container_from_iterator(iterator it); + static set_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(const_iterator) - static const set_impl &container_from_iterator(const_iterator it); + static const set_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::key_comp()const key_compare key_comp() const; @@ -183,10 +183,10 @@ class set_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::rbtree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::swap void swap(set_impl& other); @@ -244,24 +244,24 @@ class set_impl { tree_type::insert_unique(b, e); } //! @copydoc ::boost::intrusive::rbtree::insert_unique_commit - iterator insert_commit(reference value, const insert_commit_data &commit_data) + iterator insert_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { return tree_type::insert_unique_commit(value, commit_data); } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::rbtree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &) size_type erase(const key_type &key); @@ -272,11 +272,11 @@ class set_impl //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer) template<class Disposer> @@ -287,11 +287,11 @@ class set_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::rbtree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::clear_and_dispose template<class Disposer> - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -391,28 +391,28 @@ class set_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::merge_unique template<class ...Options2> @@ -525,46 +525,46 @@ class set //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value)); - set() + BOOST_INTRUSIVE_FORCEINLINE set() : Base() {} - explicit set( const key_compare &cmp, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE explicit set( const key_compare &cmp, const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} template<class Iterator> - set( Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE set( Iterator b, Iterator e , const key_compare &cmp = key_compare() , const value_traits &v_traits = value_traits()) : Base(b, e, cmp, v_traits) {} - set(BOOST_RV_REF(set) x) + BOOST_INTRUSIVE_FORCEINLINE set(BOOST_RV_REF(set) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - set& operator=(BOOST_RV_REF(set) x) + BOOST_INTRUSIVE_FORCEINLINE set& operator=(BOOST_RV_REF(set) x) { return static_cast<set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const set &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const set &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(set) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(set) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static set &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<set &>(Base::container_from_end_iterator(end_iterator)); } - static const set &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const set &>(Base::container_from_end_iterator(end_iterator)); } - static set &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static set &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast<set &>(Base::container_from_iterator(it)); } - static const set &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast<const set &>(Base::container_from_iterator(it)); } }; @@ -657,61 +657,61 @@ class multiset_impl ~multiset_impl(); //! @copydoc ::boost::intrusive::rbtree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(iterator) - static multiset_impl &container_from_end_iterator(iterator end_iterator); + static multiset_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(const_iterator) - static const multiset_impl &container_from_end_iterator(const_iterator end_iterator); + static const multiset_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(iterator) - static multiset_impl &container_from_iterator(iterator it); + static multiset_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(const_iterator) - static const multiset_impl &container_from_iterator(const_iterator it); + static const multiset_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::key_comp()const key_compare key_comp() const; @@ -720,10 +720,10 @@ class multiset_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::rbtree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::swap void swap(multiset_impl& other); @@ -758,19 +758,19 @@ class multiset_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::rbtree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &) size_type erase(const key_type &key); @@ -781,11 +781,11 @@ class multiset_impl //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer) template<class Disposer> @@ -796,11 +796,11 @@ class multiset_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::rbtree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::clear_and_dispose template<class Disposer> - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::count(const key_type &)const size_type count(const key_type &key) const; @@ -886,28 +886,28 @@ class multiset_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::rbtree::merge_equal template<class ...Options2> @@ -1020,46 +1020,46 @@ class multiset //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value)); - multiset() + BOOST_INTRUSIVE_FORCEINLINE multiset() : Base() {} - explicit multiset( const key_compare &cmp, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE explicit multiset( const key_compare &cmp, const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} template<class Iterator> - multiset( Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE multiset( Iterator b, Iterator e , const key_compare &cmp = key_compare() , const value_traits &v_traits = value_traits()) : Base(b, e, cmp, v_traits) {} - multiset(BOOST_RV_REF(multiset) x) + BOOST_INTRUSIVE_FORCEINLINE multiset(BOOST_RV_REF(multiset) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - multiset& operator=(BOOST_RV_REF(multiset) x) + BOOST_INTRUSIVE_FORCEINLINE multiset& operator=(BOOST_RV_REF(multiset) x) { return static_cast<multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const multiset &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const multiset &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(multiset) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(multiset) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static multiset &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<multiset &>(Base::container_from_end_iterator(end_iterator)); } - static const multiset &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const multiset &>(Base::container_from_end_iterator(end_iterator)); } - static multiset &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast<multiset &>(Base::container_from_iterator(it)); } - static const multiset &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast<const multiset &>(Base::container_from_iterator(it)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/set_hook.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/set_hook.hpp index e303b6442b..fed331cced 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/set_hook.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/set_hook.hpp @@ -99,7 +99,7 @@ class set_base_hook //! initializes the node to an unlinked state. //! //! <b>Throws</b>: Nothing. - set_base_hook(); + set_base_hook() BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -110,7 +110,7 @@ class set_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - set_base_hook(const set_base_hook& ); + set_base_hook(const set_base_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: Empty function. The argument is ignored. //! @@ -120,7 +120,7 @@ class set_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - set_base_hook& operator=(const set_base_hook& ); + set_base_hook& operator=(const set_base_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -142,7 +142,7 @@ class set_base_hook //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - void swap_nodes(set_base_hook &other); + void swap_nodes(set_base_hook &other) BOOST_NOEXCEPT; //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink. //! @@ -151,13 +151,13 @@ class set_base_hook //! will return a valid iterator. //! //! <b>Complexity</b>: Constant - bool is_linked() const; + bool is_linked() const BOOST_NOEXCEPT; //! <b>Effects</b>: Removes the node if it's inserted in a container. //! This function is only allowed if link_mode is \c auto_unlink. //! //! <b>Throws</b>: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; @@ -226,7 +226,7 @@ class set_member_hook //! initializes the node to an unlinked state. //! //! <b>Throws</b>: Nothing. - set_member_hook(); + set_member_hook() BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -237,7 +237,7 @@ class set_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - set_member_hook(const set_member_hook& ); + set_member_hook(const set_member_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: Empty function. The argument is ignored. //! @@ -247,7 +247,7 @@ class set_member_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - set_member_hook& operator=(const set_member_hook& ); + set_member_hook& operator=(const set_member_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -269,7 +269,7 @@ class set_member_hook //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - void swap_nodes(set_member_hook &other); + void swap_nodes(set_member_hook &other) BOOST_NOEXCEPT; //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink. //! @@ -278,13 +278,13 @@ class set_member_hook //! will return a valid iterator. //! //! <b>Complexity</b>: Constant - bool is_linked() const; + bool is_linked() const BOOST_NOEXCEPT; //! <b>Effects</b>: Removes the node if it's inserted in a container. //! This function is only allowed if link_mode is \c auto_unlink. //! //! <b>Throws</b>: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/sgtree.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/sgtree.hpp index 033efb878d..9e687da10f 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/sgtree.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/sgtree.hpp @@ -39,7 +39,6 @@ #include <cstddef> #include <boost/intrusive/detail/minimal_less_equal_header.hpp> #include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair -#include <cmath> #include <cstddef> #if defined(BOOST_HAS_PRAGMA_ONCE) @@ -347,61 +346,61 @@ class sgtree_impl ~sgtree_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static sgtree_impl &container_from_end_iterator(iterator end_iterator); + static sgtree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const sgtree_impl &container_from_end_iterator(const_iterator end_iterator); + static const sgtree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static sgtree_impl &container_from_iterator(iterator it); + static sgtree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const sgtree_impl &container_from_iterator(const_iterator it); + static const sgtree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -410,10 +409,10 @@ class sgtree_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -447,8 +446,7 @@ class sgtree_impl iterator insert_equal(reference value) { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); std::size_t max_tree_size = (std::size_t)this->max_tree_size_; node_ptr p = node_algorithms::insert_equal_upper_bound (this->tree_type::header_ptr(), to_insert, this->key_node_comp(this->key_comp()) @@ -462,8 +460,7 @@ class sgtree_impl iterator insert_equal(const_iterator hint, reference value) { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); std::size_t max_tree_size = (std::size_t)this->max_tree_size_; node_ptr p = node_algorithms::insert_equal ( this->tree_type::header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp()) @@ -542,11 +539,10 @@ class sgtree_impl { return this->insert_unique_check(hint, key, this->key_comp(), commit_data); } //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); std::size_t max_tree_size = (std::size_t)this->max_tree_size_; node_algorithms::insert_unique_commit ( this->tree_type::header_ptr(), to_insert, commit_data @@ -572,11 +568,10 @@ class sgtree_impl } //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value) + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); std::size_t max_tree_size = (std::size_t)this->max_tree_size_; node_ptr p = node_algorithms::insert_before ( this->tree_type::header_ptr(), pos.pointed_node(), to_insert @@ -587,11 +582,10 @@ class sgtree_impl } //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); std::size_t max_tree_size = (std::size_t)this->max_tree_size_; node_algorithms::push_back ( this->tree_type::header_ptr(), to_insert @@ -601,11 +595,10 @@ class sgtree_impl } //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); std::size_t max_tree_size = (std::size_t)this->max_tree_size_; node_algorithms::push_front ( this->tree_type::header_ptr(), to_insert @@ -616,26 +609,25 @@ class sgtree_impl //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i) + iterator erase(const_iterator i) BOOST_NOEXCEPT { const_iterator ret(i); ++ret; node_ptr to_erase(i.pointed_node()); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase)); std::size_t max_tree_size = this->max_tree_size_; node_algorithms::erase ( this->tree_type::header_ptr(), to_erase, (std::size_t)this->size() , max_tree_size, this->get_alpha_by_max_size_func()); this->max_tree_size_ = (size_type)max_tree_size; this->tree_type::sz_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); return ret.unconst(); } //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e) + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT { size_type n; return private_erase(b, e, n); } //! @copydoc ::boost::intrusive::bstree::erase(const key_type &) @@ -656,7 +648,7 @@ class sgtree_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase(i.pointed_node()); iterator ret(this->erase(i)); @@ -666,13 +658,13 @@ class sgtree_impl #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template<class Disposer> - iterator erase_and_dispose(iterator i, Disposer disposer) + iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_and_dispose(const_iterator(i), disposer); } #endif //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT { size_type n; return private_erase(b, e, n, disposer); } //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) @@ -698,7 +690,7 @@ class sgtree_impl } //! @copydoc ::boost::intrusive::bstree::clear - void clear() + void clear() BOOST_NOEXCEPT { tree_type::clear(); this->max_tree_size_ = 0; @@ -706,7 +698,7 @@ class sgtree_impl //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template<class Disposer> - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { tree_type::clear_and_dispose(disposer); this->max_tree_size_ = 0; @@ -857,34 +849,34 @@ class sgtree_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rebalance - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rebalance_subtree - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT; friend bool operator< (const sgtree_impl &x, const sgtree_impl &y); @@ -907,7 +899,7 @@ class sgtree_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - float balance_factor() const + float balance_factor() const BOOST_NOEXCEPT { return this->get_alpha_traits().get_alpha(); } //! <b>Requires</b>: new_alpha must be a value between 0.5 and 1.0 @@ -918,7 +910,7 @@ class sgtree_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the elements in the subtree. - void balance_factor(float new_alpha) + void balance_factor(float new_alpha) BOOST_NOEXCEPT { //The alpha factor CAN't be changed if the fixed, floating operation-less //1/sqrt(2) alpha factor option is activated @@ -937,14 +929,14 @@ class sgtree_impl /// @cond private: template<class Disposer> - iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer) + iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer) BOOST_NOEXCEPT { for(n = 0; b != e; ++n) this->erase_and_dispose(b++, disposer); return b.unconst(); } - iterator private_erase(const_iterator b, const_iterator e, size_type &n) + iterator private_erase(const_iterator b, const_iterator e, size_type &n) BOOST_NOEXCEPT { for(n = 0; b != e; ++n) this->erase(b++); @@ -1028,46 +1020,46 @@ class sgtree //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value)); - sgtree() + BOOST_INTRUSIVE_FORCEINLINE sgtree() : Base() {} - explicit sgtree(const key_compare &cmp, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE explicit sgtree(const key_compare &cmp, const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} template<class Iterator> - sgtree( bool unique, Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE sgtree( bool unique, Iterator b, Iterator e , const key_compare &cmp = key_compare() , const value_traits &v_traits = value_traits()) : Base(unique, b, e, cmp, v_traits) {} - sgtree(BOOST_RV_REF(sgtree) x) + BOOST_INTRUSIVE_FORCEINLINE sgtree(BOOST_RV_REF(sgtree) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - sgtree& operator=(BOOST_RV_REF(sgtree) x) + BOOST_INTRUSIVE_FORCEINLINE sgtree& operator=(BOOST_RV_REF(sgtree) x) { return static_cast<sgtree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const sgtree &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const sgtree &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(sgtree) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(sgtree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static sgtree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static sgtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<sgtree &>(Base::container_from_end_iterator(end_iterator)); } - static const sgtree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const sgtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const sgtree &>(Base::container_from_end_iterator(end_iterator)); } - static sgtree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static sgtree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast<sgtree &>(Base::container_from_iterator(it)); } - static const sgtree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const sgtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast<const sgtree &>(Base::container_from_iterator(it)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/sgtree_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/sgtree_algorithms.hpp index e6002a73b0..27add031f2 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/sgtree_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/sgtree_algorithms.hpp @@ -65,8 +65,8 @@ class sgtree_algorithms public: typedef typename NodeTraits::node node; typedef NodeTraits node_traits; - typedef typename NodeTraits::node_ptr node_ptr; - typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; /// @cond private: @@ -85,63 +85,63 @@ class sgtree_algorithms }; #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const const_node_ptr & n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const const_node_ptr & header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const const_node_ptr & header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(const node_ptr & header1, const node_ptr & header2); + static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&) - static void swap_nodes(const node_ptr & node1, const node_ptr & node2); + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&) - static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2); + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&) - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node); + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&) - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node); + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT; //Unlink is not possible since tree metadata is needed to update the tree - //!static void unlink(const node_ptr & node); + //!static void unlink(node_ptr node) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const const_node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const const_node_ptr & header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr) + static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr) + static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&) - static void init(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) + static void init(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(const node_ptr&) - static void init_header(const node_ptr & header); + //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr) + static void init_header(node_ptr header) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) template<class AlphaByMaxSize> - static node_ptr erase(const node_ptr & header, const node_ptr & z, std::size_t tree_size, std::size_t &max_tree_size, AlphaByMaxSize alpha_by_maxsize) + static node_ptr erase(node_ptr header, node_ptr z, std::size_t tree_size, std::size_t &max_tree_size, AlphaByMaxSize alpha_by_maxsize) { bstree_algo::erase(header, z); --tree_size; if (tree_size > 0 && - tree_size < alpha_by_maxsize(max_tree_size)){ + tree_size < static_cast<std::size_t>(alpha_by_maxsize(max_tree_size))){ bstree_algo::rebalance(header); max_tree_size = tree_size; } @@ -149,51 +149,51 @@ class sgtree_algorithms } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template <class Cloner, class Disposer> static void clone - (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer); + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer); - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer) template<class Disposer> - static void clear_and_dispose(const node_ptr & header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> bounded_range - (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed); - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) template<class KeyType, class KeyNodePtrCompare> - static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp); #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare, class H_Alpha> static node_ptr insert_equal_upper_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp + (node_ptr h, node_ptr new_node, NodePtrCompare comp ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) { std::size_t depth; @@ -202,10 +202,10 @@ class sgtree_algorithms return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare, class H_Alpha> static node_ptr insert_equal_lower_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp + (node_ptr h, node_ptr new_node, NodePtrCompare comp ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) { std::size_t depth; @@ -214,10 +214,10 @@ class sgtree_algorithms return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare) template<class NodePtrCompare, class H_Alpha> static node_ptr insert_equal - (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) { std::size_t depth; @@ -226,10 +226,10 @@ class sgtree_algorithms return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr) template<class H_Alpha> static node_ptr insert_before - (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node + (node_ptr header, node_ptr pos, node_ptr new_node ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) { std::size_t depth; @@ -238,30 +238,30 @@ class sgtree_algorithms return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) template<class H_Alpha> - static void push_back(const node_ptr & header, const node_ptr & new_node - ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + static void push_back(node_ptr header, node_ptr new_node + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT { std::size_t depth; bstree_algo::push_back(header, new_node, &depth); rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size); } - //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr) template<class H_Alpha> - static void push_front(const node_ptr & header, const node_ptr & new_node - ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + static void push_front(node_ptr header, node_ptr new_node + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT { std::size_t depth; bstree_algo::push_front(header, new_node, &depth); rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const const_node_ptr & header, const KeyType &key + (const_node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { std::size_t depth; @@ -271,10 +271,10 @@ class sgtree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const const_node_ptr & header, const node_ptr &hint, const KeyType &key + (const_node_ptr header, node_ptr hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { std::size_t depth; @@ -285,18 +285,18 @@ class sgtree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data&) template<class H_Alpha> BOOST_INTRUSIVE_FORCEINLINE static void insert_unique_commit - (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) { return insert_commit(header, new_value, commit_data, tree_size, h_alpha, max_tree_size); } //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique template<class NodePtrCompare, class H_Alpha, class AlphaByMaxSize> static bool transfer_unique - ( const node_ptr & header1, NodePtrCompare comp, std::size_t tree1_size, std::size_t &max_tree1_size - , const node_ptr &header2, const node_ptr & z, std::size_t tree2_size, std::size_t &max_tree2_size + ( node_ptr header1, NodePtrCompare comp, std::size_t tree1_size, std::size_t &max_tree1_size + , node_ptr header2, node_ptr z, std::size_t tree2_size, std::size_t &max_tree2_size ,H_Alpha h_alpha, AlphaByMaxSize alpha_by_maxsize) { insert_commit_data commit_data; @@ -311,8 +311,8 @@ class sgtree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal template<class NodePtrCompare, class H_Alpha, class AlphaByMaxSize> static void transfer_equal - ( const node_ptr & header1, NodePtrCompare comp, std::size_t tree1_size, std::size_t &max_tree1_size - , const node_ptr &header2, const node_ptr & z, std::size_t tree2_size, std::size_t &max_tree2_size + ( node_ptr header1, NodePtrCompare comp, std::size_t tree1_size, std::size_t &max_tree1_size + , node_ptr header2, node_ptr z, std::size_t tree2_size, std::size_t &max_tree2_size ,H_Alpha h_alpha, AlphaByMaxSize alpha_by_maxsize) { insert_commit_data commit_data; @@ -323,13 +323,13 @@ class sgtree_algorithms #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const const_node_ptr & p); + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static void rebalance(const node_ptr & header); + static void rebalance(node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::rebalance_subtree - static node_ptr rebalance_subtree(const node_ptr & old_root) + static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED /// @cond @@ -337,7 +337,7 @@ class sgtree_algorithms template<class KeyType, class KeyNodePtrCompare> static void insert_equal_upper_bound_check - (const node_ptr & header, const KeyType &key + (node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { std::size_t depth; @@ -347,8 +347,8 @@ class sgtree_algorithms template<class H_Alpha> static void insert_commit - (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data - ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data + ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT { bstree_algo::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(new_value, commit_data.depth, tree_size+1, h_alpha, max_tree_size); @@ -356,8 +356,8 @@ class sgtree_algorithms template<class H_Alpha> static void rebalance_after_insertion - (const node_ptr &x, std::size_t depth - , std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) + (node_ptr x, std::size_t depth + , std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT { if(tree_size > max_tree_size) max_tree_size = tree_size; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/slist.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/slist.hpp index 1f7ace1842..ac64e413fa 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/slist.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/slist.hpp @@ -37,13 +37,13 @@ #include <boost/intrusive/detail/simple_disposers.hpp> #include <boost/intrusive/detail/size_holder.hpp> #include <boost/intrusive/detail/algorithm.hpp> +#include <boost/intrusive/detail/value_functors.hpp> +#include <boost/intrusive/detail/node_cloner_disposer.hpp> #include <boost/move/utility_core.hpp> #include <boost/static_assert.hpp> -#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//std::less #include <cstddef> //std::size_t -#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once @@ -172,56 +172,54 @@ class slist_impl //A list with cached last node is incompatible with auto-unlink hooks! BOOST_STATIC_ASSERT(!(cache_last && ((int)value_traits::link_mode == (int)auto_unlink))); - node_ptr get_end_node() - { return node_ptr(linear ? node_ptr() : this->get_root_node()); } + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_end_node() + { return node_algorithms::end_node(this->get_root_node()); } - const_node_ptr get_end_node() const - { - return const_node_ptr - (linear ? const_node_ptr() : this->get_root_node()); } + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_end_node() const + { return node_algorithms::end_node(this->get_root_node()); } - node_ptr get_root_node() + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_root_node() { return data_.root_plus_size_.header_holder_.get_node(); } - const_node_ptr get_root_node() const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_root_node() const { return data_.root_plus_size_.header_holder_.get_node(); } - node_ptr get_last_node() + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_last_node() { return this->get_last_node(detail::bool_<cache_last>()); } - const_node_ptr get_last_node() const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_last_node() const { return this->get_last_node(detail::bool_<cache_last>()); } - void set_last_node(const node_ptr &n) + BOOST_INTRUSIVE_FORCEINLINE void set_last_node(node_ptr n) { return this->set_last_node(n, detail::bool_<cache_last>()); } - static node_ptr get_last_node(detail::bool_<false>) + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_last_node(detail::bool_<false>) { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); return node_ptr(); } - static void set_last_node(const node_ptr &, detail::bool_<false>) + BOOST_INTRUSIVE_FORCEINLINE static void set_last_node(node_ptr , detail::bool_<false>) { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); } - node_ptr get_last_node(detail::bool_<true>) + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_last_node(detail::bool_<true>) { return node_ptr(data_.root_plus_size_.last_); } - const_node_ptr get_last_node(detail::bool_<true>) const + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_last_node(detail::bool_<true>) const { return const_node_ptr(data_.root_plus_size_.last_); } - void set_last_node(const node_ptr & n, detail::bool_<true>) + BOOST_INTRUSIVE_FORCEINLINE void set_last_node(node_ptr n, detail::bool_<true>) { data_.root_plus_size_.last_ = n; } void set_default_constructed_state() { node_algorithms::init_header(this->get_root_node()); this->priv_size_traits().set_size(size_type(0)); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(this->get_root_node()); } } @@ -233,7 +231,7 @@ class slist_impl {}; struct data_t - : public slist_impl::value_traits + : public value_traits { typedef typename slist_impl::value_traits value_traits; explicit data_t(const value_traits &val_traits) @@ -243,22 +241,22 @@ class slist_impl root_plus_size root_plus_size_; } data_; - size_traits &priv_size_traits() + BOOST_INTRUSIVE_FORCEINLINE size_traits &priv_size_traits() { return data_.root_plus_size_; } - const size_traits &priv_size_traits() const + BOOST_INTRUSIVE_FORCEINLINE const size_traits &priv_size_traits() const { return data_.root_plus_size_; } - const value_traits &priv_value_traits() const + BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const { return data_; } - value_traits &priv_value_traits() + BOOST_INTRUSIVE_FORCEINLINE value_traits &priv_value_traits() { return data_; } typedef typename boost::intrusive::value_traits_pointers <ValueTraits>::const_value_traits_ptr const_value_traits_ptr; - const_value_traits_ptr priv_value_traits_ptr() const + BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const { return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); } /// @endcond @@ -282,13 +280,13 @@ class slist_impl //! list. Iterators of this list and all the references are not invalidated. //! //! <b>Warning</b>: Experimental function, don't use it! - slist_impl( const node_ptr & f, const node_ptr & before_l + slist_impl( node_ptr f, node_ptr before_l , size_type n, const value_traits &v_traits = value_traits()) : data_(v_traits) { if(n){ this->priv_size_traits().set_size(n); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(before_l); } node_traits::set_next(this->get_root_node(), f); @@ -371,7 +369,7 @@ class slist_impl //! it's a safe-mode or auto-unlink value. Otherwise constant. ~slist_impl() { - if(is_safe_autounlink<ValueTraits::link_mode>::value){ + BOOST_IF_CONSTEXPR(is_safe_autounlink<ValueTraits::link_mode>::value){ this->clear(); node_algorithms::init(this->get_root_node()); } @@ -385,9 +383,9 @@ class slist_impl //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased elements. - void clear() + void clear() BOOST_NOEXCEPT { - if(safemode_or_autounlink){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ this->clear_and_dispose(detail::null_disposer()); } else{ @@ -406,16 +404,12 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators to the erased elements. template <class Disposer> - void clear_and_dispose(Disposer disposer) + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT { - const_iterator it(this->begin()), itend(this->end()); - while(it != itend){ - node_ptr to_erase(it.pointed_node()); - ++it; - if(safemode_or_autounlink) - node_algorithms::init(to_erase); - disposer(priv_value_traits().to_value_ptr(to_erase)); - } + node_algorithms::detach_and_dispose + ( this->get_root_node() + , detail::node_disposer<Disposer, value_traits, CommonSListAlgorithms> + (disposer, &this->priv_value_traits()) ); this->set_default_constructed_state(); } @@ -429,11 +423,11 @@ class slist_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - void push_front(reference value) + void push_front(reference value) BOOST_NOEXCEPT { node_ptr to_insert = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert)); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if(this->empty()){ this->set_last_node(to_insert); } @@ -453,13 +447,13 @@ class slist_impl //! //! <b>Note</b>: Does not affect the validity of iterators and references. //! This function is only available is cache_last<> is true. - void push_back(reference value) + void push_back(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((cache_last)); node_ptr n = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n)); node_algorithms::link_after(this->get_last_node(), n); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(n); } this->priv_size_traits().increment(); @@ -473,7 +467,7 @@ class slist_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element. - void pop_front() + void pop_front() BOOST_NOEXCEPT { return this->pop_front_and_dispose(detail::null_disposer()); } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. @@ -487,15 +481,15 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators to the erased element. template<class Disposer> - void pop_front_and_dispose(Disposer disposer) + void pop_front_and_dispose(Disposer disposer) BOOST_NOEXCEPT { node_ptr to_erase = node_traits::get_next(this->get_root_node()); node_algorithms::unlink_after(this->get_root_node()); this->priv_size_traits().decrement(); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if(this->empty()){ this->set_last_node(this->get_root_node()); } @@ -507,7 +501,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - reference front() + BOOST_INTRUSIVE_FORCEINLINE reference front() BOOST_NOEXCEPT { return *this->priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! <b>Effects</b>: Returns a const_reference to the first element of the list. @@ -515,7 +509,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_reference front() const + BOOST_INTRUSIVE_FORCEINLINE const_reference front() const BOOST_NOEXCEPT { return *this->priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } //! <b>Effects</b>: Returns a reference to the last element of the list. @@ -526,7 +520,7 @@ class slist_impl //! //! <b>Note</b>: Does not affect the validity of iterators and references. //! This function is only available is cache_last<> is true. - reference back() + reference back() BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((cache_last)); return *this->priv_value_traits().to_value_ptr(this->get_last_node()); @@ -540,7 +534,7 @@ class slist_impl //! //! <b>Note</b>: Does not affect the validity of iterators and references. //! This function is only available is cache_last<> is true. - const_reference back() const + BOOST_INTRUSIVE_FORCEINLINE const_reference back() const BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((cache_last)); return *this->priv_value_traits().to_value_ptr(this->get_last_node()); @@ -551,7 +545,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - iterator begin() + BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT { return iterator (node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. @@ -559,7 +553,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT { return const_iterator (node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. @@ -567,7 +561,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator cbegin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT { return const_iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns an iterator to the end of the list. @@ -575,7 +569,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - iterator end() + BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT { return iterator(this->get_end_node(), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a const_iterator to the end of the list. @@ -583,7 +577,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator end() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT { return const_iterator(detail::uncast(this->get_end_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a const_iterator to the end of the list. @@ -591,7 +585,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator cend() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT { return this->end(); } //! <b>Effects</b>: Returns an iterator that points to a position @@ -600,7 +594,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - iterator before_begin() + BOOST_INTRUSIVE_FORCEINLINE iterator before_begin() BOOST_NOEXCEPT { return iterator(this->get_root_node(), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns an iterator that points to a position @@ -609,7 +603,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator before_begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator before_begin() const BOOST_NOEXCEPT { return const_iterator(detail::uncast(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns an iterator that points to a position @@ -618,7 +612,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - const_iterator cbefore_begin() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator cbefore_begin() const BOOST_NOEXCEPT { return this->before_begin(); } //! <b>Effects</b>: Returns an iterator to the last element contained in the list. @@ -628,7 +622,7 @@ class slist_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: This function is present only if cached_last<> option is true. - iterator last() + BOOST_INTRUSIVE_FORCEINLINE iterator last() BOOST_NOEXCEPT { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); @@ -642,7 +636,7 @@ class slist_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: This function is present only if cached_last<> option is true. - const_iterator last() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator last() const BOOST_NOEXCEPT { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); @@ -656,7 +650,7 @@ class slist_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: This function is present only if cached_last<> option is true. - const_iterator clast() const + BOOST_INTRUSIVE_FORCEINLINE const_iterator clast() const BOOST_NOEXCEPT { return const_iterator(this->get_last_node(), this->priv_value_traits_ptr()); } //! <b>Precondition</b>: end_iterator must be a valid end iterator @@ -667,7 +661,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - static slist_impl &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static slist_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return slist_impl::priv_container_from_end_iterator(end_iterator); } //! <b>Precondition</b>: end_iterator must be a valid end const_iterator @@ -678,7 +672,7 @@ class slist_impl //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Constant. - static const slist_impl &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const slist_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return slist_impl::priv_container_from_end_iterator(end_iterator); } //! <b>Effects</b>: Returns the number of the elements contained in the list. @@ -689,9 +683,9 @@ class slist_impl //! if constant_time_size is false. Constant time otherwise. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - size_type size() const + BOOST_INTRUSIVE_FORCEINLINE size_type size() const BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) return this->priv_size_traits().get_size(); else return node_algorithms::count(this->get_root_node()) - 1; @@ -704,8 +698,8 @@ class slist_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - bool empty() const - { return node_algorithms::unique(this->get_root_node()); } + BOOST_INTRUSIVE_FORCEINLINE bool empty() const BOOST_NOEXCEPT + { return node_algorithms::is_empty(this->get_root_node()); } //! <b>Effects</b>: Swaps the elements of x and *this. //! @@ -717,7 +711,7 @@ class slist_impl //! <b>Note</b>: Does not affect the validity of iterators and references. void swap(slist_impl& other) { - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ priv_swap_cache_last(this, &other); } else{ @@ -735,7 +729,7 @@ class slist_impl //! <b>Complexity</b>: Linear to the number of elements plus the number shifts. //! //! <b>Note</b>: Iterators Does not affect the validity of iterators and references. - void shift_backwards(size_type n = 1) + void shift_backwards(size_type n = 1) BOOST_NOEXCEPT { this->priv_shift_backwards(n, detail::bool_<linear>()); } //! <b>Effects</b>: Moves forward all the elements, so that the second @@ -747,7 +741,7 @@ class slist_impl //! <b>Complexity</b>: Linear to the number of elements plus the number shifts. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - void shift_forward(size_type n = 1) + void shift_forward(size_type n = 1) BOOST_NOEXCEPT { this->priv_shift_forward(n, detail::bool_<linear>()); } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. @@ -819,7 +813,7 @@ class slist_impl //! <b>Complexity</b>: Constant. //! //! <b>Note</b>: Does not affect the validity of iterators and references. - iterator insert_after(const_iterator prev_p, reference value) + iterator insert_after(const_iterator prev_p, reference value) BOOST_NOEXCEPT { node_ptr n = priv_value_traits().to_node_ptr(value); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n)); @@ -845,7 +839,7 @@ class slist_impl //! //! <b>Note</b>: Does not affect the validity of iterators and references. template<class Iterator> - void insert_after(const_iterator prev_p, Iterator f, Iterator l) + void insert_after(const_iterator prev_p, Iterator f, Iterator l) BOOST_NOEXCEPT { //Insert first nodes avoiding cache and size checks size_type count = 0; @@ -860,7 +854,7 @@ class slist_impl if(cache_last && (this->get_last_node() == prev_p.pointed_node())){ this->set_last_node(prev_n); } - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().increase(count); } } @@ -877,7 +871,7 @@ class slist_impl //! Constant-time if cache_last<> is true and p == end(). //! //! <b>Note</b>: Does not affect the validity of iterators and references. - iterator insert(const_iterator p, reference value) + iterator insert(const_iterator p, reference value) BOOST_NOEXCEPT { return this->insert_after(this->previous(p), value); } //! <b>Requires</b>: Dereferencing iterator must yield @@ -895,7 +889,7 @@ class slist_impl //! //! <b>Note</b>: Does not affect the validity of iterators and references. template<class Iterator> - void insert(const_iterator p, Iterator b, Iterator e) + void insert(const_iterator p, Iterator b, Iterator e) BOOST_NOEXCEPT { return this->insert_after(this->previous(p), b, e); } //! <b>Effects</b>: Erases the element after the element pointed by prev of @@ -910,7 +904,7 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase_after(const_iterator prev) + iterator erase_after(const_iterator prev) BOOST_NOEXCEPT { return this->erase_after_and_dispose(prev, detail::null_disposer()); } //! <b>Effects</b>: Erases the range (before_f, l) from @@ -926,15 +920,15 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase_after(const_iterator before_f, const_iterator l) + iterator erase_after(const_iterator before_f, const_iterator l) BOOST_NOEXCEPT { - if(safemode_or_autounlink || constant_time_size){ + BOOST_IF_CONSTEXPR(safemode_or_autounlink || constant_time_size){ return this->erase_after_and_dispose(before_f, l, detail::null_disposer()); } else{ const node_ptr bfp = before_f.pointed_node(); const node_ptr lp = l.pointed_node(); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if(lp == this->get_end_node()){ this->set_last_node(bfp); } @@ -958,22 +952,23 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase_after(const_iterator before_f, const_iterator l, size_type n) + iterator erase_after(const_iterator before_f, const_iterator l, size_type n) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance((++const_iterator(before_f)).pointed_node(), l.pointed_node()) == n); - if(safemode_or_autounlink){ + (void)n; + BOOST_IF_CONSTEXPR(safemode_or_autounlink){ return this->erase_after(before_f, l); } else{ const node_ptr bfp = before_f.pointed_node(); const node_ptr lp = l.pointed_node(); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if((lp == this->get_end_node())){ this->set_last_node(bfp); } } node_algorithms::unlink_after(bfp, lp); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().decrease(n); } return l.unconst(); @@ -992,7 +987,7 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase(const_iterator i) + iterator erase(const_iterator i) BOOST_NOEXCEPT { return this->erase_after(this->previous(i)); } //! <b>Requires</b>: f and l must be valid iterator to elements in *this. @@ -1009,7 +1004,7 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased elements. - iterator erase(const_iterator f, const_iterator l) + iterator erase(const_iterator f, const_iterator l) BOOST_NOEXCEPT { return this->erase_after(this->previous(f), l); } //! <b>Effects</b>: Erases the range [f, l) from @@ -1026,7 +1021,7 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased element. - iterator erase(const_iterator f, const_iterator l, size_type n) + iterator erase(const_iterator f, const_iterator l, size_type n) BOOST_NOEXCEPT { return this->erase_after(this->previous(f), l, n); } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. @@ -1044,7 +1039,7 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators to the erased element. template<class Disposer> - iterator erase_after_and_dispose(const_iterator prev, Disposer disposer) + iterator erase_after_and_dispose(const_iterator prev, Disposer disposer) BOOST_NOEXCEPT { const_iterator it(prev); ++it; @@ -1055,7 +1050,7 @@ class slist_impl if(cache_last && (to_erase == this->get_last_node())){ this->set_last_node(prev_n); } - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); @@ -1064,7 +1059,7 @@ class slist_impl /// @cond - static iterator s_insert_after(const_iterator const prev_p, reference value) + static iterator s_insert_after(const_iterator const prev_p, reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits))); node_ptr const n = value_traits::to_node_ptr(value); @@ -1074,7 +1069,7 @@ class slist_impl } template<class Disposer> - static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer) + static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits))); const_iterator it(prev); @@ -1083,14 +1078,14 @@ class slist_impl ++it; node_ptr prev_n(prev.pointed_node()); node_algorithms::unlink_after(prev_n); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(value_traits::to_value_ptr(to_erase)); return it.unconst(); } template<class Disposer> - static iterator s_erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer) + static iterator s_erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits))); node_ptr bfp(before_f.pointed_node()), lp(l.pointed_node()); @@ -1099,14 +1094,14 @@ class slist_impl while(fp != lp){ node_ptr to_erase(fp); fp = node_traits::get_next(fp); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(value_traits::to_value_ptr(to_erase)); } return l.unconst(); } - static iterator s_erase_after(const_iterator prev) + static iterator s_erase_after(const_iterator prev) BOOST_NOEXCEPT { return s_erase_after_and_dispose(prev, detail::null_disposer()); } /// @endcond @@ -1126,7 +1121,7 @@ class slist_impl //! //! <b>Note</b>: Invalidates the iterators to the erased element. template<class Disposer> - iterator erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer) + iterator erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer) BOOST_NOEXCEPT { node_ptr bfp(before_f.pointed_node()), lp(l.pointed_node()); node_ptr fp(node_traits::get_next(bfp)); @@ -1134,7 +1129,7 @@ class slist_impl while(fp != lp){ node_ptr to_erase(fp); fp = node_traits::get_next(fp); - if(safemode_or_autounlink) + BOOST_IF_CONSTEXPR(safemode_or_autounlink) node_algorithms::init(to_erase); disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); @@ -1161,12 +1156,12 @@ class slist_impl //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased element. template<class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer) + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_after_and_dispose(this->previous(i), disposer); } #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template<class Disposer> - iterator erase_and_dispose(iterator i, Disposer disposer) + iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT { return this->erase_and_dispose(const_iterator(i), disposer); } #endif @@ -1188,7 +1183,7 @@ class slist_impl //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased elements. template<class Disposer> - iterator erase_and_dispose(const_iterator f, const_iterator l, Disposer disposer) + iterator erase_and_dispose(const_iterator f, const_iterator l, Disposer disposer) BOOST_NOEXCEPT { return this->erase_after_and_dispose(this->previous(f), l, disposer); } //! <b>Requires</b>: Dereferencing iterator must yield @@ -1257,7 +1252,7 @@ class slist_impl //! assigned to the last spliced element or prev if x is empty. //! This iterator can be used as new "prev" iterator for a new splice_after call. //! that will splice new values after the previously spliced values. - void splice_after(const_iterator prev, slist_impl &x, const_iterator *l = 0) + void splice_after(const_iterator prev, slist_impl &x, const_iterator *l = 0) BOOST_NOEXCEPT { if(x.empty()){ if(l) *l = prev; @@ -1270,7 +1265,7 @@ class slist_impl const_iterator last_x(x.previous(x.end())); //constant time if cache_last is active node_ptr prev_n(prev.pointed_node()); node_ptr last_x_n(last_x.pointed_node()); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ x.set_last_node(x.get_root_node()); if(node_traits::get_next(prev_n) == this->get_end_node()){ this->set_last_node(last_x_n); @@ -1296,7 +1291,7 @@ class slist_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator prev_ele) + void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator prev_ele) BOOST_NOEXCEPT { const_iterator elem = prev_ele; this->splice_after(prev_pos, x, prev_ele, ++elem, 1); @@ -1317,9 +1312,9 @@ class slist_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l) + void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l) BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) this->splice_after(prev_pos, x, before_f, before_l, node_algorithms::distance(before_f.pointed_node(), before_l.pointed_node())); else this->priv_splice_after @@ -1340,12 +1335,13 @@ class slist_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l, size_type n) + void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l, size_type n) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance(before_f.pointed_node(), before_l.pointed_node()) == n); + (void)n; this->priv_splice_after (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node()); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().increase(n); x.priv_size_traits().decrease(n); } @@ -1372,7 +1368,7 @@ class slist_impl //! assigned to the last spliced element or prev if x is empty. //! This iterator can be used as new "prev" iterator for a new splice_after call. //! that will splice new values after the previously spliced values. - void splice(const_iterator it, slist_impl &x, const_iterator *l = 0) + void splice(const_iterator it, slist_impl &x, const_iterator *l = 0) BOOST_NOEXCEPT { this->splice_after(this->previous(it), x, l); } //! <b>Requires</b>: it p must be a valid iterator of *this. @@ -1389,7 +1385,7 @@ class slist_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator pos, slist_impl &x, const_iterator elem) + void splice(const_iterator pos, slist_impl &x, const_iterator elem) BOOST_NOEXCEPT { return this->splice_after(this->previous(pos), x, x.previous(elem)); } //! <b>Requires</b>: pos must be a dereferenceable iterator in *this @@ -1409,7 +1405,7 @@ class slist_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l) + void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l) BOOST_NOEXCEPT { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l)); } //! <b>Requires</b>: pos must be a dereferenceable iterator in *this @@ -1428,10 +1424,10 @@ class slist_impl //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l, size_type n) + void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l, size_type n) BOOST_NOEXCEPT { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l), n); } - //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. + //! <b>Effects</b>: This function sorts the list *this according to operator<. //! The sort is stable, that is, the relative order of equivalent elements is preserved. //! //! <b>Throws</b>: If value_traits::node_traits::node @@ -1463,7 +1459,7 @@ class slist_impl BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty()); const_iterator last_element(carry.previous(last_inserted, carry.end())); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ counter[i].splice_after( counter[i].cbefore_begin(), carry , carry.cbefore_begin(), last_element , carry.size()); @@ -1480,7 +1476,7 @@ class slist_impl counter[i].merge(counter[i-1], p, &last_inserted); --fill; const_iterator last_element(counter[fill].previous(last_inserted, counter[fill].end())); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin() , last_element, counter[fill].size()); } @@ -1501,14 +1497,14 @@ class slist_impl //! //! <b>Throws</b>: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or std::less<value_type> throws. Basic guarantee. + //! or operator< throws. Basic guarantee. //! //! <b>Complexity</b>: This function is linear time: it performs at most //! size() + x.size() - 1 comparisons. //! //! <b>Note</b>: Iterators and references are not invalidated. void sort() - { this->sort(std::less<value_type>()); } + { this->sort(value_less<value_type>()); } //! <b>Requires</b>: p must be a comparison function that induces a strict weak //! ordering and both *this and x must be sorted according to that ordering @@ -1557,18 +1553,18 @@ class slist_impl } //! <b>Effects</b>: This function removes all of x's elements and inserts them - //! in order into *this according to std::less<value_type>. The merge is stable; + //! in order into *this according to operator<. The merge is stable; //! that is, if an element from *this is equivalent to one from x, then the element //! from *this will precede the one from x. //! - //! <b>Throws</b>: if std::less<value_type> throws. Basic guarantee. + //! <b>Throws</b>: if operator< throws. Basic guarantee. //! //! <b>Complexity</b>: This function is linear time: it performs at most //! size() + x.size() - 1 comparisons. //! //! <b>Note</b>: Iterators and references are not invalidated void merge(slist_impl& x) - { this->merge(x, std::less<value_type>()); } + { this->merge(x, value_less<value_type>()); } //! <b>Effects</b>: Reverses the order of elements in the list. //! @@ -1577,7 +1573,7 @@ class slist_impl //! <b>Complexity</b>: This function is linear to the contained elements. //! //! <b>Note</b>: Iterators and references are not invalidated - void reverse() + void reverse() BOOST_NOEXCEPT { if(cache_last && !this->empty()){ this->set_last_node(node_traits::get_next(this->get_root_node())); @@ -1588,14 +1584,14 @@ class slist_impl //! <b>Effects</b>: Removes all the elements that compare equal to value. //! No destructors are called. //! - //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. + //! <b>Throws</b>: If operator== throws. Basic guarantee. //! //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. //! //! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. This function is //! linear time: it performs exactly size() comparisons for equality. - void remove(const_reference value) + void remove(const_reference value) BOOST_NOEXCEPT { this->remove_if(detail::equal_to_value<const_reference>(value)); } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. @@ -1603,14 +1599,14 @@ class slist_impl //! <b>Effects</b>: Removes all the elements that compare equal to value. //! Disposer::operator()(pointer) is called for every removed element. //! - //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. + //! <b>Throws</b>: If operator== throws. Basic guarantee. //! //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality. //! //! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. template<class Disposer> - void remove_and_dispose(const_reference value, Disposer disposer) + void remove_and_dispose(const_reference value, Disposer disposer) BOOST_NOEXCEPT { this->remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); } //! <b>Effects</b>: Removes all the elements for which a specified @@ -1630,7 +1626,7 @@ class slist_impl node_algorithms::stable_partition (bbeg, this->get_end_node(), detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info); //After cache last is set, slist invariants are preserved... - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(info.new_last_node); } //...so erase can be safely called @@ -1659,7 +1655,7 @@ class slist_impl node_algorithms::stable_partition (bbeg, this->get_end_node(), detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info); //After cache last is set, slist invariants are preserved... - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(info.new_last_node); } //...so erase can be safely called @@ -1671,14 +1667,14 @@ class slist_impl //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! elements that are equal from the list. No destructors are called. //! - //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. + //! <b>Throws</b>: If operator== throws. Basic guarantee. //! //! <b>Complexity</b>: Linear time (size()-1) comparisons calls to pred()). //! //! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! and iterators to elements that are not removed remain valid. void unique() - { this->unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); } + { this->unique_and_dispose(value_equal<value_type>(), detail::null_disposer()); } //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! elements that satisfy some binary predicate from the list. @@ -1700,7 +1696,7 @@ class slist_impl //! elements that satisfy some binary predicate from the list. //! Disposer::operator()(pointer) is called for every removed element. //! - //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. + //! <b>Throws</b>: If operator== throws. Basic guarantee. //! //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons. //! @@ -1708,7 +1704,7 @@ class slist_impl //! and iterators to elements that are not removed remain valid. template<class Disposer> void unique_and_dispose(Disposer disposer) - { this->unique(std::equal_to<value_type>(), disposer); } + { this->unique(value_equal<value_type>(), disposer); } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. //! @@ -1739,7 +1735,7 @@ class slist_impl ++cur; } } - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(bcur.pointed_node()); } } @@ -1756,7 +1752,7 @@ class slist_impl //! <b>Note</b>: Iterators and references are not invalidated. //! This static function is available only if the <i>value traits</i> //! is stateless. - static iterator s_iterator_to(reference value) + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr()); @@ -1773,7 +1769,7 @@ class slist_impl //! <b>Note</b>: Iterators and references are not invalidated. //! This static function is available only if the <i>value traits</i> //! is stateless. - static const_iterator s_iterator_to(const_reference value) + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT((!stateful_value_traits)); reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value)); @@ -1789,7 +1785,7 @@ class slist_impl //! <b>Complexity</b>: Constant time. //! //! <b>Note</b>: Iterators and references are not invalidated. - iterator iterator_to(reference value) + iterator iterator_to(reference value) BOOST_NOEXCEPT { BOOST_INTRUSIVE_INVARIANT_ASSERT(linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(value))); return iterator (this->priv_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); @@ -1804,7 +1800,7 @@ class slist_impl //! <b>Complexity</b>: Constant time. //! //! <b>Note</b>: Iterators and references are not invalidated. - const_iterator iterator_to(const_reference value) const + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT { reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value)); BOOST_INTRUSIVE_INVARIANT_ASSERT (linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(r))); @@ -1819,7 +1815,7 @@ class slist_impl //! //! <b>Complexity</b>: Linear to the number of elements before i. //! Constant if cache_last<> is true and i == end(). - iterator previous(iterator i) + iterator previous(iterator i) BOOST_NOEXCEPT { return this->previous(this->cbefore_begin(), i); } //! <b>Returns</b>: The const_iterator to the element before i in the list. @@ -1830,7 +1826,7 @@ class slist_impl //! //! <b>Complexity</b>: Linear to the number of elements before i. //! Constant if cache_last<> is true and i == end(). - const_iterator previous(const_iterator i) const + const_iterator previous(const_iterator i) const BOOST_NOEXCEPT { return this->previous(this->cbefore_begin(), i); } //! <b>Returns</b>: The iterator to the element before i in the list, @@ -1842,7 +1838,7 @@ class slist_impl //! //! <b>Complexity</b>: Linear to the number of elements before i. //! Constant if cache_last<> is true and i == end(). - iterator previous(const_iterator prev_from, iterator i) + iterator previous(const_iterator prev_from, iterator i) BOOST_NOEXCEPT { return this->previous(prev_from, const_iterator(i)).unconst(); } //! <b>Returns</b>: The const_iterator to the element before i in the list, @@ -1854,7 +1850,7 @@ class slist_impl //! //! <b>Complexity</b>: Linear to the number of elements before i. //! Constant if cache_last<> is true and i == end(). - const_iterator previous(const_iterator prev_from, const_iterator i) const + const_iterator previous(const_iterator prev_from, const_iterator i) const BOOST_NOEXCEPT { if(cache_last && (i.pointed_node() == this->get_end_node())){ return const_iterator(detail::uncast(this->get_last_node()), this->priv_value_traits_ptr()); @@ -1882,9 +1878,9 @@ class slist_impl //! point to elements of this list. Iterators of this list and all the references are not invalidated. //! //! <b>Warning</b>: Experimental function, don't use it! - void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l) + void incorporate_after(const_iterator prev_pos, node_ptr f, node_ptr before_l) BOOST_NOEXCEPT { - if(constant_time_size) + BOOST_IF_CONSTEXPR(constant_time_size) this->incorporate_after(prev_pos, f, before_l, node_algorithms::distance(f.pointed_node(), before_l.pointed_node())+1); else this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); @@ -1906,7 +1902,7 @@ class slist_impl //! point to elements of this list. Iterators of this list and all the references are not invalidated. //! //! <b>Warning</b>: Experimental function, don't use it! - void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l, size_type n) + void incorporate_after(const_iterator prev_pos, node_ptr f, node_ptr before_l, size_type n) BOOST_NOEXCEPT { if(n){ BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0); @@ -1916,7 +1912,7 @@ class slist_impl , iterator(before_l, this->priv_value_traits_ptr()))) +1 == n); this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); - if(constant_time_size){ + BOOST_IF_CONSTEXPR(constant_time_size){ this->priv_size_traits().increase(n); } } @@ -1937,8 +1933,7 @@ class slist_impl BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_next(header_ptr)); if (node_traits::get_next(header_ptr) == header_ptr) { - if (constant_time_size) - BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == 0); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!constant_time_size || this->priv_size_traits().get_size() == 0); return; } size_t node_count = 0; @@ -1946,7 +1941,7 @@ class slist_impl while (true) { const_node_ptr next_p = node_traits::get_next(p); - if (!linear) + BOOST_IF_CONSTEXPR(!linear) { BOOST_INTRUSIVE_INVARIANT_ASSERT(next_p); } @@ -1956,15 +1951,13 @@ class slist_impl } if ((!linear && next_p == header_ptr) || (linear && !next_p)) { - if (cache_last) - BOOST_INTRUSIVE_INVARIANT_ASSERT(get_last_node() == p); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!cache_last || get_last_node() == p); break; } p = next_p; ++node_count; } - if (constant_time_size) - BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!constant_time_size || this->priv_size_traits().get_size() == node_count); } @@ -1995,7 +1988,7 @@ class slist_impl { x.swap(y); } private: - void priv_splice_after(const node_ptr & prev_pos_n, slist_impl &x, const node_ptr & before_f_n, const node_ptr & before_l_n) + void priv_splice_after(node_ptr prev_pos_n, slist_impl &x, node_ptr before_f_n, node_ptr before_l_n) { if (cache_last && (before_f_n != before_l_n)){ if(prev_pos_n == this->get_last_node()){ @@ -2008,9 +2001,9 @@ class slist_impl node_algorithms::transfer_after(prev_pos_n, before_f_n, before_l_n); } - void priv_incorporate_after(const node_ptr & prev_pos_n, const node_ptr & first_n, const node_ptr & before_l_n) + void priv_incorporate_after(node_ptr prev_pos_n, node_ptr first_n, node_ptr before_l_n) { - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ if(prev_pos_n == this->get_last_node()){ this->set_last_node(before_l_n); } @@ -2038,12 +2031,12 @@ class slist_impl void priv_shift_backwards(size_type n, detail::bool_<true>) { - std::pair<node_ptr, node_ptr> ret( + typename node_algorithms::node_pair ret( node_algorithms::move_first_n_forward (node_traits::get_next(this->get_root_node()), (std::size_t)n)); if(ret.first){ node_traits::set_next(this->get_root_node(), ret.first); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(ret.second); } } @@ -2059,12 +2052,12 @@ class slist_impl void priv_shift_forward(size_type n, detail::bool_<true>) { - std::pair<node_ptr, node_ptr> ret( + typename node_algorithms::node_pair ret( node_algorithms::move_first_n_backwards (node_traits::get_next(this->get_root_node()), (std::size_t)n)); if(ret.first){ node_traits::set_next(this->get_root_node(), ret.first); - if(cache_last){ + BOOST_IF_CONSTEXPR(cache_last){ this->set_last_node(ret.second); } } @@ -2108,11 +2101,11 @@ class slist_impl } //circular version - static void priv_swap_lists(const node_ptr & this_node, const node_ptr & other_node, detail::bool_<false>) + static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_<false>) { node_algorithms::swap_nodes(this_node, other_node); } //linear version - static void priv_swap_lists(const node_ptr & this_node, const node_ptr & other_node, detail::bool_<true>) + static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_<true>) { node_algorithms::swap_trailing_nodes(this_node, other_node); } static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) @@ -2202,45 +2195,45 @@ class slist typedef typename Base::size_type size_type; typedef typename Base::node_ptr node_ptr; - slist() + BOOST_INTRUSIVE_FORCEINLINE slist() : Base() {} - explicit slist(const value_traits &v_traits) + BOOST_INTRUSIVE_FORCEINLINE explicit slist(const value_traits &v_traits) : Base(v_traits) {} struct incorporate_t{}; - slist( const node_ptr & f, const node_ptr & before_l + BOOST_INTRUSIVE_FORCEINLINE slist( node_ptr f, node_ptr before_l , size_type n, const value_traits &v_traits = value_traits()) : Base(f, before_l, n, v_traits) {} template<class Iterator> - slist(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE slist(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) : Base(b, e, v_traits) {} - slist(BOOST_RV_REF(slist) x) + BOOST_INTRUSIVE_FORCEINLINE slist(BOOST_RV_REF(slist) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - slist& operator=(BOOST_RV_REF(slist) x) + BOOST_INTRUSIVE_FORCEINLINE slist& operator=(BOOST_RV_REF(slist) x) { return static_cast<slist &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const slist &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const slist &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(slist) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(slist) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static slist &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static slist &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); } - static const slist &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const slist &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const slist &>(Base::container_from_end_iterator(end_iterator)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/slist_hook.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/slist_hook.hpp index 0f37772c6d..380818cf20 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/slist_hook.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/slist_hook.hpp @@ -97,7 +97,7 @@ class slist_base_hook //! initializes the node to an unlinked state. //! //! <b>Throws</b>: Nothing. - slist_base_hook(); + slist_base_hook() BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link //! initializes the node to an unlinked state. The argument is ignored. @@ -108,7 +108,7 @@ class slist_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - slist_base_hook(const slist_base_hook& ); + slist_base_hook(const slist_base_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: Empty function. The argument is ignored. //! @@ -118,7 +118,7 @@ class slist_base_hook //! makes classes using the hook STL-compliant without forcing the //! user to do some additional work. \c swap can be used to emulate //! move-semantics. - slist_base_hook& operator=(const slist_base_hook& ); + slist_base_hook& operator=(const slist_base_hook& ) BOOST_NOEXCEPT; //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does //! nothing (ie. no code is generated). If link_mode is \c safe_link and the @@ -140,7 +140,7 @@ class slist_base_hook //! <b>Complexity</b>: Constant //! //! <b>Throws</b>: Nothing. - void swap_nodes(slist_base_hook &other); + void swap_nodes(slist_base_hook &other) BOOST_NOEXCEPT; //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink. //! @@ -148,14 +148,16 @@ class slist_base_hook //! otherwise. This function can be used to test whether \c slist::iterator_to //! will return a valid iterator. //! + //! <b>Throws</b>: Nothing. + //! //! <b>Complexity</b>: Constant - bool is_linked() const; + bool is_linked() const BOOST_NOEXCEPT; //! <b>Effects</b>: Removes the node if it's inserted in a container. //! This function is only allowed if link_mode is \c auto_unlink. //! //! <b>Throws</b>: Nothing. - void unlink(); + void unlink() BOOST_NOEXCEPT; #endif }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/splaytree.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/splaytree.hpp index f6a1a93a9d..44e5c78670 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/splaytree.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/splaytree.hpp @@ -148,61 +148,61 @@ class splaytree_impl ~splaytree_impl(); //! @copydoc ::boost::intrusive::bstree::begin() - iterator begin(); + iterator begin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::begin()const - const_iterator begin() const; + const_iterator begin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cbegin()const - const_iterator cbegin() const; + const_iterator cbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end() - iterator end(); + iterator end() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::end()const - const_iterator end() const; + const_iterator end() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::cend()const - const_iterator cend() const; + const_iterator cend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin() - reverse_iterator rbegin(); + reverse_iterator rbegin() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rbegin()const - const_reverse_iterator rbegin() const; + const_reverse_iterator rbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crbegin()const - const_reverse_iterator crbegin() const; + const_reverse_iterator crbegin() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend() - reverse_iterator rend(); + reverse_iterator rend() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rend()const - const_reverse_iterator rend() const; + const_reverse_iterator rend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::crend()const - const_reverse_iterator crend() const; + const_reverse_iterator crend() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root() - iterator root(); + iterator root() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::root()const - const_iterator root() const; + const_iterator root() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::croot()const - const_iterator croot() const; + const_iterator croot() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) - static splaytree_impl &container_from_end_iterator(iterator end_iterator); + static splaytree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) - static const splaytree_impl &container_from_end_iterator(const_iterator end_iterator); + static const splaytree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) - static splaytree_impl &container_from_iterator(iterator it); + static splaytree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) - static const splaytree_impl &container_from_iterator(const_iterator it); + static const splaytree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::key_comp()const key_compare key_comp() const; @@ -211,10 +211,10 @@ class splaytree_impl value_compare value_comp() const; //! @copydoc ::boost::intrusive::bstree::empty()const - bool empty() const; + bool empty() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::size()const - size_type size() const; + size_type size() const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::swap void swap(splaytree_impl& other); @@ -273,26 +273,26 @@ class splaytree_impl ,KeyTypeKeyCompare comp, insert_commit_data &commit_data); //! @copydoc ::boost::intrusive::bstree::insert_unique_commit - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator) template<class Iterator> void insert_unique(Iterator b, Iterator e); //! @copydoc ::boost::intrusive::bstree::insert_before - iterator insert_before(const_iterator pos, reference value); + iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_back - void push_back(reference value); + void push_back(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::push_front - void push_front(reference value); + void push_front(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) - iterator erase(const_iterator i); + iterator erase(const_iterator i) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) - iterator erase(const_iterator b, const_iterator e); + iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase(const key_type &) size_type erase(const key_type &key); @@ -303,11 +303,11 @@ class splaytree_impl //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator i, Disposer disposer); + iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template<class Disposer> - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer) template<class Disposer> @@ -318,11 +318,11 @@ class splaytree_impl size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer); //! @copydoc ::boost::intrusive::bstree::clear - void clear(); + void clear() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template<class Disposer> - void clear_and_dispose(Disposer disposer); + void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const //! Additional note: non-const function, splaying is performed. @@ -440,28 +440,28 @@ class splaytree_impl (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) - static iterator s_iterator_to(reference value); + static iterator s_iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) - static const_iterator s_iterator_to(const_reference value); + static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) - iterator iterator_to(reference value); + iterator iterator_to(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const - const_iterator iterator_to(const_reference value) const; + const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::init_node(reference) - static void init_node(reference value); + static void init_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance - pointer unlink_leftmost_without_rebalance(); + pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::replace_node - void replace_node(iterator replace_this, reference with_this); + void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::remove_node - void remove_node(reference value); + void remove_node(reference value) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::merge_unique(bstree<T, Options2...>&) template<class T, class ...Options2> @@ -481,7 +481,7 @@ class splaytree_impl //! <b>Complexity</b>: Amortized logarithmic. //! //! <b>Throws</b>: Nothing. - void splay_up(iterator i) + void splay_up(iterator i) BOOST_NOEXCEPT { return node_algorithms::splay_up(i.pointed_node(), tree_type::header_ptr()); } //! <b>Effects</b>: Rearranges the container so that if *this stores an element @@ -517,10 +517,10 @@ class splaytree_impl #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree::rebalance - void rebalance(); + void rebalance() BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree::rebalance_subtree - iterator rebalance_subtree(iterator root); + iterator rebalance_subtree(iterator root) BOOST_NOEXCEPT; friend bool operator< (const splaytree_impl &x, const splaytree_impl &y); @@ -613,46 +613,46 @@ class splaytree //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value)); - splaytree() + BOOST_INTRUSIVE_FORCEINLINE splaytree() : Base() {} - explicit splaytree( const key_compare &cmp, const value_traits &v_traits = value_traits()) + BOOST_INTRUSIVE_FORCEINLINE explicit splaytree( const key_compare &cmp, const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} template<class Iterator> - splaytree( bool unique, Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE splaytree( bool unique, Iterator b, Iterator e , const key_compare &cmp = key_compare() , const value_traits &v_traits = value_traits()) : Base(unique, b, e, cmp, v_traits) {} - splaytree(BOOST_RV_REF(splaytree) x) + BOOST_INTRUSIVE_FORCEINLINE splaytree(BOOST_RV_REF(splaytree) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - splaytree& operator=(BOOST_RV_REF(splaytree) x) + BOOST_INTRUSIVE_FORCEINLINE splaytree& operator=(BOOST_RV_REF(splaytree) x) { return static_cast<splaytree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template <class Cloner, class Disposer> - void clone_from(const splaytree &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const splaytree &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template <class Cloner, class Disposer> - void clone_from(BOOST_RV_REF(splaytree) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(BOOST_RV_REF(splaytree) src, Cloner cloner, Disposer disposer) { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } - static splaytree &container_from_end_iterator(iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static splaytree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT { return static_cast<splaytree &>(Base::container_from_end_iterator(end_iterator)); } - static const splaytree &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const splaytree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT { return static_cast<const splaytree &>(Base::container_from_end_iterator(end_iterator)); } - static splaytree &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static splaytree &container_from_iterator(iterator it) BOOST_NOEXCEPT { return static_cast<splaytree &>(Base::container_from_iterator(it)); } - static const splaytree &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const splaytree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT { return static_cast<const splaytree &>(Base::container_from_iterator(it)); } }; diff --git a/contrib/restricted/boost/intrusive/include/boost/intrusive/splaytree_algorithms.hpp b/contrib/restricted/boost/intrusive/include/boost/intrusive/splaytree_algorithms.hpp index be2e18227e..b36fddd293 100644 --- a/contrib/restricted/boost/intrusive/include/boost/intrusive/splaytree_algorithms.hpp +++ b/contrib/restricted/boost/intrusive/include/boost/intrusive/splaytree_algorithms.hpp @@ -54,7 +54,7 @@ struct splaydown_assemble_and_fix_header { typedef typename NodeTraits::node_ptr node_ptr; - splaydown_assemble_and_fix_header(const node_ptr & t, const node_ptr & header, const node_ptr &leftmost, const node_ptr &rightmost) + splaydown_assemble_and_fix_header(node_ptr t, node_ptr header, node_ptr leftmost, node_ptr rightmost) BOOST_NOEXCEPT : t_(t) , null_node_(header) , l_(null_node_) @@ -79,7 +79,7 @@ struct splaydown_assemble_and_fix_header private: - void assemble() + void assemble() BOOST_NOEXCEPT { //procedure assemble; // left(r), right(l) := right(t), left(t); @@ -175,59 +175,59 @@ class splaytree_algorithms public: #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) - static node_ptr get_header(const const_node_ptr & n); + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr) + static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node - static node_ptr begin_node(const const_node_ptr & header); + static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::end_node - static node_ptr end_node(const const_node_ptr & header); + static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree - static void swap_tree(const node_ptr & header1, const node_ptr & header2); + static void swap_tree(node_ptr header1, node_ptr header2); - //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&) - static void swap_nodes(const node_ptr & node1, const node_ptr & node2); + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr) + static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&) - static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2); + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr) + static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&) - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node); + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr) + static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&) - static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node); + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr) + static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(const node_ptr&) - static void unlink(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr) + static void unlink(node_ptr node) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance - static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header); + static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) - static bool unique(const const_node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr) + static bool unique(const_node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) - static std::size_t size(const const_node_ptr & header); + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr) + static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) - static node_ptr next_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr) + static node_ptr next_node(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) - static node_ptr prev_node(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr) + static node_ptr prev_node(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&) - static void init(const node_ptr & node); + //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr) + static void init(node_ptr node) BOOST_NOEXCEPT; - //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(const node_ptr&) - static void init_header(const node_ptr & header); + //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr) + static void init_header(node_ptr header) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr) //! Additional notes: the previous node of z is splayed to speed up range deletions. - static void erase(const node_ptr & header, const node_ptr & z) + static void erase(node_ptr header, node_ptr z) BOOST_NOEXCEPT { //posibility 1 if(NodeTraits::get_left(z)){ @@ -254,7 +254,7 @@ class splaytree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique template<class NodePtrCompare> static bool transfer_unique - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) { typename bstree_algo::insert_commit_data commit_data; bool const transferable = bstree_algo::insert_unique_check(header1, z, comp, commit_data).second; @@ -269,7 +269,7 @@ class splaytree_algorithms //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal template<class NodePtrCompare> static void transfer_equal - (const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z) + (node_ptr header1, NodePtrCompare comp, node_ptr header2, node_ptr z) { insert_commit_data commit_data; splay_down(header1, z, comp); @@ -279,21 +279,21 @@ class splaytree_algorithms } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer) template <class Cloner, class Disposer> static void clone - (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer); + (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer); - //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer) template<class Disposer> - static void clear_and_dispose(const node_ptr & header, Disposer disposer); + static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: an element with key `key` is splayed. template<class KeyType, class KeyNodePtrCompare> static std::size_t count - (const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { std::pair<node_ptr, node_ptr> ret = equal_range(header, key, comp); std::size_t n = 0; @@ -304,18 +304,18 @@ class splaytree_algorithms return n; } - //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template<class KeyType, class KeyNodePtrCompare> static std::size_t count - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::count(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: the first node of the range is splayed. template<class KeyType, class KeyNodePtrCompare> static node_ptr lower_bound - (const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { splay_down(detail::uncast(header), key, comp); node_ptr y = bstree_algo::lower_bound(header, key, comp); @@ -323,18 +323,18 @@ class splaytree_algorithms return y; } - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template<class KeyType, class KeyNodePtrCompare> static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::lower_bound(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: the first node of the range is splayed. template<class KeyType, class KeyNodePtrCompare> static node_ptr upper_bound - (const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { splay_down(detail::uncast(header), key, comp); node_ptr y = bstree_algo::upper_bound(header, key, comp); @@ -342,35 +342,35 @@ class splaytree_algorithms return y; } - //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template<class KeyType, class KeyNodePtrCompare> static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::upper_bound(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) //! Additional notes: the found node of the lower bound is splayed. template<class KeyType, class KeyNodePtrCompare> static node_ptr find - (const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { splay_down(detail::uncast(header), key, comp); return bstree_algo::find(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template<class KeyType, class KeyNodePtrCompare> static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::find(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: the first node of the range is splayed. template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> equal_range - (const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { splay_down(detail::uncast(header), key, comp); std::pair<node_ptr, node_ptr> ret = bstree_algo::equal_range(header, key, comp); @@ -378,18 +378,18 @@ class splaytree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::equal_range(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional notes: the first node of the range is splayed. template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> lower_bound_range - (const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { splay_down(detail::uncast(header), key, comp); std::pair<node_ptr, node_ptr> ret = bstree_algo::lower_bound_range(header, key, comp); @@ -397,18 +397,18 @@ class splaytree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const_node_ptr,const KeyType&,KeyNodePtrCompare) //! Additional note: no splaying is performed template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> lower_bound_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::lower_bound_range(header, key, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) //! Additional notes: the first node of the range is splayed. template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> bounded_range - (const node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + (node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed) { splay_down(detail::uncast(header), lower_key, comp); @@ -418,86 +418,86 @@ class splaytree_algorithms return ret; } - //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) //! Additional note: no splaying is performed template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, node_ptr> bounded_range - (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp , bool left_closed, bool right_closed) { return bstree_algo::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(node_ptr,node_ptr,NodePtrCompare) //! Additional note: the inserted node is splayed template<class NodePtrCompare> static node_ptr insert_equal_upper_bound - (const node_ptr & header, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr header, node_ptr new_node, NodePtrCompare comp) { splay_down(header, new_node, comp); return bstree_algo::insert_equal_upper_bound(header, new_node, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(node_ptr,node_ptr,NodePtrCompare) //! Additional note: the inserted node is splayed template<class NodePtrCompare> static node_ptr insert_equal_lower_bound - (const node_ptr & header, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr header, node_ptr new_node, NodePtrCompare comp) { splay_down(header, new_node, comp); return bstree_algo::insert_equal_lower_bound(header, new_node, comp); - } + } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(node_ptr,node_ptr,node_ptr,NodePtrCompare) //! Additional note: the inserted node is splayed template<class NodePtrCompare> static node_ptr insert_equal - (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp) + (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp) { splay_down(header, new_node, comp); return bstree_algo::insert_equal(header, hint, new_node, comp); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(node_ptr,node_ptr,node_ptr) //! Additional note: the inserted node is splayed static node_ptr insert_before - (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node) + (node_ptr header, node_ptr pos, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::insert_before(header, pos, new_node); splay_up(new_node, header); return new_node; } - //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(node_ptr,node_ptr) //! Additional note: the inserted node is splayed - static void push_back(const node_ptr & header, const node_ptr & new_node) + static void push_back(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_back(header, new_node); splay_up(new_node, header); } - //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&) + //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(node_ptr,node_ptr) //! Additional note: the inserted node is splayed - static void push_front(const node_ptr & header, const node_ptr & new_node) + static void push_front(node_ptr header, node_ptr new_node) BOOST_NOEXCEPT { bstree_algo::push_front(header, new_node); splay_up(new_node, header); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) //! Additional note: nodes with the given key are splayed template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const node_ptr & header, const KeyType &key + (node_ptr header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { splay_down(header, key, comp); return bstree_algo::insert_unique_check(header, key, comp, commit_data); } - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const_node_ptr,node_ptr,const KeyType&,KeyNodePtrCompare,insert_commit_data&) //! Additional note: nodes with the given key are splayed template<class KeyType, class KeyNodePtrCompare> static std::pair<node_ptr, bool> insert_unique_check - (const node_ptr & header, const node_ptr &hint, const KeyType &key + (node_ptr header, node_ptr hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { splay_down(header, key, comp); @@ -505,28 +505,28 @@ class splaytree_algorithms } #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data&) + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(node_ptr,node_ptr,const insert_commit_data&) static void insert_unique_commit - (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data); + (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::is_header - static bool is_header(const const_node_ptr & p); + static bool is_header(const_node_ptr p) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::rebalance - static void rebalance(const node_ptr & header); + static void rebalance(node_ptr header) BOOST_NOEXCEPT; //! @copydoc ::boost::intrusive::bstree_algorithms::rebalance_subtree - static node_ptr rebalance_subtree(const node_ptr & old_root); + static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT; #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED // bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow - static void splay_up(const node_ptr & node, const node_ptr & header) + static void splay_up(node_ptr node, node_ptr header) BOOST_NOEXCEPT { priv_splay_up<true>(node, header); } // top-down splay | complexity : logarithmic | exception : strong, note A template<class KeyType, class KeyNodePtrCompare> - static node_ptr splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0) + static node_ptr splay_down(node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0) { return priv_splay_down<true>(header, key, comp, pfound); } private: @@ -535,7 +535,7 @@ class splaytree_algorithms // bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow template<bool SimpleSplay> - static void priv_splay_up(const node_ptr & node, const node_ptr & header) + static void priv_splay_up(node_ptr node, node_ptr header) BOOST_NOEXCEPT { // If (node == header) do a splay for the right most node instead // this is to boost performance of equal_range/count on equivalent containers in the case @@ -572,7 +572,7 @@ class splaytree_algorithms } template<bool SimpleSplay, class KeyType, class KeyNodePtrCompare> - static node_ptr priv_splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0) + static node_ptr priv_splay_down(node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0) { //Most splay tree implementations use a dummy/null node to implement. //this function. This has some problems for a generic library like Intrusive: @@ -660,7 +660,7 @@ class splaytree_algorithms } // break link to left child node and attach it to left tree pointed to by l | complexity : constant | exception : nothrow - static void link_left(node_ptr & t, node_ptr & l) + static void link_left(node_ptr & t, node_ptr & l) BOOST_NOEXCEPT { //procedure link_left; // t, l, right(l) := right(t), t, t @@ -672,7 +672,7 @@ class splaytree_algorithms } // break link to right child node and attach it to right tree pointed to by r | complexity : constant | exception : nothrow - static void link_right(node_ptr & t, node_ptr & r) + static void link_right(node_ptr & t, node_ptr & r) BOOST_NOEXCEPT { //procedure link_right; // t, r, left(r) := left(t), t, t @@ -684,7 +684,7 @@ class splaytree_algorithms } // rotate n with its parent | complexity : constant | exception : nothrow - static void rotate(const node_ptr & n) + static void rotate(node_ptr n) BOOST_NOEXCEPT { //procedure rotate_left; // t, right(t), left(right(t)) := right(t), left(right(t)), t diff --git a/contrib/restricted/boost/move/LICENSE b/contrib/restricted/boost/move/LICENSE new file mode 100644 index 0000000000..36b7cd93cd --- /dev/null +++ b/contrib/restricted/boost/move/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/contrib/restricted/boost/move/README.md b/contrib/restricted/boost/move/README.md new file mode 100644 index 0000000000..22f854cf0d --- /dev/null +++ b/contrib/restricted/boost/move/README.md @@ -0,0 +1,35 @@ +Move, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), provides C++0x move semantics in C++03 compilers and allows writing portable code that works optimally in C++03 and C++0x compilers. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +### Properties + +* C++03 +* Header-Only + +### Build Status + +Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | +:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | +[`master`](https://github.com/boostorg/move/tree/master) | [![Build Status](https://travis-ci.org/boostorg/move.svg?branch=master)](https://travis-ci.org/boostorg/move) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/move-0k1xg/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-move) | [![codecov](https://codecov.io/gh/boostorg/move/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/move/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/move.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/move.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/move.html) +[`develop`](https://github.com/boostorg/move/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/move.svg?branch=develop)](https://travis-ci.org/boostorg/move) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/move-0k1xg/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-move) | [![codecov](https://codecov.io/gh/boostorg/move/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/move/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/move.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/move.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/move.html) + +### Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `doc` | documentation | +| `example` | examples | +| `include` | headers | +| `proj` | ide projects | +| `test` | unit tests | + +### More information + +* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-move) +* [Report bugs](https://github.com/boostorg/move/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). +* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[move]` tag at the beginning of the subject line. + diff --git a/contrib/restricted/boost/move/include/boost/move/algo/adaptive_merge.hpp b/contrib/restricted/boost/move/include/boost/move/algo/adaptive_merge.hpp index 0040fda065..9f39920bd8 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/adaptive_merge.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/adaptive_merge.hpp @@ -15,6 +15,11 @@ #include <boost/move/detail/config_begin.hpp> #include <boost/move/algo/detail/adaptive_sort_merge.hpp> +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + namespace boost { namespace movelib { @@ -23,21 +28,22 @@ namespace detail_adaptive { template<class RandIt, class Compare, class XBuf> inline void adaptive_merge_combine_blocks( RandIt first - , typename iterator_traits<RandIt>::size_type len1 - , typename iterator_traits<RandIt>::size_type len2 - , typename iterator_traits<RandIt>::size_type collected - , typename iterator_traits<RandIt>::size_type n_keys - , typename iterator_traits<RandIt>::size_type l_block + , typename iter_size<RandIt>::type len1 + , typename iter_size<RandIt>::type len2 + , typename iter_size<RandIt>::type collected + , typename iter_size<RandIt>::type n_keys + , typename iter_size<RandIt>::type l_block , bool use_internal_buf , bool xbuf_used , Compare comp , XBuf & xbuf ) { - typedef typename iterator_traits<RandIt>::size_type size_type; - size_type const len = len1+len2; - size_type const l_combine = len-collected; - size_type const l_combine1 = len1-collected; + typedef typename iter_size<RandIt>::type size_type; + + size_type const len = size_type(len1+len2); + size_type const l_combine = size_type(len-collected); + size_type const l_combine1 = size_type(len1-collected); if(n_keys){ RandIt const first_data = first+collected; @@ -63,7 +69,8 @@ inline void adaptive_merge_combine_blocks( RandIt first , n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs if(use_internal_buf){ op_merge_blocks_with_buf - (keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, swap_op(), first_data-l_block); + ( keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b + , l_irreg2, comp, swap_op(), first_data-l_block); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A mrg buf: ", len); } else{ @@ -94,49 +101,55 @@ inline void adaptive_merge_combine_blocks( RandIt first template<class RandIt, class Compare, class XBuf> inline void adaptive_merge_final_merge( RandIt first - , typename iterator_traits<RandIt>::size_type len1 - , typename iterator_traits<RandIt>::size_type len2 - , typename iterator_traits<RandIt>::size_type collected - , typename iterator_traits<RandIt>::size_type l_intbuf - , typename iterator_traits<RandIt>::size_type l_block - , bool use_internal_buf + , typename iter_size<RandIt>::type len1 + , typename iter_size<RandIt>::type len2 + , typename iter_size<RandIt>::type collected + , typename iter_size<RandIt>::type l_intbuf + , typename iter_size<RandIt>::type //l_block + , bool //use_internal_buf , bool xbuf_used , Compare comp , XBuf & xbuf ) { - typedef typename iterator_traits<RandIt>::size_type size_type; - (void)l_block; - size_type n_keys = collected-l_intbuf; - size_type len = len1+len2; - if(use_internal_buf){ - if(xbuf_used){ - xbuf.clear(); - //Nothing to do - if(n_keys){ - unstable_sort(first, first+n_keys, comp, xbuf); - stable_merge(first, first+n_keys, first+len, comp, xbuf); - BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A key mrg: ", len); - } - } - else{ - xbuf.clear(); - unstable_sort(first, first+collected, comp, xbuf); - BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b srt: ", len); - stable_merge(first, first+collected, first+len, comp, xbuf); - BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b mrg: ", len); - } - } - else{ + typedef typename iter_size<RandIt>::type size_type; + + size_type n_keys = size_type(collected-l_intbuf); + size_type len = size_type(len1+len2); + if (!xbuf_used || n_keys) { xbuf.clear(); - unstable_sort(first, first+collected, comp, xbuf); + const size_type middle = xbuf_used && n_keys ? n_keys: collected; + unstable_sort(first, first + middle, comp, xbuf); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b srt: ", len); - stable_merge(first, first+collected, first+len1+len2, comp, xbuf); - BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b mrg: ", len); + stable_merge(first, first + middle, first + len, comp, xbuf); } BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A fin mrg: ", len); } +template<class SizeType> +inline static SizeType adaptive_merge_n_keys_without_external_keys(SizeType l_block, SizeType len1, SizeType len2, SizeType l_intbuf) +{ + typedef SizeType size_type; + //This is the minimum number of keys to implement the ideal algorithm + size_type n_keys = size_type(len1/l_block + len2/l_block); + const size_type second_half_blocks = size_type(len2/l_block); + const size_type first_half_aux = size_type(len1 - l_intbuf); + while(n_keys >= ((first_half_aux-n_keys)/l_block + second_half_blocks)){ + --n_keys; + } + ++n_keys; + return n_keys; +} + +template<class SizeType> +inline static SizeType adaptive_merge_n_keys_with_external_keys(SizeType l_block, SizeType len1, SizeType len2, SizeType l_intbuf) +{ + typedef SizeType size_type; + //This is the minimum number of keys to implement the ideal algorithm + size_type n_keys = size_type((len1-l_intbuf)/l_block + len2/l_block); + return n_keys; +} + template<class SizeType, class Xbuf> inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1, SizeType len2, Xbuf & xbuf, SizeType &l_intbuf_inout) { @@ -144,19 +157,18 @@ inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1, size_type l_block = rl_block; size_type l_intbuf = xbuf.capacity() >= l_block ? 0u : l_block; - while(xbuf.capacity() >= l_block*2){ - l_block *= 2; + if (xbuf.capacity() > l_block){ + l_block = xbuf.capacity(); } //This is the minimum number of keys to implement the ideal algorithm - size_type n_keys = len1/l_block+len2/l_block; - while(n_keys >= ((len1-l_intbuf-n_keys)/l_block + len2/l_block)){ - --n_keys; - } - ++n_keys; + size_type n_keys = adaptive_merge_n_keys_without_external_keys(l_block, len1, len2, l_intbuf); BOOST_ASSERT(n_keys >= ((len1-l_intbuf-n_keys)/l_block + len2/l_block)); - if(xbuf.template supports_aligned_trailing<size_type>(l_block, n_keys)){ + if(xbuf.template supports_aligned_trailing<size_type> + ( l_block + , adaptive_merge_n_keys_with_external_keys(l_block, len1, len2, l_intbuf))) + { n_keys = 0u; } l_intbuf_inout = l_intbuf; @@ -210,19 +222,20 @@ inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1, template<class RandIt, class Compare, class XBuf> void adaptive_merge_impl ( RandIt first - , typename iterator_traits<RandIt>::size_type len1 - , typename iterator_traits<RandIt>::size_type len2 + , typename iter_size<RandIt>::type len1 + , typename iter_size<RandIt>::type len2 , Compare comp , XBuf & xbuf ) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; if(xbuf.capacity() >= min_value<size_type>(len1, len2)){ - buffered_merge(first, first+len1, first+(len1+len2), comp, xbuf); + buffered_merge( first, first+len1 + , first + len1+len2, comp, xbuf); } else{ - const size_type len = len1+len2; + const size_type len = size_type(len1+len2); //Calculate ideal parameters and try to collect needed unique keys size_type l_block = size_type(ceil_sqrt(len)); @@ -237,7 +250,7 @@ void adaptive_merge_impl //internal buffer is needed so l_intbuf will remain 0. size_type l_intbuf = 0; size_type n_keys = adaptive_merge_n_keys_intbuf(l_block, len1, len2, xbuf, l_intbuf); - size_type const to_collect = l_intbuf+n_keys; + size_type const to_collect = size_type(l_intbuf+n_keys); //Try to extract needed unique values from the first range size_type const collected = collect_unique(first, first+len1, to_collect, comp, xbuf); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("\n A collect: ", len); @@ -303,18 +316,48 @@ void adaptive_merge_impl template<class RandIt, class Compare> void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp , typename iterator_traits<RandIt>::value_type* uninitialized = 0 - , std::size_t uninitialized_len = 0) + , typename iter_size<RandIt>::type uninitialized_len = 0) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; typedef typename iterator_traits<RandIt>::value_type value_type; - ::boost::movelib::detail_adaptive::adaptive_xbuf<value_type> xbuf(uninitialized, uninitialized_len); + if (first == middle || middle == last){ + return; + } + + //Reduce ranges to merge if possible + do { + if (comp(*middle, *first)){ + break; + } + ++first; + if (first == middle) + return; + } while(1); + + RandIt first_high(middle); + --first_high; + do { + --last; + if (comp(*last, *first_high)){ + ++last; + break; + } + if (last == middle) + return; + } while(1); + + ::boost::movelib::adaptive_xbuf<value_type, value_type*, size_type> xbuf(uninitialized, size_type(uninitialized_len)); ::boost::movelib::detail_adaptive::adaptive_merge_impl(first, size_type(middle - first), size_type(last - middle), comp, xbuf); } } //namespace movelib { } //namespace boost { +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic pop +#endif + #include <boost/move/detail/config_end.hpp> #endif //#define BOOST_MOVE_ADAPTIVE_MERGE_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/algo/detail/adaptive_sort_merge.hpp b/contrib/restricted/boost/move/include/boost/move/algo/detail/adaptive_sort_merge.hpp index 1606fde66a..220c0b5604 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/detail/adaptive_sort_merge.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/detail/adaptive_sort_merge.hpp @@ -43,6 +43,7 @@ #define BOOST_MOVE_ADAPTIVE_SORT_MERGE_HPP #include <boost/move/detail/config_begin.hpp> + #include <boost/move/detail/reverse_iterator.hpp> #include <boost/move/algo/move.hpp> #include <boost/move/algo/detail/merge.hpp> @@ -52,8 +53,15 @@ #include <boost/move/algo/detail/heap_sort.hpp> #include <boost/move/algo/detail/merge.hpp> #include <boost/move/algo/detail/is_sorted.hpp> +#include <boost/core/ignore_unused.hpp> #include <boost/assert.hpp> #include <boost/cstdint.hpp> +#include <limits.h> + +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif #ifndef BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL #define BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL 1 @@ -131,248 +139,18 @@ const T &max_value(const T &a, const T &b) } template<class ForwardIt, class Pred, class V> -typename iterator_traits<ForwardIt>::size_type +typename iter_size<ForwardIt>::type count_if_with(ForwardIt first, ForwardIt last, Pred pred, const V &v) { - typedef typename iterator_traits<ForwardIt>::size_type size_type; + typedef typename iter_size<ForwardIt>::type size_type; size_type count = 0; while(first != last) { - count += static_cast<size_type>(0 != pred(*first, v)); + count = size_type(count + static_cast<size_type>(0 != pred(*first, v))); ++first; } return count; } -template<class T, class RandRawIt = T*> -class adaptive_xbuf -{ - adaptive_xbuf(const adaptive_xbuf &); - adaptive_xbuf & operator=(const adaptive_xbuf &); - - public: - typedef RandRawIt iterator; - - adaptive_xbuf() - : m_ptr(), m_size(0), m_capacity(0) - {} - - adaptive_xbuf(RandRawIt raw_memory, std::size_t capacity) - : m_ptr(raw_memory), m_size(0), m_capacity(capacity) - {} - - template<class RandIt> - void move_assign(RandIt first, std::size_t n) - { - if(n <= m_size){ - boost::move(first, first+n, m_ptr); - std::size_t size = m_size; - while(size-- != n){ - m_ptr[size].~T(); - } - m_size = n; - } - else{ - RandRawIt result = boost::move(first, first+m_size, m_ptr); - boost::uninitialized_move(first+m_size, first+n, result); - m_size = n; - } - } - - template<class RandIt> - void push_back(RandIt first, std::size_t n) - { - BOOST_ASSERT(m_capacity - m_size >= n); - boost::uninitialized_move(first, first+n, m_ptr+m_size); - m_size += n; - } - - template<class RandIt> - iterator add(RandIt it) - { - BOOST_ASSERT(m_size < m_capacity); - RandRawIt p_ret = m_ptr + m_size; - ::new(&*p_ret) T(::boost::move(*it)); - ++m_size; - return p_ret; - } - - template<class RandIt> - void insert(iterator pos, RandIt it) - { - if(pos == (m_ptr + m_size)){ - this->add(it); - } - else{ - this->add(m_ptr+m_size-1); - //m_size updated - boost::move_backward(pos, m_ptr+m_size-2, m_ptr+m_size-1); - *pos = boost::move(*it); - } - } - - void set_size(std::size_t size) - { - m_size = size; - } - - void shrink_to_fit(std::size_t const size) - { - if(m_size > size){ - for(std::size_t szt_i = size; szt_i != m_size; ++szt_i){ - m_ptr[szt_i].~T(); - } - m_size = size; - } - } - - void initialize_until(std::size_t const size, T &t) - { - BOOST_ASSERT(m_size < m_capacity); - if(m_size < size){ - ::new((void*)&m_ptr[m_size]) T(::boost::move(t)); - ++m_size; - for(; m_size != size; ++m_size){ - ::new((void*)&m_ptr[m_size]) T(::boost::move(m_ptr[m_size-1])); - } - t = ::boost::move(m_ptr[m_size-1]); - } - } - - private: - template<class RIt> - static bool is_raw_ptr(RIt) - { - return false; - } - - static bool is_raw_ptr(T*) - { - return true; - } - - public: - template<class U> - bool supports_aligned_trailing(std::size_t size, std::size_t trail_count) const - { - if(this->is_raw_ptr(this->data()) && m_capacity){ - uintptr_t u_addr_sz = uintptr_t(&*(this->data()+size)); - uintptr_t u_addr_cp = uintptr_t(&*(this->data()+this->capacity())); - u_addr_sz = ((u_addr_sz + sizeof(U)-1)/sizeof(U))*sizeof(U); - return (u_addr_cp >= u_addr_sz) && ((u_addr_cp - u_addr_sz)/sizeof(U) >= trail_count); - } - return false; - } - - template<class U> - U *aligned_trailing() const - { - return this->aligned_trailing<U>(this->size()); - } - - template<class U> - U *aligned_trailing(std::size_t pos) const - { - uintptr_t u_addr = uintptr_t(&*(this->data()+pos)); - u_addr = ((u_addr + sizeof(U)-1)/sizeof(U))*sizeof(U); - return (U*)u_addr; - } - - ~adaptive_xbuf() - { - this->clear(); - } - - std::size_t capacity() const - { return m_capacity; } - - iterator data() const - { return m_ptr; } - - iterator end() const - { return m_ptr+m_size; } - - std::size_t size() const - { return m_size; } - - bool empty() const - { return !m_size; } - - void clear() - { - this->shrink_to_fit(0u); - } - - private: - RandRawIt m_ptr; - std::size_t m_size; - std::size_t m_capacity; -}; - -template<class Iterator, class Op> -class range_xbuf -{ - range_xbuf(const range_xbuf &); - range_xbuf & operator=(const range_xbuf &); - - public: - typedef typename iterator_traits<Iterator>::size_type size_type; - typedef Iterator iterator; - - range_xbuf(Iterator first, Iterator last) - : m_first(first), m_last(first), m_cap(last) - {} - - template<class RandIt> - void move_assign(RandIt first, std::size_t n) - { - BOOST_ASSERT(size_type(n) <= size_type(m_cap-m_first)); - m_last = Op()(forward_t(), first, first+n, m_first); - } - - ~range_xbuf() - {} - - std::size_t capacity() const - { return m_cap-m_first; } - - Iterator data() const - { return m_first; } - - Iterator end() const - { return m_last; } - - std::size_t size() const - { return m_last-m_first; } - - bool empty() const - { return m_first == m_last; } - - void clear() - { - m_last = m_first; - } - - template<class RandIt> - iterator add(RandIt it) - { - Iterator pos(m_last); - *pos = boost::move(*it); - ++m_last; - return pos; - } - - void set_size(std::size_t size) - { - m_last = m_first; - m_last += size; - } - - private: - Iterator const m_first; - Iterator m_last; - Iterator const m_cap; -}; - template<class RandIt, class Compare> RandIt skip_until_merge @@ -407,6 +185,49 @@ void swap_and_update_key } } +template<class RandItKeys> +void update_key +(RandItKeys const key_next + , RandItKeys const key_range2 + , RandItKeys &key_mid) +{ + if (key_next != key_range2) { + ::boost::adl_move_swap(*key_next, *key_range2); + if (key_next == key_mid) { + key_mid = key_range2; + } + else if (key_mid == key_range2) { + key_mid = key_next; + } + } +} + +template<class RandItKeys, class RandIt, class RandIt2, class Op> +RandIt2 buffer_and_update_key +(RandItKeys const key_next + , RandItKeys const key_range2 + , RandItKeys &key_mid + , RandIt begin + , RandIt end + , RandIt with + , RandIt2 buffer + , Op op) +{ + if (begin != with) { + while(begin != end) { + op(three_way_t(), begin++, with++, buffer++); + } + ::boost::adl_move_swap(*key_next, *key_range2); + if (key_next == key_mid) { + key_mid = key_range2; + } + else if (key_mid == key_range2) { + key_mid = key_next; + } + } + return buffer; +} + /////////////////////////////////////////////////////////////////////////////// // // MERGE BUFFERLESS @@ -451,28 +272,28 @@ RandIt partial_merge_bufferless template<class SizeType> static SizeType needed_keys_count(SizeType n_block_a, SizeType n_block_b) { - return n_block_a + n_block_b; + return SizeType(n_block_a + n_block_b); } template<class RandItKeys, class KeyCompare, class RandIt, class Compare> -typename iterator_traits<RandIt>::size_type +typename iter_size<RandIt>::type find_next_block - ( RandItKeys key_first + ( RandItKeys const key_first , KeyCompare key_comp , RandIt const first - , typename iterator_traits<RandIt>::size_type const l_block - , typename iterator_traits<RandIt>::size_type const ix_first_block - , typename iterator_traits<RandIt>::size_type const ix_last_block + , typename iter_size<RandIt>::type const l_block + , typename iter_size<RandIt>::type const ix_first_block + , typename iter_size<RandIt>::type const ix_last_block , Compare comp) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; typedef typename iterator_traits<RandIt>::value_type value_type; typedef typename iterator_traits<RandItKeys>::value_type key_type; BOOST_ASSERT(ix_first_block <= ix_last_block); size_type ix_min_block = 0u; for (size_type szt_i = ix_first_block; szt_i < ix_last_block; ++szt_i) { - const value_type &min_val = first[ix_min_block*l_block]; - const value_type &cur_val = first[szt_i*l_block]; + const value_type &min_val = first[size_type(ix_min_block*l_block)]; + const value_type &cur_val = first[size_type(szt_i*l_block)]; const key_type &min_key = key_first[ix_min_block]; const key_type &cur_key = key_first[szt_i]; @@ -488,18 +309,19 @@ typename iterator_traits<RandIt>::size_type template<class RandItKeys, class KeyCompare, class RandIt, class Compare> void merge_blocks_bufferless - ( RandItKeys key_first + ( RandItKeys const key_first , KeyCompare key_comp , RandIt const first - , typename iterator_traits<RandIt>::size_type const l_block - , typename iterator_traits<RandIt>::size_type const l_irreg1 - , typename iterator_traits<RandIt>::size_type const n_block_a - , typename iterator_traits<RandIt>::size_type const n_block_b - , typename iterator_traits<RandIt>::size_type const l_irreg2 + , typename iter_size<RandIt>::type const l_block + , typename iter_size<RandIt>::type const l_irreg1 + , typename iter_size<RandIt>::type const n_block_a + , typename iter_size<RandIt>::type const n_block_b + , typename iter_size<RandIt>::type const l_irreg2 , Compare comp) { - typedef typename iterator_traits<RandIt>::size_type size_type; - size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count; + typedef typename iter_size<RandIt>::type size_type; + size_type const key_count = needed_keys_count(n_block_a, n_block_b); + ::boost::ignore_unused(key_count); //BOOST_ASSERT(n_block_a || n_block_b); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a])); @@ -507,91 +329,57 @@ void merge_blocks_bufferless size_type n_bef_irreg2 = 0; bool l_irreg_pos_count = true; RandItKeys key_mid(key_first + n_block_a); - RandIt const first_irr2 = first + l_irreg1 + (n_block_a+n_block_b)*l_block; + RandIt const first_irr2 = first + size_type(l_irreg1 + (n_block_a+n_block_b)*l_block); RandIt const last_irr2 = first_irr2 + l_irreg2; { //Selection sort blocks - size_type n_block_left = n_block_b + n_block_a; + size_type n_block_left = size_type(n_block_b + n_block_a); RandItKeys key_range2(key_first); size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; - size_type max_check = min_value(min_check+1, n_block_left); - for (RandIt f = first+l_irreg1; n_block_left; --n_block_left, ++key_range2, f += l_block, min_check -= min_check != 0, max_check -= max_check != 0) { + size_type max_check = min_value<size_type>(size_type(min_check+1), n_block_left); + for ( RandIt f = first+l_irreg1; n_block_left; --n_block_left) { size_type const next_key_idx = find_next_block(key_range2, key_comp, f, l_block, min_check, max_check, comp); RandItKeys const key_next(key_range2 + next_key_idx); - max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left); + max_check = min_value<size_type>(max_value<size_type>(max_check, size_type(next_key_idx+2)), n_block_left); - RandIt const first_min = f + next_key_idx*l_block; + RandIt const first_min = f + size_type(next_key_idx*l_block); //Check if irregular b block should go here. //If so, break to the special code handling the irregular block if (l_irreg_pos_count && l_irreg2 && comp(*first_irr2, *first_min)){ l_irreg_pos_count = false; } - n_bef_irreg2 += l_irreg_pos_count; + n_bef_irreg2 = size_type(n_bef_irreg2+l_irreg_pos_count); swap_and_update_key(key_next, key_range2, key_mid, f, f + l_block, first_min); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(f, f+l_block, comp)); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, first_min + l_block, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(f, f+l_block, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, first_min + l_block, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((f == (first+l_irreg1)) || !comp(*f, *(f-l_block))); + //Update context + ++key_range2; + f += l_block; + min_check = size_type(min_check - (min_check != 0)); + max_check = size_type(max_check - (max_check != 0)); } } - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first+l_irreg1+n_bef_irreg2*l_block, first_irr2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first+l_irreg1+n_bef_irreg2*l_block, first_irr2, comp)); RandIt first1 = first; RandIt last1 = first+l_irreg1; RandItKeys const key_end (key_first+n_bef_irreg2); bool is_range1_A = true; - for( ; key_first != key_end; ++key_first){ - bool is_range2_A = key_mid == (key_first+key_count) || key_comp(*key_first, *key_mid); + for(RandItKeys key_next = key_first; key_next != key_end; ++key_next){ + bool is_range2_A = key_mid == (key_first+key_count) || key_comp(*key_next, *key_mid); first1 = is_range1_A == is_range2_A ? last1 : partial_merge_bufferless(first1, last1, last1 + l_block, &is_range1_A, comp); last1 += l_block; - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, first1, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, first1, comp)); } merge_bufferless(is_range1_A ? first1 : last1, first_irr2, last_irr2, comp); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, last_irr2, comp)); -} - -/////////////////////////////////////////////////////////////////////////////// -// -// BUFFERED MERGE -// -/////////////////////////////////////////////////////////////////////////////// -template<class RandIt, class Compare, class Op, class Buf> -void op_buffered_merge - ( RandIt first, RandIt const middle, RandIt last - , Compare comp, Op op - , Buf &xbuf) -{ - if(first != middle && middle != last && comp(*middle, middle[-1])){ - typedef typename iterator_traits<RandIt>::size_type size_type; - size_type const len1 = size_type(middle-first); - size_type const len2 = size_type(last-middle); - if(len1 <= len2){ - first = boost::movelib::upper_bound(first, middle, *middle, comp); - xbuf.move_assign(first, size_type(middle-first)); - op_merge_with_right_placed - (xbuf.data(), xbuf.end(), first, middle, last, comp, op); - } - else{ - last = boost::movelib::lower_bound(middle, last, middle[-1], comp); - xbuf.move_assign(middle, size_type(last-middle)); - op_merge_with_left_placed - (first, middle, last, xbuf.data(), xbuf.end(), comp, op); - } - } -} - -template<class RandIt, class Compare, class XBuf> -void buffered_merge - ( RandIt first, RandIt const middle, RandIt last - , Compare comp - , XBuf &xbuf) -{ - op_buffered_merge(first, middle, last, comp, move_op(), xbuf); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last_irr2, comp)); } // Complexity: 2*distance(first, last)+max_collected^2/2 @@ -601,14 +389,15 @@ void buffered_merge // // Returns the number of collected keys template<class RandIt, class Compare, class XBuf> -typename iterator_traits<RandIt>::size_type +typename iter_size<RandIt>::type collect_unique ( RandIt const first, RandIt const last - , typename iterator_traits<RandIt>::size_type const max_collected, Compare comp + , typename iter_size<RandIt>::type const max_collected, Compare comp , XBuf & xbuf) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; size_type h = 0; + if(max_collected){ ++h; // first key is always here RandIt h0 = first; @@ -654,22 +443,28 @@ typename iterator_traits<RandIt>::size_type } template<class Unsigned> -Unsigned floor_sqrt(Unsigned const n) +Unsigned floor_sqrt(Unsigned n) { - Unsigned x = n; - Unsigned y = x/2 + (x&1); - while (y < x){ - x = y; - y = (x + n / x)/2; + Unsigned rem = 0, root = 0; + const unsigned bits = sizeof(Unsigned)*CHAR_BIT; + + for (unsigned i = bits / 2; i > 0; i--) { + root = Unsigned(root << 1u); + rem = Unsigned(Unsigned(rem << 2u) | Unsigned(n >> (bits - 2u))); + n = Unsigned(n << 2u); + if (root < rem) { + rem = Unsigned(rem - Unsigned(root | 1u)); + root = Unsigned(root + 2u); + } } - return x; + return Unsigned(root >> 1u); } template<class Unsigned> Unsigned ceil_sqrt(Unsigned const n) { Unsigned r = floor_sqrt(n); - return r + Unsigned((n%r) != 0); + return Unsigned(r + Unsigned((n%r) != 0)); } template<class Unsigned> @@ -683,7 +478,7 @@ Unsigned floor_merge_multiple(Unsigned const n, Unsigned &base, Unsigned &pow) } base = s; pow = p; - return s << p; + return Unsigned(s << p); } template<class Unsigned> @@ -700,7 +495,7 @@ Unsigned ceil_merge_multiple(Unsigned const n, Unsigned &base, Unsigned &pow) ++pow; } } - return base << pow; + return Unsigned(base << pow); } template<class Unsigned> @@ -743,26 +538,27 @@ template<class RandIt, class Compare> void slow_stable_sort ( RandIt const first, RandIt const last, Compare comp) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; + size_type L = size_type(last - first); { //Use insertion sort to merge first elements size_type m = 0; while((L - m) > size_type(AdaptiveSortInsertionSortThreshold)){ insertion_sort(first+m, first+m+size_type(AdaptiveSortInsertionSortThreshold), comp); - m += AdaptiveSortInsertionSortThreshold; + m = size_type(m + AdaptiveSortInsertionSortThreshold); } insertion_sort(first+m, last, comp); } size_type h = AdaptiveSortInsertionSortThreshold; - for(bool do_merge = L > h; do_merge; h*=2){ + for(bool do_merge = L > h; do_merge; h = size_type(h*2)){ do_merge = (L - h) > h; size_type p0 = 0; if(do_merge){ - size_type const h_2 = 2*h; + size_type const h_2 = size_type(2*h); while((L-p0) > h_2){ merge_bufferless(first+p0, first+p0+h, first+p0+h_2, comp); - p0 += h_2; + p0 = size_type(p0 + h_2); } } if((L-p0) > h){ @@ -794,7 +590,7 @@ Unsigned lblock_for_combine //See if half keys are at least 4 and if half keys fulfill Unsigned const new_buf = n_keys/2; - Unsigned const new_keys = n_keys-new_buf; + Unsigned const new_keys = Unsigned(n_keys-new_buf); use_buf = new_keys >= 4 && new_keys >= l_data/new_buf; if(use_buf){ return new_buf; @@ -812,9 +608,9 @@ Unsigned lblock_for_combine template<class RandIt, class Compare, class XBuf> void stable_sort( RandIt first, RandIt last, Compare comp, XBuf & xbuf) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; size_type const len = size_type(last - first); - size_type const half_len = len/2 + (len&1); + size_type const half_len = size_type(len/2u + (len&1u)); if(std::size_t(xbuf.capacity() - xbuf.size()) >= half_len) { merge_sort(first, last, comp, xbuf.data()+xbuf.size()); } @@ -828,7 +624,8 @@ void unstable_sort( RandIt first, RandIt last , Comp comp , XBuf & xbuf) { - heap_sort(first, last, comp);(void)xbuf; + heap_sort(first, last, comp); + ::boost::ignore_unused(xbuf); } template<class RandIt, class Compare, class XBuf> @@ -838,17 +635,19 @@ void stable_merge , XBuf &xbuf) { BOOST_ASSERT(xbuf.empty()); - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; size_type const len1 = size_type(middle-first); size_type const len2 = size_type(last-middle); - size_type const l_min = min_value(len1, len2); + size_type const l_min = min_value<size_type>(len1, len2); if(xbuf.capacity() >= l_min){ buffered_merge(first, middle, last, comp, xbuf); xbuf.clear(); } else{ - merge_bufferless(first, middle, last, comp); + //merge_bufferless(first, middle, last, comp); + merge_adaptive_ONlogN(first, middle, last, comp, xbuf.begin(), xbuf.capacity()); } + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last, boost::movelib::unantistable(comp))); } template<class RandIt, class Comp, class XBuf> @@ -868,7 +667,7 @@ void initialize_keys( RandIt first, RandIt last typedef typename iterator_traits<RandIt>::value_type value_type; std::size_t count = std::size_t(last - first); for(std::size_t i = 0; i != count; ++i){ - *first = value_type(i); + *first = static_cast<value_type>(i); ++first; } } @@ -878,11 +677,11 @@ Unsigned calculate_total_combined(Unsigned const len, Unsigned const l_prev_merg { typedef Unsigned size_type; - size_type const l_combined = 2*l_prev_merged; - size_type l_irreg_combined = len%l_combined; + size_type const l_combined = size_type(2*l_prev_merged); + size_type l_irreg_combined = size_type(len%l_combined); size_type l_total_combined = len; if(l_irreg_combined <= l_prev_merged){ - l_total_combined -= l_irreg_combined; + l_total_combined = size_type(l_total_combined - l_irreg_combined); l_irreg_combined = 0; } if(pl_irreg_combined) @@ -909,12 +708,12 @@ void combine_params typedef SizeType size_type; //Initial parameters for selection sort blocks - l_irreg1 = l_prev_merged%l_block; - l_irreg2 = (l_combined-l_irreg1)%l_block; + l_irreg1 = size_type(l_prev_merged%l_block); + l_irreg2 = size_type((l_combined-l_irreg1)%l_block); BOOST_ASSERT(((l_combined-l_irreg1-l_irreg2)%l_block) == 0); - size_type const n_reg_block = (l_combined-l_irreg1-l_irreg2)/l_block; + size_type const n_reg_block = size_type((l_combined-l_irreg1-l_irreg2)/l_block); n_block_a = l_prev_merged/l_block; - n_block_b = n_reg_block - n_block_a; + n_block_b = size_type(n_reg_block - n_block_a); BOOST_ASSERT(n_reg_block>=n_block_a); //Key initialization @@ -1154,29 +953,31 @@ OutputIt op_merge_blocks_with_irreg , RandIt2 &first_irr , RandIt2 const last_irr , OutputIt dest - , typename iterator_traits<RandIt>::size_type const l_block - , typename iterator_traits<RandIt>::size_type n_block_left - , typename iterator_traits<RandIt>::size_type min_check - , typename iterator_traits<RandIt>::size_type max_check + , typename iter_size<RandIt>::type const l_block + , typename iter_size<RandIt>::type n_block_left + , typename iter_size<RandIt>::type min_check + , typename iter_size<RandIt>::type max_check , Compare comp, bool const is_stable, Op op) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; - for(; n_block_left; --n_block_left, ++key_first, min_check -= min_check != 0, max_check -= max_check != 0){ + for(; n_block_left; --n_block_left){ size_type next_key_idx = find_next_block(key_first, key_comp, first_reg, l_block, min_check, max_check, comp); - max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left); + max_check = min_value(max_value(max_check, size_type(next_key_idx+2u)), n_block_left); RandIt const last_reg = first_reg + l_block; - RandIt first_min = first_reg + next_key_idx*l_block; - RandIt const last_min = first_min + l_block; (void)last_min; + RandIt first_min = first_reg + size_type(next_key_idx*l_block); + RandIt const last_min = first_min + l_block; + boost::ignore_unused(last_min); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_reg, last_reg, comp)); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!next_key_idx || is_sorted(first_min, last_min, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_reg, last_reg, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!next_key_idx || boost::movelib::is_sorted(first_min, last_min, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((!next_key_idx || !comp(*first_reg, *first_min ))); - OutputIt orig_dest = dest; (void)orig_dest; + OutputIt orig_dest = dest; + boost::ignore_unused(orig_dest); dest = next_key_idx ? op_partial_merge_and_swap(first_irr, last_irr, first_reg, last_reg, first_min, dest, comp, op, is_stable) : op_partial_merge (first_irr, last_irr, first_reg, last_reg, dest, comp, op, is_stable); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(orig_dest, dest, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(orig_dest, dest, comp)); if(first_reg == dest){ dest = next_key_idx ? ::boost::adl_move_swap_ranges(first_min, last_min, first_reg) @@ -1190,8 +991,11 @@ OutputIt op_merge_blocks_with_irreg RandItKeys const key_next(key_first + next_key_idx); swap_and_update_key(key_next, key_first, key_mid, last_reg, last_reg, first_min); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(orig_dest, dest, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(orig_dest, dest, comp)); first_reg = last_reg; + ++key_first; + min_check = size_type(min_check - (min_check != 0)); + max_check = size_type(max_check - (max_check != 0)); } return dest; } @@ -1211,29 +1015,32 @@ void op_merge_blocks_left ( RandItKeys const key_first , KeyCompare key_comp , RandIt const first - , typename iterator_traits<RandIt>::size_type const l_block - , typename iterator_traits<RandIt>::size_type const l_irreg1 - , typename iterator_traits<RandIt>::size_type const n_block_a - , typename iterator_traits<RandIt>::size_type const n_block_b - , typename iterator_traits<RandIt>::size_type const l_irreg2 + , typename iter_size<RandIt>::type const l_block + , typename iter_size<RandIt>::type const l_irreg1 + , typename iter_size<RandIt>::type const n_block_a + , typename iter_size<RandIt>::type const n_block_b + , typename iter_size<RandIt>::type const l_irreg2 , Compare comp, Op op) { - typedef typename iterator_traits<RandIt>::size_type size_type; - size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count; + typedef typename iter_size<RandIt>::type size_type; + + size_type const key_count = needed_keys_count(n_block_a, n_block_b); + boost::ignore_unused(key_count); + // BOOST_ASSERT(n_block_a || n_block_b); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a])); size_type n_block_b_left = n_block_b; size_type n_block_a_left = n_block_a; - size_type n_block_left = n_block_b + n_block_a; + size_type n_block_left = size_type(n_block_b + n_block_a); RandItKeys key_mid(key_first + n_block_a); RandIt buffer = first - l_block; RandIt first1 = first; RandIt last1 = first1 + l_irreg1; RandIt first2 = last1; - RandIt const irreg2 = first2 + n_block_left*l_block; + RandIt const irreg2 = first2 + size_type(n_block_left*l_block); bool is_range1_A = true; RandItKeys key_range2(key_first); @@ -1242,17 +1049,19 @@ void op_merge_blocks_left //Process all regular blocks before the irregular B block //////////////////////////////////////////////////////////////////////////// size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; - size_type max_check = min_value(min_check+1, n_block_left); - for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) { + size_type max_check = min_value<size_type>(size_type(min_check+1u), n_block_left); + for (; n_block_left; --n_block_left) { size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp); - max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left); - RandIt const first_min = first2 + next_key_idx*l_block; - RandIt const last_min = first_min + l_block; (void)last_min; + max_check = min_value<size_type>(max_value<size_type>(max_check, size_type(next_key_idx+2u)), n_block_left); + RandIt const first_min = first2 + size_type(next_key_idx*l_block); + RandIt const last_min = first_min + l_block; + + boost::ignore_unused(last_min); RandIt const last2 = first2 + l_block; - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first1, last1, comp)); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp)); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || is_sorted(first_min, last_min, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first1, last1, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || boost::movelib::is_sorted(first_min, last_min, comp)); //Check if irregular b block should go here. //If so, break to the special code handling the irregular block @@ -1269,7 +1078,7 @@ void op_merge_blocks_left (!is_buffer_middle && size_type(first1-buffer) == l_block && first2 == last1)); if(is_range1_A == is_range2_A){ - BOOST_ASSERT((first1 == last1) || !comp(*first_min, last1[-1])); + BOOST_ASSERT((first1 == last1) || !comp(*first_min, last1[typename iterator_traits<RandIt>::difference_type(-1)])); if(!is_buffer_middle){ buffer = op(forward_t(), first1, last1, buffer); } @@ -1292,8 +1101,9 @@ void op_merge_blocks_left unmerged = op_partial_merge_and_save (buffer, buffer+(last1-first1), first2, last2, first_min, buf_beg, buf_end, comp, op, is_range1_A); } - (void)unmerged; - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, unmerged, comp)); + + boost::ignore_unused(unmerged); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, unmerged, comp)); swap_and_update_key( key_next, key_range2, key_mid, first2, last2 , last_min - size_type(last2 - first2)); @@ -1314,6 +1124,10 @@ void op_merge_blocks_left BOOST_MOVE_ADAPTIVE_SORT_INVARIANT( (is_range2_A && n_block_a_left) || (!is_range2_A && n_block_b_left)); is_range2_A ? --n_block_a_left : --n_block_b_left; first2 = last2; + //Update context + ++key_range2; + min_check = size_type(min_check - (min_check != 0)); + max_check = size_type(max_check - (max_check != 0)); } BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_range2 + n_block_left, key_comp, *key_mid)); @@ -1342,7 +1156,7 @@ void op_merge_blocks_left else if(!is_buffer_middle){ buffer = op(forward_t(), first1, last1, buffer); } - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, buffer, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, buffer, comp)); //////////////////////////////////////////////////////////////////////////// //Process irregular B block and remaining A blocks @@ -1350,8 +1164,9 @@ void op_merge_blocks_left buffer = op_merge_blocks_with_irreg ( key_range2, key_mid, key_comp, first2, first_irr2, last_irr2 , buffer, l_block, n_block_left, min_check, max_check, comp, false, op); - buffer = op(forward_t(), first_irr2, last_irr2, buffer);(void)buffer; - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, buffer, comp)); + buffer = op(forward_t(), first_irr2, last_irr2, buffer); + boost::ignore_unused(buffer); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, buffer, comp)); } // first - first element to merge. @@ -1366,11 +1181,11 @@ void merge_blocks_left ( RandItKeys const key_first , KeyCompare key_comp , RandIt const first - , typename iterator_traits<RandIt>::size_type const l_block - , typename iterator_traits<RandIt>::size_type const l_irreg1 - , typename iterator_traits<RandIt>::size_type const n_block_a - , typename iterator_traits<RandIt>::size_type const n_block_b - , typename iterator_traits<RandIt>::size_type const l_irreg2 + , typename iter_size<RandIt>::type const l_block + , typename iter_size<RandIt>::type const l_irreg1 + , typename iter_size<RandIt>::type const n_block_a + , typename iter_size<RandIt>::type const n_block_b + , typename iter_size<RandIt>::type const l_irreg2 , Compare comp , bool const xbuf_used) { @@ -1397,17 +1212,18 @@ void merge_blocks_right ( RandItKeys const key_first , KeyCompare key_comp , RandIt const first - , typename iterator_traits<RandIt>::size_type const l_block - , typename iterator_traits<RandIt>::size_type const n_block_a - , typename iterator_traits<RandIt>::size_type const n_block_b - , typename iterator_traits<RandIt>::size_type const l_irreg2 + , typename iter_size<RandIt>::type const l_block + , typename iter_size<RandIt>::type const n_block_a + , typename iter_size<RandIt>::type const n_block_b + , typename iter_size<RandIt>::type const l_irreg2 , Compare comp , bool const xbuf_used) { + typedef typename iter_size<RandIt>::type size_type; merge_blocks_left ( (make_reverse_iterator)(key_first + needed_keys_count(n_block_a, n_block_b)) , inverse<KeyCompare>(key_comp) - , (make_reverse_iterator)(first + ((n_block_a+n_block_b)*l_block+l_irreg2)) + , (make_reverse_iterator)(first + size_type((n_block_a+n_block_b)*l_block+l_irreg2)) , l_block , l_irreg2 , n_block_b @@ -1430,24 +1246,25 @@ void op_merge_blocks_with_buf ( RandItKeys key_first , KeyCompare key_comp , RandIt const first - , typename iterator_traits<RandIt>::size_type const l_block - , typename iterator_traits<RandIt>::size_type const l_irreg1 - , typename iterator_traits<RandIt>::size_type const n_block_a - , typename iterator_traits<RandIt>::size_type const n_block_b - , typename iterator_traits<RandIt>::size_type const l_irreg2 + , typename iter_size<RandIt>::type const l_block + , typename iter_size<RandIt>::type const l_irreg1 + , typename iter_size<RandIt>::type const n_block_a + , typename iter_size<RandIt>::type const n_block_b + , typename iter_size<RandIt>::type const l_irreg2 , Compare comp , Op op , RandItBuf const buf_first) { - typedef typename iterator_traits<RandIt>::size_type size_type; - size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count; + typedef typename iter_size<RandIt>::type size_type; + size_type const key_count = needed_keys_count(n_block_a, n_block_b); + boost::ignore_unused(key_count); //BOOST_ASSERT(n_block_a || n_block_b); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a])); size_type n_block_b_left = n_block_b; size_type n_block_a_left = n_block_a; - size_type n_block_left = n_block_b + n_block_a; + size_type n_block_left = size_type(n_block_b + n_block_a); RandItKeys key_mid(key_first + n_block_a); RandItBuf buffer = buf_first; @@ -1455,8 +1272,10 @@ void op_merge_blocks_with_buf RandIt first1 = first; RandIt last1 = first1 + l_irreg1; RandIt first2 = last1; - RandIt const first_irr2 = first2 + n_block_left*l_block; + RandIt const first_irr2 = first2 + size_type(n_block_left*l_block); bool is_range1_A = true; + const size_type len = size_type(l_block * n_block_a + l_block * n_block_b + l_irreg1 + l_irreg2); + boost::ignore_unused(len); RandItKeys key_range2(key_first); @@ -1464,18 +1283,20 @@ void op_merge_blocks_with_buf //Process all regular blocks before the irregular B block //////////////////////////////////////////////////////////////////////////// size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; - size_type max_check = min_value(min_check+1, n_block_left); - for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) { + size_type max_check = min_value(size_type(min_check+1), n_block_left); + for (; n_block_left; --n_block_left) { size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp); - max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left); - RandIt first_min = first2 + next_key_idx*l_block; - RandIt const last_min = first_min + l_block; (void)last_min; + max_check = min_value(max_value(max_check, size_type(next_key_idx+2)), n_block_left); + RandIt first_min = first2 + size_type(next_key_idx*l_block); + RandIt const last_min = first_min + l_block; + boost::ignore_unused(last_min); RandIt const last2 = first2 + l_block; - bool const buffer_empty = buffer == buffer_end; (void)buffer_empty; - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(buffer_empty ? is_sorted(first1, last1, comp) : is_sorted(buffer, buffer_end, comp)); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp)); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || is_sorted(first_min, last_min, comp)); + bool const buffer_empty = buffer == buffer_end; + boost::ignore_unused(buffer_empty); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(buffer_empty ? boost::movelib::is_sorted(first1, last1, comp) : boost::movelib::is_sorted(buffer, buffer_end, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || boost::movelib::is_sorted(first_min, last_min, comp)); //Check if irregular b block should go here. //If so, break to the special code handling the irregular block @@ -1491,64 +1312,78 @@ void op_merge_blocks_with_buf BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((first1 == last1) || (buffer_empty ? !comp(*first_min, last1[-1]) : !comp(*first_min, buffer_end[-1]))); //If buffered, put those elements in place RandIt res = op(forward_t(), buffer, buffer_end, first1); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_fwd: ", len); buffer = buffer_end = buf_first; - BOOST_ASSERT(buffer_empty || res == last1); (void)res; - swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp)); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, last_min, comp)); + BOOST_ASSERT(buffer_empty || res == last1); + boost::ignore_unused(res); + //swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); + buffer_end = buffer_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min, buffer = buf_first, op); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_swp: ", len); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, last_min, comp)); first1 = first2; - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, first1, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, first1, comp)); } else { RandIt const unmerged = op_partial_merge_and_save(first1, last1, first2, last2, first_min, buffer, buffer_end, comp, op, is_range1_A); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_mrs: ", len); bool const is_range_1_empty = buffer == buffer_end; BOOST_ASSERT(is_range_1_empty || (buffer_end-buffer) == (last1+l_block-unmerged)); if(is_range_1_empty){ buffer = buffer_end = buf_first; first_min = last_min - (last2 - first2); + //swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); + buffer_end = buffer_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min, buf_first, op); } else{ first_min = last_min; + //swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); + update_key(key_next, key_range2, key_mid); } BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!is_range_1_empty || (last_min-first_min) == (last2-unmerged)); - swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); - - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, last_min, comp)); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_swp: ", len); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, last_min, comp)); is_range1_A ^= is_range_1_empty; first1 = unmerged; - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, unmerged, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, unmerged, comp)); } BOOST_ASSERT( (is_range2_A && n_block_a_left) || (!is_range2_A && n_block_b_left)); is_range2_A ? --n_block_a_left : --n_block_b_left; last1 += l_block; first2 = last2; + //Update context + ++key_range2; + min_check = size_type(min_check - (min_check != 0)); + max_check = size_type(max_check - (max_check != 0)); } - - RandIt res = op(forward_t(), buffer, buffer_end, first1); (void)res; - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, res, comp)); + RandIt res = op(forward_t(), buffer, buffer_end, first1); + boost::ignore_unused(res); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, res, comp)); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_fwd: ", len); //////////////////////////////////////////////////////////////////////////// //Process irregular B block and remaining A blocks //////////////////////////////////////////////////////////////////////////// RandIt const last_irr2 = first_irr2 + l_irreg2; op(forward_t(), first_irr2, first_irr2+l_irreg2, buf_first); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_fwir:", len); buffer = buf_first; buffer_end = buffer+l_irreg2; reverse_iterator<RandItBuf> rbuf_beg(buffer_end); RandIt dest = op_merge_blocks_with_irreg ((make_reverse_iterator)(key_first + n_block_b + n_block_a), (make_reverse_iterator)(key_mid), inverse<KeyCompare>(key_comp) - , (make_reverse_iterator)(first_irr2), rbuf_beg - , (make_reverse_iterator)(buffer), (make_reverse_iterator)(last_irr2) + , (make_reverse_iterator)(first_irr2), rbuf_beg, (make_reverse_iterator)(buffer), (make_reverse_iterator)(last_irr2) , l_block, n_block_left, 0, n_block_left , inverse<Compare>(comp), true, op).base(); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(dest, last_irr2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(dest, last_irr2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_irg: ", len); buffer_end = rbuf_beg.base(); BOOST_ASSERT((dest-last1) == (buffer_end-buffer)); op_merge_with_left_placed(is_range1_A ? first1 : last1, last1, dest, buffer, buffer_end, comp, op); - - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, last_irr2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_with_left_plc:", len); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last_irr2, comp)); } ////////////////////////////////// @@ -1562,20 +1397,21 @@ void op_merge_blocks_with_buf ////////////////////////////////// template<class RandIt, class Compare, class Op> -typename iterator_traits<RandIt>::size_type +typename iter_size<RandIt>::type op_insertion_sort_step_left ( RandIt const first - , typename iterator_traits<RandIt>::size_type const length - , typename iterator_traits<RandIt>::size_type const step + , typename iter_size<RandIt>::type const length + , typename iter_size<RandIt>::type const step , Compare comp, Op op) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; + size_type const s = min_value<size_type>(step, AdaptiveSortInsertionSortThreshold); size_type m = 0; - while((length - m) > s){ + while(size_type(length - m) > s){ insertion_sort_op(first+m, first+m+s, first+m-s, comp, op); - m += s; + m = size_type(m + s); } insertion_sort_op(first+m, first+length, first+m-s, comp, op); return s; @@ -1584,14 +1420,14 @@ typename iterator_traits<RandIt>::size_type template<class RandIt, class Compare, class Op> void op_merge_right_step_once ( RandIt first_block - , typename iterator_traits<RandIt>::size_type const elements_in_blocks - , typename iterator_traits<RandIt>::size_type const l_build_buf + , typename iter_size<RandIt>::type const elements_in_blocks + , typename iter_size<RandIt>::type const l_build_buf , Compare comp , Op op) { - typedef typename iterator_traits<RandIt>::size_type size_type; - size_type restk = elements_in_blocks%(2*l_build_buf); - size_type p = elements_in_blocks - restk; + typedef typename iter_size<RandIt>::type size_type; + size_type restk = size_type(elements_in_blocks%(2*l_build_buf)); + size_type p = size_type(elements_in_blocks - restk); BOOST_ASSERT(0 == (p%(2*l_build_buf))); if(restk <= l_build_buf){ @@ -1601,8 +1437,10 @@ void op_merge_right_step_once op_merge_right(first_block+p, first_block+p+l_build_buf, first_block+p+restk, first_block+p+restk+l_build_buf, comp, op); } while(p>0){ - p -= 2*l_build_buf; - op_merge_right(first_block+p, first_block+p+l_build_buf, first_block+p+2*l_build_buf, first_block+p+3*l_build_buf, comp, op); + p = size_type(p - 2u*l_build_buf); + op_merge_right( first_block+p, first_block+size_type(p+l_build_buf) + , first_block+size_type(p+2*l_build_buf) + , first_block+size_type(p+3*l_build_buf), comp, op); } } @@ -1617,20 +1455,20 @@ void op_merge_right_step_once ////////////////////////////////// ////////////////////////////////// template<class RandIt, class Compare> -typename iterator_traits<RandIt>::size_type +typename iter_size<RandIt>::type insertion_sort_step ( RandIt const first - , typename iterator_traits<RandIt>::size_type const length - , typename iterator_traits<RandIt>::size_type const step + , typename iter_size<RandIt>::type const length + , typename iter_size<RandIt>::type const step , Compare comp) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; size_type const s = min_value<size_type>(step, AdaptiveSortInsertionSortThreshold); size_type m = 0; while((length - m) > s){ insertion_sort(first+m, first+m+s, comp); - m += s; + m = size_type(m + s); } insertion_sort(first+m, first+length, comp); return s; @@ -1646,36 +1484,40 @@ typename iterator_traits<RandIt>::size_type ////////////////////////////////// ////////////////////////////////// template<class RandIt, class Compare, class Op> -typename iterator_traits<RandIt>::size_type +typename iter_size<RandIt>::type op_merge_left_step_multiple ( RandIt first_block - , typename iterator_traits<RandIt>::size_type const elements_in_blocks - , typename iterator_traits<RandIt>::size_type l_merged - , typename iterator_traits<RandIt>::size_type const l_build_buf - , typename iterator_traits<RandIt>::size_type l_left_space + , typename iter_size<RandIt>::type const elements_in_blocks + , typename iter_size<RandIt>::type l_merged + , typename iter_size<RandIt>::type const l_build_buf + , typename iter_size<RandIt>::type l_left_space , Compare comp , Op op) { - typedef typename iterator_traits<RandIt>::size_type size_type; - for(; l_merged < l_build_buf && l_left_space >= l_merged; l_merged*=2){ + typedef typename iter_size<RandIt>::type size_type; + for(; l_merged < l_build_buf && l_left_space >= l_merged; l_merged = size_type(l_merged*2u)){ size_type p0=0; RandIt pos = first_block; while((elements_in_blocks - p0) > 2*l_merged) { - op_merge_left(pos-l_merged, pos, pos+l_merged, pos+2*l_merged, comp, op); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, pos+l_merged, comp)); - p0 += 2*l_merged; + op_merge_left(pos-l_merged, pos, pos+l_merged, pos+size_type(2*l_merged), comp, op); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(pos-l_merged, pos+l_merged, comp)); + p0 = size_type(p0 + 2u*l_merged); pos = first_block+p0; } if((elements_in_blocks-p0) > l_merged) { op_merge_left(pos-l_merged, pos, pos+l_merged, first_block+elements_in_blocks, comp, op); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, pos-l_merged+(first_block+elements_in_blocks-pos), comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT + (boost::movelib::is_sorted + (pos-l_merged, pos+size_type((first_block+elements_in_blocks-pos))-l_merged, comp)); } else { op(forward_t(), pos, first_block+elements_in_blocks, pos-l_merged); - BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, first_block+elements_in_blocks-l_merged, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT + (boost::movelib::is_sorted + (pos-l_merged, first_block+size_type(elements_in_blocks-l_merged), comp)); } - first_block -= l_merged; - l_left_space -= l_merged; + first_block -= l_merged; + l_left_space = size_type(l_left_space - l_merged); } return l_merged; } @@ -1685,6 +1527,10 @@ typename iterator_traits<RandIt>::size_type } //namespace movelib { } //namespace boost { +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic pop +#endif + #include <boost/move/detail/config_end.hpp> #endif //#define BOOST_MOVE_ADAPTIVE_SORT_MERGE_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/algo/detail/heap_sort.hpp b/contrib/restricted/boost/move/include/boost/move/algo/detail/heap_sort.hpp index 5474d9f5c4..871cdd0c09 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/detail/heap_sort.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/detail/heap_sort.hpp @@ -23,42 +23,48 @@ #endif #include <boost/move/detail/config_begin.hpp> + #include <boost/move/detail/workaround.hpp> #include <boost/move/detail/iterator_traits.hpp> #include <boost/move/algo/detail/is_sorted.hpp> #include <boost/move/utility_core.hpp> +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + namespace boost { namespace movelib{ template <class RandomAccessIterator, class Compare> class heap_sort_helper { - typedef typename boost::movelib::iterator_traits<RandomAccessIterator>::size_type size_type; + typedef typename boost::movelib::iter_size<RandomAccessIterator>::type size_type; typedef typename boost::movelib::iterator_traits<RandomAccessIterator>::value_type value_type; static void adjust_heap(RandomAccessIterator first, size_type hole_index, size_type const len, value_type &value, Compare comp) { size_type const top_index = hole_index; - size_type second_child = 2 * (hole_index + 1); + size_type second_child = size_type(2u*(hole_index + 1u)); while (second_child < len) { - if (comp(*(first + second_child), *(first + (second_child - 1)))) + if (comp(*(first + second_child), *(first + size_type(second_child - 1u)))) second_child--; *(first + hole_index) = boost::move(*(first + second_child)); hole_index = second_child; - second_child = 2 * (second_child + 1); + second_child = size_type(2u * (second_child + 1u)); } if (second_child == len) { - *(first + hole_index) = boost::move(*(first + (second_child - 1))); - hole_index = second_child - 1; + *(first + hole_index) = boost::move(*(first + size_type(second_child - 1u))); + hole_index = size_type(second_child - 1); } { //push_heap-like ending - size_type parent = (hole_index - 1) / 2; + size_type parent = size_type((hole_index - 1u) / 2u); while (hole_index > top_index && comp(*(first + parent), value)) { *(first + hole_index) = boost::move(*(first + parent)); hole_index = parent; - parent = (hole_index - 1) / 2; + parent = size_type((hole_index - 1u) / 2u); } *(first + hole_index) = boost::move(value); } @@ -68,7 +74,7 @@ class heap_sort_helper { size_type const len = size_type(last - first); if (len > 1) { - size_type parent = len/2u - 1u; + size_type parent = size_type(len/2u - 1u); do { value_type v(boost::move(*(first + parent))); @@ -106,6 +112,10 @@ BOOST_MOVE_FORCEINLINE void heap_sort(RandomAccessIterator first, RandomAccessIt }} //namespace boost { namespace movelib{ +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic pop +#endif + #include <boost/move/detail/config_end.hpp> #endif //#ifndef BOOST_MOVE_DETAIL_HEAP_SORT_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/algo/detail/insertion_sort.hpp b/contrib/restricted/boost/move/include/boost/move/algo/detail/insertion_sort.hpp index 5c378c3e36..77f0b6980a 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/detail/insertion_sort.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/detail/insertion_sort.hpp @@ -33,6 +33,11 @@ #include <boost/move/detail/placement_new.hpp> #include <boost/move/detail/iterator_to_raw_pointer.hpp> +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + namespace boost { namespace movelib{ // @cond @@ -125,4 +130,8 @@ void insertion_sort_uninitialized_copy }} //namespace boost { namespace movelib{ +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic pop +#endif + #endif //#ifndef BOOST_MOVE_DETAIL_INSERT_SORT_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/algo/detail/merge.hpp b/contrib/restricted/boost/move/include/boost/move/algo/detail/merge.hpp index 860773579c..f631923196 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/detail/merge.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/detail/merge.hpp @@ -11,18 +11,280 @@ #ifndef BOOST_MOVE_MERGE_HPP #define BOOST_MOVE_MERGE_HPP +#include <boost/core/ignore_unused.hpp> #include <boost/move/algo/move.hpp> #include <boost/move/adl_move_swap.hpp> #include <boost/move/algo/detail/basic_op.hpp> #include <boost/move/detail/iterator_traits.hpp> #include <boost/move/detail/destruct_n.hpp> #include <boost/move/algo/predicate.hpp> +#include <boost/move/algo/detail/search.hpp> #include <boost/move/detail/iterator_to_raw_pointer.hpp> #include <boost/assert.hpp> +#include <cstddef> + +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif namespace boost { namespace movelib { +template<class T, class RandRawIt = T*, class SizeType = typename iter_size<RandRawIt>::type> +class adaptive_xbuf +{ + adaptive_xbuf(const adaptive_xbuf &); + adaptive_xbuf & operator=(const adaptive_xbuf &); + + #if !defined(UINTPTR_MAX) + typedef std::size_t uintptr_t; + #endif + + public: + typedef RandRawIt iterator; + typedef SizeType size_type; + + BOOST_MOVE_FORCEINLINE adaptive_xbuf() + : m_ptr(), m_size(0), m_capacity(0) + {} + + BOOST_MOVE_FORCEINLINE adaptive_xbuf(RandRawIt raw_memory, size_type cap) + : m_ptr(raw_memory), m_size(0), m_capacity(cap) + {} + + template<class RandIt> + void move_assign(RandIt first, size_type n) + { + typedef typename iterator_traits<RandIt>::difference_type rand_diff_t; + if(n <= m_size){ + boost::move(first, first+rand_diff_t(n), m_ptr); + size_type sz = m_size; + while(sz-- != n){ + m_ptr[sz].~T(); + } + m_size = n; + } + else{ + RandRawIt result = boost::move(first, first+rand_diff_t(m_size), m_ptr); + boost::uninitialized_move(first+rand_diff_t(m_size), first+rand_diff_t(n), result); + m_size = n; + } + } + + template<class RandIt> + void push_back(RandIt first, size_type n) + { + BOOST_ASSERT(m_capacity - m_size >= n); + boost::uninitialized_move(first, first+n, m_ptr+m_size); + m_size += n; + } + + template<class RandIt> + iterator add(RandIt it) + { + BOOST_ASSERT(m_size < m_capacity); + RandRawIt p_ret = m_ptr + m_size; + ::new(&*p_ret) T(::boost::move(*it)); + ++m_size; + return p_ret; + } + + template<class RandIt> + void insert(iterator pos, RandIt it) + { + if(pos == (m_ptr + m_size)){ + this->add(it); + } + else{ + this->add(m_ptr+m_size-1); + //m_size updated + boost::move_backward(pos, m_ptr+m_size-2, m_ptr+m_size-1); + *pos = boost::move(*it); + } + } + + BOOST_MOVE_FORCEINLINE void set_size(size_type sz) + { + m_size = sz; + } + + void shrink_to_fit(size_type const sz) + { + if(m_size > sz){ + for(size_type szt_i = sz; szt_i != m_size; ++szt_i){ + m_ptr[szt_i].~T(); + } + m_size = sz; + } + } + + void initialize_until(size_type const sz, T &t) + { + BOOST_ASSERT(m_size < m_capacity); + if(m_size < sz){ + BOOST_TRY + { + ::new((void*)&m_ptr[m_size]) T(::boost::move(t)); + ++m_size; + for(; m_size != sz; ++m_size){ + ::new((void*)&m_ptr[m_size]) T(::boost::move(m_ptr[m_size-1])); + } + t = ::boost::move(m_ptr[m_size-1]); + } + BOOST_CATCH(...) + { + while(m_size) + { + --m_size; + m_ptr[m_size].~T(); + } + } + BOOST_CATCH_END + } + } + + private: + template<class RIt> + BOOST_MOVE_FORCEINLINE static bool is_raw_ptr(RIt) + { + return false; + } + + BOOST_MOVE_FORCEINLINE static bool is_raw_ptr(T*) + { + return true; + } + + public: + template<class U> + bool supports_aligned_trailing(size_type sz, size_type trail_count) const + { + if(this->is_raw_ptr(this->data()) && m_capacity){ + uintptr_t u_addr_sz = uintptr_t(&*(this->data()+sz)); + uintptr_t u_addr_cp = uintptr_t(&*(this->data()+this->capacity())); + u_addr_sz = ((u_addr_sz + sizeof(U)-1)/sizeof(U))*sizeof(U); + return (u_addr_cp >= u_addr_sz) && ((u_addr_cp - u_addr_sz)/sizeof(U) >= trail_count); + } + return false; + } + + template<class U> + BOOST_MOVE_FORCEINLINE U *aligned_trailing() const + { + return this->aligned_trailing<U>(this->size()); + } + + template<class U> + BOOST_MOVE_FORCEINLINE U *aligned_trailing(size_type pos) const + { + uintptr_t u_addr = uintptr_t(&*(this->data()+pos)); + u_addr = ((u_addr + sizeof(U)-1)/sizeof(U))*sizeof(U); + return (U*)u_addr; + } + + BOOST_MOVE_FORCEINLINE ~adaptive_xbuf() + { + this->clear(); + } + + BOOST_MOVE_FORCEINLINE size_type capacity() const + { return m_capacity; } + + BOOST_MOVE_FORCEINLINE iterator data() const + { return m_ptr; } + + BOOST_MOVE_FORCEINLINE iterator begin() const + { return m_ptr; } + + BOOST_MOVE_FORCEINLINE iterator end() const + { return m_ptr+m_size; } + + BOOST_MOVE_FORCEINLINE size_type size() const + { return m_size; } + + BOOST_MOVE_FORCEINLINE bool empty() const + { return !m_size; } + + BOOST_MOVE_FORCEINLINE void clear() + { + this->shrink_to_fit(0u); + } + + private: + RandRawIt m_ptr; + size_type m_size; + size_type m_capacity; +}; + +template<class Iterator, class SizeType, class Op> +class range_xbuf +{ + range_xbuf(const range_xbuf &); + range_xbuf & operator=(const range_xbuf &); + + public: + typedef SizeType size_type; + typedef Iterator iterator; + + range_xbuf(Iterator first, Iterator last) + : m_first(first), m_last(first), m_cap(last) + {} + + template<class RandIt> + void move_assign(RandIt first, size_type n) + { + BOOST_ASSERT(size_type(n) <= size_type(m_cap-m_first)); + typedef typename iter_difference<RandIt>::type d_type; + m_last = Op()(forward_t(), first, first+d_type(n), m_first); + } + + ~range_xbuf() + {} + + size_type capacity() const + { return m_cap-m_first; } + + Iterator data() const + { return m_first; } + + Iterator end() const + { return m_last; } + + size_type size() const + { return m_last-m_first; } + + bool empty() const + { return m_first == m_last; } + + void clear() + { + m_last = m_first; + } + + template<class RandIt> + iterator add(RandIt it) + { + Iterator pos(m_last); + *pos = boost::move(*it); + ++m_last; + return pos; + } + + void set_size(size_type sz) + { + m_last = m_first; + m_last += sz; + } + + private: + Iterator const m_first; + Iterator m_last; + Iterator const m_cap; +}; + + + // @cond /* @@ -54,26 +316,28 @@ Unsigned gcd(Unsigned x, Unsigned y) else{ Unsigned z = 1; while((!(x&1)) & (!(y&1))){ - z <<=1, x>>=1, y>>=1; + z = Unsigned(z << 1); + x = Unsigned(x >> 1); + y = Unsigned(y >> 1); } while(x && y){ if(!(x&1)) - x >>=1; + x = Unsigned(x >> 1); else if(!(y&1)) - y >>=1; + y = Unsigned (y >> 1); else if(x >=y) - x = (x-y) >> 1; + x = Unsigned((x-y) >> 1u); else - y = (y-x) >> 1; + y = Unsigned((y-x) >> 1); } - return z*(x+y); + return Unsigned(z*(x+y)); } } template<typename RandIt> RandIt rotate_gcd(RandIt first, RandIt middle, RandIt last) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; typedef typename iterator_traits<RandIt>::value_type value_type; if(first == middle) @@ -97,7 +361,7 @@ RandIt rotate_gcd(RandIt first, RandIt middle, RandIt last) *it_j = boost::move(*it_k); it_j = it_k; size_type const left = size_type(last - it_j); - it_k = left > middle_pos ? it_j + middle_pos : first + (middle_pos - left); + it_k = left > middle_pos ? it_j + middle_pos : first + middle_pos - left; } while(it_k != it_i); *it_j = boost::move(temp); } @@ -105,57 +369,6 @@ RandIt rotate_gcd(RandIt first, RandIt middle, RandIt last) return ret; } -template <class RandIt, class T, class Compare> -RandIt lower_bound - (RandIt first, const RandIt last, const T& key, Compare comp) -{ - typedef typename iterator_traits - <RandIt>::size_type size_type; - size_type len = size_type(last - first); - RandIt middle; - - while (len) { - size_type step = len >> 1; - middle = first; - middle += step; - - if (comp(*middle, key)) { - first = ++middle; - len -= step + 1; - } - else{ - len = step; - } - } - return first; -} - -template <class RandIt, class T, class Compare> -RandIt upper_bound - (RandIt first, const RandIt last, const T& key, Compare comp) -{ - typedef typename iterator_traits - <RandIt>::size_type size_type; - size_type len = size_type(last - first); - RandIt middle; - - while (len) { - size_type step = len >> 1; - middle = first; - middle += step; - - if (!comp(key, *middle)) { - first = ++middle; - len -= step + 1; - } - else{ - len = step; - } - } - return first; -} - - template<class RandIt, class Compare, class Op> void op_merge_left( RandIt buf_first , RandIt first1 @@ -256,6 +469,45 @@ void swap_merge_right op_merge_right(first1, last1, last2, buf_last, comp, swap_op()); } +/////////////////////////////////////////////////////////////////////////////// +// +// BUFFERED MERGE +// +/////////////////////////////////////////////////////////////////////////////// +template<class RandIt, class Compare, class Op, class Buf> +void op_buffered_merge + ( RandIt first, RandIt const middle, RandIt last + , Compare comp, Op op + , Buf &xbuf) +{ + if(first != middle && middle != last && comp(*middle, middle[-1])){ + typedef typename iter_size<RandIt>::type size_type; + size_type const len1 = size_type(middle-first); + size_type const len2 = size_type(last-middle); + if(len1 <= len2){ + first = boost::movelib::upper_bound(first, middle, *middle, comp); + xbuf.move_assign(first, size_type(middle-first)); + op_merge_with_right_placed + (xbuf.data(), xbuf.end(), first, middle, last, comp, op); + } + else{ + last = boost::movelib::lower_bound(middle, last, middle[-1], comp); + xbuf.move_assign(middle, size_type(last-middle)); + op_merge_with_left_placed + (first, middle, last, xbuf.data(), xbuf.end(), comp, op); + } + } +} + +template<class RandIt, class Compare, class XBuf> +void buffered_merge + ( RandIt first, RandIt const middle, RandIt last + , Compare comp + , XBuf &xbuf) +{ + op_buffered_merge(first, middle, last, comp, move_op(), xbuf); +} + //Complexity: min(len1,len2)^2 + max(len1,len2) template<class RandIt, class Compare> void merge_bufferless_ON2(RandIt first, RandIt middle, RandIt last, Compare comp) @@ -289,13 +541,16 @@ void merge_bufferless_ON2(RandIt first, RandIt middle, RandIt last, Compare comp } } -static const std::size_t MergeBufferlessONLogNRotationThreshold = 32; +static const std::size_t MergeBufferlessONLogNRotationThreshold = 16u; -template <class RandIt, class Distance, class Compare> +template <class RandIt, class Compare> void merge_bufferless_ONlogN_recursive - (RandIt first, RandIt middle, RandIt last, Distance len1, Distance len2, Compare comp) + ( RandIt first, RandIt middle, RandIt last + , typename iter_size<RandIt>::type len1 + , typename iter_size<RandIt>::type len2 + , Compare comp) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; while(1) { //trivial cases @@ -317,8 +572,8 @@ void merge_bufferless_ONlogN_recursive RandIt first_cut = first; RandIt second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; + size_type len11 = 0; + size_type len22 = 0; if (len1 > len2) { len11 = len1 / 2; first_cut += len11; @@ -334,16 +589,17 @@ void merge_bufferless_ONlogN_recursive RandIt new_middle = rotate_gcd(first_cut, middle, second_cut); //Avoid one recursive call doing a manual tail call elimination on the biggest range - const Distance len_internal = len11+len22; + const size_type len_internal = size_type(len11+len22); if( len_internal < (len1 + len2 - len_internal) ) { - merge_bufferless_ONlogN_recursive(first, first_cut, new_middle, len11, len22, comp); + merge_bufferless_ONlogN_recursive(first, first_cut, new_middle, len11, len22, comp); first = new_middle; middle = second_cut; - len1 -= len11; - len2 -= len22; + len1 = size_type(len1-len11); + len2 = size_type(len2-len22); } else { - merge_bufferless_ONlogN_recursive(new_middle, second_cut, last, len1 - len11, len2 - len22, comp); + merge_bufferless_ONlogN_recursive + (new_middle, second_cut, last, size_type(len1 - len11), size_type(len2 - len22), comp); middle = first_cut; last = new_middle; len1 = len11; @@ -352,12 +608,14 @@ void merge_bufferless_ONlogN_recursive } } + //Complexity: NlogN template<class RandIt, class Compare> void merge_bufferless_ONlogN(RandIt first, RandIt middle, RandIt last, Compare comp) { + typedef typename iter_size<RandIt>::type size_type; merge_bufferless_ONlogN_recursive - (first, middle, last, middle - first, last - middle, comp); + (first, middle, last, size_type(middle - first), size_type(last - middle), comp); } template<class RandIt, class Compare> @@ -383,7 +641,7 @@ void op_merge_with_right_placed if (r_first == r_last) { InputOutIterator end = op(forward_t(), first, last, dest_first); BOOST_ASSERT(end == r_last); - (void)end; + boost::ignore_unused(end); return; } else if (comp(*r_first, *first)) { @@ -420,7 +678,7 @@ void op_merge_with_left_placed if(first == last) { BidirOutIterator res = op(backward_t(), r_first, r_last, dest_last); BOOST_ASSERT(last == res); - (void)res; + boost::ignore_unused(res); return; } --r_last; @@ -441,7 +699,7 @@ void op_merge_with_left_placed // @endcond -// [irst, last) are already in the right part of the destination range. +// [first, last) are already in the right part of the destination range. template <class Compare, class BidirIterator, class BidirOutIterator> void merge_with_left_placed ( BidirOutIterator const first, BidirOutIterator last, BidirOutIterator dest_last @@ -484,7 +742,7 @@ void uninitialized_merge_with_right_placed d.release(); InputOutIterator end = ::boost::move(first, last, original_r_first); BOOST_ASSERT(end == r_last); - (void)end; + boost::ignore_unused(end); return; } else if (comp(*r_first, *first)) { @@ -503,51 +761,138 @@ void uninitialized_merge_with_right_placed merge_with_right_placed(first, last, original_r_first, r_first, r_last, comp); } -/* -// [r_first, r_last) are already in the right part of the destination range. -// [dest_first, r_first) is uninitialized memory -template <class Compare, class BidirOutIterator, class BidirIterator> -void uninitialized_merge_with_left_placed - ( BidirOutIterator dest_first, BidirOutIterator r_first, BidirOutIterator r_last - , BidirIterator first, BidirIterator last - , Compare comp) +/// This is a helper function for the merge routines. +template<typename BidirectionalIterator1, typename BidirectionalIterator2> + BidirectionalIterator1 + rotate_adaptive(BidirectionalIterator1 first, + BidirectionalIterator1 middle, + BidirectionalIterator1 last, + typename iter_size<BidirectionalIterator1>::type len1, + typename iter_size<BidirectionalIterator1>::type len2, + BidirectionalIterator2 buffer, + typename iter_size<BidirectionalIterator1>::type buffer_size) { - BOOST_ASSERT((last - first) == (r_last - r_first)); - typedef typename iterator_traits<BidirOutIterator>::value_type value_type; - BidirOutIterator const original_r_last = r_last; - - destruct_n<value_type> d(&*dest_last); - - while ( first != last && dest_first != original_r_first ) { - if (r_first == r_last) { - for(; dest_first != original_r_first; ++dest_first, ++first){ - ::new(&*dest_first) value_type(::boost::move(*first)); - d.incr(); - } - d.release(); - BidirOutIterator end = ::boost::move(first, last, original_r_first); - BOOST_ASSERT(end == r_last); - (void)end; - return; + if (len1 > len2 && len2 <= buffer_size) + { + if(len2) //Protect against self-move ranges + { + BidirectionalIterator2 buffer_end = boost::move(middle, last, buffer); + boost::move_backward(first, middle, last); + return boost::move(buffer, buffer_end, first); } - else if (comp(*r_first, *first)) { - ::new(&*dest_first) value_type(::boost::move(*r_first)); - d.incr(); - ++r_first; + else + return first; + } + else if (len1 <= buffer_size) + { + if(len1) //Protect against self-move ranges + { + BidirectionalIterator2 buffer_end = boost::move(first, middle, buffer); + BidirectionalIterator1 ret = boost::move(middle, last, first); + boost::move(buffer, buffer_end, ret); + return ret; } - else { - ::new(&*dest_first) value_type(::boost::move(*first)); - d.incr(); - ++first; + else + return last; + } + else + return rotate_gcd(first, middle, last); +} + +template<typename BidirectionalIterator, + typename Pointer, typename Compare> + void merge_adaptive_ONlogN_recursive + (BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, + typename iter_size<BidirectionalIterator>::type len1, + typename iter_size<BidirectionalIterator>::type len2, + Pointer buffer, + typename iter_size<BidirectionalIterator>::type buffer_size, + Compare comp) +{ + typedef typename iter_size<BidirectionalIterator>::type size_type; + //trivial cases + if (!len2 || !len1) { + // no-op + } + else if (len1 <= buffer_size || len2 <= buffer_size) { + range_xbuf<Pointer, size_type, move_op> rxbuf(buffer, buffer + buffer_size); + buffered_merge(first, middle, last, comp, rxbuf); + } + else if (size_type(len1 + len2) == 2u) { + if (comp(*middle, *first)) + adl_move_swap(*first, *middle); + } + else if (size_type(len1 + len2) < MergeBufferlessONLogNRotationThreshold) { + merge_bufferless_ON2(first, middle, last, comp); + } + else { + BidirectionalIterator first_cut = first; + BidirectionalIterator second_cut = middle; + size_type len11 = 0; + size_type len22 = 0; + if (len1 > len2) //(len1 < len2) + { + len11 = len1 / 2; + first_cut += len11; + second_cut = boost::movelib::lower_bound(middle, last, *first_cut, comp); + len22 = size_type(second_cut - middle); } - ++dest_first; + else + { + len22 = len2 / 2; + second_cut += len22; + first_cut = boost::movelib::upper_bound(first, middle, *second_cut, comp); + len11 = size_type(first_cut - first); + } + + BidirectionalIterator new_middle + = rotate_adaptive(first_cut, middle, second_cut, + size_type(len1 - len11), len22, buffer, + buffer_size); + merge_adaptive_ONlogN_recursive(first, first_cut, new_middle, len11, + len22, buffer, buffer_size, comp); + merge_adaptive_ONlogN_recursive(new_middle, second_cut, last, + size_type(len1 - len11), size_type(len2 - len22), buffer, buffer_size, comp); + } +} + + +template<typename BidirectionalIterator, typename Compare, typename RandRawIt> +void merge_adaptive_ONlogN(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, + Compare comp, + RandRawIt uninitialized, + typename iter_size<BidirectionalIterator>::type uninitialized_len) +{ + typedef typename iterator_traits<BidirectionalIterator>::value_type value_type; + typedef typename iter_size<BidirectionalIterator>::type size_type; + + if (first == middle || middle == last) + return; + + if(uninitialized_len) + { + const size_type len1 = size_type(middle - first); + const size_type len2 = size_type(last - middle); + + ::boost::movelib::adaptive_xbuf<value_type, RandRawIt> xbuf(uninitialized, uninitialized_len); + xbuf.initialize_until(uninitialized_len, *first); + merge_adaptive_ONlogN_recursive(first, middle, last, len1, len2, xbuf.begin(), uninitialized_len, comp); + } + else + { + merge_bufferless(first, middle, last, comp); } - d.release(); - merge_with_right_placed(first, last, original_r_first, r_first, r_last, comp); } -*/ } //namespace movelib { } //namespace boost { +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic pop +#endif + #endif //#define BOOST_MOVE_MERGE_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/algo/detail/merge_sort.hpp b/contrib/restricted/boost/move/include/boost/move/algo/detail/merge_sort.hpp index 62d185acb6..dbc4797caa 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/detail/merge_sort.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/detail/merge_sort.hpp @@ -34,6 +34,11 @@ #include <boost/move/algo/detail/insertion_sort.hpp> #include <cassert> +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + namespace boost { namespace movelib { @@ -44,7 +49,7 @@ static const unsigned MergeSortInsertionSortThreshold = 16; template <class RandIt, class Compare> void inplace_stable_sort(RandIt first, RandIt last, Compare comp) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; if (size_type(last - first) <= size_type(MergeSortInsertionSortThreshold)) { insertion_sort(first, last, comp); return; @@ -62,14 +67,14 @@ template<class RandIt, class RandIt2, class Compare> void merge_sort_copy( RandIt first, RandIt last , RandIt2 dest, Compare comp) { - typedef typename iterator_traits<RandIt>::size_type size_type; - + typedef typename iter_size<RandIt>::type size_type; + size_type const count = size_type(last - first); if(count <= MergeSortInsertionSortThreshold){ insertion_sort_copy(first, last, dest, comp); } else{ - size_type const half = count/2; + size_type const half = size_type(count/2u); merge_sort_copy(first + half, last , dest+half , comp); merge_sort_copy(first , first + half, first + half, comp); merge_with_right_placed @@ -84,7 +89,7 @@ void merge_sort_uninitialized_copy( RandIt first, RandIt last , RandItRaw uninitialized , Compare comp) { - typedef typename iterator_traits<RandIt>::size_type size_type; + typedef typename iter_size<RandIt>::type size_type; typedef typename iterator_traits<RandIt>::value_type value_type; size_type const count = size_type(last - first); @@ -95,7 +100,7 @@ void merge_sort_uninitialized_copy( RandIt first, RandIt last size_type const half = count/2; merge_sort_uninitialized_copy(first + half, last, uninitialized + half, comp); destruct_n<value_type, RandItRaw> d(uninitialized+half); - d.incr(count-half); + d.incr(size_type(count-half)); merge_sort_copy(first, first + half, first + half, comp); uninitialized_merge_with_right_placed ( first + half, first + half + half @@ -109,16 +114,16 @@ template<class RandIt, class RandItRaw, class Compare> void merge_sort( RandIt first, RandIt last, Compare comp , RandItRaw uninitialized) { - typedef typename iterator_traits<RandIt>::size_type size_type; - typedef typename iterator_traits<RandIt>::value_type value_type; + typedef typename iter_size<RandIt>::type size_type; + typedef typename iterator_traits<RandIt>::value_type value_type; size_type const count = size_type(last - first); if(count <= MergeSortInsertionSortThreshold){ insertion_sort(first, last, comp); } else{ - size_type const half = count/2; - size_type const rest = count - half; + size_type const half = size_type(count/2u); + size_type const rest = size_type(count - half); RandIt const half_it = first + half; RandIt const rest_it = first + rest; @@ -132,8 +137,80 @@ void merge_sort( RandIt first, RandIt last, Compare comp } } +///@cond + +template<class RandIt, class RandItRaw, class Compare> +void merge_sort_with_constructed_buffer( RandIt first, RandIt last, Compare comp, RandItRaw buffer) +{ + typedef typename iter_size<RandIt>::type size_type; + + size_type const count = size_type(last - first); + if(count <= MergeSortInsertionSortThreshold){ + insertion_sort(first, last, comp); + } + else{ + size_type const half = size_type(count/2); + size_type const rest = size_type(count - half); + RandIt const half_it = first + half; + RandIt const rest_it = first + rest; + + merge_sort_copy(half_it, last, buffer, comp); + merge_sort_copy(first, half_it, rest_it, comp); + merge_with_right_placed + (buffer, buffer + rest + , first, rest_it, last, antistable<Compare>(comp)); + } +} + +template<typename RandIt, typename Pointer, + typename Distance, typename Compare> +void stable_sort_ONlogN_recursive(RandIt first, RandIt last, Pointer buffer, Distance buffer_size, Compare comp) +{ + typedef typename iter_size<RandIt>::type size_type; + if (size_type(last - first) <= size_type(MergeSortInsertionSortThreshold)) { + insertion_sort(first, last, comp); + } + else { + const size_type len = size_type(last - first) / 2u; + const RandIt middle = first + len; + if (len > ((buffer_size+1)/2)){ + stable_sort_ONlogN_recursive(first, middle, buffer, buffer_size, comp); + stable_sort_ONlogN_recursive(middle, last, buffer, buffer_size, comp); + } + else{ + merge_sort_with_constructed_buffer(first, middle, comp, buffer); + merge_sort_with_constructed_buffer(middle, last, comp, buffer); + } + merge_adaptive_ONlogN_recursive(first, middle, last, + size_type(middle - first), + size_type(last - middle), + buffer, buffer_size, + comp); + } +} + +template<typename BidirectionalIterator, typename Compare, typename RandRawIt> +void stable_sort_adaptive_ONlogN2(BidirectionalIterator first, + BidirectionalIterator last, + Compare comp, + RandRawIt uninitialized, + std::size_t uninitialized_len) +{ + typedef typename iterator_traits<BidirectionalIterator>::value_type value_type; + + ::boost::movelib::adaptive_xbuf<value_type, RandRawIt> xbuf(uninitialized, uninitialized_len); + xbuf.initialize_until(uninitialized_len, *first); + stable_sort_ONlogN_recursive(first, last, uninitialized, uninitialized_len, comp); +} + +///@endcond + }} //namespace boost { namespace movelib{ +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic pop +#endif + #include <boost/move/detail/config_end.hpp> #endif //#ifndef BOOST_MOVE_DETAIL_MERGE_SORT_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/algo/detail/search.hpp b/contrib/restricted/boost/move/include/boost/move/algo/detail/search.hpp new file mode 100644 index 0000000000..9433fbd491 --- /dev/null +++ b/contrib/restricted/boost/move/include/boost/move/algo/detail/search.hpp @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2022-2022. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_DETAIL_SEARCH_HPP +#define BOOST_MOVE_DETAIL_SEARCH_HPP + +#include <boost/move/detail/iterator_traits.hpp> + +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +namespace boost { +namespace movelib { + +template <class RandIt, class T, class Compare> +RandIt lower_bound + (RandIt first, const RandIt last, const T& key, Compare comp) +{ + typedef typename iter_size<RandIt>::type size_type; + size_type len = size_type(last - first); + RandIt middle; + + while (len) { + size_type step = size_type(len >> 1); + middle = first; + middle += step; + + if (comp(*middle, key)) { + first = ++middle; + len = size_type(len - (step + 1)); + } + else{ + len = step; + } + } + return first; +} + +template <class RandIt, class T, class Compare> +RandIt upper_bound + (RandIt first, const RandIt last, const T& key, Compare comp) +{ + typedef typename iter_size<RandIt>::type size_type; + size_type len = size_type(last - first); + RandIt middle; + + while (len) { + size_type step = size_type(len >> 1); + middle = first; + middle += step; + + if (!comp(key, *middle)) { + first = ++middle; + len = size_type(len - (step + 1)); + } + else{ + len = step; + } + } + return first; +} + +} //namespace movelib { +} //namespace boost { + +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic pop +#endif + +#endif //#define BOOST_MOVE_DETAIL_SEARCH_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/algo/detail/set_difference.hpp b/contrib/restricted/boost/move/include/boost/move/algo/detail/set_difference.hpp index 51d047592a..812ca5f3af 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/detail/set_difference.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/detail/set_difference.hpp @@ -15,8 +15,12 @@ #include <boost/move/iterator.hpp> #include <boost/move/utility_core.hpp> -namespace boost { +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif +namespace boost { namespace move_detail{ template<class InputIt, class OutputIt> @@ -174,7 +178,7 @@ ForwardOutputIt1 inplace_set_unique_difference ++first2; } else if (comp(*first1, *first2)){ - //skip any adjacent equivalent elementin range 1 + //skip any adjacent equivalent element in range 1 ForwardOutputIt1 result = first1; if (++first1 != last1 && !comp(*result, *first1)) { //Some elements from range 1 must be skipped, no longer an inplace operation @@ -199,7 +203,9 @@ ForwardOutputIt1 inplace_set_unique_difference return first1; } - +#if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600)) +#pragma GCC diagnostic pop +#endif } //namespace movelib { } //namespace boost { diff --git a/contrib/restricted/boost/move/include/boost/move/algo/move.hpp b/contrib/restricted/boost/move/include/boost/move/algo/move.hpp index 2390877a43..1c97c89526 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/move.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/move.hpp @@ -27,7 +27,11 @@ #include <boost/move/utility_core.hpp> #include <boost/move/detail/iterator_traits.hpp> #include <boost/move/detail/iterator_to_raw_pointer.hpp> -#include <boost/detail/no_exceptions_support.hpp> +#include <boost/move/detail/addressof.hpp> +#include <boost/core/no_exceptions_support.hpp> +#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) +#include <algorithm> +#endif namespace boost { diff --git a/contrib/restricted/boost/move/include/boost/move/algo/predicate.hpp b/contrib/restricted/boost/move/include/boost/move/algo/predicate.hpp index 01f9586e89..18dc4ee048 100644 --- a/contrib/restricted/boost/move/include/boost/move/algo/predicate.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algo/predicate.hpp @@ -24,36 +24,47 @@ namespace movelib { template<class Comp> struct antistable { - explicit antistable(Comp &comp) + BOOST_MOVE_FORCEINLINE explicit antistable(Comp &comp) : m_comp(comp) {} - antistable(const antistable & other) + BOOST_MOVE_FORCEINLINE antistable(const antistable & other) : m_comp(other.m_comp) {} template<class U, class V> - bool operator()(const U &u, const V & v) + BOOST_MOVE_FORCEINLINE bool operator()(const U &u, const V & v) { return !m_comp(v, u); } + BOOST_MOVE_FORCEINLINE const Comp &get() const + { return m_comp; } + private: antistable & operator=(const antistable &); Comp &m_comp; }; +template<class Comp> +Comp unantistable(Comp comp) +{ return comp; } + +template<class Comp> +Comp unantistable(antistable<Comp> comp) +{ return comp.get(); } + template <class Comp> class negate { public: - negate() + BOOST_MOVE_FORCEINLINE negate() {} - explicit negate(Comp comp) + BOOST_MOVE_FORCEINLINE explicit negate(Comp comp) : m_comp(comp) {} template <class T1, class T2> - bool operator()(const T1& l, const T2& r) + BOOST_MOVE_FORCEINLINE bool operator()(const T1& l, const T2& r) { return !m_comp(l, r); } @@ -67,15 +78,15 @@ template <class Comp> class inverse { public: - inverse() + BOOST_MOVE_FORCEINLINE inverse() {} - explicit inverse(Comp comp) + BOOST_MOVE_FORCEINLINE explicit inverse(Comp comp) : m_comp(comp) {} template <class T1, class T2> - bool operator()(const T1& l, const T2& r) + BOOST_MOVE_FORCEINLINE bool operator()(const T1& l, const T2& r) { return m_comp(r, l); } diff --git a/contrib/restricted/boost/move/include/boost/move/algorithm.hpp b/contrib/restricted/boost/move/include/boost/move/algorithm.hpp index 825d7716c2..880d661e7d 100644 --- a/contrib/restricted/boost/move/include/boost/move/algorithm.hpp +++ b/contrib/restricted/boost/move/include/boost/move/algorithm.hpp @@ -27,7 +27,7 @@ #include <boost/move/utility_core.hpp> #include <boost/move/iterator.hpp> #include <boost/move/algo/move.hpp> -#include <boost/detail/no_exceptions_support.hpp> +#include <boost/core/no_exceptions_support.hpp> #include <algorithm> //copy, copy_backward #include <memory> //uninitialized_copy diff --git a/contrib/restricted/boost/move/include/boost/move/core.hpp b/contrib/restricted/boost/move/include/boost/move/core.hpp index 300496d26b..68f8f2a126 100644 --- a/contrib/restricted/boost/move/include/boost/move/core.hpp +++ b/contrib/restricted/boost/move/include/boost/move/core.hpp @@ -57,14 +57,15 @@ #include <boost/move/detail/type_traits.hpp> - #if defined(BOOST_MOVE_ADDRESS_SANITIZER_ON) - #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast<RV_TYPE>(ARG) - #else - #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) static_cast<RV_TYPE>(ARG) - #endif + #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast<RV_TYPE>(ARG) + #define BOOST_MOVE_TO_LV_CAST(LV_TYPE, ARG) static_cast<LV_TYPE>(ARG) //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers - #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS + #if defined(BOOST_GCC) && (BOOST_GCC >= 40400) && (BOOST_GCC < 40500) + #define BOOST_RV_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS + #else + #define BOOST_RV_ATTRIBUTE_MAY_ALIAS + #endif namespace boost { @@ -74,7 +75,7 @@ // ////////////////////////////////////////////////////////////////////////////// template <class T> - class rv + class BOOST_RV_ATTRIBUTE_MAY_ALIAS rv : public ::boost::move_detail::if_c < ::boost::move_detail::is_class<T>::value , T @@ -85,7 +86,7 @@ ~rv(); rv(rv const&); void operator=(rv const&); - } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS; + }; ////////////////////////////////////////////////////////////////////////////// @@ -218,6 +219,10 @@ return x; } + template <class T> + BOOST_MOVE_FORCEINLINE T& unrv(::boost::rv<T> &rv) BOOST_NOEXCEPT + { return BOOST_MOVE_TO_LV_CAST(T&, rv); } + } //namespace move_detail { } //namespace boost { @@ -229,6 +234,11 @@ ::boost::move((BASE_TYPE&)(ARG)) // + #define BOOST_MOVE_TO_LV(ARG) \ + ::boost::move_detail::unrv(ARG) + // + + ////////////////////////////////////////////////////////////////////////////// // // BOOST_MOVABLE_BUT_NOT_COPYABLE @@ -480,6 +490,17 @@ ::boost::move((BASE_TYPE&)(ARG)) // + //!This macro is used to achieve portable optimal move constructors. + //! + //!In C++03 mode, when accessing a member of type through a rvalue (implemented as a `rv<T> &` type, where rv<T> derives + //!from T) triggers a potential UB as the program never creates objects of type rv<T>. This macro casts back `rv<T>` to + //!`T&` so that access to member types are done through the original type. + //! + //!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of + //!a base type is implicit, so it's a no-op. + #define BOOST_MOVE_TO_LV(ARG) ARG + // + namespace boost { namespace move_detail { diff --git a/contrib/restricted/boost/move/include/boost/move/default_delete.hpp b/contrib/restricted/boost/move/include/boost/move/default_delete.hpp index 31ae67aa07..275794eae2 100644 --- a/contrib/restricted/boost/move/include/boost/move/default_delete.hpp +++ b/contrib/restricted/boost/move/include/boost/move/default_delete.hpp @@ -112,6 +112,33 @@ void call_delete(T *p, is_array_del<false>) delete p; } +template< class T, class U + , bool enable = def_del_compatible_cond< U, T>::value && + !move_upmu::is_array<T>::value && + !move_upmu::is_same<typename move_upmu::remove_cv<T>::type, void>::value && + !move_upmu::is_same<typename move_upmu::remove_cv<U>::type, typename move_upmu::remove_cv<T>::type>::value + > +struct missing_virtual_destructor_default_delete +{ static const bool value = !move_upmu::has_virtual_destructor<T>::value; }; + +template<class T, class U> +struct missing_virtual_destructor_default_delete<T, U, false> +{ static const bool value = false; }; + +////////////////////////////////////// +// missing_virtual_destructor +////////////////////////////////////// + +template<class Deleter, class U> +struct missing_virtual_destructor +{ static const bool value = false; }; + +template<class T, class U> +struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U > + : missing_virtual_destructor_default_delete<T, U> +{}; + + } //namespace move_upd { // @endcond @@ -163,7 +190,7 @@ struct default_delete { //If T is not an array type, U derives from T //and T has no virtual destructor, then you have a problem - BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value )); + BOOST_STATIC_ASSERT(( !bmupd::missing_virtual_destructor<default_delete, U>::value )); } //! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object. @@ -178,7 +205,7 @@ struct default_delete { //If T is not an array type, U derives from T //and T has no virtual destructor, then you have a problem - BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value )); + BOOST_STATIC_ASSERT(( !bmupd::missing_virtual_destructor<default_delete, U>::value )); return *this; } @@ -198,7 +225,7 @@ struct default_delete BOOST_STATIC_ASSERT(sizeof(U) > 0); //If T is not an array type, U derives from T //and T has no virtual destructor, then you have a problem - BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value )); + BOOST_STATIC_ASSERT(( !bmupd::missing_virtual_destructor<default_delete, U>::value )); element_type * const p = static_cast<element_type*>(ptr); move_upd::call_delete(p, move_upd::is_array_del<bmupmu::is_array<T>::value>()); } diff --git a/contrib/restricted/boost/move/include/boost/move/detail/addressof.hpp b/contrib/restricted/boost/move/include/boost/move/detail/addressof.hpp new file mode 100644 index 0000000000..8679fa9438 --- /dev/null +++ b/contrib/restricted/boost/move/include/boost/move/detail/addressof.hpp @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. 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/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_DETAIL_ADDRESSOF_HPP +#define BOOST_MOVE_DETAIL_ADDRESSOF_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include <boost/move/detail/workaround.hpp> + +namespace boost { +namespace move_detail { + +#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215 +#define BOOST_MOVE_HAS_BUILTIN_ADDRESSOF +#elif defined(BOOST_GCC) && BOOST_GCC >= 70000 +#define BOOST_MOVE_HAS_BUILTIN_ADDRESSOF +#elif defined(__has_builtin) +#if __has_builtin(__builtin_addressof) +#define BOOST_MOVE_HAS_BUILTIN_ADDRESSOF +#endif +#endif + +#ifdef BOOST_MOVE_HAS_BUILTIN_ADDRESSOF + +template<class T> +BOOST_MOVE_FORCEINLINE T *addressof( T & v ) BOOST_NOEXCEPT +{ + return __builtin_addressof(v); +} + +#else //BOOST_MOVE_HAS_BUILTIN_ADDRESSOF + +template <typename T> +BOOST_MOVE_FORCEINLINE T* addressof(T& obj) +{ + return static_cast<T*>( + static_cast<void*>( + const_cast<char*>( + &reinterpret_cast<const volatile char&>(obj) + ))); +} + +#endif //BOOST_MOVE_HAS_BUILTIN_ADDRESSOF + +} //namespace move_detail { +} //namespace boost { + +#endif //#ifndef BOOST_MOVE_DETAIL_ADDRESSOF_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/detail/config_begin.hpp b/contrib/restricted/boost/move/include/boost/move/detail/config_begin.hpp index 637eb158bd..4e95a4aba7 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/config_begin.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/config_begin.hpp @@ -13,6 +13,7 @@ #ifdef BOOST_MSVC # pragma warning (push) +# pragma warning (disable : 4619) // there is no warning number 'XXXX' # pragma warning (disable : 4324) // structure was padded due to __declspec(align()) # pragma warning (disable : 4675) // "function": resolved overload was found by argument-dependent lookup # pragma warning (disable : 4996) // "function": was declared deprecated (_CRT_SECURE_NO_DEPRECATE/_SCL_SECURE_NO_WARNINGS) diff --git a/contrib/restricted/boost/move/include/boost/move/detail/force_ptr.hpp b/contrib/restricted/boost/move/include/boost/move/detail/force_ptr.hpp new file mode 100644 index 0000000000..3abed2d8cf --- /dev/null +++ b/contrib/restricted/boost/move/include/boost/move/detail/force_ptr.hpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. 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/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_DETAIL_FORCE_CAST_HPP +#define BOOST_MOVE_DETAIL_FORCE_CAST_HPP + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include <boost/move/detail/workaround.hpp> + +namespace boost { +namespace move_detail { + + +template <typename T> +BOOST_MOVE_FORCEINLINE T force_ptr(const volatile void *p) +{ + return static_cast<T>(const_cast<void*>(p)); +} + +} //namespace move_detail { +} //namespace boost { + +#endif //#ifndef BOOST_MOVE_DETAIL_FORCE_CAST_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/detail/fwd_macros.hpp b/contrib/restricted/boost/move/include/boost/move/detail/fwd_macros.hpp index a5df5f1be7..dcc4b07c8b 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/fwd_macros.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/fwd_macros.hpp @@ -336,6 +336,18 @@ namespace move_detail { #define BOOST_MOVE_VAL_INITQ8 BOOST_MOVE_VAL_INITQ7, m_q7(q7) #define BOOST_MOVE_VAL_INITQ9 BOOST_MOVE_VAL_INITQ8, m_q8(q8) +//BOOST_MOVE_UREFANONN +#define BOOST_MOVE_UREFANON0 +#define BOOST_MOVE_UREFANON1 BOOST_FWD_REF(P0) +#define BOOST_MOVE_UREFANON2 BOOST_MOVE_UREFANON1, BOOST_FWD_REF(P1) +#define BOOST_MOVE_UREFANON3 BOOST_MOVE_UREFANON2, BOOST_FWD_REF(P2) +#define BOOST_MOVE_UREFANON4 BOOST_MOVE_UREFANON3, BOOST_FWD_REF(P3) +#define BOOST_MOVE_UREFANON5 BOOST_MOVE_UREFANON4, BOOST_FWD_REF(P4) +#define BOOST_MOVE_UREFANON6 BOOST_MOVE_UREFANON5, BOOST_FWD_REF(P5) +#define BOOST_MOVE_UREFANON7 BOOST_MOVE_UREFANON6, BOOST_FWD_REF(P6) +#define BOOST_MOVE_UREFANON8 BOOST_MOVE_UREFANON7, BOOST_FWD_REF(P7) +#define BOOST_MOVE_UREFANON9 BOOST_MOVE_UREFANON8, BOOST_FWD_REF(P8) + //BOOST_MOVE_UREFN #define BOOST_MOVE_UREF0 #define BOOST_MOVE_UREF1 BOOST_FWD_REF(P0) p0 diff --git a/contrib/restricted/boost/move/include/boost/move/detail/iterator_to_raw_pointer.hpp b/contrib/restricted/boost/move/include/boost/move/detail/iterator_to_raw_pointer.hpp index 97ee3a6595..67afd6c1ef 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/iterator_to_raw_pointer.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/iterator_to_raw_pointer.hpp @@ -27,11 +27,11 @@ namespace movelib { namespace detail { template <class T> -inline T* iterator_to_pointer(T* i) +BOOST_MOVE_FORCEINLINE T* iterator_to_pointer(T* i) { return i; } template <class Iterator> -inline typename boost::movelib::iterator_traits<Iterator>::pointer +BOOST_MOVE_FORCEINLINE typename boost::movelib::iterator_traits<Iterator>::pointer iterator_to_pointer(const Iterator &i) { return i.operator->(); } @@ -46,7 +46,7 @@ struct iterator_to_element_ptr } //namespace detail { template <class Iterator> -inline typename boost::movelib::detail::iterator_to_element_ptr<Iterator>::type +BOOST_MOVE_FORCEINLINE typename boost::movelib::detail::iterator_to_element_ptr<Iterator>::type iterator_to_raw_pointer(const Iterator &i) { return ::boost::movelib::to_raw_pointer diff --git a/contrib/restricted/boost/move/include/boost/move/detail/iterator_traits.hpp b/contrib/restricted/boost/move/include/boost/move/detail/iterator_traits.hpp index 5ffcb2cf05..9ea01c25e6 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/iterator_traits.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/iterator_traits.hpp @@ -22,10 +22,44 @@ # pragma once #endif +#if (BOOST_CXX_VERSION > 201703L) && defined(__cpp_lib_concepts) + +#include <iterator> + +#define BOOST_MOVE_CONTIGUOUS_ITERATOR_TAG + +namespace boost { +namespace movelib { + + using std::iterator_traits; + + template<class T> + struct iter_difference + { + typedef typename std::iterator_traits<T>::difference_type type; + }; + + template<class T> + struct iter_value + { + typedef typename std::iterator_traits<T>::value_type type; + }; + + template<class T> + struct iter_category + { + typedef typename std::iterator_traits<T>::iterator_category type; + }; + +}} //namespace boost::movelib + +#else + #include <cstddef> #include <boost/move/detail/type_traits.hpp> #include <boost/move/detail/std_ns_begin.hpp> + BOOST_MOVE_STD_NS_BEG struct input_iterator_tag; @@ -34,20 +68,73 @@ struct bidirectional_iterator_tag; struct random_access_iterator_tag; struct output_iterator_tag; +#if ( (defined(BOOST_GNU_STDLIB) && (__cplusplus > 201703L))\ + || (defined(_LIBCPP_VERSION) && (_LIBCPP_STD_VER > 17))\ + || (defined(_YVALS) && defined(_CPPLIB_VER) && defined(__cpp_lib_concepts))\ + || (__cplusplus >= 202002L)\ + ) +# define BOOST_MOVE_CONTIGUOUS_ITERATOR_TAG +struct contiguous_iterator_tag; + +#endif + BOOST_MOVE_STD_NS_END + #include <boost/move/detail/std_ns_end.hpp> namespace boost{ namespace movelib{ +template<class T> +struct iter_difference +{ + typedef typename T::difference_type type; +}; + +template<class T> +struct iter_difference<T*> +{ + typedef std::ptrdiff_t type; +}; + +template<class T> +struct iter_value +{ + typedef typename T::value_type type; +}; + +template<class T> +struct iter_value<T*> +{ + typedef T type; +}; + +template<class T> +struct iter_value<const T*> +{ + typedef T type; +}; + +template<class T> +struct iter_category +{ + typedef typename T::iterator_category type; +}; + + +template<class T> +struct iter_category<T*> +{ + typedef std::random_access_iterator_tag type; +}; + template<class Iterator> struct iterator_traits { - typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::value_type value_type; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::reference reference; - typedef typename Iterator::iterator_category iterator_category; - typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type; + typedef typename iter_difference<Iterator>::type difference_type; + typedef typename iter_value<Iterator>::type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename iter_category<Iterator>::type iterator_category; }; template<class T> @@ -58,7 +145,6 @@ struct iterator_traits<T*> typedef T* pointer; typedef T& reference; typedef std::random_access_iterator_tag iterator_category; - typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type; }; template<class T> @@ -69,9 +155,23 @@ struct iterator_traits<const T*> typedef const T* pointer; typedef const T& reference; typedef std::random_access_iterator_tag iterator_category; - typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type; }; -}} //namespace boost { namespace movelib{ +}} //namespace boost::movelib + +#endif // + +#include <boost/move/detail/type_traits.hpp> + +namespace boost { +namespace movelib { + +template<class T> +struct iter_size + : boost::move_detail:: + make_unsigned<typename iter_difference<T>::type > +{}; + +}} //namespace boost move_detail { #endif //#ifndef BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP diff --git a/contrib/restricted/boost/move/include/boost/move/detail/meta_utils.hpp b/contrib/restricted/boost/move/include/boost/move/detail/meta_utils.hpp index e45394c97d..7c90de287e 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/meta_utils.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/meta_utils.hpp @@ -21,6 +21,7 @@ #include <boost/move/detail/workaround.hpp> //forceinline #include <boost/move/detail/meta_utils_core.hpp> #include <cstddef> //for std::size_t +#include <boost/move/detail/addressof.hpp> //Small meta-typetraits to support move @@ -56,8 +57,8 @@ struct apply template< bool C_ > struct bool_ : integral_constant<bool, C_> { - operator bool() const { return C_; } - bool operator()() const { return C_; } + BOOST_MOVE_FORCEINLINE operator bool() const { return C_; } + BOOST_MOVE_FORCEINLINE bool operator()() const { return C_; } }; typedef bool_<true> true_; @@ -67,6 +68,12 @@ typedef bool_<false> false_; // nat ////////////////////////////////////// struct nat{}; +struct nat2{}; +struct nat3{}; + +template <unsigned N> +struct natN +{}; ////////////////////////////////////// // yes_type/no_type @@ -218,7 +225,7 @@ struct identity { typedef T type; typedef typename add_const_lvalue_reference<T>::type reference; - reference operator()(reference t) + BOOST_MOVE_FORCEINLINE reference operator()(reference t) const { return t; } }; @@ -239,36 +246,7 @@ struct is_class_or_union ////////////////////////////////////// // addressof ////////////////////////////////////// -template<class T> -struct addr_impl_ref -{ - T & v_; - BOOST_MOVE_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {} - BOOST_MOVE_FORCEINLINE operator T& () const { return v_; } - - private: - addr_impl_ref & operator=(const addr_impl_ref &); -}; -template<class T> -struct addressof_impl -{ - BOOST_MOVE_FORCEINLINE static T * f( T & v, long ) - { - return reinterpret_cast<T*>( - &const_cast<char&>(reinterpret_cast<const volatile char &>(v))); - } - - BOOST_MOVE_FORCEINLINE static T * f( T * v, int ) - { return v; } -}; - -template<class T> -BOOST_MOVE_FORCEINLINE T * addressof( T & v ) -{ - return ::boost::move_detail::addressof_impl<T>::f - ( ::boost::move_detail::addr_impl_ref<T>( v ), 0 ); -} ////////////////////////////////////// // has_pointer_type diff --git a/contrib/restricted/boost/move/include/boost/move/detail/meta_utils_core.hpp b/contrib/restricted/boost/move/include/boost/move/detail/meta_utils_core.hpp index 40dbb6efc3..4e11673834 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/meta_utils_core.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/meta_utils_core.hpp @@ -27,6 +27,9 @@ namespace boost { namespace move_detail { +template<typename T> +struct voider { typedef void type; }; + ////////////////////////////////////// // if_c ////////////////////////////////////// @@ -52,7 +55,9 @@ struct if_ : if_c<0 != T1::value, T2, T3> ////////////////////////////////////// // enable_if_c ////////////////////////////////////// -template <bool B, class T = void> +struct enable_if_nat{}; + +template <bool B, class T = enable_if_nat> struct enable_if_c { typedef T type; @@ -64,13 +69,13 @@ struct enable_if_c<false, T> {}; ////////////////////////////////////// // enable_if ////////////////////////////////////// -template <class Cond, class T = void> +template <class Cond, class T = enable_if_nat> struct enable_if : enable_if_c<Cond::value, T> {}; ////////////////////////////////////// // disable_if_c ////////////////////////////////////// -template <bool B, class T = void> +template <bool B, class T = enable_if_nat> struct disable_if_c : enable_if_c<!B, T> {}; @@ -78,7 +83,7 @@ struct disable_if_c ////////////////////////////////////// // disable_if ////////////////////////////////////// -template <class Cond, class T = void> +template <class Cond, class T = enable_if_nat> struct disable_if : enable_if_c<!Cond::value, T> {}; ////////////////////////////////////// @@ -117,13 +122,13 @@ struct is_same<T, T> ////////////////////////////////////// // enable_if_same ////////////////////////////////////// -template <class T, class U, class R = void> +template <class T, class U, class R = enable_if_nat> struct enable_if_same : enable_if<is_same<T, U>, R> {}; ////////////////////////////////////// // disable_if_same ////////////////////////////////////// -template <class T, class U, class R = void> +template <class T, class U, class R = enable_if_nat> struct disable_if_same : disable_if<is_same<T, U>, R> {}; } //namespace move_detail { diff --git a/contrib/restricted/boost/move/include/boost/move/detail/reverse_iterator.hpp b/contrib/restricted/boost/move/include/boost/move/detail/reverse_iterator.hpp index 73f59ce79f..7fda6edf0d 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/reverse_iterator.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/reverse_iterator.hpp @@ -28,6 +28,14 @@ namespace boost { namespace movelib { +template<class I> +BOOST_MOVE_FORCEINLINE typename iterator_traits<I>::pointer iterator_arrow_result(const I &i) +{ return i.operator->(); } + +template<class T> +BOOST_MOVE_FORCEINLINE T * iterator_arrow_result(T *p) +{ return p; } + template<class It> class reverse_iterator { @@ -41,37 +49,38 @@ class reverse_iterator typedef It iterator_type; - reverse_iterator() + BOOST_MOVE_FORCEINLINE reverse_iterator() : m_current() //Value initialization to achieve "null iterators" (N3644) {} - explicit reverse_iterator(It r) + BOOST_MOVE_FORCEINLINE explicit reverse_iterator(It r) : m_current(r) {} - reverse_iterator(const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE reverse_iterator(const reverse_iterator& r) : m_current(r.base()) {} template<class OtherIt> - reverse_iterator( const reverse_iterator<OtherIt>& r - , typename boost::move_detail::enable_if_convertible<OtherIt, It>::type* =0 + BOOST_MOVE_FORCEINLINE + reverse_iterator( const reverse_iterator<OtherIt>& r + , typename boost::move_detail::enable_if_convertible<OtherIt, It>::type* =0 ) : m_current(r.base()) {} - reverse_iterator & operator=( const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE reverse_iterator & operator=( const reverse_iterator& r) { m_current = r.base(); return *this; } template<class OtherIt> - typename boost::move_detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type + BOOST_MOVE_FORCEINLINE typename boost::move_detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type operator=( const reverse_iterator<OtherIt>& r) { m_current = r.base(); return *this; } - It base() const + BOOST_MOVE_FORCEINLINE It base() const { return m_current; } - reference operator*() const + BOOST_MOVE_FORCEINLINE reference operator*() const { It temp(m_current); --temp; @@ -79,78 +88,78 @@ class reverse_iterator return r; } - pointer operator->() const + BOOST_MOVE_FORCEINLINE pointer operator->() const { It temp(m_current); --temp; - return iterator_arrow_result(temp); + return (iterator_arrow_result)(temp); } - reference operator[](difference_type off) const + BOOST_MOVE_FORCEINLINE reference operator[](difference_type off) const { - return this->m_current[-off - 1]; + return this->m_current[difference_type(-off - 1)]; } - reverse_iterator& operator++() + BOOST_MOVE_FORCEINLINE reverse_iterator& operator++() { --m_current; return *this; } - reverse_iterator operator++(int) + BOOST_MOVE_FORCEINLINE reverse_iterator operator++(int) { reverse_iterator temp((*this)); --m_current; return temp; } - reverse_iterator& operator--() + BOOST_MOVE_FORCEINLINE reverse_iterator& operator--() { ++m_current; return *this; } - reverse_iterator operator--(int) + BOOST_MOVE_FORCEINLINE reverse_iterator operator--(int) { reverse_iterator temp((*this)); ++m_current; return temp; } - friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current == r.m_current; } - friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current != r.m_current; } - friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current > r.m_current; } - friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current >= r.m_current; } - friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current < r.m_current; } - friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) { return l.m_current <= r.m_current; } - reverse_iterator& operator+=(difference_type off) + BOOST_MOVE_FORCEINLINE reverse_iterator& operator+=(difference_type off) { m_current -= off; return *this; } - reverse_iterator& operator-=(difference_type off) + BOOST_MOVE_FORCEINLINE reverse_iterator& operator-=(difference_type off) { m_current += off; return *this; } - friend reverse_iterator operator+(reverse_iterator l, difference_type off) + BOOST_MOVE_FORCEINLINE friend reverse_iterator operator+(reverse_iterator l, difference_type off) { return (l += off); } - friend reverse_iterator operator+(difference_type off, reverse_iterator r) + BOOST_MOVE_FORCEINLINE friend reverse_iterator operator+(difference_type off, reverse_iterator r) { return (r += off); } - friend reverse_iterator operator-(reverse_iterator l, difference_type off) + BOOST_MOVE_FORCEINLINE friend reverse_iterator operator-(reverse_iterator l, difference_type off) { return (l-= off); } - friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) + BOOST_MOVE_FORCEINLINE friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) { return r.m_current - l.m_current; } private: @@ -158,10 +167,8 @@ class reverse_iterator }; template< class Iterator > -reverse_iterator<Iterator> make_reverse_iterator( Iterator i ) -{ - return reverse_iterator<Iterator>(i); -} +BOOST_MOVE_FORCEINLINE reverse_iterator<Iterator> make_reverse_iterator( Iterator i ) +{ return reverse_iterator<Iterator>(i); } } //namespace movelib { } //namespace boost { diff --git a/contrib/restricted/boost/move/include/boost/move/detail/std_ns_begin.hpp b/contrib/restricted/boost/move/include/boost/move/detail/std_ns_begin.hpp index a768e61a15..1d28117b7c 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/std_ns_begin.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/std_ns_begin.hpp @@ -24,7 +24,11 @@ #define BOOST_MOVE_STD_NS_BEG _GLIBCXX_BEGIN_NAMESPACE(std) #define BOOST_MOVE_STD_NS_END _GLIBCXX_END_NAMESPACE #else + #if defined(_MSC_VER) && (_MSC_VER >= 1915) + #pragma warning (push) + #pragma warning (disable : 4643) // Forward declaring 'X' in namespace std is not permitted by the C++ Standard + #endif + #define BOOST_MOVE_STD_NS_BEG namespace std{ #define BOOST_MOVE_STD_NS_END } #endif - diff --git a/contrib/restricted/boost/move/include/boost/move/detail/std_ns_end.hpp b/contrib/restricted/boost/move/include/boost/move/detail/std_ns_end.hpp index 097505995b..61af2d7b1e 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/std_ns_end.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/std_ns_end.hpp @@ -11,4 +11,6 @@ #ifdef BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH #pragma GCC diagnostic pop #undef BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH +#elif defined(_MSC_VER) && (_MSC_VER >= 1915) + #pragma warning (pop) #endif //BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH diff --git a/contrib/restricted/boost/move/include/boost/move/detail/type_traits.hpp b/contrib/restricted/boost/move/include/boost/move/detail/type_traits.hpp index a3326d00e1..e5b7684d65 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/type_traits.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/type_traits.hpp @@ -65,6 +65,8 @@ // BOOST_MOVE_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw // BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw // BOOST_MOVE_IS_ENUM(T) should evaluate to true it t is a union type. +// BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) should evaluate to true if T has a non-throwing move constructor. +// BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) should evaluate to true if T has a non-throwing move assignment operator. // // The following can also be defined: when detected our implementation is greatly simplified. // @@ -102,51 +104,123 @@ # define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__has_trivial_move_constructor(T) || ::boost::move_detail::is_pod<T>::value) # define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) (__has_trivial_move_assign(T) || ::boost::move_detail::is_pod<T>::value) # endif +# if _MSC_FULL_VER >= 180020827 +# define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) (__is_nothrow_assignable(T&, T&&)) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) (__is_nothrow_constructible(T, T&&)) +# endif #endif -#if defined(BOOST_CLANG) && defined(__has_feature) +#if defined(BOOST_CLANG) +// BOOST_MOVE_HAS_TRAIT +# if defined __is_identifier +# define BOOST_MOVE_HAS_TRAIT(T) (__has_extension(T) || !__is_identifier(__##T)) +# elif defined(__has_extension) +# define BOOST_MOVE_HAS_TRAIT(T) __has_extension(T) +# else +# define BOOST_MOVE_HAS_TRAIT(T) 0 +# endif -# if __has_feature(is_union) +// BOOST_MOVE_IS_UNION +# if BOOST_MOVE_HAS_TRAIT(is_union) # define BOOST_MOVE_IS_UNION(T) __is_union(T) # endif -# if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_pod) + +// BOOST_MOVE_IS_ENUM +# if BOOST_MOVE_HAS_TRAIT(is_enum) +# define BOOST_MOVE_IS_ENUM(T) __is_enum(T) +# endif + +// BOOST_MOVE_IS_POD +# if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && BOOST_MOVE_HAS_TRAIT(is_pod) # define BOOST_MOVE_IS_POD(T) __is_pod(T) # endif -# if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty) + +// BOOST_MOVE_IS_EMPTY +# if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && BOOST_MOVE_HAS_TRAIT(is_empty) # define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) # endif -# if __has_feature(has_trivial_constructor) + +// BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR +# if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible) +# define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __is_trivially_constructible(T) +# elif BOOST_MOVE_HAS_TRAIT(has_trivial_constructor) # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # endif -# if __has_feature(has_trivial_copy) + +// BOOST_MOVE_HAS_TRIVIAL_COPY +# if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible) +# define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__is_constructible(T, const T &) && __is_trivially_constructible(T, const T &)) +# elif BOOST_MOVE_HAS_TRAIT(has_trivial_copy) # define BOOST_MOVE_HAS_TRIVIAL_COPY(T) __has_trivial_copy(T) # endif -# if __has_feature(has_trivial_assign) -# define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) ) + +// BOOST_MOVE_HAS_TRIVIAL_ASSIGN +# if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_trivially_assignable) +# define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__is_assignable(T, const T &) && __is_trivially_assignable(T, const T &)) +# elif BOOST_MOVE_HAS_TRAIT(has_trivial_copy) +# define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) __has_trivial_assign(T) # endif -# if __has_feature(has_trivial_destructor) + +// BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR +# if BOOST_MOVE_HAS_TRAIT(is_trivially_destructible) +# define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __is_trivially_destructible(T) +# elif BOOST_MOVE_HAS_TRAIT(has_trivial_destructor) # define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) # endif -# if __has_feature(has_nothrow_constructor) + +// BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR +# if BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible) +# define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __is_nothrow_constructible(T) +# elif BOOST_MOVE_HAS_TRAIT(has_nothrow_constructor) # define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T) # endif -# if __has_feature(has_nothrow_copy) + +// BOOST_MOVE_HAS_NOTHROW_COPY +# if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible) +# define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__is_constructible(T, const T &) && __is_nothrow_constructible(T, const T &)) +# elif BOOST_MOVE_HAS_TRAIT(has_nothrow_copy) # define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T)) # endif -# if __has_feature(is_nothrow_copy_assignable) + +// BOOST_MOVE_HAS_NOTHROW_ASSIGN +# if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_nothrow_assignable) +# define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__is_assignable(T, const T &) && __is_nothrow_assignable(T, const T &)) +# elif BOOST_MOVE_HAS_TRAIT(has_nothrow_assign) # define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T)) # endif -# if __has_feature(is_enum) -# define BOOST_MOVE_IS_ENUM(T) __is_enum(T) -# endif -# if __has_feature(has_trivial_move_constructor) + +// BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible) +# define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_constructible(T, T&&) && __is_trivially_constructible(T, T&&)) +# elif BOOST_MOVE_HAS_TRAIT(has_trivial_move_constructor) # define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) __has_trivial_move_constructor(T) # endif -# if __has_feature(has_trivial_move_assign) + +// BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_trivially_assignable) +# define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) (__is_assignable(T, T&&) && __is_trivially_assignable(T, T&&)) +# elif BOOST_MOVE_HAS_TRAIT(has_trivial_move_assign) # define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) __has_trivial_move_assign(T) # endif + +// BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) (__is_constructible(T, T&&) && __is_nothrow_constructible(T, T&&)) +# elif BOOST_MOVE_HAS_TRAIT(has_nothrow_move_constructor) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) __has_nothrow_move_constructor(T) +# endif + +// BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_nothrow_assignable) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) (__is_assignable(T, T&&) && __is_nothrow_assignable(T, T&&)) +# elif BOOST_MOVE_HAS_TRAIT(has_nothrow_move_assign) +# define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) __has_nothrow_move_assign(T) +# endif + +// BOOST_MOVE_ALIGNMENT_OF # define BOOST_MOVE_ALIGNMENT_OF(T) __alignof(T) -#endif + +#endif //#if defined(BOOST_CLANG) #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG) @@ -160,14 +234,106 @@ # define BOOST_MOVE_IS_POD(T) __is_pod(T) # define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_MOVE_INTEL_TT_OPTS)) -# define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS)) -# define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_MOVE_INTEL_TT_OPTS) ) + +# if defined(BOOST_GCC) && (BOOST_GCC > 50000) +# define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__is_trivially_constructible(T, const T &)) +# define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__is_trivially_assignable(T, const T &)) +# else +# define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS)) +# define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_MOVE_INTEL_TT_OPTS) ) +# endif + # define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_MOVE_INTEL_TT_OPTS) # define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_MOVE_INTEL_TT_OPTS) # define BOOST_MOVE_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_MOVE_INTEL_TT_OPTS)) # define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_MOVE_INTEL_TT_OPTS)) +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_SFINAE_EXPR) + + template <typename T> + T && boost_move_tt_declval() BOOST_NOEXCEPT; + +# if defined(BOOST_GCC) && (BOOST_GCC >= 80000) +// __is_assignable / __is_constructible implemented +# define BOOST_MOVE_IS_ASSIGNABLE(T, U) __is_assignable(T, U) +# define BOOST_MOVE_IS_CONSTRUCTIBLE(T, U) __is_constructible(T, U) +# else + + template<typename Tt, typename Ut> + class boost_move_tt_is_assignable + { + struct twochar { char dummy[2]; }; + template < class T + , class U + , class = decltype(boost_move_tt_declval<T>() = boost_move_tt_declval<U>()) + > static char test(int); + + template<class, class> static twochar test(...); + + public: + static const bool value = sizeof(test<Tt, Ut>(0)) == sizeof(char); + }; + + template<typename Tt, typename Ut> + class boost_move_tt_is_constructible + { + struct twochar { char dummy[2]; }; + template < class T + , class U + , class = decltype(T(boost_move_tt_declval<U>())) + > static char test(int); + + template<class, class> static twochar test(...); + + public: + static const bool value = sizeof(test<Tt, Ut>(0)) == sizeof(char); + }; + +# define BOOST_MOVE_IS_ASSIGNABLE(T, U) boost_move_tt_is_assignable<T,U>::value +# define BOOST_MOVE_IS_CONSTRUCTIBLE(T, U) boost_move_tt_is_constructible<T, U>::value + +# endif + + template <typename T, typename U, bool = BOOST_MOVE_IS_ASSIGNABLE(T, U)> + struct boost_move_tt_is_nothrow_assignable + { + static const bool value = false; + }; + + template <typename T, typename U> + struct boost_move_tt_is_nothrow_assignable<T, U, true> + { + #if !defined(BOOST_NO_CXX11_NOEXCEPT) + static const bool value = noexcept(boost_move_tt_declval<T>() = boost_move_tt_declval<U>()); + #else + static const bool value = false; + #endif + }; + + template <typename T, typename U, bool = BOOST_MOVE_IS_CONSTRUCTIBLE(T, U)> + struct boost_move_tt_is_nothrow_constructible + { + static const bool value = false; + }; + + template <typename T, typename U> + struct boost_move_tt_is_nothrow_constructible<T, U, true> + { + #if !defined(BOOST_NO_CXX11_NOEXCEPT) + static const bool value = noexcept(T(boost_move_tt_declval<U>())); + #else + static const bool value = false; + #endif + }; + +# define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) boost_move_tt_is_nothrow_assignable<T, T&&>::value +# define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) boost_move_tt_is_nothrow_constructible<T, T&&>::value + +# endif + # define BOOST_MOVE_IS_ENUM(T) __is_enum(T) + +// BOOST_MOVE_ALIGNMENT_OF # if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) // GCC sometimes lies about alignment requirements // of type double on 32-bit unix platforms, use the @@ -193,7 +359,7 @@ # define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T) #endif -# if defined(__CODEGEARC__) +# if defined(BOOST_CODEGEARC) # define BOOST_MOVE_IS_UNION(T) __is_union(T) # define BOOST_MOVE_IS_POD(T) __is_pod(T) # define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) @@ -243,13 +409,13 @@ #endif #ifdef BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR - #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) + #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value #else #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value #endif #ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR - #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) + #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value #else #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value #endif @@ -263,45 +429,45 @@ #endif #ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN - #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) + #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value #else #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value #endif #ifdef BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR - #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) + #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value #else #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value #endif #ifdef BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR - #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) + #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value #else #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value #endif #ifdef BOOST_MOVE_HAS_NOTHROW_COPY - #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_NOTHROW_COPY(T) + #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_NOTHROW_COPY(T) || ::boost::move_detail::is_pod<T>::value #else - #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value + #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T) BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) #endif -#ifdef BOOST_MOVE_HAS_NOTHROW_MOVE - #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE(T) +#ifdef BOOST_MOVE_HAS_NOTHROW_ASSIGN + #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value #else - #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value + #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) #endif -#ifdef BOOST_MOVE_HAS_NOTHROW_ASSIGN - #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) +#ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR + #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value #else - #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value + #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T) #endif #ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN - #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) + #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value #else - #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value + #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T) #endif #ifdef BOOST_MOVE_IS_ENUM @@ -404,6 +570,15 @@ template<typename T> struct remove_cv<const volatile T> { typedef T type; }; template<typename T> struct remove_cv<volatile T> { typedef T type; }; ////////////////////////// +// remove_cvref +////////////////////////// +template<class T> +struct remove_cvref + : remove_cv<typename remove_reference<T>::type> +{ +}; + +////////////////////////// // make_unsigned ////////////////////////// template <class T> @@ -817,8 +992,6 @@ struct is_trivially_default_constructible template<class T> struct is_trivially_copy_constructible { - //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with - //deleted copy constructors so make sure the type is copy constructible. static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T); }; @@ -835,8 +1008,6 @@ struct is_trivially_move_constructible template<class T> struct is_trivially_copy_assignable { - //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with - //deleted copy constructors so make sure the type is copy constructible. static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T); }; @@ -852,7 +1023,6 @@ struct is_trivially_move_assignable ////////////////////////////////////// template<class T> struct is_nothrow_default_constructible - : is_pod<T> { static const bool value = BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T); }; ////////////////////////////////////// @@ -902,6 +1072,7 @@ struct alignment_of_hack char c; T t2; alignment_of_hack(); + ~alignment_of_hack(); }; template <unsigned A, unsigned S> @@ -931,7 +1102,7 @@ struct alignment_of class alignment_dummy; typedef void (*function_ptr)(); typedef int (alignment_dummy::*member_ptr); -typedef int (alignment_dummy::*member_function_ptr)(); + struct alignment_struct { long double dummy[4]; }; @@ -954,7 +1125,6 @@ union max_align long double long_double_[4]; alignment_dummy *unknown_class_ptr_; function_ptr function_ptr_; - member_function_ptr member_function_ptr_; alignment_struct alignment_struct_; }; @@ -964,7 +1134,46 @@ typedef union max_align max_align_t; // aligned_storage ///////////////////////////// -#if !defined(BOOST_NO_ALIGNMENT) +#if defined(_MSC_VER) && defined(_M_IX86) + +// Special version for usual alignments on x86 MSVC because it might crash +// when passsing aligned types by value even for 8 byte alignment. +template<std::size_t Align> +struct aligned_struct; + +template <> struct aligned_struct<1> { char data; }; +template <> struct aligned_struct<2> { short data; }; +template <> struct aligned_struct<4> { int data; }; +template <> struct aligned_struct<8> { double data; }; + +#define BOOST_MOVE_ALIGNED_STRUCT(x) \ + template <> struct aligned_struct<x> { \ + __declspec(align(x)) char data; \ + } +BOOST_MOVE_ALIGNED_STRUCT(16); +BOOST_MOVE_ALIGNED_STRUCT(32); +BOOST_MOVE_ALIGNED_STRUCT(64); +BOOST_MOVE_ALIGNED_STRUCT(128); +BOOST_MOVE_ALIGNED_STRUCT(512); +BOOST_MOVE_ALIGNED_STRUCT(1024); +BOOST_MOVE_ALIGNED_STRUCT(2048); +BOOST_MOVE_ALIGNED_STRUCT(4096); + +template<std::size_t Len, std::size_t Align> +union aligned_union +{ + typedef aligned_struct<Align> aligner_t; + aligner_t aligner; + unsigned char data[Len > sizeof(aligner_t) ? Len : sizeof(aligner_t)]; +}; + +template<std::size_t Len, std::size_t Align> +struct aligned_storage_impl +{ + typedef aligned_union<Len, Align> type; +}; + +#elif !defined(BOOST_NO_ALIGNMENT) template<std::size_t Len, std::size_t Align> struct aligned_struct; @@ -973,7 +1182,7 @@ struct aligned_struct; template<std::size_t Len>\ struct BOOST_ALIGNMENT(A) aligned_struct<Len, A>\ {\ - char data[Len];\ + unsigned char data[Len];\ };\ // @@ -999,8 +1208,9 @@ BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1000) template<std::size_t Len, std::size_t Align> union aligned_struct_wrapper { + typedef aligned_struct<Len, Align> aligner_t; aligned_struct<Len, Align> aligner; - char data[sizeof(aligned_struct<Len, Align>)]; + unsigned char data[Len > sizeof(aligner_t) ? Len : sizeof(aligner_t)]; }; template<std::size_t Len, std::size_t Align> @@ -1015,7 +1225,7 @@ template<class T, std::size_t Len> union aligned_union { T aligner; - char data[Len]; + unsigned char data[Len > sizeof(T) ? Len : sizeof(T)]; }; template<std::size_t Len, std::size_t Align, class T, bool Ok> diff --git a/contrib/restricted/boost/move/include/boost/move/detail/unique_ptr_meta_utils.hpp b/contrib/restricted/boost/move/include/boost/move/detail/unique_ptr_meta_utils.hpp index e11124d898..4c6aeb5b2b 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/unique_ptr_meta_utils.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/unique_ptr_meta_utils.hpp @@ -546,7 +546,7 @@ struct is_unary_function # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) #elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) -#elif defined(__CODEGEARC__) +#elif defined(BOOST_CODEGEARC) # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) #endif @@ -559,32 +559,6 @@ struct is_unary_function struct has_virtual_destructor{ static const bool value = true; }; #endif -////////////////////////////////////// -// missing_virtual_destructor -////////////////////////////////////// - -template< class T, class U - , bool enable = is_convertible< U*, T*>::value && - !is_array<T>::value && - !is_same<typename remove_cv<T>::type, void>::value && - !is_same<typename remove_cv<U>::type, typename remove_cv<T>::type>::value - > -struct missing_virtual_destructor_default_delete -{ static const bool value = !has_virtual_destructor<T>::value; }; - -template<class T, class U> -struct missing_virtual_destructor_default_delete<T, U, false> -{ static const bool value = false; }; - -template<class Deleter, class U> -struct missing_virtual_destructor -{ static const bool value = false; }; - -template<class T, class U> -struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U > - : missing_virtual_destructor_default_delete<T, U> -{}; - } //namespace move_upmu { } //namespace boost { diff --git a/contrib/restricted/boost/move/include/boost/move/detail/workaround.hpp b/contrib/restricted/boost/move/include/boost/move/detail/workaround.hpp index 1d16f24332..77e01148e8 100644 --- a/contrib/restricted/boost/move/include/boost/move/detail/workaround.hpp +++ b/contrib/restricted/boost/move/include/boost/move/detail/workaround.hpp @@ -52,14 +52,16 @@ #define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG #endif +//#define BOOST_MOVE_DISABLE_FORCEINLINE + #if defined(BOOST_MOVE_DISABLE_FORCEINLINE) #define BOOST_MOVE_FORCEINLINE inline #elif defined(BOOST_MOVE_FORCEINLINE_IS_BOOST_FORCELINE) #define BOOST_MOVE_FORCEINLINE BOOST_FORCEINLINE -#elif defined(BOOST_MSVC) && defined(_DEBUG) - //"__forceinline" and MSVC seems to have some bugs in debug mode +#elif defined(BOOST_MSVC) && (_MSC_VER < 1900 || defined(_DEBUG)) + //"__forceinline" and MSVC seems to have some bugs in old versions and in debug mode #define BOOST_MOVE_FORCEINLINE inline -#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) +#elif defined(BOOST_GCC) && (__GNUC__ <= 5) //Older GCCs have problems with forceinline #define BOOST_MOVE_FORCEINLINE inline #else diff --git a/contrib/restricted/boost/move/include/boost/move/iterator.hpp b/contrib/restricted/boost/move/include/boost/move/iterator.hpp index f36df23c0c..c289c08364 100644 --- a/contrib/restricted/boost/move/include/boost/move/iterator.hpp +++ b/contrib/restricted/boost/move/include/boost/move/iterator.hpp @@ -170,7 +170,7 @@ struct is_move_iterator< ::boost::move_iterator<I> > //! //! <b>Returns</b>: move_iterator<It>(i). template<class It> -inline move_iterator<It> make_move_iterator(const It &it) +BOOST_MOVE_FORCEINLINE move_iterator<It> make_move_iterator(const It &it) { return move_iterator<It>(it); } ////////////////////////////////////////////////////////////////////////////// diff --git a/contrib/restricted/boost/move/include/boost/move/make_unique.hpp b/contrib/restricted/boost/move/include/boost/move/make_unique.hpp index ef106dbb55..2d421fcf46 100644 --- a/contrib/restricted/boost/move/include/boost/move/make_unique.hpp +++ b/contrib/restricted/boost/move/include/boost/move/make_unique.hpp @@ -38,12 +38,22 @@ #if !defined(BOOST_MOVE_DOXYGEN_INVOKED) +#if defined(_MSC_VER) && (_MSC_VER >= 1915) + #pragma warning (push) + #pragma warning (disable : 4643) // Forward declaring 'X' in namespace std is not permitted by the C++ Standard +#endif + namespace std { //no namespace versioning in clang+libc++ struct nothrow_t; } //namespace std { +#if defined(_MSC_VER) && (_MSC_VER >= 1915) + #pragma warning (pop) +#endif + + namespace boost{ namespace move_upmu { diff --git a/contrib/restricted/boost/move/include/boost/move/unique_ptr.hpp b/contrib/restricted/boost/move/include/boost/move/unique_ptr.hpp index 2d794e8ed5..5f9a107e50 100644 --- a/contrib/restricted/boost/move/include/boost/move/unique_ptr.hpp +++ b/contrib/restricted/boost/move/include/boost/move/unique_ptr.hpp @@ -430,7 +430,7 @@ class unique_ptr { //If T is not an array type, element_type_t<Pointer> derives from T //it uses the default deleter and T has no virtual destructor, then you have a problem - BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor + BOOST_STATIC_ASSERT(( !bmupd::missing_virtual_destructor <D, typename bmupd::get_element_type<Pointer>::type>::value )); //If this constructor is instantiated with a pointer type or reference type //for the template argument D, the program is ill-formed. @@ -468,7 +468,7 @@ class unique_ptr { //If T is not an array type, element_type_t<Pointer> derives from T //it uses the default deleter and T has no virtual destructor, then you have a problem - BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor + BOOST_STATIC_ASSERT(( !bmupd::missing_virtual_destructor <D, typename bmupd::get_element_type<Pointer>::type>::value )); } @@ -506,7 +506,7 @@ class unique_ptr { //If T is not an array type, element_type_t<Pointer> derives from T //it uses the default deleter and T has no virtual destructor, then you have a problem - BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor + BOOST_STATIC_ASSERT(( !bmupd::missing_virtual_destructor <D, typename bmupd::get_element_type<Pointer>::type>::value )); } @@ -553,7 +553,7 @@ class unique_ptr { //If T is not an array type, U derives from T //it uses the default deleter and T has no virtual destructor, then you have a problem - BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor + BOOST_STATIC_ASSERT(( !bmupd::missing_virtual_destructor <D, typename unique_ptr<U, E>::pointer>::value )); } @@ -711,7 +711,7 @@ class unique_ptr { //If T is not an array type, element_type_t<Pointer> derives from T //it uses the default deleter and T has no virtual destructor, then you have a problem - BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor + BOOST_STATIC_ASSERT(( !bmupd::missing_virtual_destructor <D, typename bmupd::get_element_type<Pointer>::type>::value )); pointer tmp = m_data.m_p; m_data.m_p = p; diff --git a/contrib/restricted/boost/move/include/boost/move/utility_core.hpp b/contrib/restricted/boost/move/include/boost/move/utility_core.hpp index 55042a9bb1..edc1a73b74 100644 --- a/contrib/restricted/boost/move/include/boost/move/utility_core.hpp +++ b/contrib/restricted/boost/move/include/boost/move/utility_core.hpp @@ -258,44 +258,47 @@ #endif //BOOST_MOVE_DOXYGEN_INVOKED - ////////////////////////////////////////////////////////////////////////////// - // - // move_if_not_lvalue_reference - // - ////////////////////////////////////////////////////////////////////////////// + } //namespace boost { + #endif //BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE - #if defined(BOOST_MOVE_DOXYGEN_INVOKED) - //! <b>Effects</b>: Calls `boost::move` if `input_reference` is not a lvalue reference. - //! Otherwise returns the reference - template <class T> output_reference move_if_not_lvalue_reference(input_reference) noexcept; - #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + ////////////////////////////////////////////////////////////////////////////// + // + // move_if_not_lvalue_reference + // + ////////////////////////////////////////////////////////////////////////////// - //Old move approach, lvalues could bind to rvalue references + namespace boost { - template <class T> - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT - { return t; } + #if defined(BOOST_MOVE_DOXYGEN_INVOKED) + //! <b>Effects</b>: Calls `boost::move` if `input_reference` is not a lvalue reference. + //! Otherwise returns the reference + template <class T> output_reference move_if_not_lvalue_reference(input_reference) noexcept; + #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) - #else //Old move + //Old move approach, lvalues could bind to rvalue references - template <class T> - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT - { return static_cast<T&&>(t); } + template <class T> + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT + { return t; } - template <class T> - BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT - { - //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue."; - BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value); - return static_cast<T&&>(t); - } + #else //Old move - #endif //BOOST_MOVE_DOXYGEN_INVOKED + template <class T> + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT + { return static_cast<T&&>(t); } - } //namespace boost { + template <class T> + BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT + { + //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue."; + BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value); + return static_cast<T&&>(t); + } + + #endif //BOOST_MOVE_DOXYGEN_INVOKED - #endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) + } //namespace boost { #endif //BOOST_NO_CXX11_RVALUE_REFERENCES |