update boost
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,7 +14,8 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
@@ -28,11 +29,10 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <functional>
|
||||
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/core/ref.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -16,12 +16,15 @@
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <boost/type_traits/is_empty.hpp>
|
||||
#include <memory>
|
||||
#else
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/multi_index/detail/vartempl_support.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/type_traits/is_empty.hpp>
|
||||
#include <new>
|
||||
#endif
|
||||
|
||||
@@ -35,6 +38,19 @@ namespace detail{
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
|
||||
template<typename T> struct void_helper{typedef void type;};
|
||||
|
||||
template<typename Allocator,typename=void>
|
||||
struct allocator_is_always_equal:boost::is_empty<Allocator>{};
|
||||
|
||||
template<typename Allocator>
|
||||
struct allocator_is_always_equal<
|
||||
Allocator,
|
||||
typename void_helper<
|
||||
typename std::allocator_traits<Allocator>::is_always_equal
|
||||
>::type
|
||||
>:std::allocator_traits<Allocator>::is_always_equal{};
|
||||
|
||||
template<typename Allocator>
|
||||
struct allocator_traits:std::allocator_traits<Allocator>
|
||||
{
|
||||
@@ -42,6 +58,10 @@ struct allocator_traits:std::allocator_traits<Allocator>
|
||||
|
||||
typedef std::allocator_traits<Allocator> super;
|
||||
|
||||
/* pre-C++17 compatibilty */
|
||||
|
||||
typedef allocator_is_always_equal<Allocator> is_always_equal;
|
||||
|
||||
template<typename T>
|
||||
struct rebind_alloc
|
||||
{
|
||||
@@ -75,6 +95,11 @@ struct allocator_traits
|
||||
typedef typename Allocator::difference_type difference_type;
|
||||
typedef typename Allocator::size_type size_type;
|
||||
|
||||
typedef boost::false_type propagate_on_container_copy_assignment;
|
||||
typedef boost::false_type propagate_on_container_move_assignment;
|
||||
typedef boost::false_type propagate_on_container_swap;
|
||||
typedef boost::is_empty<Allocator> is_always_equal;
|
||||
|
||||
template<typename T>
|
||||
struct rebind_alloc
|
||||
{
|
||||
@@ -123,6 +148,11 @@ struct allocator_traits
|
||||
#endif
|
||||
|
||||
static size_type max_size(Allocator& a)BOOST_NOEXCEPT{return a.max_size();}
|
||||
|
||||
static Allocator select_on_container_copy_construction(const Allocator& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_ANY_CONTAINER_VIEW_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_ANY_CONTAINER_VIEW_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* type-erased, non-owning view over a ConstIterator-container's range */
|
||||
|
||||
template<typename ConstIterator>
|
||||
class any_container_view
|
||||
{
|
||||
public:
|
||||
template<typename Container>
|
||||
any_container_view(const Container& x):px(&x),pt(vtable_for<Container>()){}
|
||||
|
||||
const void* container()const{return px;}
|
||||
ConstIterator begin()const{return pt->begin(px);}
|
||||
ConstIterator end()const{return pt->end(px);}
|
||||
|
||||
private:
|
||||
struct vtable
|
||||
{
|
||||
ConstIterator (*begin)(const void*);
|
||||
ConstIterator (*end)(const void*);
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
static ConstIterator begin_for(const void* px)
|
||||
{
|
||||
return static_cast<const Container*>(px)->begin();
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
static ConstIterator end_for(const void* px)
|
||||
{
|
||||
return static_cast<const Container*>(px)->end();
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
vtable* vtable_for()
|
||||
{
|
||||
static vtable v=
|
||||
{
|
||||
&begin_for<Container>,
|
||||
&end_for<Container>
|
||||
};
|
||||
|
||||
return &v;
|
||||
}
|
||||
|
||||
const void* px;
|
||||
vtable* pt;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2016 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,9 +14,9 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
@@ -34,7 +34,7 @@ struct archive_constructed:private noncopyable
|
||||
template<class Archive>
|
||||
archive_constructed(Archive& ar,const unsigned int version)
|
||||
{
|
||||
serialization::load_construct_data_adl(ar,&get(),version);
|
||||
core::load_construct_data_adl(ar,&get(),version);
|
||||
BOOST_TRY{
|
||||
ar>>get();
|
||||
}
|
||||
@@ -48,9 +48,9 @@ struct archive_constructed:private noncopyable
|
||||
template<class Archive>
|
||||
archive_constructed(const char* name,Archive& ar,const unsigned int version)
|
||||
{
|
||||
serialization::load_construct_data_adl(ar,&get(),version);
|
||||
core::load_construct_data_adl(ar,&get(),version);
|
||||
BOOST_TRY{
|
||||
ar>>serialization::make_nvp(name,get());
|
||||
ar>>core::make_nvp(name,get());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
(&get())->~T();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/adl_swap.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace boost{
|
||||
@@ -64,11 +65,25 @@ struct auto_space:private noncopyable
|
||||
|
||||
void swap(auto_space& x)
|
||||
{
|
||||
if(al_!=x.al_)adl_swap(al_,x.al_);
|
||||
swap(
|
||||
x,
|
||||
boost::integral_constant<
|
||||
bool,alloc_traits::propagate_on_container_swap::value>());
|
||||
}
|
||||
|
||||
void swap(auto_space& x,boost::true_type /* swap_allocators */)
|
||||
{
|
||||
adl_swap(al_,x.al_);
|
||||
std::swap(n_,x.n_);
|
||||
std::swap(data_,x.data_);
|
||||
}
|
||||
|
||||
void swap(auto_space& x,boost::false_type /* swap_allocators */)
|
||||
{
|
||||
std::swap(n_,x.n_);
|
||||
std::swap(data_,x.data_);
|
||||
}
|
||||
|
||||
private:
|
||||
allocator al_;
|
||||
size_type n_;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
struct bad_archive_exception:std::runtime_error
|
||||
{
|
||||
bad_archive_exception():std::runtime_error("Invalid or corrupted archive"){}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,8 +17,7 @@
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
@@ -67,7 +66,11 @@ public:
|
||||
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
|
||||
*/
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,const unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
@@ -75,14 +78,14 @@ public:
|
||||
void save(Archive& ar,const unsigned int)const
|
||||
{
|
||||
node_base_type* bnode=node;
|
||||
ar<<serialization::make_nvp("pointer",bnode);
|
||||
ar<<core::make_nvp("pointer",bnode);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
ar>>core::make_nvp("pointer",bnode);
|
||||
node=static_cast<Node*>(bnode);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,10 +15,10 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/hash_index_node.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/seq/elem.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
@@ -27,8 +27,8 @@
|
||||
#include <limits.h>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/multi_index/detail/bad_archive_exception.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#endif
|
||||
|
||||
@@ -173,6 +173,13 @@ public:
|
||||
spc.swap(x.spc);
|
||||
}
|
||||
|
||||
template<typename BoolConstant>
|
||||
void swap(bucket_array& x,BoolConstant swap_allocators)
|
||||
{
|
||||
std::swap(size_index_,x.size_index_);
|
||||
spc.swap(x.spc,swap_allocators);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef auto_space<base_node_impl_type,Allocator> auto_space_type;
|
||||
typedef typename auto_space_type::size_type auto_space_size_type;
|
||||
@@ -229,8 +236,7 @@ inline void load_construct_data(
|
||||
Archive&,boost::multi_index::detail::bucket_array<Allocator>*,
|
||||
const unsigned int)
|
||||
{
|
||||
throw_exception(
|
||||
archive::archive_exception(archive::archive_exception::other_exception));
|
||||
throw_exception(bad_archive_exception());
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -31,13 +31,15 @@ struct converter
|
||||
static Index& index(MultiIndexContainer& x){return x;}
|
||||
|
||||
static typename Index::const_iterator const_iterator(
|
||||
const MultiIndexContainer& x,typename MultiIndexContainer::node_type* node)
|
||||
const MultiIndexContainer& x,
|
||||
typename MultiIndexContainer::final_node_type* node)
|
||||
{
|
||||
return x.Index::make_iterator(node);
|
||||
}
|
||||
|
||||
static typename Index::iterator iterator(
|
||||
MultiIndexContainer& x,typename MultiIndexContainer::node_type* node)
|
||||
MultiIndexContainer& x,
|
||||
typename MultiIndexContainer::final_node_type* node)
|
||||
{
|
||||
return x.Index::make_iterator(node);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -16,11 +16,13 @@
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace boost{
|
||||
@@ -55,6 +57,18 @@ struct copy_map_entry
|
||||
}
|
||||
};
|
||||
|
||||
struct copy_map_value_copier
|
||||
{
|
||||
template<typename Value>
|
||||
const Value& operator()(Value& x)const{return x;}
|
||||
};
|
||||
|
||||
struct copy_map_value_mover
|
||||
{
|
||||
template<typename Value>
|
||||
BOOST_RV_REF(Value) operator()(Value& x)const{return boost::move(x);}
|
||||
};
|
||||
|
||||
template <typename Node,typename Allocator>
|
||||
class copy_map:private noncopyable
|
||||
{
|
||||
@@ -88,27 +102,8 @@ public:
|
||||
const_iterator begin()const{return raw_ptr<const_iterator>(spc.data());}
|
||||
const_iterator end()const{return raw_ptr<const_iterator>(spc.data()+n);}
|
||||
|
||||
void clone(Node* node)
|
||||
{
|
||||
(spc.data()+n)->first=node;
|
||||
(spc.data()+n)->second=raw_ptr<Node*>(allocate());
|
||||
BOOST_TRY{
|
||||
alloc_traits::construct(
|
||||
al_,boost::addressof((spc.data()+n)->second->value()),node->value());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
deallocate((spc.data()+n)->second);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
++n;
|
||||
|
||||
if(n==size_){
|
||||
std::sort(
|
||||
raw_ptr<copy_map_entry<Node>*>(spc.data()),
|
||||
raw_ptr<copy_map_entry<Node>*>(spc.data())+size_);
|
||||
}
|
||||
}
|
||||
void copy_clone(Node* node){clone(node,copy_map_value_copier());}
|
||||
void move_clone(Node* node){clone(node,copy_map_value_mover());}
|
||||
|
||||
Node* find(Node* node)const
|
||||
{
|
||||
@@ -140,6 +135,30 @@ private:
|
||||
{
|
||||
alloc_traits::deallocate(al_,static_cast<pointer>(node),1);
|
||||
}
|
||||
|
||||
template<typename ValueAccess>
|
||||
void clone(Node* node,ValueAccess access)
|
||||
{
|
||||
(spc.data()+n)->first=node;
|
||||
(spc.data()+n)->second=raw_ptr<Node*>(allocate());
|
||||
BOOST_TRY{
|
||||
alloc_traits::construct(
|
||||
al_,boost::addressof((spc.data()+n)->second->value()),
|
||||
access(node->value()));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
deallocate((spc.data()+n)->second);
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
++n;
|
||||
|
||||
if(n==size_){
|
||||
std::sort(
|
||||
raw_ptr<copy_map_entry<Node>*>(spc.data()),
|
||||
raw_ptr<copy_map_entry<Node>*>(spc.data())+size_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#if !defined(BOOST_CONFIG_HPP)
|
||||
#error <boost/config.hpp> must be included before this header
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DETAIL_UNDEF_IF_CONSTEXPR_MACRO)
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR)
|
||||
#define BOOST_MULTI_INDEX_IF_CONSTEXPR if constexpr
|
||||
#else
|
||||
#define BOOST_MULTI_INDEX_IF_CONSTEXPR if
|
||||
#if defined(BOOST_MSVC)
|
||||
#define BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) /* conditional expression is constant */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#undef BOOST_MULTI_INDEX_IF_CONSTEXPR
|
||||
#if defined(BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED)
|
||||
#pragma warning(pop)
|
||||
#undef BOOST_MULTI_INDEX_DETAIL_C4127_DISABLED
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,7 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/mpl/aux_/na.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,9 +17,7 @@
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
@@ -34,10 +32,13 @@ namespace detail{
|
||||
struct hashed_index_global_iterator_tag{};
|
||||
struct hashed_index_local_iterator_tag{};
|
||||
|
||||
template<typename Node,typename BucketArray,typename Category>
|
||||
template<
|
||||
typename Node,typename BucketArray,
|
||||
typename IndexCategory,typename IteratorCategory
|
||||
>
|
||||
class hashed_index_iterator:
|
||||
public forward_iterator_helper<
|
||||
hashed_index_iterator<Node,BucketArray,Category>,
|
||||
hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory>,
|
||||
typename Node::value_type,
|
||||
typename Node::difference_type,
|
||||
const typename Node::value_type*,
|
||||
@@ -55,7 +56,7 @@ public:
|
||||
|
||||
hashed_index_iterator& operator++()
|
||||
{
|
||||
this->increment(Category());
|
||||
this->increment(IteratorCategory());
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -64,7 +65,11 @@ public:
|
||||
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
|
||||
*/
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,const unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
@@ -72,13 +77,13 @@ public:
|
||||
void save(Archive& ar,const unsigned int)const
|
||||
{
|
||||
node_base_type* bnode=node;
|
||||
ar<<serialization::make_nvp("pointer",bnode);
|
||||
ar<<core::make_nvp("pointer",bnode);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int version)
|
||||
{
|
||||
load(ar,version,Category());
|
||||
load(ar,version,IteratorCategory());
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
@@ -86,11 +91,11 @@ public:
|
||||
Archive& ar,const unsigned int version,hashed_index_global_iterator_tag)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
ar>>core::make_nvp("pointer",bnode);
|
||||
node=static_cast<Node*>(bnode);
|
||||
if(version<1){
|
||||
BucketArray* throw_away; /* consume unused ptr */
|
||||
ar>>serialization::make_nvp("pointer",throw_away);
|
||||
ar>>core::make_nvp("pointer",throw_away);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,11 +104,11 @@ public:
|
||||
Archive& ar,const unsigned int version,hashed_index_local_iterator_tag)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
ar>>core::make_nvp("pointer",bnode);
|
||||
node=static_cast<Node*>(bnode);
|
||||
if(version<1){
|
||||
BucketArray* buckets;
|
||||
ar>>serialization::make_nvp("pointer",buckets);
|
||||
ar>>core::make_nvp("pointer",buckets);
|
||||
if(buckets&&node&&node->impl()==buckets->end()->prior()){
|
||||
/* end local_iterators used to point to end node, now they are null */
|
||||
node=0;
|
||||
@@ -122,21 +127,26 @@ private:
|
||||
|
||||
void increment(hashed_index_global_iterator_tag)
|
||||
{
|
||||
Node::increment(node);
|
||||
Node::template increment<IndexCategory>(node);
|
||||
}
|
||||
|
||||
void increment(hashed_index_local_iterator_tag)
|
||||
{
|
||||
Node::increment_local(node);
|
||||
Node::template increment_local<IndexCategory>(node);
|
||||
}
|
||||
|
||||
Node* node;
|
||||
};
|
||||
|
||||
template<typename Node,typename BucketArray,typename Category>
|
||||
template<
|
||||
typename Node,typename BucketArray,
|
||||
typename IndexCategory,typename IteratorCategory
|
||||
>
|
||||
bool operator==(
|
||||
const hashed_index_iterator<Node,BucketArray,Category>& x,
|
||||
const hashed_index_iterator<Node,BucketArray,Category>& y)
|
||||
const hashed_index_iterator<
|
||||
Node,BucketArray,IndexCategory,IteratorCategory>& x,
|
||||
const hashed_index_iterator<
|
||||
Node,BucketArray,IndexCategory,IteratorCategory>& y)
|
||||
{
|
||||
return x.get_node()==y.get_node();
|
||||
}
|
||||
@@ -151,9 +161,14 @@ bool operator==(
|
||||
*/
|
||||
|
||||
namespace serialization {
|
||||
template<typename Node,typename BucketArray,typename Category>
|
||||
template<
|
||||
typename Node,typename BucketArray,
|
||||
typename IndexCategory,typename IteratorCategory
|
||||
>
|
||||
struct version<
|
||||
boost::multi_index::detail::hashed_index_iterator<Node,BucketArray,Category>
|
||||
boost::multi_index::detail::hashed_index_iterator<
|
||||
Node,BucketArray,IndexCategory,IteratorCategory
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int,value=1);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2019 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -700,7 +700,7 @@ struct hashed_index_node_trampoline:
|
||||
typedef hashed_index_node_impl<impl_allocator_type> impl_type;
|
||||
};
|
||||
|
||||
template<typename Super,typename Category>
|
||||
template<typename Super>
|
||||
struct hashed_index_node:
|
||||
Super,hashed_index_node_trampoline<Super>
|
||||
{
|
||||
@@ -709,14 +709,17 @@ private:
|
||||
|
||||
public:
|
||||
typedef typename trampoline::impl_type impl_type;
|
||||
typedef hashed_index_node_alg<
|
||||
impl_type,Category> node_alg;
|
||||
typedef typename trampoline::base_pointer impl_base_pointer;
|
||||
typedef typename trampoline::const_base_pointer const_impl_base_pointer;
|
||||
typedef typename trampoline::pointer impl_pointer;
|
||||
typedef typename trampoline::const_pointer const_impl_pointer;
|
||||
typedef typename trampoline::difference_type difference_type;
|
||||
|
||||
template<typename Category>
|
||||
struct node_alg{
|
||||
typedef hashed_index_node_alg<impl_type,Category> type;
|
||||
};
|
||||
|
||||
impl_pointer& prior(){return trampoline::prior();}
|
||||
impl_pointer prior()const{return trampoline::prior();}
|
||||
impl_base_pointer& next(){return trampoline::next();}
|
||||
@@ -752,14 +755,16 @@ public:
|
||||
|
||||
/* interoperability with hashed_index_iterator */
|
||||
|
||||
template<typename Category>
|
||||
static void increment(hashed_index_node*& x)
|
||||
{
|
||||
x=from_impl(node_alg::after(x->impl()));
|
||||
x=from_impl(node_alg<Category>::type::after(x->impl()));
|
||||
}
|
||||
|
||||
template<typename Category>
|
||||
static void increment_local(hashed_index_node*& x)
|
||||
{
|
||||
x=from_impl(node_alg::after_local(x->impl()));
|
||||
x=from_impl(node_alg<Category>::type::after_local(x->impl()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -13,7 +13,7 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_ACCESS_SEQUENCE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INDEX_ACCESS_SEQUENCE_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/multi_index_container_fwd.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Successive access to the indices of a multi_index_container. Used as dst in
|
||||
* backbone function extract_(x,dst) to retrieve the destination indices
|
||||
* where iterators referring to x must be transferred to (in merging
|
||||
* operations).
|
||||
*/
|
||||
|
||||
template<typename MultiIndexContainer,int N=0>
|
||||
struct index_access_sequence;
|
||||
|
||||
struct index_access_sequence_terminal
|
||||
{
|
||||
index_access_sequence_terminal(void*){}
|
||||
};
|
||||
|
||||
template<typename MultiIndexContainer,int N>
|
||||
struct index_access_sequence_normal
|
||||
{
|
||||
MultiIndexContainer* p;
|
||||
|
||||
index_access_sequence_normal(MultiIndexContainer* p_):p(p_){}
|
||||
|
||||
typename nth_index<MultiIndexContainer,N>::type&
|
||||
get(){return p->template get<N>();}
|
||||
|
||||
index_access_sequence<MultiIndexContainer,N+1>
|
||||
next(){return index_access_sequence<MultiIndexContainer,N+1>(p);}
|
||||
};
|
||||
|
||||
template<typename MultiIndexContainer,int N>
|
||||
struct index_access_sequence_base:
|
||||
mpl::if_c<
|
||||
N<mpl::size<typename MultiIndexContainer::index_type_list>::type::value,
|
||||
index_access_sequence_normal<MultiIndexContainer,N>,
|
||||
index_access_sequence_terminal
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename MultiIndexContainer,int N>
|
||||
struct index_access_sequence:
|
||||
index_access_sequence_base<MultiIndexContainer,N>::type
|
||||
{
|
||||
typedef typename index_access_sequence_base<
|
||||
MultiIndexContainer,N>::type super;
|
||||
|
||||
index_access_sequence(MultiIndexContainer* p):super(p){}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,14 +15,15 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/multi_index/detail/copy_map.hpp>
|
||||
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
|
||||
#include <boost/multi_index/detail/index_access_sequence.hpp>
|
||||
#include <boost/multi_index/detail/node_handle.hpp>
|
||||
#include <boost/multi_index/detail/node_type.hpp>
|
||||
#include <boost/multi_index/detail/vartempl_support.hpp>
|
||||
#include <boost/multi_index_container_fwd.hpp>
|
||||
@@ -56,7 +57,7 @@ template<typename Value,typename IndexSpecifierList,typename Allocator>
|
||||
class index_base
|
||||
{
|
||||
protected:
|
||||
typedef index_node_base<Value,Allocator> node_type;
|
||||
typedef index_node_base<Value,Allocator> index_node_type;
|
||||
typedef typename multi_index_node_type<
|
||||
Value,IndexSpecifierList,Allocator>::type final_node_type;
|
||||
typedef multi_index_container<
|
||||
@@ -65,6 +66,8 @@ protected:
|
||||
typedef typename rebind_alloc_for<
|
||||
Allocator,typename Allocator::value_type
|
||||
>::type final_allocator_type;
|
||||
typedef node_handle<
|
||||
final_node_type,final_allocator_type> final_node_handle_type;
|
||||
typedef mpl::vector0<> index_type_list;
|
||||
typedef mpl::vector0<> iterator_type_list;
|
||||
typedef mpl::vector0<> const_iterator_type_list;
|
||||
@@ -74,10 +77,10 @@ protected:
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
typedef index_saver<
|
||||
node_type,
|
||||
index_node_type,
|
||||
final_allocator_type> index_saver_type;
|
||||
typedef index_loader<
|
||||
node_type,
|
||||
index_node_type,
|
||||
final_node_type,
|
||||
final_allocator_type> index_loader_type;
|
||||
#endif
|
||||
@@ -132,57 +135,63 @@ protected:
|
||||
return x;
|
||||
}
|
||||
|
||||
template<typename MultiIndexContainer>
|
||||
final_node_type* insert_(
|
||||
const value_type& v,node_type*,final_node_type*& x,lvalue_tag)
|
||||
const value_type&,final_node_type*& x,MultiIndexContainer* p)
|
||||
{
|
||||
p->final_extract_for_transfer_(
|
||||
x,index_access_sequence<final_type>(&final()));
|
||||
return x;
|
||||
}
|
||||
|
||||
final_node_type* insert_(
|
||||
const value_type& v,index_node_type*,final_node_type*& x,lvalue_tag)
|
||||
{
|
||||
return insert_(v,x,lvalue_tag());
|
||||
}
|
||||
|
||||
final_node_type* insert_(
|
||||
const value_type& v,node_type*,final_node_type*& x,rvalue_tag)
|
||||
const value_type& v,index_node_type*,final_node_type*& x,rvalue_tag)
|
||||
{
|
||||
return insert_(v,x,rvalue_tag());
|
||||
}
|
||||
|
||||
final_node_type* insert_(
|
||||
const value_type&,node_type*,final_node_type*& x,emplaced_tag)
|
||||
const value_type&,index_node_type*,final_node_type*& x,emplaced_tag)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
void erase_(node_type* x)
|
||||
{
|
||||
final().destroy_value(static_cast<final_node_type*>(x));
|
||||
}
|
||||
|
||||
void delete_node_(node_type* x)
|
||||
{
|
||||
final().destroy_value(static_cast<final_node_type*>(x));
|
||||
}
|
||||
template<typename Dst>
|
||||
void extract_(index_node_type*,Dst){}
|
||||
|
||||
void clear_(){}
|
||||
|
||||
void swap_(index_base<Value,IndexSpecifierList,Allocator>&){}
|
||||
template<typename BoolConstant>
|
||||
void swap_(
|
||||
index_base<Value,IndexSpecifierList,Allocator>&,
|
||||
BoolConstant /* swap_allocators */)
|
||||
{}
|
||||
|
||||
void swap_elements_(index_base<Value,IndexSpecifierList,Allocator>&){}
|
||||
|
||||
bool replace_(const value_type& v,node_type* x,lvalue_tag)
|
||||
bool replace_(const value_type& v,index_node_type* x,lvalue_tag)
|
||||
{
|
||||
x->value()=v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool replace_(const value_type& v,node_type* x,rvalue_tag)
|
||||
bool replace_(const value_type& v,index_node_type* x,rvalue_tag)
|
||||
{
|
||||
x->value()=boost::move(const_cast<value_type&>(v));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool modify_(node_type*){return true;}
|
||||
bool modify_(index_node_type*){return true;}
|
||||
|
||||
bool modify_rollback_(node_type*){return true;}
|
||||
bool modify_rollback_(index_node_type*){return true;}
|
||||
|
||||
bool check_rollback_(node_type*)const{return true;}
|
||||
bool check_rollback_(index_node_type*)const{return true;}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
/* serialization */
|
||||
@@ -205,6 +214,10 @@ protected:
|
||||
final_type& final(){return *static_cast<final_type*>(this);}
|
||||
const final_type& final()const{return *static_cast<const final_type*>(this);}
|
||||
|
||||
template<typename Index>
|
||||
static typename Index::final_type& final(Index& x) /* cross-index access */
|
||||
{return static_cast<typename Index::final_type&>(x);}
|
||||
|
||||
final_node_type* final_header()const{return final().header();}
|
||||
|
||||
bool final_empty_()const{return final().empty_();}
|
||||
@@ -221,6 +234,12 @@ protected:
|
||||
template<typename T>
|
||||
std::pair<final_node_type*,bool> final_insert_ref_(T& t)
|
||||
{return final().insert_ref_(t);}
|
||||
std::pair<final_node_type*,bool> final_insert_nh_(final_node_handle_type& nh)
|
||||
{return final().insert_nh_(nh);}
|
||||
|
||||
template<typename Index>
|
||||
std::pair<final_node_type*,bool> final_transfer_(Index& x,final_node_type* n)
|
||||
{return final().transfer_(x,n);}
|
||||
|
||||
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
||||
std::pair<final_node_type*,bool> final_emplace_(
|
||||
@@ -243,6 +262,9 @@ protected:
|
||||
std::pair<final_node_type*,bool> final_insert_ref_(
|
||||
T& t,final_node_type* position)
|
||||
{return final().insert_ref_(t,position);}
|
||||
std::pair<final_node_type*,bool> final_insert_nh_(
|
||||
final_node_handle_type& nh,final_node_type* position)
|
||||
{return final().insert_nh_(nh,position);}
|
||||
|
||||
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
||||
std::pair<final_node_type*,bool> final_emplace_hint_(
|
||||
@@ -252,12 +274,30 @@ protected:
|
||||
position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
|
||||
}
|
||||
|
||||
final_node_handle_type final_extract_(final_node_type* x)
|
||||
{
|
||||
return final().extract_(x);
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
void final_extract_for_transfer_(final_node_type* x,Dst dst)
|
||||
{
|
||||
final().extract_for_transfer_(x,dst);
|
||||
}
|
||||
|
||||
void final_erase_(final_node_type* x){final().erase_(x);}
|
||||
|
||||
void final_delete_node_(final_node_type* x){final().delete_node_(x);}
|
||||
void final_delete_all_nodes_(){final().delete_all_nodes_();}
|
||||
void final_clear_(){final().clear_();}
|
||||
|
||||
template<typename Index>
|
||||
void final_transfer_range_(
|
||||
Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{final().transfer_range_(x,first,last);}
|
||||
|
||||
void final_swap_(final_type& x){final().swap_(x);}
|
||||
|
||||
bool final_replace_(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/bad_archive_exception.hpp>
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -30,7 +30,8 @@ namespace multi_index{
|
||||
namespace detail{
|
||||
|
||||
/* Counterpart of index_saver (check index_saver.hpp for serialization
|
||||
* details.)* multi_index_container is in charge of supplying the info about
|
||||
* details.)
|
||||
* multi_index_container is in charge of supplying the info about
|
||||
* the base sequence, and each index can subsequently load itself using the
|
||||
* const interface of index_loader.
|
||||
*/
|
||||
@@ -47,14 +48,14 @@ public:
|
||||
template<class Archive>
|
||||
void add(Node* node,Archive& ar,const unsigned int)
|
||||
{
|
||||
ar>>serialization::make_nvp("position",*node);
|
||||
ar>>core::make_nvp("position",*node);
|
||||
entries()[n++]=node;
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void add_track(Node* node,Archive& ar,const unsigned int)
|
||||
{
|
||||
ar>>serialization::make_nvp("position",*node);
|
||||
ar>>core::make_nvp("position",*node);
|
||||
}
|
||||
|
||||
/* A rearranger is passed two nodes, and is expected to
|
||||
@@ -102,7 +103,7 @@ private:
|
||||
FinalNode* unchecked_load_node(Archive& ar)const
|
||||
{
|
||||
Node* node=0;
|
||||
ar>>serialization::make_nvp("pointer",node);
|
||||
ar>>core::make_nvp("pointer",node);
|
||||
return static_cast<FinalNode*>(node);
|
||||
}
|
||||
|
||||
@@ -110,7 +111,7 @@ private:
|
||||
FinalNode* load_node(Archive& ar)const
|
||||
{
|
||||
Node* node=0;
|
||||
ar>>serialization::make_nvp("pointer",node);
|
||||
ar>>core::make_nvp("pointer",node);
|
||||
check_node(node);
|
||||
return static_cast<FinalNode*>(node);
|
||||
}
|
||||
@@ -118,9 +119,7 @@ private:
|
||||
void check_node(Node* node)const
|
||||
{
|
||||
if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){
|
||||
throw_exception(
|
||||
archive::archive_exception(
|
||||
archive::archive_exception::other_exception));
|
||||
throw_exception(bad_archive_exception());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/raw_ptr.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2016 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -18,8 +18,8 @@
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/multi_index/detail/bad_archive_exception.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#endif
|
||||
|
||||
@@ -117,8 +117,7 @@ inline void load_construct_data(
|
||||
Archive&,boost::multi_index::detail::index_node_base<Value,Allocator>*,
|
||||
const unsigned int)
|
||||
{
|
||||
throw_exception(
|
||||
archive::archive_exception(archive::archive_exception::other_exception));
|
||||
throw_exception(bad_archive_exception());
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/multi_index/detail/index_matcher.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost{
|
||||
@@ -43,14 +43,14 @@ public:
|
||||
template<class Archive>
|
||||
void add(Node* node,Archive& ar,const unsigned int)
|
||||
{
|
||||
ar<<serialization::make_nvp("position",*node);
|
||||
ar<<core::make_nvp("position",*node);
|
||||
alg.add(node);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void add_track(Node* node,Archive& ar,const unsigned int)
|
||||
{
|
||||
ar<<serialization::make_nvp("position",*node);
|
||||
ar<<core::make_nvp("position",*node);
|
||||
}
|
||||
|
||||
template<typename IndexIterator,class Archive>
|
||||
@@ -120,7 +120,7 @@ private:
|
||||
template<typename Archive>
|
||||
static void save_node(Node* node,Archive& ar)
|
||||
{
|
||||
ar<<serialization::make_nvp("pointer",node);
|
||||
ar<<core::make_nvp("pointer",node);
|
||||
}
|
||||
|
||||
index_matcher::algorithm<Node,Allocator> alg;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_INVALIDATE_ITERATORS_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_INVALIDATE_ITERATORS_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* invalidate_iterators mimics the interface of index_access_sequence (see
|
||||
* index_access_sequence.hpp) but returns dummy indices whose iterator type
|
||||
* won't ever match those of the source: the net effect is that safe iterator
|
||||
* transfer resolves to iterator invalidation, so backbone function invocation
|
||||
* extract_(x,invalidate_iterators()) is used in extraction scenarios other
|
||||
* than merging.
|
||||
*/
|
||||
|
||||
struct invalidate_iterators
|
||||
{
|
||||
typedef void iterator;
|
||||
|
||||
invalidate_iterators& get(){return *this;}
|
||||
invalidate_iterators& next(){return *this;}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
52
linx64/include/boost/multi_index/detail/is_function.hpp
Normal file
52
linx64/include/boost/multi_index/detail/is_function.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright 2003-2019 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_FUNCTION_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_IS_FUNCTION_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)||\
|
||||
BOOST_WORKAROUND(_LIBCPP_VERSION,<30700)||\
|
||||
BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40802)
|
||||
/* libc++: std::is_function<void() const> fails,
|
||||
* https://bugs.llvm.org/show_bug.cgi?id=20084
|
||||
*
|
||||
* libstdc++-v3: std::is_function does not support ref-qualified function types,
|
||||
* https://github.com/gcc-mirror/gcc/commit/
|
||||
* 2fa630fb50ba29d8e891c52a75aaec261b07874e#
|
||||
* diff-6547f965a8d66bf35a6388fcf404aaa3
|
||||
*/
|
||||
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
|
||||
namespace boost{namespace multi_index{namespace detail{
|
||||
|
||||
template<typename T>
|
||||
struct is_function:boost::is_function<T>{};
|
||||
|
||||
}}} /* namespace boost::multi_index::detail */
|
||||
|
||||
#else
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{namespace multi_index{namespace detail{
|
||||
|
||||
template<typename T>
|
||||
struct is_function:std::is_function<T>{};
|
||||
|
||||
}}} /* namespace boost::multi_index::detail */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2014 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -41,17 +41,17 @@ struct is_transparent:mpl::true_{};
|
||||
!defined(BOOST_NO_CXX11_DECLTYPE)&& \
|
||||
(defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL))
|
||||
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
#include <boost/type_traits/function_traits.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_final.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
|
||||
267
linx64/include/boost/multi_index/detail/node_handle.hpp
Normal file
267
linx64/include/boost/multi_index/detail/node_handle.hpp
Normal file
@@ -0,0 +1,267 @@
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_NODE_HANDLE_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_NODE_HANDLE_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/multi_index_container_fwd.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <new>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Node handle template class following [container.node] specs.
|
||||
*/
|
||||
|
||||
#include <boost/multi_index/detail/define_if_constexpr_macro.hpp>
|
||||
|
||||
template<typename Node,typename Allocator>
|
||||
class node_handle
|
||||
{
|
||||
public:
|
||||
typedef typename Node::value_type value_type;
|
||||
typedef Allocator allocator_type;
|
||||
|
||||
private:
|
||||
typedef allocator_traits<allocator_type> alloc_traits;
|
||||
|
||||
public:
|
||||
node_handle()BOOST_NOEXCEPT:node(0){}
|
||||
|
||||
node_handle(BOOST_RV_REF(node_handle) x)BOOST_NOEXCEPT:node(x.node)
|
||||
{
|
||||
if(!x.empty()){
|
||||
move_construct_allocator(boost::move(x));
|
||||
x.destroy_allocator();
|
||||
x.node=0;
|
||||
}
|
||||
}
|
||||
|
||||
~node_handle()
|
||||
{
|
||||
if(!empty()){
|
||||
delete_node();
|
||||
destroy_allocator();
|
||||
}
|
||||
}
|
||||
|
||||
node_handle& operator=(BOOST_RV_REF(node_handle) x)
|
||||
{
|
||||
if(this!=&x){
|
||||
if(!empty()){
|
||||
delete_node();
|
||||
if(!x.empty()){
|
||||
BOOST_MULTI_INDEX_IF_CONSTEXPR(
|
||||
alloc_traits::propagate_on_container_move_assignment::value){
|
||||
move_assign_allocator(boost::move(x));
|
||||
}
|
||||
x.destroy_allocator();
|
||||
}
|
||||
else{
|
||||
destroy_allocator();
|
||||
}
|
||||
}
|
||||
else if(!x.empty()){
|
||||
move_construct_allocator(boost::move(x));
|
||||
x.destroy_allocator();
|
||||
}
|
||||
node=x.node;
|
||||
x.node=0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
value_type& value()const{return node->value();}
|
||||
allocator_type get_allocator()const{return *allocator_ptr();}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
explicit
|
||||
#endif
|
||||
operator bool()const BOOST_NOEXCEPT{return (node!=0);}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_GCC_VERSION,>=70000)&&__cplusplus<201103L
|
||||
/* https://github.com/boostorg/config/issues/336 */
|
||||
#else
|
||||
BOOST_ATTRIBUTE_NODISCARD
|
||||
#endif
|
||||
bool empty()const BOOST_NOEXCEPT{return (node==0);}
|
||||
|
||||
void swap(node_handle& x)
|
||||
BOOST_NOEXCEPT_IF(
|
||||
alloc_traits::propagate_on_container_swap::value||
|
||||
alloc_traits::is_always_equal::value)
|
||||
{
|
||||
if(!empty()){
|
||||
if(!x.empty()){
|
||||
BOOST_MULTI_INDEX_IF_CONSTEXPR(
|
||||
alloc_traits::propagate_on_container_swap::value){
|
||||
using std::swap;
|
||||
swap(*allocator_ptr(),*x.allocator_ptr());
|
||||
}
|
||||
}
|
||||
else{
|
||||
x.move_construct_allocator(boost::move(*this));
|
||||
destroy_allocator();
|
||||
}
|
||||
}
|
||||
else if(!x.empty()){
|
||||
move_construct_allocator(boost::move(x));
|
||||
x.destroy_allocator();
|
||||
}
|
||||
std::swap(node,x.node);
|
||||
}
|
||||
|
||||
friend void swap(node_handle& x,node_handle& y)
|
||||
BOOST_NOEXCEPT_IF(noexcept(x.swap(y)))
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle)
|
||||
|
||||
template <typename,typename,typename>
|
||||
friend class boost::multi_index::multi_index_container;
|
||||
|
||||
node_handle(Node* node_,const allocator_type& al):node(node_)
|
||||
{
|
||||
::new (static_cast<void*>(allocator_ptr())) allocator_type(al);
|
||||
}
|
||||
|
||||
void release_node()
|
||||
{
|
||||
if(!empty()){
|
||||
node=0;
|
||||
destroy_allocator();
|
||||
}
|
||||
}
|
||||
|
||||
#include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp>
|
||||
|
||||
const allocator_type* allocator_ptr()const
|
||||
{
|
||||
return reinterpret_cast<const allocator_type*>(&space);
|
||||
}
|
||||
|
||||
allocator_type* allocator_ptr()
|
||||
{
|
||||
return reinterpret_cast<allocator_type*>(&space);
|
||||
}
|
||||
|
||||
#include <boost/multi_index/detail/restore_wstrict_aliasing.hpp>
|
||||
|
||||
void move_construct_allocator(BOOST_RV_REF(node_handle) x)
|
||||
{
|
||||
::new (static_cast<void*>(allocator_ptr()))
|
||||
allocator_type(boost::move(*x.allocator_ptr()));
|
||||
}
|
||||
|
||||
void move_assign_allocator(BOOST_RV_REF(node_handle) x)
|
||||
{
|
||||
*allocator_ptr()=boost::move(*x.allocator_ptr());
|
||||
}
|
||||
|
||||
void destroy_allocator(){allocator_ptr()->~allocator_type();}
|
||||
|
||||
void delete_node()
|
||||
{
|
||||
typedef typename rebind_alloc_for<
|
||||
allocator_type,Node
|
||||
>::type node_allocator;
|
||||
typedef detail::allocator_traits<node_allocator> node_alloc_traits;
|
||||
typedef typename node_alloc_traits::pointer node_pointer;
|
||||
|
||||
alloc_traits::destroy(*allocator_ptr(),boost::addressof(node->value()));
|
||||
node_allocator nal(*allocator_ptr());
|
||||
node_alloc_traits::deallocate(nal,static_cast<node_pointer>(node),1);
|
||||
}
|
||||
|
||||
Node* node;
|
||||
typename aligned_storage<
|
||||
sizeof(allocator_type),
|
||||
alignment_of<allocator_type>::value
|
||||
>::type space;
|
||||
};
|
||||
|
||||
#include <boost/multi_index/detail/undef_if_constexpr_macro.hpp>
|
||||
|
||||
/* node handle insert return type template class following
|
||||
* [container.insert.return] specs.
|
||||
*/
|
||||
|
||||
template<typename Iterator,typename NodeHandle>
|
||||
struct insert_return_type
|
||||
{
|
||||
insert_return_type(
|
||||
Iterator position_,bool inserted_,BOOST_RV_REF(NodeHandle) node_):
|
||||
position(position_),inserted(inserted_),node(boost::move(node_)){}
|
||||
insert_return_type(BOOST_RV_REF(insert_return_type) x):
|
||||
position(x.position),inserted(x.inserted),node(boost::move(x.node)){}
|
||||
|
||||
insert_return_type& operator=(BOOST_RV_REF(insert_return_type) x)
|
||||
{
|
||||
position=x.position;
|
||||
inserted=x.inserted;
|
||||
node=boost::move(x.node);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator position;
|
||||
bool inserted;
|
||||
NodeHandle node;
|
||||
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type)
|
||||
};
|
||||
|
||||
/* utility for SFINAEing merge and related operations */
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
|
||||
#define BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(Dst,Src,T) \
|
||||
typename enable_if_c< \
|
||||
!is_const< Dst >::value&&!is_const< Src >::value&& \
|
||||
is_same<typename Dst::node_type,typename Src::node_type>::value, \
|
||||
T \
|
||||
>::type
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(Dst,Src,T) T
|
||||
|
||||
#endif
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2019 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -44,20 +44,24 @@
|
||||
#include <algorithm>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/ref.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/foreach_fwd.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/adl_swap.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/multi_index/detail/bidir_node_iterator.hpp>
|
||||
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/invalidate_iterators.hpp>
|
||||
#include <boost/multi_index/detail/modify_key_adaptor.hpp>
|
||||
#include <boost/multi_index/detail/node_handle.hpp>
|
||||
#include <boost/multi_index/detail/ord_index_node.hpp>
|
||||
#include <boost/multi_index/detail/ord_index_ops.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
@@ -66,7 +70,6 @@
|
||||
#include <boost/multi_index/detail/value_compare.hpp>
|
||||
#include <boost/multi_index/detail/vartempl_support.hpp>
|
||||
#include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <utility>
|
||||
@@ -76,8 +79,8 @@
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/archive/archive_exception.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/multi_index/detail/bad_archive_exception.hpp>
|
||||
#include <boost/multi_index/detail/duplicates_iterator.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#endif
|
||||
@@ -112,6 +115,11 @@ namespace detail{
|
||||
struct ordered_unique_tag{};
|
||||
struct ordered_non_unique_tag{};
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4355) /* this used in base member initializer list */
|
||||
#endif
|
||||
|
||||
template<
|
||||
typename KeyFromValue,typename Compare,
|
||||
typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
|
||||
@@ -124,13 +132,6 @@ template<
|
||||
>
|
||||
class ordered_index_impl:
|
||||
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,public safe_mode::safe_container<
|
||||
ordered_index_impl<
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> >
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
@@ -142,21 +143,27 @@ class ordered_index_impl:
|
||||
#pragma parse_mfunc_templ off
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
/* cross-index access */
|
||||
|
||||
template <typename,typename,typename> friend class index_base;
|
||||
#endif
|
||||
|
||||
typedef typename SuperMeta::type super;
|
||||
|
||||
protected:
|
||||
typedef ordered_index_node<
|
||||
AugmentPolicy,typename super::node_type> node_type;
|
||||
AugmentPolicy,typename super::index_node_type> index_node_type;
|
||||
|
||||
protected: /* for the benefit of AugmentPolicy::augmented_interface */
|
||||
typedef typename node_type::impl_type node_impl_type;
|
||||
typedef typename index_node_type::impl_type node_impl_type;
|
||||
typedef typename node_impl_type::pointer node_impl_pointer;
|
||||
|
||||
public:
|
||||
/* types */
|
||||
|
||||
typedef typename KeyFromValue::result_type key_type;
|
||||
typedef typename node_type::value_type value_type;
|
||||
typedef typename index_node_type::value_type value_type;
|
||||
typedef KeyFromValue key_from_value;
|
||||
typedef Compare key_compare;
|
||||
typedef value_comparison<
|
||||
@@ -168,10 +175,9 @@ public:
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
typedef safe_mode::safe_iterator<
|
||||
bidir_node_iterator<node_type>,
|
||||
ordered_index_impl> iterator;
|
||||
bidir_node_iterator<index_node_type> > iterator;
|
||||
#else
|
||||
typedef bidir_node_iterator<node_type> iterator;
|
||||
typedef bidir_node_iterator<index_node_type> iterator;
|
||||
#endif
|
||||
|
||||
typedef iterator const_iterator;
|
||||
@@ -188,6 +194,9 @@ public:
|
||||
boost::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef typename
|
||||
boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef typename super::final_node_handle_type node_type;
|
||||
typedef detail::insert_return_type<
|
||||
iterator,node_type> insert_return_type;
|
||||
typedef TagList tag_list;
|
||||
|
||||
protected:
|
||||
@@ -216,8 +225,7 @@ protected:
|
||||
|
||||
protected:
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
typedef safe_mode::safe_container<
|
||||
ordered_index_impl> safe_super;
|
||||
typedef safe_mode::safe_container<iterator> safe_container;
|
||||
#endif
|
||||
|
||||
typedef typename call_traits<
|
||||
@@ -225,11 +233,9 @@ protected:
|
||||
typedef typename call_traits<
|
||||
key_type>::param_type key_param_type;
|
||||
|
||||
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
|
||||
* expansion.
|
||||
*/
|
||||
/* needed to avoid commas in some macros */
|
||||
|
||||
typedef std::pair<iterator,bool> emplace_return_type;
|
||||
typedef std::pair<iterator,bool> pair_return_type;
|
||||
|
||||
public:
|
||||
|
||||
@@ -273,12 +279,14 @@ public:
|
||||
|
||||
iterator iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(boost::addressof(x)));
|
||||
return make_iterator(
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(boost::addressof(x)));
|
||||
return make_iterator(
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
/* capacity */
|
||||
@@ -290,7 +298,7 @@ public:
|
||||
/* modifiers */
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||
emplace_return_type,emplace,emplace_impl)
|
||||
pair_return_type,emplace,emplace_impl)
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
||||
iterator,emplace_hint,emplace_hint_impl,iterator,position)
|
||||
@@ -333,12 +341,7 @@ public:
|
||||
void insert(InputIterator first,InputIterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
node_type* hint=header(); /* end() */
|
||||
for(;first!=last;++first){
|
||||
hint=this->final_insert_ref_(
|
||||
*first,static_cast<final_node_type*>(hint)).first;
|
||||
node_type::increment(hint);
|
||||
}
|
||||
for(;first!=last;++first)this->final_insert_ref_(*first);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
@@ -348,6 +351,42 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
insert_return_type insert(BOOST_RV_REF(node_type) nh)
|
||||
{
|
||||
if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
|
||||
return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator position,BOOST_RV_REF(node_type) nh)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
std::pair<final_node_type*,bool> p=this->final_insert_nh_(
|
||||
nh,static_cast<final_node_type*>(position.get_node()));
|
||||
return make_iterator(p.first);
|
||||
}
|
||||
|
||||
node_type extract(const_iterator position)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
return this->final_extract_(
|
||||
static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
node_type extract(key_param_type x)
|
||||
{
|
||||
iterator position=lower_bound(x);
|
||||
if(position==end()||comp_(x,key(*position)))return node_type();
|
||||
else return extract(position);
|
||||
}
|
||||
|
||||
iterator erase(iterator position)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
@@ -485,6 +524,75 @@ public:
|
||||
this->final_clear_();
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
||||
merge(Index& x)
|
||||
{
|
||||
merge(x,x.begin(),x.end());
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
||||
merge(BOOST_RV_REF(Index) x){merge(static_cast<Index&>(x));}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||
ordered_index_impl,Index,pair_return_type)
|
||||
merge(Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
|
||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
if(x.end().get_node()==this->header()){ /* same container */
|
||||
return std::pair<iterator,bool>(
|
||||
make_iterator(static_cast<final_node_type*>(i.get_node())),true);
|
||||
}
|
||||
else{
|
||||
std::pair<final_node_type*,bool> p=this->final_transfer_(
|
||||
x,static_cast<final_node_type*>(i.get_node()));
|
||||
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||
ordered_index_impl,Index,pair_return_type)
|
||||
merge(BOOST_RV_REF(Index) x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||
{
|
||||
return merge(static_cast<Index&>(x),i);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
||||
merge(
|
||||
Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
||||
if(x.end().get_node()!=this->header()){ /* different containers */
|
||||
this->final_transfer_range_(x,first,last);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
||||
merge(
|
||||
BOOST_RV_REF(Index) x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{
|
||||
merge(static_cast<Index&>(x),first,last);
|
||||
}
|
||||
|
||||
/* observers */
|
||||
|
||||
key_from_value key_extractor()const{return key;}
|
||||
@@ -524,6 +632,19 @@ public:
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
bool contains(const CompatibleKey& x)const
|
||||
{
|
||||
return contains(x,comp_);
|
||||
}
|
||||
|
||||
template<typename CompatibleKey,typename CompatibleCompare>
|
||||
bool contains(
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
{
|
||||
return find(x,comp)!=end();
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
iterator lower_bound(const CompatibleKey& x)const
|
||||
{
|
||||
@@ -558,7 +679,7 @@ public:
|
||||
std::pair<iterator,iterator> equal_range(
|
||||
const CompatibleKey& x)const
|
||||
{
|
||||
std::pair<node_type*,node_type*> p=
|
||||
std::pair<index_node_type*,index_node_type*> p=
|
||||
ordered_index_equal_range(root(),header(),key,x,comp_);
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(p.first),make_iterator(p.second));
|
||||
@@ -568,7 +689,7 @@ public:
|
||||
std::pair<iterator,iterator> equal_range(
|
||||
const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
{
|
||||
std::pair<node_type*,node_type*> p=
|
||||
std::pair<index_node_type*,index_node_type*> p=
|
||||
ordered_index_equal_range(root(),header(),key,x,comp);
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(p.first),make_iterator(p.second));
|
||||
@@ -602,6 +723,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
super(args_list.get_tail(),al),
|
||||
key(tuples::get<0>(args_list.get_head())),
|
||||
comp_(tuples::get<1>(args_list.get_head()))
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
empty_initialize();
|
||||
}
|
||||
@@ -610,13 +736,13 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
const ordered_index_impl<
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x):
|
||||
super(x),
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
#endif
|
||||
|
||||
key(x.key),
|
||||
comp_(x.comp_)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
/* Copy ctor just takes the key and compare objects from x. The rest is
|
||||
* done in a subsequent call to copy_().
|
||||
@@ -628,13 +754,13 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
|
||||
do_not_copy_elements_tag):
|
||||
super(x,do_not_copy_elements_tag()),
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
#endif
|
||||
|
||||
key(x.key),
|
||||
comp_(x.comp_)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
empty_initialize();
|
||||
}
|
||||
@@ -645,12 +771,13 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
iterator make_iterator(node_type* node){return iterator(node,this);}
|
||||
const_iterator make_iterator(node_type* node)const
|
||||
{return const_iterator(node,const_cast<ordered_index_impl*>(this));}
|
||||
iterator make_iterator(index_node_type* node)
|
||||
{return iterator(node,&safe);}
|
||||
const_iterator make_iterator(index_node_type* node)const
|
||||
{return const_iterator(node,const_cast<safe_container*>(&safe));}
|
||||
#else
|
||||
iterator make_iterator(node_type* node){return iterator(node);}
|
||||
const_iterator make_iterator(node_type* node)const
|
||||
iterator make_iterator(index_node_type* node){return iterator(node);}
|
||||
const_iterator make_iterator(index_node_type* node)const
|
||||
{return const_iterator(node);}
|
||||
#endif
|
||||
|
||||
@@ -666,21 +793,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
header()->color()=x.header()->color();
|
||||
AugmentPolicy::copy(x.header()->impl(),header()->impl());
|
||||
|
||||
node_type* root_cpy=map.find(static_cast<final_node_type*>(x.root()));
|
||||
index_node_type* root_cpy=map.find(
|
||||
static_cast<final_node_type*>(x.root()));
|
||||
header()->parent()=root_cpy->impl();
|
||||
|
||||
node_type* leftmost_cpy=map.find(
|
||||
index_node_type* leftmost_cpy=map.find(
|
||||
static_cast<final_node_type*>(x.leftmost()));
|
||||
header()->left()=leftmost_cpy->impl();
|
||||
|
||||
node_type* rightmost_cpy=map.find(
|
||||
index_node_type* rightmost_cpy=map.find(
|
||||
static_cast<final_node_type*>(x.rightmost()));
|
||||
header()->right()=rightmost_cpy->impl();
|
||||
|
||||
typedef typename copy_map_type::const_iterator copy_map_iterator;
|
||||
for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
|
||||
node_type* org=it->first;
|
||||
node_type* cpy=it->second;
|
||||
index_node_type* org=it->first;
|
||||
index_node_type* cpy=it->second;
|
||||
|
||||
cpy->color()=org->color();
|
||||
AugmentPolicy::copy(org->impl(),cpy->impl());
|
||||
@@ -688,8 +816,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
node_impl_pointer parent_org=org->parent();
|
||||
if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
|
||||
else{
|
||||
node_type* parent_cpy=map.find(
|
||||
static_cast<final_node_type*>(node_type::from_impl(parent_org)));
|
||||
index_node_type* parent_cpy=map.find(
|
||||
static_cast<final_node_type*>(
|
||||
index_node_type::from_impl(parent_org)));
|
||||
cpy->parent()=parent_cpy->impl();
|
||||
if(parent_org->left()==org->impl()){
|
||||
parent_cpy->left()=cpy->impl();
|
||||
@@ -716,42 +845,48 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
{
|
||||
link_info inf;
|
||||
if(!link_point(key(v),inf,Category())){
|
||||
return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
|
||||
return static_cast<final_node_type*>(
|
||||
index_node_type::from_impl(inf.pos));
|
||||
}
|
||||
|
||||
final_node_type* res=super::insert_(v,x,variant);
|
||||
if(res==x){
|
||||
node_impl_type::link(
|
||||
static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
|
||||
static_cast<index_node_type*>(x)->impl(),
|
||||
inf.side,inf.pos,header()->impl());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Variant>
|
||||
final_node_type* insert_(
|
||||
value_param_type v,node_type* position,final_node_type*& x,Variant variant)
|
||||
value_param_type v,index_node_type* position,
|
||||
final_node_type*& x,Variant variant)
|
||||
{
|
||||
link_info inf;
|
||||
if(!hinted_link_point(key(v),position,inf,Category())){
|
||||
return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
|
||||
return static_cast<final_node_type*>(
|
||||
index_node_type::from_impl(inf.pos));
|
||||
}
|
||||
|
||||
final_node_type* res=super::insert_(v,position,x,variant);
|
||||
if(res==x){
|
||||
node_impl_type::link(
|
||||
static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
|
||||
static_cast<index_node_type*>(x)->impl(),
|
||||
inf.side,inf.pos,header()->impl());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void erase_(node_type* x)
|
||||
template<typename Dst>
|
||||
void extract_(index_node_type* x,Dst dst)
|
||||
{
|
||||
node_impl_type::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_extract(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
super::erase_(x);
|
||||
super::extract_(x,dst.next());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
transfer_iterators(dst.get(),x);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -766,22 +901,24 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
empty_initialize();
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::detach_dereferenceable_iterators();
|
||||
safe.detach_dereferenceable_iterators();
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename BoolConstant>
|
||||
void swap_(
|
||||
ordered_index_impl<
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
|
||||
BoolConstant swap_allocators)
|
||||
{
|
||||
std::swap(key,x.key);
|
||||
std::swap(comp_,x.comp_);
|
||||
adl_swap(key,x.key);
|
||||
adl_swap(comp_,x.comp_);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::swap(x);
|
||||
safe.swap(x.safe);
|
||||
#endif
|
||||
|
||||
super::swap_(x);
|
||||
super::swap_(x,swap_allocators);
|
||||
}
|
||||
|
||||
void swap_elements_(
|
||||
@@ -789,23 +926,23 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::swap(x);
|
||||
safe.swap(x.safe);
|
||||
#endif
|
||||
|
||||
super::swap_elements_(x);
|
||||
}
|
||||
|
||||
template<typename Variant>
|
||||
bool replace_(value_param_type v,node_type* x,Variant variant)
|
||||
bool replace_(value_param_type v,index_node_type* x,Variant variant)
|
||||
{
|
||||
if(in_place(v,x,Category())){
|
||||
return super::replace_(v,x,variant);
|
||||
}
|
||||
|
||||
node_type* next=x;
|
||||
node_type::increment(next);
|
||||
index_node_type* next=x;
|
||||
index_node_type::increment(next);
|
||||
|
||||
node_impl_type::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_extract(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
|
||||
BOOST_TRY{
|
||||
@@ -824,24 +961,24 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_(node_type* x)
|
||||
bool modify_(index_node_type* x)
|
||||
{
|
||||
bool b;
|
||||
BOOST_TRY{
|
||||
b=in_place(x->value(),x,Category());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
erase_(x);
|
||||
extract_(x,invalidate_iterators());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
if(!b){
|
||||
node_impl_type::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_extract(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
BOOST_TRY{
|
||||
link_info inf;
|
||||
if(!link_point(key(x->value()),inf,Category())){
|
||||
super::erase_(x);
|
||||
super::extract_(x,invalidate_iterators());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
@@ -851,7 +988,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
super::erase_(x);
|
||||
super::extract_(x,invalidate_iterators());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
@@ -864,7 +1001,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
|
||||
BOOST_TRY{
|
||||
if(!super::modify_(x)){
|
||||
node_impl_type::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_extract(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
@@ -876,7 +1013,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
else return true;
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
node_impl_type::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_extract(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
@@ -888,16 +1025,16 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_rollback_(node_type* x)
|
||||
bool modify_rollback_(index_node_type* x)
|
||||
{
|
||||
if(in_place(x->value(),x,Category())){
|
||||
return super::modify_rollback_(x);
|
||||
}
|
||||
|
||||
node_type* next=x;
|
||||
node_type::increment(next);
|
||||
index_node_type* next=x;
|
||||
index_node_type::increment(next);
|
||||
|
||||
node_impl_type::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_extract(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
|
||||
BOOST_TRY{
|
||||
@@ -917,7 +1054,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool check_rollback_(node_type* x)const
|
||||
bool check_rollback_(index_node_type* x)const
|
||||
{
|
||||
return in_place(x->value(),x,Category())&&super::check_rollback_(x);
|
||||
}
|
||||
@@ -955,9 +1092,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
std::size_t len=node_impl_type::black_count(
|
||||
leftmost()->impl(),root()->impl());
|
||||
for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
|
||||
node_type* x=it.get_node();
|
||||
node_type* left_x=node_type::from_impl(x->left());
|
||||
node_type* right_x=node_type::from_impl(x->right());
|
||||
index_node_type* x=it.get_node();
|
||||
index_node_type* left_x=index_node_type::from_impl(x->left());
|
||||
index_node_type* right_x=index_node_type::from_impl(x->right());
|
||||
|
||||
if(x->color()==red){
|
||||
if((left_x&&left_x->color()==red)||
|
||||
@@ -990,10 +1127,14 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
#endif
|
||||
|
||||
protected: /* for the benefit of AugmentPolicy::augmented_interface */
|
||||
node_type* header()const{return this->final_header();}
|
||||
node_type* root()const{return node_type::from_impl(header()->parent());}
|
||||
node_type* leftmost()const{return node_type::from_impl(header()->left());}
|
||||
node_type* rightmost()const{return node_type::from_impl(header()->right());}
|
||||
index_node_type* header()const
|
||||
{return this->final_header();}
|
||||
index_node_type* root()const
|
||||
{return index_node_type::from_impl(header()->parent());}
|
||||
index_node_type* leftmost()const
|
||||
{return index_node_type::from_impl(header()->left());}
|
||||
index_node_type* rightmost()const
|
||||
{return index_node_type::from_impl(header()->right());}
|
||||
|
||||
private:
|
||||
void empty_initialize()
|
||||
@@ -1017,22 +1158,22 @@ private:
|
||||
|
||||
bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
|
||||
{
|
||||
node_type* y=header();
|
||||
node_type* x=root();
|
||||
index_node_type* y=header();
|
||||
index_node_type* x=root();
|
||||
bool c=true;
|
||||
while(x){
|
||||
y=x;
|
||||
c=comp_(k,key(x->value()));
|
||||
x=node_type::from_impl(c?x->left():x->right());
|
||||
x=index_node_type::from_impl(c?x->left():x->right());
|
||||
}
|
||||
node_type* yy=y;
|
||||
index_node_type* yy=y;
|
||||
if(c){
|
||||
if(yy==leftmost()){
|
||||
inf.side=to_left;
|
||||
inf.pos=y->impl();
|
||||
return true;
|
||||
}
|
||||
else node_type::decrement(yy);
|
||||
else index_node_type::decrement(yy);
|
||||
}
|
||||
|
||||
if(comp_(key(yy->value()),k)){
|
||||
@@ -1048,13 +1189,13 @@ private:
|
||||
|
||||
bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
|
||||
{
|
||||
node_type* y=header();
|
||||
node_type* x=root();
|
||||
index_node_type* y=header();
|
||||
index_node_type* x=root();
|
||||
bool c=true;
|
||||
while (x){
|
||||
y=x;
|
||||
c=comp_(k,key(x->value()));
|
||||
x=node_type::from_impl(c?x->left():x->right());
|
||||
x=index_node_type::from_impl(c?x->left():x->right());
|
||||
}
|
||||
inf.side=c?to_left:to_right;
|
||||
inf.pos=y->impl();
|
||||
@@ -1063,13 +1204,13 @@ private:
|
||||
|
||||
bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
|
||||
{
|
||||
node_type* y=header();
|
||||
node_type* x=root();
|
||||
index_node_type* y=header();
|
||||
index_node_type* x=root();
|
||||
bool c=false;
|
||||
while (x){
|
||||
y=x;
|
||||
c=comp_(key(x->value()),k);
|
||||
x=node_type::from_impl(c?x->right():x->left());
|
||||
x=index_node_type::from_impl(c?x->right():x->left());
|
||||
}
|
||||
inf.side=c?to_right:to_left;
|
||||
inf.pos=y->impl();
|
||||
@@ -1077,7 +1218,8 @@ private:
|
||||
}
|
||||
|
||||
bool hinted_link_point(
|
||||
key_param_type k,node_type* position,link_info& inf,ordered_unique_tag)
|
||||
key_param_type k,index_node_type* position,
|
||||
link_info& inf,ordered_unique_tag)
|
||||
{
|
||||
if(position->impl()==header()->left()){
|
||||
if(size()>0&&comp_(k,key(position->value()))){
|
||||
@@ -1096,8 +1238,8 @@ private:
|
||||
else return link_point(k,inf,ordered_unique_tag());
|
||||
}
|
||||
else{
|
||||
node_type* before=position;
|
||||
node_type::decrement(before);
|
||||
index_node_type* before=position;
|
||||
index_node_type::decrement(before);
|
||||
if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
|
||||
if(before->right()==node_impl_pointer(0)){
|
||||
inf.side=to_right;
|
||||
@@ -1115,7 +1257,8 @@ private:
|
||||
}
|
||||
|
||||
bool hinted_link_point(
|
||||
key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag)
|
||||
key_param_type k,index_node_type* position,
|
||||
link_info& inf,ordered_non_unique_tag)
|
||||
{
|
||||
if(position->impl()==header()->left()){
|
||||
if(size()>0&&!comp_(key(position->value()),k)){
|
||||
@@ -1134,8 +1277,8 @@ private:
|
||||
else return link_point(k,inf,ordered_non_unique_tag());
|
||||
}
|
||||
else{
|
||||
node_type* before=position;
|
||||
node_type::decrement(before);
|
||||
index_node_type* before=position;
|
||||
index_node_type::decrement(before);
|
||||
if(!comp_(k,key(before->value()))){
|
||||
if(!comp_(key(position->value()),k)){
|
||||
if(before->right()==node_impl_pointer(0)){
|
||||
@@ -1155,49 +1298,57 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void delete_all_nodes(node_type* x)
|
||||
void delete_all_nodes(index_node_type* x)
|
||||
{
|
||||
if(!x)return;
|
||||
|
||||
delete_all_nodes(node_type::from_impl(x->left()));
|
||||
delete_all_nodes(node_type::from_impl(x->right()));
|
||||
delete_all_nodes(index_node_type::from_impl(x->left()));
|
||||
delete_all_nodes(index_node_type::from_impl(x->right()));
|
||||
this->final_delete_node_(static_cast<final_node_type*>(x));
|
||||
}
|
||||
|
||||
bool in_place(value_param_type v,node_type* x,ordered_unique_tag)const
|
||||
bool in_place(value_param_type v,index_node_type* x,ordered_unique_tag)const
|
||||
{
|
||||
node_type* y;
|
||||
index_node_type* y;
|
||||
if(x!=leftmost()){
|
||||
y=x;
|
||||
node_type::decrement(y);
|
||||
index_node_type::decrement(y);
|
||||
if(!comp_(key(y->value()),key(v)))return false;
|
||||
}
|
||||
|
||||
y=x;
|
||||
node_type::increment(y);
|
||||
index_node_type::increment(y);
|
||||
return y==header()||comp_(key(v),key(y->value()));
|
||||
}
|
||||
|
||||
bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag)const
|
||||
bool in_place(
|
||||
value_param_type v,index_node_type* x,ordered_non_unique_tag)const
|
||||
{
|
||||
node_type* y;
|
||||
index_node_type* y;
|
||||
if(x!=leftmost()){
|
||||
y=x;
|
||||
node_type::decrement(y);
|
||||
index_node_type::decrement(y);
|
||||
if(comp_(key(v),key(y->value())))return false;
|
||||
}
|
||||
|
||||
y=x;
|
||||
node_type::increment(y);
|
||||
index_node_type::increment(y);
|
||||
return y==header()||!comp_(key(y->value()),key(v));
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
void detach_iterators(node_type* x)
|
||||
void detach_iterators(index_node_type* x)
|
||||
{
|
||||
iterator it=make_iterator(x);
|
||||
safe_mode::detach_equivalent_iterators(it);
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
void transfer_iterators(Dst& dst,index_node_type* x)
|
||||
{
|
||||
iterator it=make_iterator(x);
|
||||
safe_mode::transfer_equivalent_iterators(dst,it);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
||||
@@ -1227,23 +1378,23 @@ private:
|
||||
std::pair<iterator,iterator>
|
||||
range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
|
||||
{
|
||||
node_type* y=header();
|
||||
node_type* z=root();
|
||||
index_node_type* y=header();
|
||||
index_node_type* z=root();
|
||||
|
||||
while(z){
|
||||
if(!lower(key(z->value()))){
|
||||
z=node_type::from_impl(z->right());
|
||||
z=index_node_type::from_impl(z->right());
|
||||
}
|
||||
else if(!upper(key(z->value()))){
|
||||
y=z;
|
||||
z=node_type::from_impl(z->left());
|
||||
z=index_node_type::from_impl(z->left());
|
||||
}
|
||||
else{
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(
|
||||
lower_range(node_type::from_impl(z->left()),z,lower)),
|
||||
lower_range(index_node_type::from_impl(z->left()),z,lower)),
|
||||
make_iterator(
|
||||
upper_range(node_type::from_impl(z->right()),y,upper)));
|
||||
upper_range(index_node_type::from_impl(z->right()),y,upper)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1276,28 +1427,30 @@ private:
|
||||
}
|
||||
|
||||
template<typename LowerBounder>
|
||||
node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const
|
||||
index_node_type * lower_range(
|
||||
index_node_type* top,index_node_type* y,LowerBounder lower)const
|
||||
{
|
||||
while(top){
|
||||
if(lower(key(top->value()))){
|
||||
y=top;
|
||||
top=node_type::from_impl(top->left());
|
||||
top=index_node_type::from_impl(top->left());
|
||||
}
|
||||
else top=node_type::from_impl(top->right());
|
||||
else top=index_node_type::from_impl(top->right());
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
template<typename UpperBounder>
|
||||
node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const
|
||||
index_node_type * upper_range(
|
||||
index_node_type* top,index_node_type* y,UpperBounder upper)const
|
||||
{
|
||||
while(top){
|
||||
if(!upper(key(top->value()))){
|
||||
y=top;
|
||||
top=node_type::from_impl(top->left());
|
||||
top=index_node_type::from_impl(top->left());
|
||||
}
|
||||
else top=node_type::from_impl(top->right());
|
||||
else top=index_node_type::from_impl(top->right());
|
||||
}
|
||||
|
||||
return y;
|
||||
@@ -1325,7 +1478,7 @@ private:
|
||||
Archive& ar,const unsigned int version,const index_saver_type& sm,
|
||||
ordered_non_unique_tag)const
|
||||
{
|
||||
typedef duplicates_iterator<node_type,value_compare> dup_iterator;
|
||||
typedef duplicates_iterator<index_node_type,value_compare> dup_iterator;
|
||||
|
||||
sm.save(
|
||||
dup_iterator(begin().get_node(),end().get_node(),value_comp()),
|
||||
@@ -1347,21 +1500,19 @@ private:
|
||||
super::load_(ar,version,lm);
|
||||
}
|
||||
|
||||
void rearranger(node_type* position,node_type *x)
|
||||
void rearranger(index_node_type* position,index_node_type *x)
|
||||
{
|
||||
if(!position||comp_(key(position->value()),key(x->value()))){
|
||||
position=lower_bound(key(x->value())).get_node();
|
||||
}
|
||||
else if(comp_(key(x->value()),key(position->value()))){
|
||||
/* inconsistent rearrangement */
|
||||
throw_exception(
|
||||
archive::archive_exception(
|
||||
archive::archive_exception::other_exception));
|
||||
throw_exception(bad_archive_exception());
|
||||
}
|
||||
else node_type::increment(position);
|
||||
else index_node_type::increment(position);
|
||||
|
||||
if(position!=x){
|
||||
node_impl_type::rebalance_for_erase(
|
||||
node_impl_type::rebalance_for_extract(
|
||||
x->impl(),header()->parent(),header()->left(),header()->right());
|
||||
node_impl_type::restore(
|
||||
x->impl(),position->impl(),header()->impl());
|
||||
@@ -1373,6 +1524,10 @@ protected: /* for the benefit of AugmentPolicy::augmented_interface */
|
||||
key_from_value key;
|
||||
key_compare comp_;
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_container safe;
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
#pragma parse_mfunc_templ reset
|
||||
@@ -1433,6 +1588,10 @@ protected:
|
||||
super(x,do_not_copy_elements_tag()){}
|
||||
};
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4355 */
|
||||
#endif
|
||||
|
||||
/* comparison */
|
||||
|
||||
template<
|
||||
@@ -1560,16 +1719,22 @@ void swap(
|
||||
|
||||
/* Boost.Foreach compatibility */
|
||||
|
||||
namespace boost{
|
||||
namespace foreach{
|
||||
|
||||
template<typename>
|
||||
struct is_noncopyable;
|
||||
|
||||
template<
|
||||
typename KeyFromValue,typename Compare,
|
||||
typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
|
||||
>
|
||||
inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
||||
struct is_noncopyable<
|
||||
boost::multi_index::detail::ordered_index<
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&,
|
||||
boost_foreach_argument_dependent_lookup_hack)
|
||||
{
|
||||
return 0;
|
||||
KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>
|
||||
>:boost::mpl::true_{};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2019 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -412,7 +412,7 @@ public:
|
||||
ordered_index_node_impl::rebalance(x,header->parent());
|
||||
}
|
||||
|
||||
static pointer rebalance_for_erase(
|
||||
static pointer rebalance_for_extract(
|
||||
pointer z,parent_ref root,pointer& leftmost,pointer& rightmost)
|
||||
{
|
||||
pointer y=z;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,10 +15,10 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/rnd_index_ptr_array.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2021 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -169,6 +169,25 @@ struct random_access_index_node_impl
|
||||
}
|
||||
}
|
||||
|
||||
static ptr_pointer gather_nulls(
|
||||
ptr_pointer pbegin,ptr_pointer pend,ptr_pointer x)
|
||||
{
|
||||
for(ptr_pointer p=pbegin;p!=x;++p){
|
||||
if(*p){
|
||||
*pbegin=*p;
|
||||
(*pbegin)->up()=pbegin;
|
||||
++pbegin;
|
||||
}
|
||||
}
|
||||
for(ptr_pointer p=pend;p!=x;){
|
||||
if(*--p){
|
||||
*--pend=*p;
|
||||
(*pend)->up()=pend;
|
||||
}
|
||||
}
|
||||
return pbegin;
|
||||
}
|
||||
|
||||
private:
|
||||
ptr_pointer up_;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,10 +15,10 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/rnd_index_node.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -110,6 +110,14 @@ public:
|
||||
spc.swap(x.spc);
|
||||
}
|
||||
|
||||
template<typename BoolConstant>
|
||||
void swap(random_access_index_ptr_array& x,BoolConstant swap_allocators)
|
||||
{
|
||||
std::swap(size_,x.size_);
|
||||
std::swap(capacity_,x.capacity_);
|
||||
spc.swap(x.spc,swap_allocators);
|
||||
}
|
||||
|
||||
private:
|
||||
size_type size_;
|
||||
size_type capacity_;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,8 +17,7 @@
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
@@ -77,7 +76,11 @@ public:
|
||||
* see explanation in safe_mode_iterator notes in safe_mode.hpp.
|
||||
*/
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,const unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
typedef typename Node::base_type node_base_type;
|
||||
|
||||
@@ -85,14 +88,14 @@ public:
|
||||
void save(Archive& ar,const unsigned int)const
|
||||
{
|
||||
node_base_type* bnode=node;
|
||||
ar<<serialization::make_nvp("pointer",bnode);
|
||||
ar<<core::make_nvp("pointer",bnode);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& ar,const unsigned int)
|
||||
{
|
||||
node_base_type* bnode;
|
||||
ar>>serialization::make_nvp("pointer",bnode);
|
||||
ar>>core::make_nvp("pointer",bnode);
|
||||
node=static_cast<Node*>(bnode);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
/* Safe mode machinery, in the spirit of Cay Hortmann's "Safe STL"
|
||||
* (http://www.horstmann.com/safestl.html).
|
||||
* In this mode, containers of type Container are derived from
|
||||
* safe_container<Container>, and their corresponding iterators
|
||||
* are wrapped with safe_iterator. These classes provide
|
||||
* In this mode, containers have to redefine their iterators as
|
||||
* safe_iterator<base_iterator> and keep a tracking object member of
|
||||
* type safe_container<safe_iterator<base_iterator> >. These classes provide
|
||||
* an internal record of which iterators are at a given moment associated
|
||||
* to a given container, and properly mark the iterators as invalid
|
||||
* when the container gets destroyed.
|
||||
@@ -80,6 +80,11 @@
|
||||
safe_mode::check_is_owner(it,cont), \
|
||||
safe_mode::not_owner);
|
||||
|
||||
#define BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,cont) \
|
||||
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \
|
||||
safe_mode::check_belongs_in_some_index(it,cont), \
|
||||
safe_mode::not_owner);
|
||||
|
||||
#define BOOST_MULTI_INDEX_CHECK_SAME_OWNER(it0,it1) \
|
||||
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \
|
||||
safe_mode::check_same_owner(it0,it1), \
|
||||
@@ -105,22 +110,29 @@
|
||||
safe_mode::check_different_container(cont0,cont1), \
|
||||
safe_mode::same_container);
|
||||
|
||||
#define BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(cont0,cont1) \
|
||||
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \
|
||||
safe_mode::check_equal_allocators(cont0,cont1), \
|
||||
safe_mode::unequal_allocators);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/any_container_view.hpp>
|
||||
#include <boost/multi_index/detail/iter_adaptor.hpp>
|
||||
#include <boost/multi_index/safe_mode_errors.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
#include <boost/detail/lightweight_mutex.hpp>
|
||||
#include <boost/multi_index/detail/scoped_bilock.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
@@ -158,18 +170,29 @@ inline bool check_decrementable_iterator(const Iterator& it)
|
||||
return (it.valid()&&it!=it.owner()->begin())||it.unchecked();
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
template<typename Iterator,typename Container>
|
||||
inline bool check_is_owner(
|
||||
const Iterator& it,const typename Iterator::container_type& cont)
|
||||
const Iterator& it,const Container& cont)
|
||||
{
|
||||
return (it.valid()&&it.owner()==&cont)||it.unchecked();
|
||||
return (it.valid()&&
|
||||
it.owner()->container()==cont.end().owner()->container())
|
||||
||it.unchecked();
|
||||
}
|
||||
|
||||
template<typename Iterator,typename MultiIndexContainer>
|
||||
inline bool check_belongs_in_some_index(
|
||||
const Iterator& it,const MultiIndexContainer& cont)
|
||||
{
|
||||
return (it.valid()&&it.owner()->end().get_node()==cont.end().get_node())
|
||||
||it.unchecked();
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
inline bool check_same_owner(const Iterator& it0,const Iterator& it1)
|
||||
{
|
||||
return (it0.valid()&&it1.valid()&&it0.owner()==it1.owner())||
|
||||
it0.unchecked()||it1.unchecked();
|
||||
return (it0.valid()&&it1.valid()&&
|
||||
it0.owner()->container()==it1.owner()->container())
|
||||
||it0.unchecked()||it1.unchecked();
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
@@ -213,6 +236,28 @@ inline bool check_outside_range(
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Iterator1,typename Iterator2>
|
||||
inline bool check_outside_range(
|
||||
const Iterator1& it,const Iterator2& it0,const Iterator2& it1)
|
||||
{
|
||||
if(it.valid()&&it!=it.owner()->end()&&it0.valid()){
|
||||
Iterator2 last=it0.owner()->end();
|
||||
bool found=false;
|
||||
|
||||
Iterator2 first=it0;
|
||||
for(;first!=last;++first){
|
||||
if(first==it1)break;
|
||||
|
||||
/* crucial that this check goes after previous break */
|
||||
|
||||
if(boost::addressof(*first)==boost::addressof(*it))found=true;
|
||||
}
|
||||
if(first!=it1)return false;
|
||||
return !found;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Iterator,typename Difference>
|
||||
inline bool check_in_bounds(const Iterator& it,Difference n)
|
||||
{
|
||||
@@ -229,42 +274,33 @@ inline bool check_different_container(
|
||||
return &cont0!=&cont1;
|
||||
}
|
||||
|
||||
/* Invalidates all iterators equivalent to that given. Safe containers
|
||||
* must call this when deleting elements: the safe mode framework cannot
|
||||
* perform this operation automatically without outside help.
|
||||
*/
|
||||
|
||||
template<typename Iterator>
|
||||
inline void detach_equivalent_iterators(Iterator& it)
|
||||
template<typename Container1,typename Container2>
|
||||
inline bool check_different_container(const Container1&,const Container2&)
|
||||
{
|
||||
if(it.valid()){
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex);
|
||||
#endif
|
||||
|
||||
Iterator *prev_,*next_;
|
||||
for(
|
||||
prev_=static_cast<Iterator*>(&it.cont->header);
|
||||
(next_=static_cast<Iterator*>(prev_->next))!=0;){
|
||||
if(next_!=&it&&*next_==it){
|
||||
prev_->next=next_->next;
|
||||
next_->cont=0;
|
||||
}
|
||||
else prev_=next_;
|
||||
}
|
||||
}
|
||||
it.detach();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Container> class safe_container; /* fwd decl. */
|
||||
template<typename Container0,typename Container1>
|
||||
inline bool check_equal_allocators(
|
||||
const Container0& cont0,const Container1& cont1)
|
||||
{
|
||||
return cont0.get_allocator()==cont1.get_allocator();
|
||||
}
|
||||
|
||||
} /* namespace multi_index::safe_mode */
|
||||
/* fwd decls */
|
||||
|
||||
namespace detail{
|
||||
template<typename Container> class safe_container;
|
||||
template<typename Iterator> void detach_equivalent_iterators(Iterator&);
|
||||
|
||||
class safe_container_base; /* fwd decl. */
|
||||
namespace safe_mode_detail{
|
||||
|
||||
/* fwd decls */
|
||||
|
||||
class safe_container_base;
|
||||
template<typename Dst,typename Iterator>
|
||||
void transfer_equivalent_iterators(Dst&,Iterator,boost::true_type);
|
||||
template<typename Dst,typename Iterator>
|
||||
inline void transfer_equivalent_iterators(Dst&,Iterator&,boost::false_type);
|
||||
|
||||
class safe_iterator_base
|
||||
{
|
||||
@@ -314,12 +350,16 @@ protected:
|
||||
const safe_container_base* owner()const{return cont;}
|
||||
|
||||
BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
friend class safe_container_base;
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template<typename> friend class safe_mode::safe_container;
|
||||
template<typename Iterator> friend
|
||||
void safe_mode::detach_equivalent_iterators(Iterator&);
|
||||
friend class safe_container_base;
|
||||
template<typename>
|
||||
friend class safe_mode::safe_container;
|
||||
template<typename Iterator>
|
||||
friend void safe_mode::detach_equivalent_iterators(Iterator&);
|
||||
template<typename Dst,typename Iterator>
|
||||
friend void safe_mode_detail::transfer_equivalent_iterators(
|
||||
Dst&,Iterator,boost::true_type);
|
||||
#endif
|
||||
|
||||
inline void attach(safe_container_base* cont_);
|
||||
@@ -335,11 +375,14 @@ public:
|
||||
safe_container_base(){}
|
||||
|
||||
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
friend class safe_iterator_base;
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template<typename Iterator> friend
|
||||
void safe_mode::detach_equivalent_iterators(Iterator&);
|
||||
friend class safe_iterator_base;
|
||||
template<typename Iterator>
|
||||
friend void safe_mode::detach_equivalent_iterators(Iterator&);
|
||||
template<typename Dst,typename Iterator>
|
||||
friend void safe_mode_detail::transfer_equivalent_iterators(
|
||||
Dst&,Iterator,boost::true_type);
|
||||
#endif
|
||||
|
||||
~safe_container_base()
|
||||
@@ -394,42 +437,38 @@ void safe_iterator_base::detach()
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
namespace safe_mode{
|
||||
} /* namespace multi_index::safe_mode::safe_mode_detail */
|
||||
|
||||
/* In order to enable safe mode on a container:
|
||||
* - The container must derive from safe_container<container_type>,
|
||||
* - The container must keep a member of type safe_container<iterator>,
|
||||
* - iterators must be generated via safe_iterator, which adapts a
|
||||
* preexistent unsafe iterator class.
|
||||
* preexistent unsafe iterator class. safe_iterators are passed the
|
||||
* address of the previous safe_container member at construction time.
|
||||
*/
|
||||
|
||||
template<typename Container>
|
||||
class safe_container;
|
||||
|
||||
template<typename Iterator,typename Container>
|
||||
template<typename Iterator>
|
||||
class safe_iterator:
|
||||
public detail::iter_adaptor<safe_iterator<Iterator,Container>,Iterator>,
|
||||
public detail::safe_iterator_base
|
||||
public detail::iter_adaptor<safe_iterator<Iterator>,Iterator>,
|
||||
public safe_mode_detail::safe_iterator_base
|
||||
{
|
||||
typedef detail::iter_adaptor<safe_iterator,Iterator> super;
|
||||
typedef detail::safe_iterator_base safe_super;
|
||||
typedef safe_mode_detail::safe_iterator_base safe_super;
|
||||
|
||||
public:
|
||||
typedef Container container_type;
|
||||
typedef typename Iterator::reference reference;
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
|
||||
safe_iterator(){}
|
||||
explicit safe_iterator(safe_container<container_type>* cont_):
|
||||
explicit safe_iterator(safe_container<safe_iterator>* cont_):
|
||||
safe_super(cont_){}
|
||||
template<typename T0>
|
||||
safe_iterator(const T0& t0,safe_container<container_type>* cont_):
|
||||
safe_iterator(const T0& t0,safe_container<safe_iterator>* cont_):
|
||||
super(Iterator(t0)),safe_super(cont_){}
|
||||
template<typename T0,typename T1>
|
||||
safe_iterator(
|
||||
const T0& t0,const T1& t1,safe_container<container_type>* cont_):
|
||||
const T0& t0,const T1& t1,safe_container<safe_iterator>* cont_):
|
||||
super(Iterator(t0,t1)),safe_super(cont_){}
|
||||
safe_iterator(const safe_iterator& x):super(x),safe_super(x){}
|
||||
|
||||
safe_iterator& operator=(const safe_iterator& x)
|
||||
{
|
||||
@@ -439,12 +478,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
const container_type* owner()const
|
||||
const safe_container<safe_iterator>* owner()const
|
||||
{
|
||||
return
|
||||
static_cast<const container_type*>(
|
||||
static_cast<const safe_container<container_type>*>(
|
||||
this->safe_super::owner()));
|
||||
static_cast<const safe_container<safe_iterator>*>(
|
||||
this->safe_super::owner());
|
||||
}
|
||||
|
||||
/* get_node is not to be used by the user */
|
||||
@@ -517,7 +555,11 @@ private:
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,const unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive& ar,const unsigned int version)const
|
||||
@@ -535,21 +577,28 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
class safe_container:public detail::safe_container_base
|
||||
template<typename Iterator>
|
||||
class safe_container:public safe_mode_detail::safe_container_base
|
||||
{
|
||||
typedef detail::safe_container_base super;
|
||||
typedef safe_mode_detail::safe_container_base super;
|
||||
|
||||
detail::any_container_view<Iterator> view;
|
||||
|
||||
public:
|
||||
template<typename Container>
|
||||
safe_container(const Container& c):view(c){}
|
||||
|
||||
const void* container()const{return view.container();}
|
||||
Iterator begin()const{return view.begin();}
|
||||
Iterator end()const{return view.end();}
|
||||
|
||||
void detach_dereferenceable_iterators()
|
||||
{
|
||||
typedef typename Container::iterator iterator;
|
||||
|
||||
iterator end_=static_cast<Container*>(this)->end();
|
||||
iterator *prev_,*next_;
|
||||
Iterator end_=view.end();
|
||||
Iterator *prev_,*next_;
|
||||
for(
|
||||
prev_=static_cast<iterator*>(&this->header);
|
||||
(next_=static_cast<iterator*>(prev_->next))!=0;){
|
||||
prev_=static_cast<Iterator*>(&this->header);
|
||||
(next_=static_cast<Iterator*>(prev_->next))!=0;){
|
||||
if(*next_!=end_){
|
||||
prev_->next=next_->next;
|
||||
next_->cont=0;
|
||||
@@ -558,21 +607,102 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void swap(safe_container<Container>& x)
|
||||
void swap(safe_container<Iterator>& x)
|
||||
{
|
||||
super::swap(x);
|
||||
}
|
||||
};
|
||||
|
||||
/* Invalidates all iterators equivalent to that given. Safe containers
|
||||
* must call this when deleting elements: the safe mode framework cannot
|
||||
* perform this operation automatically without outside help.
|
||||
*/
|
||||
|
||||
template<typename Iterator>
|
||||
inline void detach_equivalent_iterators(Iterator& it)
|
||||
{
|
||||
if(it.valid()){
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex);
|
||||
#endif
|
||||
|
||||
Iterator *prev_,*next_;
|
||||
for(
|
||||
prev_=static_cast<Iterator*>(&it.cont->header);
|
||||
(next_=static_cast<Iterator*>(prev_->next))!=0;){
|
||||
if(next_!=&it&&*next_==it){
|
||||
prev_->next=next_->next;
|
||||
next_->cont=0;
|
||||
}
|
||||
else prev_=next_;
|
||||
}
|
||||
}
|
||||
it.detach();
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfers iterators equivalent to that given to Dst, if that container has
|
||||
* the same iterator type; otherwise, detaches them.
|
||||
*/
|
||||
|
||||
template<typename Dst,typename Iterator>
|
||||
inline void transfer_equivalent_iterators(Dst& dst,Iterator& i)
|
||||
{
|
||||
safe_mode_detail::transfer_equivalent_iterators(
|
||||
dst,i,boost::is_same<Iterator,typename Dst::iterator>());
|
||||
}
|
||||
|
||||
namespace safe_mode_detail{
|
||||
|
||||
template<typename Dst,typename Iterator>
|
||||
inline void transfer_equivalent_iterators(
|
||||
Dst& dst,Iterator it,boost::true_type /* same iterator type */)
|
||||
{
|
||||
if(it.valid()){
|
||||
{
|
||||
safe_container_base* cont_=dst.end().cont;
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
detail::scoped_bilock<boost::detail::lightweight_mutex>
|
||||
scoped_bilock(it.cont->mutex,cont_->mutex);
|
||||
#endif
|
||||
|
||||
Iterator *prev_,*next_;
|
||||
for(
|
||||
prev_=static_cast<Iterator*>(&it.cont->header);
|
||||
(next_=static_cast<Iterator*>(prev_->next))!=0;){
|
||||
if(next_!=&it&&*next_==it){
|
||||
prev_->next=next_->next;
|
||||
next_->cont=cont_;
|
||||
next_->next=cont_->header.next;
|
||||
cont_->header.next=next_;
|
||||
}
|
||||
else prev_=next_;
|
||||
}
|
||||
}
|
||||
/* nothing to do with it, was passed by value and will die now */
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Dst,typename Iterator>
|
||||
inline void transfer_equivalent_iterators(
|
||||
Dst&,Iterator& it,boost::false_type /* same iterator type */)
|
||||
{
|
||||
detach_equivalent_iterators(it);
|
||||
}
|
||||
|
||||
} /* namespace multi_index::safe_mode::safe_mode_detail */
|
||||
|
||||
} /* namespace multi_index::safe_mode */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
namespace serialization{
|
||||
template<typename Iterator,typename Container>
|
||||
template<typename Iterator>
|
||||
struct version<
|
||||
boost::multi_index::safe_mode::safe_iterator<Iterator,Container>
|
||||
boost::multi_index::safe_mode::safe_iterator<Iterator>
|
||||
>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -13,7 +13,7 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
70
linx64/include/boost/multi_index/detail/scoped_bilock.hpp
Normal file
70
linx64/include/boost/multi_index/detail/scoped_bilock.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_MULTI_INDEX_DETAIL_SCOPED_BILOCK_HPP
|
||||
#define BOOST_MULTI_INDEX_DETAIL_SCOPED_BILOCK_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <functional>
|
||||
#include <new>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace multi_index{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* Locks/unlocks two RAII-lockable mutexes taking care that locking is done in
|
||||
* a deadlock-avoiding global order and no double locking happens when the two
|
||||
* mutexes are the same.
|
||||
*/
|
||||
|
||||
template<typename Mutex>
|
||||
class scoped_bilock:private noncopyable
|
||||
{
|
||||
public:
|
||||
scoped_bilock(Mutex& mutex1,Mutex& mutex2):mutex_eq(&mutex1==&mutex2)
|
||||
{
|
||||
bool mutex_lt=std::less<Mutex*>()(&mutex1,&mutex2);
|
||||
|
||||
::new (static_cast<void*>(&lock1)) scoped_lock(mutex_lt?mutex1:mutex2);
|
||||
if(!mutex_eq)
|
||||
::new (static_cast<void*>(&lock2)) scoped_lock(mutex_lt?mutex2:mutex1);
|
||||
}
|
||||
|
||||
~scoped_bilock()
|
||||
{
|
||||
reinterpret_cast<scoped_lock*>(&lock1)->~scoped_lock();
|
||||
if(!mutex_eq)
|
||||
reinterpret_cast<scoped_lock*>(&lock2)->~scoped_lock();
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename Mutex::scoped_lock scoped_lock;
|
||||
typedef typename aligned_storage<
|
||||
sizeof(scoped_lock),
|
||||
alignment_of<scoped_lock>::value
|
||||
>::type scoped_lock_space;
|
||||
|
||||
bool mutex_eq;
|
||||
scoped_lock_space lock1,lock2;
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
} /* namespace multi_index */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2016 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,7 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/multi_index/detail/seq_index_node.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,8 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -42,7 +41,11 @@ struct serialization_version
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar,const unsigned int version)
|
||||
{
|
||||
core::split_member(ar,*this,version);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive&,const unsigned int)const{}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* See http://www.boost.org/libs/multi_index for library home page.
|
||||
*/
|
||||
|
||||
#define BOOST_MULTI_INDEX_DETAIL_UNDEF_IF_CONSTEXPR_MACRO
|
||||
#include <boost/multi_index/detail/define_if_constexpr_macro.hpp>
|
||||
#undef BOOST_MULTI_INDEX_DETAIL_UNDEF_IF_CONSTEXPR_MACRO
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,13 +14,13 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,22 +17,25 @@
|
||||
#include <algorithm>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/foreach_fwd.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/multi_index/detail/access_specifier.hpp>
|
||||
#include <boost/multi_index/detail/adl_swap.hpp>
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/multi_index/detail/auto_space.hpp>
|
||||
#include <boost/multi_index/detail/bucket_array.hpp>
|
||||
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
|
||||
#include <boost/multi_index/detail/hash_index_iterator.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/invalidate_iterators.hpp>
|
||||
#include <boost/multi_index/detail/modify_key_adaptor.hpp>
|
||||
#include <boost/multi_index/detail/node_handle.hpp>
|
||||
#include <boost/multi_index/detail/promotes_arg.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
#include <boost/multi_index/detail/scope_guard.hpp>
|
||||
@@ -51,7 +54,7 @@
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
||||
@@ -79,18 +82,17 @@ namespace detail{
|
||||
* Category tags defined in hash_index_node.hpp.
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4355) /* this used in base member initializer list */
|
||||
#endif
|
||||
|
||||
template<
|
||||
typename KeyFromValue,typename Hash,typename Pred,
|
||||
typename SuperMeta,typename TagList,typename Category
|
||||
>
|
||||
class hashed_index:
|
||||
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,public safe_mode::safe_container<
|
||||
hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category> >
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
@@ -102,15 +104,22 @@ class hashed_index:
|
||||
#pragma parse_mfunc_templ off
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
/* cross-index access */
|
||||
|
||||
template <typename,typename,typename> friend class index_base;
|
||||
#endif
|
||||
|
||||
typedef typename SuperMeta::type super;
|
||||
|
||||
protected:
|
||||
typedef hashed_index_node<
|
||||
typename super::node_type,Category> node_type;
|
||||
typename super::index_node_type> index_node_type;
|
||||
|
||||
private:
|
||||
typedef typename node_type::node_alg node_alg;
|
||||
typedef typename node_type::impl_type node_impl_type;
|
||||
typedef typename index_node_type::
|
||||
template node_alg<Category>::type node_alg;
|
||||
typedef typename index_node_type::impl_type node_impl_type;
|
||||
typedef typename node_impl_type::pointer node_impl_pointer;
|
||||
typedef typename node_impl_type::base_pointer node_impl_base_pointer;
|
||||
typedef bucket_array<
|
||||
@@ -120,7 +129,7 @@ public:
|
||||
/* types */
|
||||
|
||||
typedef typename KeyFromValue::result_type key_type;
|
||||
typedef typename node_type::value_type value_type;
|
||||
typedef typename index_node_type::value_type value_type;
|
||||
typedef KeyFromValue key_from_value;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
@@ -142,22 +151,25 @@ public:
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
typedef safe_mode::safe_iterator<
|
||||
hashed_index_iterator<
|
||||
node_type,bucket_array_type,
|
||||
hashed_index_global_iterator_tag>,
|
||||
hashed_index> iterator;
|
||||
index_node_type,bucket_array_type,
|
||||
Category,
|
||||
hashed_index_global_iterator_tag> > iterator;
|
||||
#else
|
||||
typedef hashed_index_iterator<
|
||||
node_type,bucket_array_type,
|
||||
hashed_index_global_iterator_tag> iterator;
|
||||
index_node_type,bucket_array_type,
|
||||
Category,hashed_index_global_iterator_tag> iterator;
|
||||
#endif
|
||||
|
||||
typedef iterator const_iterator;
|
||||
|
||||
typedef hashed_index_iterator<
|
||||
node_type,bucket_array_type,
|
||||
hashed_index_local_iterator_tag> local_iterator;
|
||||
index_node_type,bucket_array_type,
|
||||
Category,hashed_index_local_iterator_tag> local_iterator;
|
||||
typedef local_iterator const_local_iterator;
|
||||
|
||||
typedef typename super::final_node_handle_type node_type;
|
||||
typedef detail::insert_return_type<
|
||||
iterator,node_type> insert_return_type;
|
||||
typedef TagList tag_list;
|
||||
|
||||
protected:
|
||||
@@ -183,19 +195,16 @@ protected:
|
||||
|
||||
private:
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
typedef safe_mode::safe_container<
|
||||
hashed_index> safe_super;
|
||||
typedef safe_mode::safe_container<iterator> safe_container;
|
||||
#endif
|
||||
|
||||
typedef typename call_traits<value_type>::param_type value_param_type;
|
||||
typedef typename call_traits<
|
||||
key_type>::param_type key_param_type;
|
||||
|
||||
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
|
||||
* expansion.
|
||||
*/
|
||||
/* needed to avoid commas in some macros */
|
||||
|
||||
typedef std::pair<iterator,bool> emplace_return_type;
|
||||
typedef std::pair<iterator,bool> pair_return_type;
|
||||
|
||||
public:
|
||||
|
||||
@@ -234,9 +243,17 @@ public:
|
||||
/* iterators */
|
||||
|
||||
iterator begin()BOOST_NOEXCEPT
|
||||
{return make_iterator(node_type::from_impl(header()->next()->prior()));}
|
||||
{
|
||||
return make_iterator(
|
||||
index_node_type::from_impl(header()->next()->prior()));
|
||||
|
||||
}
|
||||
const_iterator begin()const BOOST_NOEXCEPT
|
||||
{return make_iterator(node_type::from_impl(header()->next()->prior()));}
|
||||
{
|
||||
return make_iterator(
|
||||
index_node_type::from_impl(header()->next()->prior()));
|
||||
}
|
||||
|
||||
iterator end()BOOST_NOEXCEPT{return make_iterator(header());}
|
||||
const_iterator end()const BOOST_NOEXCEPT{return make_iterator(header());}
|
||||
const_iterator cbegin()const BOOST_NOEXCEPT{return begin();}
|
||||
@@ -244,18 +261,20 @@ public:
|
||||
|
||||
iterator iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(boost::addressof(x)));
|
||||
return make_iterator(
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(boost::addressof(x)));
|
||||
return make_iterator(
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
/* modifiers */
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||
emplace_return_type,emplace,emplace_impl)
|
||||
pair_return_type,emplace,emplace_impl)
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
||||
iterator,emplace_hint,emplace_hint_impl,iterator,position)
|
||||
@@ -308,6 +327,42 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
insert_return_type insert(BOOST_RV_REF(node_type) nh)
|
||||
{
|
||||
if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
|
||||
return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
|
||||
}
|
||||
|
||||
iterator insert(const_iterator position,BOOST_RV_REF(node_type) nh)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
std::pair<final_node_type*,bool> p=this->final_insert_nh_(
|
||||
nh,static_cast<final_node_type*>(position.get_node()));
|
||||
return make_iterator(p.first);
|
||||
}
|
||||
|
||||
node_type extract(const_iterator position)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
return this->final_extract_(
|
||||
static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
node_type extract(key_param_type x)
|
||||
{
|
||||
iterator position=find(x);
|
||||
if(position==end())return node_type();
|
||||
else return extract(position);
|
||||
}
|
||||
|
||||
iterator erase(iterator position)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
@@ -325,13 +380,13 @@ public:
|
||||
std::size_t buc=buckets.position(hash_(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq_(k,key(node_type::from_impl(x)->value()))){
|
||||
if(eq_(k,key(index_node_type::from_impl(x)->value()))){
|
||||
node_impl_pointer y=end_of_range(x);
|
||||
size_type s=0;
|
||||
do{
|
||||
node_impl_pointer z=node_alg::after(x);
|
||||
this->final_erase_(
|
||||
static_cast<final_node_type*>(node_type::from_impl(x)));
|
||||
static_cast<final_node_type*>(index_node_type::from_impl(x)));
|
||||
x=z;
|
||||
++s;
|
||||
}while(x!=y);
|
||||
@@ -454,6 +509,73 @@ public:
|
||||
this->final_swap_(x.final());
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
||||
merge(Index& x)
|
||||
{
|
||||
merge(x,x.begin(),x.end());
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
||||
merge(BOOST_RV_REF(Index) x){merge(static_cast<Index&>(x));}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,pair_return_type)
|
||||
merge(Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
|
||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
if(x.end().get_node()==this->header()){ /* same container */
|
||||
return std::pair<iterator,bool>(
|
||||
make_iterator(static_cast<final_node_type*>(i.get_node())),true);
|
||||
}
|
||||
else{
|
||||
std::pair<final_node_type*,bool> p=this->final_transfer_(
|
||||
x,static_cast<final_node_type*>(i.get_node()));
|
||||
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,pair_return_type)
|
||||
merge(BOOST_RV_REF(Index) x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||
{
|
||||
return merge(static_cast<Index&>(x),i);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
||||
merge(
|
||||
Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
||||
if(x.end().get_node()!=this->header()){ /* different containers */
|
||||
this->final_transfer_range_(x,first,last);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
||||
merge(
|
||||
BOOST_RV_REF(Index) x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{
|
||||
merge(static_cast<Index&>(x),first,last);
|
||||
}
|
||||
|
||||
/* observers */
|
||||
|
||||
key_from_value key_extractor()const{return key;}
|
||||
@@ -505,6 +627,22 @@ public:
|
||||
k,hash,eq,promotes_1st_arg<CompatiblePred,CompatibleKey,key_type>());
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
bool contains(const CompatibleKey& k)const
|
||||
{
|
||||
return contains(k,hash_,eq_);
|
||||
}
|
||||
|
||||
template<
|
||||
typename CompatibleKey,typename CompatibleHash,typename CompatiblePred
|
||||
>
|
||||
bool contains(
|
||||
const CompatibleKey& k,
|
||||
const CompatibleHash& hash,const CompatiblePred& eq)const
|
||||
{
|
||||
return find(k,hash,eq)!=end();
|
||||
}
|
||||
|
||||
template<typename CompatibleKey>
|
||||
std::pair<iterator,iterator> equal_range(const CompatibleKey& k)const
|
||||
{
|
||||
@@ -555,7 +693,7 @@ public:
|
||||
{
|
||||
node_impl_pointer x=buckets.at(n)->prior();
|
||||
if(x==node_impl_pointer(0))return end(n);
|
||||
return make_local_iterator(node_type::from_impl(x));
|
||||
return make_local_iterator(index_node_type::from_impl(x));
|
||||
}
|
||||
|
||||
local_iterator end(size_type n)
|
||||
@@ -574,13 +712,13 @@ public:
|
||||
local_iterator local_iterator_to(const value_type& x)
|
||||
{
|
||||
return make_local_iterator(
|
||||
node_from_value<node_type>(boost::addressof(x)));
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
const_local_iterator local_iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_local_iterator(
|
||||
node_from_value<node_type>(boost::addressof(x)));
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
/* hash policy */
|
||||
@@ -617,6 +755,11 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
eq_(tuples::get<3>(args_list.get_head())),
|
||||
buckets(al,header()->impl(),tuples::get<0>(args_list.get_head())),
|
||||
mlf(1.0f)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
calculate_max_load();
|
||||
}
|
||||
@@ -624,17 +767,17 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
hashed_index(
|
||||
const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x):
|
||||
super(x),
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
#endif
|
||||
|
||||
key(x.key),
|
||||
hash_(x.hash_),
|
||||
eq_(x.eq_),
|
||||
buckets(x.get_allocator(),header()->impl(),x.buckets.size()),
|
||||
mlf(x.mlf),
|
||||
max_load(x.max_load)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
/* Copy ctor just takes the internal configuration objects from x. The rest
|
||||
* is done in subsequent call to copy_().
|
||||
@@ -645,16 +788,16 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x,
|
||||
do_not_copy_elements_tag):
|
||||
super(x,do_not_copy_elements_tag()),
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
#endif
|
||||
|
||||
key(x.key),
|
||||
hash_(x.hash_),
|
||||
eq_(x.eq_),
|
||||
buckets(x.get_allocator(),header()->impl(),0),
|
||||
mlf(1.0f)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
calculate_max_load();
|
||||
}
|
||||
@@ -665,33 +808,33 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
iterator make_iterator(node_type* node)
|
||||
iterator make_iterator(index_node_type* node)
|
||||
{
|
||||
return iterator(node,this);
|
||||
return iterator(node,&safe);
|
||||
}
|
||||
|
||||
const_iterator make_iterator(node_type* node)const
|
||||
const_iterator make_iterator(index_node_type* node)const
|
||||
{
|
||||
return const_iterator(node,const_cast<hashed_index*>(this));
|
||||
return const_iterator(node,const_cast<safe_container*>(&safe));
|
||||
}
|
||||
#else
|
||||
iterator make_iterator(node_type* node)
|
||||
iterator make_iterator(index_node_type* node)
|
||||
{
|
||||
return iterator(node);
|
||||
}
|
||||
|
||||
const_iterator make_iterator(node_type* node)const
|
||||
const_iterator make_iterator(index_node_type* node)const
|
||||
{
|
||||
return const_iterator(node);
|
||||
}
|
||||
#endif
|
||||
|
||||
local_iterator make_local_iterator(node_type* node)
|
||||
local_iterator make_local_iterator(index_node_type* node)
|
||||
{
|
||||
return local_iterator(node);
|
||||
}
|
||||
|
||||
const_local_iterator make_local_iterator(node_type* node)const
|
||||
const_local_iterator make_local_iterator(index_node_type* node)const
|
||||
{
|
||||
return const_local_iterator(node);
|
||||
}
|
||||
@@ -714,8 +857,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
do{
|
||||
node_impl_pointer prev_org=org->prior(),
|
||||
prev_cpy=
|
||||
static_cast<node_type*>(map.find(static_cast<final_node_type*>(
|
||||
node_type::from_impl(prev_org))))->impl();
|
||||
static_cast<index_node_type*>(map.find(static_cast<final_node_type*>(
|
||||
index_node_type::from_impl(prev_org))))->impl();
|
||||
cpy->prior()=prev_cpy;
|
||||
if(node_alg::is_first_of_bucket(org)){
|
||||
node_impl_base_pointer buc_org=prev_org->next(),
|
||||
@@ -746,8 +889,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
do{
|
||||
node_impl_pointer next_org=node_alg::after(org),
|
||||
next_cpy=
|
||||
static_cast<node_type*>(map.find(static_cast<final_node_type*>(
|
||||
node_type::from_impl(next_org))))->impl();
|
||||
static_cast<index_node_type*>(map.find(static_cast<final_node_type*>(
|
||||
index_node_type::from_impl(next_org))))->impl();
|
||||
if(node_alg::is_first_of_bucket(next_org)){
|
||||
node_impl_base_pointer buc_org=org->next(),
|
||||
buc_cpy=
|
||||
@@ -763,15 +906,17 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
else{
|
||||
cpy->next()=
|
||||
node_impl_type::base_pointer_from(
|
||||
static_cast<node_type*>(map.find(static_cast<final_node_type*>(
|
||||
node_type::from_impl(
|
||||
node_impl_type::pointer_from(org->next())))))->impl());
|
||||
static_cast<index_node_type*>(
|
||||
map.find(static_cast<final_node_type*>(
|
||||
index_node_type::from_impl(
|
||||
node_impl_type::pointer_from(org->next())))))->impl());
|
||||
}
|
||||
|
||||
if(next_org->prior()!=org){
|
||||
next_cpy->prior()=
|
||||
static_cast<node_type*>(map.find(static_cast<final_node_type*>(
|
||||
node_type::from_impl(next_org->prior()))))->impl();
|
||||
static_cast<index_node_type*>(
|
||||
map.find(static_cast<final_node_type*>(
|
||||
index_node_type::from_impl(next_org->prior()))))->impl();
|
||||
}
|
||||
else{
|
||||
next_cpy->prior()=cpy;
|
||||
@@ -795,17 +940,18 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
link_info pos(buckets.at(buc));
|
||||
if(!link_point(v,pos)){
|
||||
return static_cast<final_node_type*>(
|
||||
node_type::from_impl(node_impl_type::pointer_from(pos)));
|
||||
index_node_type::from_impl(node_impl_type::pointer_from(pos)));
|
||||
}
|
||||
|
||||
final_node_type* res=super::insert_(v,x,variant);
|
||||
if(res==x)link(static_cast<node_type*>(x),pos);
|
||||
if(res==x)link(static_cast<index_node_type*>(x),pos);
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Variant>
|
||||
final_node_type* insert_(
|
||||
value_param_type v,node_type* position,final_node_type*& x,Variant variant)
|
||||
value_param_type v,index_node_type* position,
|
||||
final_node_type*& x,Variant variant)
|
||||
{
|
||||
reserve_for_insert(size()+1);
|
||||
|
||||
@@ -813,21 +959,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
link_info pos(buckets.at(buc));
|
||||
if(!link_point(v,pos)){
|
||||
return static_cast<final_node_type*>(
|
||||
node_type::from_impl(node_impl_type::pointer_from(pos)));
|
||||
index_node_type::from_impl(node_impl_type::pointer_from(pos)));
|
||||
}
|
||||
|
||||
final_node_type* res=super::insert_(v,position,x,variant);
|
||||
if(res==x)link(static_cast<node_type*>(x),pos);
|
||||
if(res==x)link(static_cast<index_node_type*>(x),pos);
|
||||
return res;
|
||||
}
|
||||
|
||||
void erase_(node_type* x)
|
||||
template<typename Dst>
|
||||
void extract_(index_node_type* x,Dst dst)
|
||||
{
|
||||
unlink(x);
|
||||
super::erase_(x);
|
||||
super::extract_(x,dst.next());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
transfer_iterators(dst.get(),x);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -841,7 +988,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){
|
||||
node_impl_pointer y=x->prior();
|
||||
this->final_delete_node_(
|
||||
static_cast<final_node_type*>(node_type::from_impl(x)));
|
||||
static_cast<final_node_type*>(index_node_type::from_impl(x)));
|
||||
x=y;
|
||||
}
|
||||
}
|
||||
@@ -860,7 +1007,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
first->next()->prior()=first;
|
||||
}
|
||||
this->final_delete_node_(
|
||||
static_cast<final_node_type*>(node_type::from_impl(x)));
|
||||
static_cast<final_node_type*>(index_node_type::from_impl(x)));
|
||||
x=y;
|
||||
}
|
||||
}
|
||||
@@ -871,25 +1018,27 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
buckets.clear(header()->impl());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::detach_dereferenceable_iterators();
|
||||
safe.detach_dereferenceable_iterators();
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename BoolConstant>
|
||||
void swap_(
|
||||
hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x)
|
||||
hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x,
|
||||
BoolConstant swap_allocators)
|
||||
{
|
||||
std::swap(key,x.key);
|
||||
std::swap(hash_,x.hash_);
|
||||
std::swap(eq_,x.eq_);
|
||||
buckets.swap(x.buckets);
|
||||
adl_swap(key,x.key);
|
||||
adl_swap(hash_,x.hash_);
|
||||
adl_swap(eq_,x.eq_);
|
||||
buckets.swap(x.buckets,swap_allocators);
|
||||
std::swap(mlf,x.mlf);
|
||||
std::swap(max_load,x.max_load);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::swap(x);
|
||||
safe.swap(x.safe);
|
||||
#endif
|
||||
|
||||
super::swap_(x);
|
||||
super::swap_(x,swap_allocators);
|
||||
}
|
||||
|
||||
void swap_elements_(
|
||||
@@ -900,14 +1049,14 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
std::swap(max_load,x.max_load);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::swap(x);
|
||||
safe.swap(x.safe);
|
||||
#endif
|
||||
|
||||
super::swap_elements_(x);
|
||||
}
|
||||
|
||||
template<typename Variant>
|
||||
bool replace_(value_param_type v,node_type* x,Variant variant)
|
||||
bool replace_(value_param_type v,index_node_type* x,Variant variant)
|
||||
{
|
||||
if(eq_(key(v),key(x->value()))){
|
||||
return super::replace_(v,x,variant);
|
||||
@@ -933,7 +1082,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_(node_type* x)
|
||||
bool modify_(index_node_type* x)
|
||||
{
|
||||
std::size_t buc;
|
||||
bool b;
|
||||
@@ -942,7 +1091,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
b=in_place(x->impl(),key(x->value()),buc);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
erase_(x);
|
||||
extract_(x,invalidate_iterators());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
@@ -951,7 +1100,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_TRY{
|
||||
link_info pos(buckets.at(buc));
|
||||
if(!link_point(x->value(),pos)){
|
||||
super::erase_(x);
|
||||
super::extract_(x,invalidate_iterators());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
@@ -961,7 +1110,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
link(x,pos);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
super::erase_(x);
|
||||
super::extract_(x,invalidate_iterators());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
@@ -995,7 +1144,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_rollback_(node_type* x)
|
||||
bool modify_rollback_(index_node_type* x)
|
||||
{
|
||||
std::size_t buc=find_bucket(x->value());
|
||||
if(in_place(x->impl(),key(x->value()),buc)){
|
||||
@@ -1021,7 +1170,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool check_rollback_(node_type* x)const
|
||||
bool check_rollback_(index_node_type* x)const
|
||||
{
|
||||
std::size_t buc=find_bucket(x->value());
|
||||
return in_place(x->impl(),key(x->value()),buc)&&super::check_rollback_(x);
|
||||
@@ -1059,7 +1208,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
if(it2==it2_last)return false;
|
||||
|
||||
const_iterator it_last=make_iterator(
|
||||
node_type::from_impl(end_of_range(it.get_node()->impl())));
|
||||
index_node_type::from_impl(end_of_range(it.get_node()->impl())));
|
||||
if(std::distance(it,it_last)!=std::distance(it2,it2_last))return false;
|
||||
|
||||
/* From is_permutation code in
|
||||
@@ -1088,14 +1237,14 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
void save_(
|
||||
Archive& ar,const unsigned int version,const index_saver_type& sm)const
|
||||
{
|
||||
ar<<serialization::make_nvp("position",buckets);
|
||||
ar<<core::make_nvp("position",buckets);
|
||||
super::save_(ar,version,sm);
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
|
||||
{
|
||||
ar>>serialization::make_nvp("position",buckets);
|
||||
ar>>core::make_nvp("position",buckets);
|
||||
super::load_(ar,version,lm);
|
||||
}
|
||||
#endif
|
||||
@@ -1137,7 +1286,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
#endif
|
||||
|
||||
private:
|
||||
node_type* header()const{return this->final_header();}
|
||||
index_node_type* header()const{return this->final_header();}
|
||||
|
||||
std::size_t find_bucket(value_param_type v)const
|
||||
{
|
||||
@@ -1170,7 +1319,7 @@ private:
|
||||
{
|
||||
for(node_impl_pointer x=pos->prior();x!=node_impl_pointer(0);
|
||||
x=node_alg::after_local(x)){
|
||||
if(eq_(key(v),key(node_type::from_impl(x)->value()))){
|
||||
if(eq_(key(v),key(index_node_type::from_impl(x)->value()))){
|
||||
pos=node_impl_type::base_pointer_from(x);
|
||||
return false;
|
||||
}
|
||||
@@ -1183,7 +1332,7 @@ private:
|
||||
{
|
||||
for(node_impl_pointer x=pos.first->prior();x!=node_impl_pointer(0);
|
||||
x=node_alg::next_to_inspect(x)){
|
||||
if(eq_(key(v),key(node_type::from_impl(x)->value()))){
|
||||
if(eq_(key(v),key(index_node_type::from_impl(x)->value()))){
|
||||
pos.first=node_impl_type::base_pointer_from(x);
|
||||
pos.last=node_impl_type::base_pointer_from(last_of_range(x));
|
||||
return true;
|
||||
@@ -1211,8 +1360,8 @@ private:
|
||||
node_impl_pointer yy=node_impl_type::pointer_from(y);
|
||||
return
|
||||
eq_(
|
||||
key(node_type::from_impl(x)->value()),
|
||||
key(node_type::from_impl(yy)->value()))?yy:x;
|
||||
key(index_node_type::from_impl(x)->value()),
|
||||
key(index_node_type::from_impl(yy)->value()))?yy:x;
|
||||
}
|
||||
else if(z->prior()==x) /* last of bucket */
|
||||
return x;
|
||||
@@ -1238,8 +1387,8 @@ private:
|
||||
if(z==x){ /* range of size 1 or 2 */
|
||||
node_impl_pointer yy=node_impl_type::pointer_from(y);
|
||||
if(!eq_(
|
||||
key(node_type::from_impl(x)->value()),
|
||||
key(node_type::from_impl(yy)->value())))yy=x;
|
||||
key(index_node_type::from_impl(x)->value()),
|
||||
key(index_node_type::from_impl(yy)->value())))yy=x;
|
||||
return yy->next()->prior()==yy?
|
||||
node_impl_type::pointer_from(yy->next()):
|
||||
yy->next()->prior();
|
||||
@@ -1252,17 +1401,18 @@ private:
|
||||
z->next()->prior();
|
||||
}
|
||||
|
||||
void link(node_type* x,const link_info& pos)
|
||||
void link(index_node_type* x,const link_info& pos)
|
||||
{
|
||||
link(x,pos,Category());
|
||||
}
|
||||
|
||||
void link(node_type* x,node_impl_base_pointer pos,hashed_unique_tag)
|
||||
void link(index_node_type* x,node_impl_base_pointer pos,hashed_unique_tag)
|
||||
{
|
||||
node_alg::link(x->impl(),pos,header()->impl());
|
||||
}
|
||||
|
||||
void link(node_type* x,const link_info_non_unique& pos,hashed_non_unique_tag)
|
||||
void link(
|
||||
index_node_type* x,const link_info_non_unique& pos,hashed_non_unique_tag)
|
||||
{
|
||||
if(pos.last==node_impl_base_pointer(0)){
|
||||
node_alg::link(x->impl(),pos.first,header()->impl());
|
||||
@@ -1275,14 +1425,14 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void unlink(node_type* x)
|
||||
void unlink(index_node_type* x)
|
||||
{
|
||||
node_alg::unlink(x->impl());
|
||||
}
|
||||
|
||||
typedef typename node_alg::unlink_undo unlink_undo;
|
||||
|
||||
void unlink(node_type* x,unlink_undo& undo)
|
||||
void unlink(index_node_type* x,unlink_undo& undo)
|
||||
{
|
||||
node_alg::unlink(x->impl(),undo);
|
||||
}
|
||||
@@ -1325,7 +1475,7 @@ private:
|
||||
node_impl_pointer x=end_->prior();
|
||||
|
||||
/* only this can possibly throw */
|
||||
std::size_t h=hash_(key(node_type::from_impl(x)->value()));
|
||||
std::size_t h=hash_(key(index_node_type::from_impl(x)->value()));
|
||||
|
||||
hashes.data()[i]=h;
|
||||
node_ptrs.data()[i]=x;
|
||||
@@ -1378,7 +1528,7 @@ private:
|
||||
if(x==end_)break;
|
||||
|
||||
/* only this can possibly throw */
|
||||
std::size_t h=hash_(key(node_type::from_impl(x)->value()));
|
||||
std::size_t h=hash_(key(index_node_type::from_impl(x)->value()));
|
||||
|
||||
hashes.data()[i]=h;
|
||||
node_ptrs.data()[i]=x;
|
||||
@@ -1432,7 +1582,7 @@ private:
|
||||
for(node_impl_pointer y=buckets.at(buc)->prior();
|
||||
y!=node_impl_pointer(0);y=node_alg::after_local(y)){
|
||||
if(y==x)found=true;
|
||||
else if(eq_(k,key(node_type::from_impl(y)->value())))return false;
|
||||
else if(eq_(k,key(index_node_type::from_impl(y)->value())))return false;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
@@ -1449,13 +1599,13 @@ private:
|
||||
/* in place <-> equal to some other member of the group */
|
||||
return eq_(
|
||||
k,
|
||||
key(node_type::from_impl(
|
||||
key(index_node_type::from_impl(
|
||||
node_impl_type::pointer_from(y->next()))->value()));
|
||||
}
|
||||
else{
|
||||
node_impl_pointer z=
|
||||
node_alg::after_local(y->next()->prior()); /* end of range */
|
||||
if(eq_(k,key(node_type::from_impl(y)->value()))){
|
||||
if(eq_(k,key(index_node_type::from_impl(y)->value()))){
|
||||
if(found)return false; /* x lies outside */
|
||||
do{
|
||||
if(y==x)return true;
|
||||
@@ -1477,7 +1627,7 @@ private:
|
||||
range_size=1;
|
||||
found=true;
|
||||
}
|
||||
else if(eq_(k,key(node_type::from_impl(y)->value()))){
|
||||
else if(eq_(k,key(index_node_type::from_impl(y)->value()))){
|
||||
if(range_size==0&&found)return false;
|
||||
if(range_size==1&&!found)return false;
|
||||
if(range_size==2)return false;
|
||||
@@ -1495,11 +1645,18 @@ private:
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
void detach_iterators(node_type* x)
|
||||
void detach_iterators(index_node_type* x)
|
||||
{
|
||||
iterator it=make_iterator(x);
|
||||
safe_mode::detach_equivalent_iterators(it);
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
void transfer_iterators(Dst& dst,index_node_type* x)
|
||||
{
|
||||
iterator it=make_iterator(x);
|
||||
safe_mode::transfer_equivalent_iterators(dst,it);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
||||
@@ -1545,8 +1702,8 @@ private:
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
return make_iterator(node_type::from_impl(x));
|
||||
if(eq(k,key(index_node_type::from_impl(x)->value()))){
|
||||
return make_iterator(index_node_type::from_impl(x));
|
||||
}
|
||||
}
|
||||
return end();
|
||||
@@ -1572,7 +1729,7 @@ private:
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
if(eq(k,key(index_node_type::from_impl(x)->value()))){
|
||||
size_type res=0;
|
||||
node_impl_pointer y=end_of_range(x);
|
||||
do{
|
||||
@@ -1605,10 +1762,10 @@ private:
|
||||
std::size_t buc=buckets.position(hash(k));
|
||||
for(node_impl_pointer x=buckets.at(buc)->prior();
|
||||
x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){
|
||||
if(eq(k,key(node_type::from_impl(x)->value()))){
|
||||
if(eq(k,key(index_node_type::from_impl(x)->value()))){
|
||||
return std::pair<iterator,iterator>(
|
||||
make_iterator(node_type::from_impl(x)),
|
||||
make_iterator(node_type::from_impl(end_of_range(x))));
|
||||
make_iterator(index_node_type::from_impl(x)),
|
||||
make_iterator(index_node_type::from_impl(end_of_range(x))));
|
||||
}
|
||||
}
|
||||
return std::pair<iterator,iterator>(end(),end());
|
||||
@@ -1620,13 +1777,21 @@ private:
|
||||
bucket_array_type buckets;
|
||||
float mlf;
|
||||
size_type max_load;
|
||||
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_container safe;
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
#pragma parse_mfunc_templ reset
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4355 */
|
||||
#endif
|
||||
|
||||
/* comparison */
|
||||
|
||||
template<
|
||||
@@ -1681,7 +1846,7 @@ struct hashed_unique
|
||||
template<typename Super>
|
||||
struct node_class
|
||||
{
|
||||
typedef detail::hashed_index_node<Super,detail::hashed_unique_tag> type;
|
||||
typedef detail::hashed_index_node<Super> type;
|
||||
};
|
||||
|
||||
template<typename SuperMeta>
|
||||
@@ -1706,8 +1871,7 @@ struct hashed_non_unique
|
||||
template<typename Super>
|
||||
struct node_class
|
||||
{
|
||||
typedef detail::hashed_index_node<
|
||||
Super,detail::hashed_non_unique_tag> type;
|
||||
typedef detail::hashed_index_node<Super> type;
|
||||
};
|
||||
|
||||
template<typename SuperMeta>
|
||||
@@ -1725,16 +1889,21 @@ struct hashed_non_unique
|
||||
|
||||
/* Boost.Foreach compatibility */
|
||||
|
||||
namespace boost{
|
||||
namespace foreach{
|
||||
|
||||
template<typename>
|
||||
struct is_noncopyable;
|
||||
|
||||
template<
|
||||
typename KeyFromValue,typename Hash,typename Pred,
|
||||
typename SuperMeta,typename TagList,typename Category
|
||||
>
|
||||
inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
||||
boost::multi_index::detail::hashed_index<
|
||||
KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>*&,
|
||||
boost_foreach_argument_dependent_lookup_hack)
|
||||
{
|
||||
return 0;
|
||||
struct is_noncopyable<boost::multi_index::detail::hashed_index<
|
||||
KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>
|
||||
>:boost::mpl::true_{};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,12 +14,12 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/multi_index/identity_fwd.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2019 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#define BOOST_MULTI_INDEX_KEY_SUPPORTED
|
||||
|
||||
#include <boost/multi_index/detail/is_function.hpp>
|
||||
#include <boost/preprocessor/facilities/empty.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
@@ -40,28 +42,33 @@ struct typed_key_impl;
|
||||
template<typename Class,typename Type,Type Class::*PtrToMember>
|
||||
struct typed_key_impl<
|
||||
Type Class::*,PtrToMember,
|
||||
typename std::enable_if<!std::is_function<Type>::value>::type
|
||||
typename std::enable_if<!is_function<Type>::value>::type
|
||||
>
|
||||
{
|
||||
using value_type=Class;
|
||||
using type=member<Class,Type,PtrToMember>;
|
||||
};
|
||||
|
||||
template<
|
||||
typename Class,typename Type,Type (Class::*PtrToMemberFunction)()const
|
||||
>
|
||||
struct typed_key_impl<Type (Class::*)()const,PtrToMemberFunction>
|
||||
{
|
||||
using value_type=Class;
|
||||
using type=const_mem_fun<Class,Type,PtrToMemberFunction>;
|
||||
#define BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(qualifier,extractor) \
|
||||
template< \
|
||||
typename Class,typename Type,Type (Class::*PtrToMemberFunction)()qualifier \
|
||||
> \
|
||||
struct typed_key_impl<Type (Class::*)()qualifier,PtrToMemberFunction> \
|
||||
{ \
|
||||
using value_type=Class; \
|
||||
using type=extractor<Class,Type,PtrToMemberFunction>; \
|
||||
};
|
||||
|
||||
template<typename Class,typename Type,Type (Class::*PtrToMemberFunction)()>
|
||||
struct typed_key_impl<Type (Class::*)(),PtrToMemberFunction>
|
||||
{
|
||||
using value_type=Class;
|
||||
using type=mem_fun<Class,Type,PtrToMemberFunction>;
|
||||
};
|
||||
BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL( ,mem_fun)
|
||||
BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const ,const_mem_fun)
|
||||
BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(volatile ,volatile_mem_fun)
|
||||
BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const volatile ,cv_mem_fun)
|
||||
BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(& ,ref_mem_fun)
|
||||
BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const& ,cref_mem_fun)
|
||||
BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(volatile& ,vref_mem_fun)
|
||||
BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const volatile& ,cvref_mem_fun)
|
||||
|
||||
#undef BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL
|
||||
|
||||
template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
||||
struct typed_key_impl<Type (*)(Value),PtrToFunction>
|
||||
@@ -70,11 +77,48 @@ struct typed_key_impl<Type (*)(Value),PtrToFunction>
|
||||
using type=global_fun<Value,Type,PtrToFunction>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_noexcept{using type=T;};
|
||||
|
||||
#define BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(qualifier) \
|
||||
template<typename R,typename C,typename... Args> \
|
||||
struct remove_noexcept<R(C::*)(Args...)qualifier noexcept> \
|
||||
{using type=R(C::*)(Args...)qualifier;}; \
|
||||
\
|
||||
template<typename R,typename C,typename... Args> \
|
||||
struct remove_noexcept<R(C::*)(Args...,...)qualifier noexcept> \
|
||||
{using type=R(C::*)(Args...,...)qualifier;};
|
||||
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(BOOST_PP_EMPTY())
|
||||
/* VS warns without dummy arg */
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(&)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const&)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile&)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile&)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(&&)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const&&)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile&&)
|
||||
BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile&&)
|
||||
|
||||
#undef BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT
|
||||
|
||||
template<typename R,typename... Args>
|
||||
struct remove_noexcept<R(*)(Args...)noexcept>{using type=R(*)(Args...);};
|
||||
template<typename R,typename... Args>
|
||||
struct remove_noexcept<R(*)(Args...,...)noexcept>
|
||||
{using type=R(*)(Args...,...);};
|
||||
|
||||
template<typename T>
|
||||
using remove_noexcept_t=typename remove_noexcept<T>::type;
|
||||
|
||||
template<auto... Keys>
|
||||
struct key_impl;
|
||||
|
||||
template<auto Key>
|
||||
struct key_impl<Key>:typed_key_impl<decltype(Key),Key>{};
|
||||
struct key_impl<Key>:typed_key_impl<remove_noexcept_t<decltype(Key)>,Key>{};
|
||||
|
||||
template<typename... Ts>
|
||||
struct least_generic;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,9 +14,9 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
@@ -30,17 +30,30 @@ namespace multi_index{
|
||||
|
||||
/* mem_fun implements a read-only key extractor based on a given non-const
|
||||
* member function of a class.
|
||||
* const_mem_fun does the same for const member functions.
|
||||
* Additionally, mem_fun and const_mem_fun are overloaded to support
|
||||
* referece_wrappers of T and "chained pointers" to T's. By chained pointer
|
||||
* to T we mean a type P such that, given a p of Type P
|
||||
* Also, the following variations are provided:
|
||||
* const_mem_fun: const member functions
|
||||
* volatile_mem_fun: volatile member functions
|
||||
* cv_mem_fun: const volatile member functions
|
||||
* ref_mem_fun: ref-qualifed member functions (C++11)
|
||||
* cref_mem_fun: const ref-qualifed member functions (C++11)
|
||||
* vref_mem_fun: volatile ref-qualifed member functions (C++11)
|
||||
* cvref_mem_fun: const volatile ref-qualifed member functions (C++11)
|
||||
*
|
||||
* All of these classes are overloaded to support boost::referece_wrappers
|
||||
* of T and "chained pointers" to T's. By chained pointer to T we mean a type
|
||||
* P such that, given a p of Type P
|
||||
* *...n...*x is convertible to T&, for some n>=1.
|
||||
* Examples of chained pointers are raw and smart pointers, iterators and
|
||||
* arbitrary combinations of these (vg. T** or unique_ptr<T*>.)
|
||||
*/
|
||||
|
||||
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
|
||||
struct const_mem_fun
|
||||
namespace detail{
|
||||
|
||||
template<
|
||||
class Class,typename Type,
|
||||
typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
|
||||
>
|
||||
struct const_mem_fun_impl
|
||||
{
|
||||
typedef typename remove_reference<Type>::type result_type;
|
||||
|
||||
@@ -74,8 +87,11 @@ struct const_mem_fun
|
||||
}
|
||||
};
|
||||
|
||||
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()>
|
||||
struct mem_fun
|
||||
template<
|
||||
class Class,typename Type,
|
||||
typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
|
||||
>
|
||||
struct mem_fun_impl
|
||||
{
|
||||
typedef typename remove_reference<Type>::type result_type;
|
||||
|
||||
@@ -104,6 +120,62 @@ struct mem_fun
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace multi_index::detail */
|
||||
|
||||
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
|
||||
struct const_mem_fun:detail::const_mem_fun_impl<
|
||||
Class,Type,Type (Class::*)()const,PtrToMemberFunction
|
||||
>{};
|
||||
|
||||
template<
|
||||
class Class,typename Type,
|
||||
Type (Class::*PtrToMemberFunction)()const volatile
|
||||
>
|
||||
struct cv_mem_fun:detail::const_mem_fun_impl<
|
||||
Class,Type,Type (Class::*)()const volatile,PtrToMemberFunction
|
||||
>{};
|
||||
|
||||
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()>
|
||||
struct mem_fun:
|
||||
detail::mem_fun_impl<Class,Type,Type (Class::*)(),PtrToMemberFunction>{};
|
||||
|
||||
template<
|
||||
class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile
|
||||
>
|
||||
struct volatile_mem_fun:detail::mem_fun_impl<
|
||||
Class,Type,Type (Class::*)()volatile,PtrToMemberFunction
|
||||
>{};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
|
||||
|
||||
template<
|
||||
class Class,typename Type,Type (Class::*PtrToMemberFunction)()const&
|
||||
>
|
||||
struct cref_mem_fun:detail::const_mem_fun_impl<
|
||||
Class,Type,Type (Class::*)()const&,PtrToMemberFunction
|
||||
>{};
|
||||
|
||||
template<
|
||||
class Class,typename Type,
|
||||
Type (Class::*PtrToMemberFunction)()const volatile&
|
||||
>
|
||||
struct cvref_mem_fun:detail::const_mem_fun_impl<
|
||||
Class,Type,Type (Class::*)()const volatile&,PtrToMemberFunction
|
||||
>{};
|
||||
|
||||
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()&>
|
||||
struct ref_mem_fun:
|
||||
detail::mem_fun_impl<Class,Type,Type (Class::*)()&,PtrToMemberFunction>{};
|
||||
|
||||
template<
|
||||
class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile&
|
||||
>
|
||||
struct vref_mem_fun:detail::mem_fun_impl<
|
||||
Class,Type,Type (Class::*)()volatile&,PtrToMemberFunction
|
||||
>{};
|
||||
|
||||
#endif
|
||||
|
||||
/* MSVC++ 6.0 has problems with const member functions as non-type template
|
||||
* parameters, somehow it takes them as non-const. const_mem_fun_explicit
|
||||
* workarounds this deficiency by accepting an extra type parameter that
|
||||
@@ -119,7 +191,8 @@ struct mem_fun
|
||||
|
||||
template<
|
||||
class Class,typename Type,
|
||||
typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction>
|
||||
typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
|
||||
>
|
||||
struct const_mem_fun_explicit
|
||||
{
|
||||
typedef typename remove_reference<Type>::type result_type;
|
||||
@@ -156,7 +229,8 @@ struct const_mem_fun_explicit
|
||||
|
||||
template<
|
||||
class Class,typename Type,
|
||||
typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction>
|
||||
typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
|
||||
>
|
||||
struct mem_fun_explicit
|
||||
{
|
||||
typedef typename remove_reference<Type>::type result_type;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2015 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,9 +14,9 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -15,12 +15,11 @@
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <algorithm>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/foreach_fwd.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
@@ -31,6 +30,7 @@
|
||||
#include <boost/multi_index/detail/allocator_traits.hpp>
|
||||
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/node_handle.hpp>
|
||||
#include <boost/multi_index/detail/rnd_node_iterator.hpp>
|
||||
#include <boost/multi_index/detail/rnd_index_node.hpp>
|
||||
#include <boost/multi_index/detail/rnd_index_ops.hpp>
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <boost/multi_index/random_access_index_fwd.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
@@ -76,15 +77,14 @@ namespace detail{
|
||||
* to a given Super
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4355) /* this used in base member initializer list */
|
||||
#endif
|
||||
|
||||
template<typename SuperMeta,typename TagList>
|
||||
class random_access_index:
|
||||
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,public safe_mode::safe_container<
|
||||
random_access_index<SuperMeta,TagList> >
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
@@ -96,14 +96,20 @@ class random_access_index:
|
||||
#pragma parse_mfunc_templ off
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
/* cross-index access */
|
||||
|
||||
template <typename,typename,typename> friend class index_base;
|
||||
#endif
|
||||
|
||||
typedef typename SuperMeta::type super;
|
||||
|
||||
protected:
|
||||
typedef random_access_index_node<
|
||||
typename super::node_type> node_type;
|
||||
typename super::index_node_type> index_node_type;
|
||||
|
||||
private:
|
||||
typedef typename node_type::impl_type node_impl_type;
|
||||
typedef typename index_node_type::impl_type node_impl_type;
|
||||
typedef random_access_index_ptr_array<
|
||||
typename super::final_allocator_type> ptr_array;
|
||||
typedef typename ptr_array::pointer node_impl_ptr_pointer;
|
||||
@@ -111,7 +117,7 @@ private:
|
||||
public:
|
||||
/* types */
|
||||
|
||||
typedef typename node_type::value_type value_type;
|
||||
typedef typename index_node_type::value_type value_type;
|
||||
typedef tuples::null_type ctor_args;
|
||||
typedef typename super::final_allocator_type allocator_type;
|
||||
typedef value_type& reference;
|
||||
@@ -119,10 +125,9 @@ public:
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
typedef safe_mode::safe_iterator<
|
||||
rnd_node_iterator<node_type>,
|
||||
random_access_index> iterator;
|
||||
rnd_node_iterator<index_node_type> > iterator;
|
||||
#else
|
||||
typedef rnd_node_iterator<node_type> iterator;
|
||||
typedef rnd_node_iterator<index_node_type> iterator;
|
||||
#endif
|
||||
|
||||
typedef iterator const_iterator;
|
||||
@@ -139,6 +144,9 @@ public:
|
||||
boost::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef typename
|
||||
boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef typename super::final_node_handle_type node_type;
|
||||
typedef detail::insert_return_type<
|
||||
iterator,node_type> insert_return_type;
|
||||
typedef TagList tag_list;
|
||||
|
||||
protected:
|
||||
@@ -164,18 +172,15 @@ protected:
|
||||
|
||||
private:
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
typedef safe_mode::safe_container<
|
||||
random_access_index> safe_super;
|
||||
typedef safe_mode::safe_container<iterator> safe_container;
|
||||
#endif
|
||||
|
||||
typedef typename call_traits<
|
||||
value_type>::param_type value_param_type;
|
||||
|
||||
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
|
||||
* expansion.
|
||||
*/
|
||||
/* needed to avoid commas in some macros */
|
||||
|
||||
typedef std::pair<iterator,bool> emplace_return_type;
|
||||
typedef std::pair<iterator,bool> pair_return_type;
|
||||
|
||||
public:
|
||||
|
||||
@@ -228,9 +233,9 @@ public:
|
||||
/* iterators */
|
||||
|
||||
iterator begin()BOOST_NOEXCEPT
|
||||
{return make_iterator(node_type::from_impl(*ptrs.begin()));}
|
||||
{return make_iterator(index_node_type::from_impl(*ptrs.begin()));}
|
||||
const_iterator begin()const BOOST_NOEXCEPT
|
||||
{return make_iterator(node_type::from_impl(*ptrs.begin()));}
|
||||
{return make_iterator(index_node_type::from_impl(*ptrs.begin()));}
|
||||
iterator
|
||||
end()BOOST_NOEXCEPT{return make_iterator(header());}
|
||||
const_iterator
|
||||
@@ -254,12 +259,14 @@ public:
|
||||
|
||||
iterator iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(boost::addressof(x)));
|
||||
return make_iterator(
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(boost::addressof(x)));
|
||||
return make_iterator(
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
/* capacity */
|
||||
@@ -304,13 +311,13 @@ public:
|
||||
const_reference operator[](size_type n)const
|
||||
{
|
||||
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(n<size(),safe_mode::out_of_bounds);
|
||||
return node_type::from_impl(*ptrs.at(n))->value();
|
||||
return index_node_type::from_impl(*ptrs.at(n))->value();
|
||||
}
|
||||
|
||||
const_reference at(size_type n)const
|
||||
{
|
||||
if(n>=size())throw_exception(std::out_of_range("random access index"));
|
||||
return node_type::from_impl(*ptrs.at(n))->value();
|
||||
return index_node_type::from_impl(*ptrs.at(n))->value();
|
||||
}
|
||||
|
||||
const_reference front()const{return operator[](0);}
|
||||
@@ -319,7 +326,7 @@ public:
|
||||
/* modifiers */
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||
emplace_return_type,emplace_front,emplace_front_impl)
|
||||
pair_return_type,emplace_front,emplace_front_impl)
|
||||
|
||||
std::pair<iterator,bool> push_front(const value_type& x)
|
||||
{return insert(begin(),x);}
|
||||
@@ -328,7 +335,7 @@ public:
|
||||
void pop_front(){erase(begin());}
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||
emplace_return_type,emplace_back,emplace_back_impl)
|
||||
pair_return_type,emplace_back,emplace_back_impl)
|
||||
|
||||
std::pair<iterator,bool> push_back(const value_type& x)
|
||||
{return insert(end(),x);}
|
||||
@@ -337,7 +344,7 @@ public:
|
||||
void pop_back(){erase(--end());}
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
||||
emplace_return_type,emplace,emplace_impl,iterator,position)
|
||||
pair_return_type,emplace,emplace_impl,iterator,position)
|
||||
|
||||
std::pair<iterator,bool> insert(iterator position,const value_type& x)
|
||||
{
|
||||
@@ -395,6 +402,29 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
insert_return_type insert(const_iterator position,BOOST_RV_REF(node_type) nh)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
|
||||
if(p.second&&position.get_node()!=header()){
|
||||
relocate(position.get_node(),p.first);
|
||||
}
|
||||
return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
|
||||
}
|
||||
|
||||
node_type extract(const_iterator position)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
return this->final_extract_(
|
||||
static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
iterator erase(iterator position)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
@@ -496,33 +526,36 @@ public:
|
||||
|
||||
/* list operations */
|
||||
|
||||
void splice(iterator position,random_access_index<SuperMeta,TagList>& x)
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(random_access_index,Index,void)
|
||||
splice(iterator position,Index& x)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
iterator first=x.begin(),last=x.end();
|
||||
size_type n=0;
|
||||
BOOST_TRY{
|
||||
while(first!=last){
|
||||
if(push_back(*first).second){
|
||||
first=x.erase(first);
|
||||
++n;
|
||||
}
|
||||
else ++first;
|
||||
}
|
||||
if(x.end().get_node()==this->header()){ /* same container */
|
||||
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(
|
||||
position==end(),safe_mode::inside_range);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
relocate(position,end()-n,end());
|
||||
BOOST_RETHROW;
|
||||
else{
|
||||
external_splice(
|
||||
position,x,x.begin(),x.end(),
|
||||
boost::is_copy_constructible<value_type>());
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
relocate(position,end()-n,end());
|
||||
}
|
||||
|
||||
void splice(
|
||||
iterator position,random_access_index<SuperMeta,TagList>& x,iterator i)
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(random_access_index,Index,void)
|
||||
splice(iterator position,BOOST_RV_REF(Index) x)
|
||||
{
|
||||
splice(position,static_cast<Index&>(x));
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||
random_access_index,Index,pair_return_type)
|
||||
splice(
|
||||
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
@@ -530,28 +563,36 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
if(&x==this)relocate(position,i);
|
||||
if(x.end().get_node()==this->header()){ /* same container */
|
||||
index_node_type* pn=position.get_node();
|
||||
index_node_type* in=static_cast<index_node_type*>(i.get_node());
|
||||
if(pn!=in)relocate(pn,in);
|
||||
return std::pair<iterator,bool>(make_iterator(in),true);
|
||||
}
|
||||
else{
|
||||
if(insert(position,*i).second){
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
/* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following
|
||||
* workaround is needed. Left it for all compilers as it does no
|
||||
* harm.
|
||||
*/
|
||||
i.detach();
|
||||
x.erase(x.make_iterator(i.get_node()));
|
||||
#else
|
||||
x.erase(i);
|
||||
#endif
|
||||
|
||||
}
|
||||
std::pair<final_node_type*,bool> p=
|
||||
external_splice(
|
||||
position,x,i,boost::is_copy_constructible<value_type>());
|
||||
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
||||
}
|
||||
}
|
||||
|
||||
void splice(
|
||||
iterator position,random_access_index<SuperMeta,TagList>& x,
|
||||
iterator first,iterator last)
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||
random_access_index,Index,pair_return_type)
|
||||
splice(
|
||||
iterator position,BOOST_RV_REF(Index) x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||
{
|
||||
return splice(position,static_cast<Index&>(x),i);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(random_access_index,Index,void)
|
||||
splice(
|
||||
iterator position,Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
@@ -561,25 +602,24 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
if(&x==this)relocate(position,first,last);
|
||||
else{
|
||||
size_type n=0;
|
||||
BOOST_TRY{
|
||||
while(first!=last){
|
||||
if(push_back(*first).second){
|
||||
first=x.erase(first);
|
||||
++n;
|
||||
}
|
||||
else ++first;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
relocate(position,end()-n,end());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
relocate(position,end()-n,end());
|
||||
if(x.end().get_node()==this->header()){ /* same container */
|
||||
BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
|
||||
internal_splice(position,first,last);
|
||||
}
|
||||
else{
|
||||
external_splice(
|
||||
position,x,first,last,boost::is_copy_constructible<value_type>());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(random_access_index,Index,void)
|
||||
splice(
|
||||
iterator position,BOOST_RV_REF(Index) x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{
|
||||
splice(position,static_cast<Index&>(x),first,last);
|
||||
}
|
||||
|
||||
void remove(value_param_type value)
|
||||
@@ -587,9 +627,10 @@ public:
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
difference_type n=
|
||||
end()-make_iterator(
|
||||
random_access_index_remove<node_type>(
|
||||
random_access_index_remove<index_node_type>(
|
||||
ptrs,
|
||||
::boost::bind(std::equal_to<value_type>(),::boost::arg<1>(),value)));
|
||||
::boost::bind<bool>(
|
||||
std::equal_to<value_type>(),::boost::arg<1>(),value)));
|
||||
while(n--)pop_back();
|
||||
}
|
||||
|
||||
@@ -598,7 +639,8 @@ public:
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
difference_type n=
|
||||
end()-make_iterator(random_access_index_remove<node_type>(ptrs,pred));
|
||||
end()-make_iterator(
|
||||
random_access_index_remove<index_node_type>(ptrs,pred));
|
||||
while(n--)pop_back();
|
||||
}
|
||||
|
||||
@@ -607,7 +649,7 @@ public:
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
difference_type n=
|
||||
end()-make_iterator(
|
||||
random_access_index_unique<node_type>(
|
||||
random_access_index_unique<index_node_type>(
|
||||
ptrs,std::equal_to<value_type>()));
|
||||
while(n--)pop_back();
|
||||
}
|
||||
@@ -618,7 +660,7 @@ public:
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
difference_type n=
|
||||
end()-make_iterator(
|
||||
random_access_index_unique<node_type>(ptrs,binary_pred));
|
||||
random_access_index_unique<index_node_type>(ptrs,binary_pred));
|
||||
while(n--)pop_back();
|
||||
}
|
||||
|
||||
@@ -628,7 +670,7 @@ public:
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
size_type s=size();
|
||||
splice(end(),x);
|
||||
random_access_index_inplace_merge<node_type>(
|
||||
random_access_index_inplace_merge<index_node_type>(
|
||||
get_allocator(),ptrs,ptrs.at(s),std::less<value_type>());
|
||||
}
|
||||
}
|
||||
@@ -640,7 +682,7 @@ public:
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
size_type s=size();
|
||||
splice(end(),x);
|
||||
random_access_index_inplace_merge<node_type>(
|
||||
random_access_index_inplace_merge<index_node_type>(
|
||||
get_allocator(),ptrs,ptrs.at(s),comp);
|
||||
}
|
||||
}
|
||||
@@ -648,7 +690,7 @@ public:
|
||||
void sort()
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
random_access_index_sort<node_type>(
|
||||
random_access_index_sort<index_node_type>(
|
||||
get_allocator(),ptrs,std::less<value_type>());
|
||||
}
|
||||
|
||||
@@ -656,7 +698,7 @@ public:
|
||||
void sort(Compare comp)
|
||||
{
|
||||
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
|
||||
random_access_index_sort<node_type>(
|
||||
random_access_index_sort<index_node_type>(
|
||||
get_allocator(),ptrs,comp);
|
||||
}
|
||||
|
||||
@@ -701,7 +743,7 @@ public:
|
||||
for(node_impl_ptr_pointer p0=ptrs.begin(),p0_end=ptrs.end();
|
||||
p0!=p0_end;++first,++p0){
|
||||
const value_type& v1=*first;
|
||||
node_impl_ptr_pointer p1=node_from_value<node_type>(&v1)->up();
|
||||
node_impl_ptr_pointer p1=node_from_value<index_node_type>(&v1)->up();
|
||||
|
||||
std::swap(*p0,*p1);
|
||||
(*p0)->up()=p0;
|
||||
@@ -714,17 +756,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
const ctor_args_list& args_list,const allocator_type& al):
|
||||
super(args_list.get_tail(),al),
|
||||
ptrs(al,header()->impl(),0)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
random_access_index(const random_access_index<SuperMeta,TagList>& x):
|
||||
super(x),
|
||||
ptrs(x.get_allocator(),header()->impl(),x.size())
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
ptrs(x.get_allocator(),header()->impl(),x.size())
|
||||
{
|
||||
/* The actual copying takes place in subsequent call to copy_().
|
||||
*/
|
||||
@@ -733,12 +780,12 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
random_access_index(
|
||||
const random_access_index<SuperMeta,TagList>& x,do_not_copy_elements_tag):
|
||||
super(x,do_not_copy_elements_tag()),
|
||||
ptrs(x.get_allocator(),header()->impl(),0)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super(),
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
ptrs(x.get_allocator(),header()->impl(),0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -748,12 +795,13 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
iterator make_iterator(node_type* node){return iterator(node,this);}
|
||||
const_iterator make_iterator(node_type* node)const
|
||||
{return const_iterator(node,const_cast<random_access_index*>(this));}
|
||||
iterator make_iterator(index_node_type* node)
|
||||
{return iterator(node,&safe);}
|
||||
const_iterator make_iterator(index_node_type* node)const
|
||||
{return const_iterator(node,const_cast<safe_container*>(&safe));}
|
||||
#else
|
||||
iterator make_iterator(node_type* node){return iterator(node);}
|
||||
const_iterator make_iterator(node_type* node)const
|
||||
iterator make_iterator(index_node_type* node){return iterator(node);}
|
||||
const_iterator make_iterator(index_node_type* node)const
|
||||
{return const_iterator(node);}
|
||||
#endif
|
||||
|
||||
@@ -765,10 +813,10 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
end_org=x.ptrs.end();
|
||||
begin_org!=end_org;++begin_org,++begin_cpy){
|
||||
*begin_cpy=
|
||||
static_cast<node_type*>(
|
||||
static_cast<index_node_type*>(
|
||||
map.find(
|
||||
static_cast<final_node_type*>(
|
||||
node_type::from_impl(*begin_org))))->impl();
|
||||
index_node_type::from_impl(*begin_org))))->impl();
|
||||
(*begin_cpy)->up()=begin_cpy;
|
||||
}
|
||||
|
||||
@@ -781,27 +829,29 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
{
|
||||
ptrs.room_for_one();
|
||||
final_node_type* res=super::insert_(v,x,variant);
|
||||
if(res==x)ptrs.push_back(static_cast<node_type*>(x)->impl());
|
||||
if(res==x)ptrs.push_back(static_cast<index_node_type*>(x)->impl());
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Variant>
|
||||
final_node_type* insert_(
|
||||
value_param_type v,node_type* position,final_node_type*& x,Variant variant)
|
||||
value_param_type v,index_node_type* position,
|
||||
final_node_type*& x,Variant variant)
|
||||
{
|
||||
ptrs.room_for_one();
|
||||
final_node_type* res=super::insert_(v,position,x,variant);
|
||||
if(res==x)ptrs.push_back(static_cast<node_type*>(x)->impl());
|
||||
if(res==x)ptrs.push_back(static_cast<index_node_type*>(x)->impl());
|
||||
return res;
|
||||
}
|
||||
|
||||
void erase_(node_type* x)
|
||||
template<typename Dst>
|
||||
void extract_(index_node_type* x,Dst dst)
|
||||
{
|
||||
ptrs.erase(x->impl());
|
||||
super::erase_(x);
|
||||
super::extract_(x,dst.next());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
transfer_iterators(dst.get(),x);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -809,7 +859,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
{
|
||||
for(node_impl_ptr_pointer x=ptrs.begin(),x_end=ptrs.end();x!=x_end;++x){
|
||||
this->final_delete_node_(
|
||||
static_cast<final_node_type*>(node_type::from_impl(*x)));
|
||||
static_cast<final_node_type*>(index_node_type::from_impl(*x)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -819,19 +869,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
ptrs.clear();
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::detach_dereferenceable_iterators();
|
||||
safe.detach_dereferenceable_iterators();
|
||||
#endif
|
||||
}
|
||||
|
||||
void swap_(random_access_index<SuperMeta,TagList>& x)
|
||||
template<typename BoolConstant>
|
||||
void swap_(
|
||||
random_access_index<SuperMeta,TagList>& x,BoolConstant swap_allocators)
|
||||
{
|
||||
ptrs.swap(x.ptrs);
|
||||
ptrs.swap(x.ptrs,swap_allocators);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::swap(x);
|
||||
safe.swap(x.safe);
|
||||
#endif
|
||||
|
||||
super::swap_(x);
|
||||
super::swap_(x,swap_allocators);
|
||||
}
|
||||
|
||||
void swap_elements_(random_access_index<SuperMeta,TagList>& x)
|
||||
@@ -839,19 +891,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
ptrs.swap(x.ptrs);
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::swap(x);
|
||||
safe.swap(x.safe);
|
||||
#endif
|
||||
|
||||
super::swap_elements_(x);
|
||||
}
|
||||
|
||||
template<typename Variant>
|
||||
bool replace_(value_param_type v,node_type* x,Variant variant)
|
||||
bool replace_(value_param_type v,index_node_type* x,Variant variant)
|
||||
{
|
||||
return super::replace_(v,x,variant);
|
||||
}
|
||||
|
||||
bool modify_(node_type* x)
|
||||
bool modify_(index_node_type* x)
|
||||
{
|
||||
BOOST_TRY{
|
||||
if(!super::modify_(x)){
|
||||
@@ -877,12 +929,12 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_rollback_(node_type* x)
|
||||
bool modify_rollback_(index_node_type* x)
|
||||
{
|
||||
return super::modify_rollback_(x);
|
||||
}
|
||||
|
||||
bool check_rollback_(node_type* x)const
|
||||
bool check_rollback_(index_node_type* x)const
|
||||
{
|
||||
return super::check_rollback_(x);
|
||||
}
|
||||
@@ -903,7 +955,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
Archive& ar,const unsigned int version,const index_loader_type& lm)
|
||||
{
|
||||
{
|
||||
typedef random_access_index_loader<node_type,allocator_type> loader;
|
||||
typedef random_access_index_loader<
|
||||
index_node_type,allocator_type> loader;
|
||||
|
||||
loader ld(get_allocator(),ptrs);
|
||||
lm.load(
|
||||
@@ -944,25 +997,33 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
#endif
|
||||
|
||||
private:
|
||||
node_type* header()const{return this->final_header();}
|
||||
index_node_type* header()const{return this->final_header();}
|
||||
|
||||
static void relocate(node_type* position,node_type* x)
|
||||
static void relocate(index_node_type* position,index_node_type* x)
|
||||
{
|
||||
node_impl_type::relocate(position->up(),x->up());
|
||||
}
|
||||
|
||||
static void relocate(node_type* position,node_type* first,node_type* last)
|
||||
static void relocate(
|
||||
index_node_type* position,index_node_type* first,index_node_type* last)
|
||||
{
|
||||
node_impl_type::relocate(
|
||||
position->up(),first->up(),last->up());
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
void detach_iterators(node_type* x)
|
||||
void detach_iterators(index_node_type* x)
|
||||
{
|
||||
iterator it=make_iterator(x);
|
||||
safe_mode::detach_equivalent_iterators(it);
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
void transfer_iterators(Dst& dst,index_node_type* x)
|
||||
{
|
||||
iterator it=make_iterator(x);
|
||||
safe_mode::transfer_equivalent_iterators(dst,it);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class InputIterator>
|
||||
@@ -1048,7 +1109,121 @@ private:
|
||||
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
||||
}
|
||||
|
||||
ptr_array ptrs;
|
||||
template<typename Index>
|
||||
std::pair<final_node_type*,bool> external_splice(
|
||||
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i,
|
||||
boost::true_type /* copy-constructible value */)
|
||||
{
|
||||
if(get_allocator()==x.get_allocator()){
|
||||
return external_splice(position,x,i,boost::false_type());
|
||||
}
|
||||
else{
|
||||
/* backwards compatibility with old, non-transfer-based splice */
|
||||
|
||||
std::pair<iterator,bool> p=insert(position,*i);
|
||||
if(p.second)x.erase(i);
|
||||
return std::pair<final_node_type*,bool>(
|
||||
static_cast<final_node_type*>(p.first.get_node()),p.second);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
std::pair<final_node_type*,bool> external_splice(
|
||||
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i,
|
||||
boost::false_type /* copy-constructible value */)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
||||
std::pair<final_node_type*,bool> p=this->final_transfer_(
|
||||
x,static_cast<final_node_type*>(i.get_node()));
|
||||
if(p.second&&position.get_node()!=header()){
|
||||
relocate(position.get_node(),p.first);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
void internal_splice(iterator position,Iterator first,Iterator last)
|
||||
{
|
||||
/* null out [first, last) positions in ptrs array */
|
||||
|
||||
for(Iterator it=first;it!=last;++it){
|
||||
*(static_cast<index_node_type*>(it.get_node())->up())=0;
|
||||
}
|
||||
|
||||
node_impl_ptr_pointer pp=node_impl_type::gather_nulls(
|
||||
ptrs.begin(),ptrs.end(),
|
||||
static_cast<index_node_type*>(position.get_node())->up());
|
||||
|
||||
/* relink [first, last) */
|
||||
|
||||
for(Iterator it=first;it!=last;++it,++pp){
|
||||
*pp=static_cast<index_node_type*>(it.get_node());
|
||||
(*pp)->up()=pp;
|
||||
}
|
||||
}
|
||||
|
||||
void internal_splice(iterator position,iterator first,iterator last)
|
||||
{
|
||||
index_node_type* pn=position.get_node();
|
||||
index_node_type* fn=static_cast<index_node_type*>(first.get_node());
|
||||
index_node_type* ln=static_cast<index_node_type*>(last.get_node());
|
||||
if(pn!=ln)relocate(pn,fn,ln);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
void external_splice(
|
||||
iterator position,Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last,
|
||||
boost::true_type /* copy-constructible value */)
|
||||
{
|
||||
if(get_allocator()==x.get_allocator()){
|
||||
external_splice(position,x,first,last,boost::false_type());
|
||||
}
|
||||
else{
|
||||
/* backwards compatibility with old, non-transfer-based splice */
|
||||
|
||||
size_type n=size();
|
||||
BOOST_TRY{
|
||||
while(first!=last){
|
||||
if(push_back(*first).second)first=x.erase(first);
|
||||
else ++first;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
relocate(position,begin()+n,end());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
relocate(position,begin()+n,end());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
void external_splice(
|
||||
iterator position,Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last,
|
||||
boost::false_type /* copy-constructible value */)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
||||
size_type n=size();
|
||||
BOOST_TRY{
|
||||
this->final_transfer_range_(x,first,last);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
relocate(position,begin()+n,end());
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
relocate(position,begin()+n,end());
|
||||
}
|
||||
|
||||
ptr_array ptrs;
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_container safe;
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
@@ -1056,6 +1231,10 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4355 */
|
||||
#endif
|
||||
|
||||
/* comparison */
|
||||
|
||||
template<
|
||||
@@ -1163,12 +1342,18 @@ struct random_access
|
||||
|
||||
/* Boost.Foreach compatibility */
|
||||
|
||||
namespace boost{
|
||||
namespace foreach{
|
||||
|
||||
template<typename>
|
||||
struct is_noncopyable;
|
||||
|
||||
template<typename SuperMeta,typename TagList>
|
||||
inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
||||
boost::multi_index::detail::random_access_index<SuperMeta,TagList>*&,
|
||||
boost_foreach_argument_dependent_lookup_hack)
|
||||
{
|
||||
return 0;
|
||||
struct is_noncopyable<
|
||||
boost::multi_index::detail::random_access_index<SuperMeta,TagList>
|
||||
>:boost::mpl::true_{};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2018 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2022 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -40,7 +40,7 @@ class ranked_index:public OrderedIndexImpl
|
||||
typedef OrderedIndexImpl super;
|
||||
|
||||
protected:
|
||||
typedef typename super::node_type node_type;
|
||||
typedef typename super::index_node_type index_node_type;
|
||||
typedef typename super::node_impl_pointer node_impl_pointer;
|
||||
|
||||
public:
|
||||
@@ -49,11 +49,26 @@ public:
|
||||
typedef typename super::iterator iterator;
|
||||
typedef typename super::size_type size_type;
|
||||
|
||||
/* set operations */
|
||||
|
||||
template<typename CompatibleKey>
|
||||
size_type count(const CompatibleKey& x)const
|
||||
{
|
||||
return count(x,this->comp_);
|
||||
}
|
||||
|
||||
template<typename CompatibleKey,typename CompatibleCompare>
|
||||
size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
|
||||
{
|
||||
std::pair<size_type,size_type> p=this->equal_range_rank(x,comp);
|
||||
return p.second-p.first;
|
||||
}
|
||||
|
||||
/* rank operations */
|
||||
|
||||
iterator nth(size_type n)const
|
||||
{
|
||||
return this->make_iterator(node_type::from_impl(
|
||||
return this->make_iterator(index_node_type::from_impl(
|
||||
ranked_index_nth(n,this->header()->impl())));
|
||||
}
|
||||
|
||||
@@ -163,8 +178,8 @@ private:
|
||||
std::pair<size_type,size_type>
|
||||
range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
|
||||
{
|
||||
node_type* y=this->header();
|
||||
node_type* z=this->root();
|
||||
index_node_type* y=this->header();
|
||||
index_node_type* z=this->root();
|
||||
|
||||
if(!z)return std::pair<size_type,size_type>(0,0);
|
||||
|
||||
@@ -172,19 +187,19 @@ private:
|
||||
|
||||
do{
|
||||
if(!lower(this->key(z->value()))){
|
||||
z=node_type::from_impl(z->right());
|
||||
z=index_node_type::from_impl(z->right());
|
||||
}
|
||||
else if(!upper(this->key(z->value()))){
|
||||
y=z;
|
||||
s-=ranked_node_size(y->right())+1;
|
||||
z=node_type::from_impl(z->left());
|
||||
z=index_node_type::from_impl(z->left());
|
||||
}
|
||||
else{
|
||||
return std::pair<size_type,size_type>(
|
||||
s-z->impl()->size+
|
||||
lower_range_rank(node_type::from_impl(z->left()),z,lower),
|
||||
lower_range_rank(index_node_type::from_impl(z->left()),z,lower),
|
||||
s-ranked_node_size(z->right())+
|
||||
upper_range_rank(node_type::from_impl(z->right()),y,upper));
|
||||
upper_range_rank(index_node_type::from_impl(z->right()),y,upper));
|
||||
}
|
||||
}while(z);
|
||||
|
||||
@@ -218,7 +233,8 @@ private:
|
||||
|
||||
template<typename LowerBounder>
|
||||
size_type
|
||||
lower_range_rank(node_type* top,node_type* y,LowerBounder lower)const
|
||||
lower_range_rank(
|
||||
index_node_type* top,index_node_type* y,LowerBounder lower)const
|
||||
{
|
||||
if(!top)return 0;
|
||||
|
||||
@@ -228,9 +244,9 @@ private:
|
||||
if(lower(this->key(top->value()))){
|
||||
y=top;
|
||||
s-=ranked_node_size(y->right())+1;
|
||||
top=node_type::from_impl(top->left());
|
||||
top=index_node_type::from_impl(top->left());
|
||||
}
|
||||
else top=node_type::from_impl(top->right());
|
||||
else top=index_node_type::from_impl(top->right());
|
||||
}while(top);
|
||||
|
||||
return s;
|
||||
@@ -238,7 +254,8 @@ private:
|
||||
|
||||
template<typename UpperBounder>
|
||||
size_type
|
||||
upper_range_rank(node_type* top,node_type* y,UpperBounder upper)const
|
||||
upper_range_rank(
|
||||
index_node_type* top,index_node_type* y,UpperBounder upper)const
|
||||
{
|
||||
if(!top)return 0;
|
||||
|
||||
@@ -248,9 +265,9 @@ private:
|
||||
if(!upper(this->key(top->value()))){
|
||||
y=top;
|
||||
s-=ranked_node_size(y->right())+1;
|
||||
top=node_type::from_impl(top->left());
|
||||
top=index_node_type::from_impl(top->left());
|
||||
}
|
||||
else top=node_type::from_impl(top->right());
|
||||
else top=index_node_type::from_impl(top->right());
|
||||
}while(top);
|
||||
|
||||
return s;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -36,7 +36,8 @@ enum error_code
|
||||
invalid_range,
|
||||
inside_range,
|
||||
out_of_bounds,
|
||||
same_container
|
||||
same_container,
|
||||
unequal_allocators
|
||||
};
|
||||
|
||||
} /* namespace multi_index::safe_mode */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2003-2019 Joaquin M Lopez Munoz.
|
||||
/* Copyright 2003-2023 Joaquin M Lopez Munoz.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -14,12 +14,11 @@
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/foreach_fwd.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
@@ -31,6 +30,7 @@
|
||||
#include <boost/multi_index/detail/bidir_node_iterator.hpp>
|
||||
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
|
||||
#include <boost/multi_index/detail/index_node_base.hpp>
|
||||
#include <boost/multi_index/detail/node_handle.hpp>
|
||||
#include <boost/multi_index/detail/safe_mode.hpp>
|
||||
#include <boost/multi_index/detail/scope_guard.hpp>
|
||||
#include <boost/multi_index/detail/seq_index_node.hpp>
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <boost/multi_index/detail/vartempl_support.hpp>
|
||||
#include <boost/multi_index/sequenced_index_fwd.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
@@ -46,10 +47,6 @@
|
||||
#include<initializer_list>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
#include <boost/bind.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
||||
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \
|
||||
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
|
||||
@@ -70,15 +67,14 @@ namespace detail{
|
||||
|
||||
/* sequenced_index adds a layer of sequenced indexing to a given Super */
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4355) /* this used in base member initializer list */
|
||||
#endif
|
||||
|
||||
template<typename SuperMeta,typename TagList>
|
||||
class sequenced_index:
|
||||
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,public safe_mode::safe_container<
|
||||
sequenced_index<SuperMeta,TagList> >
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
@@ -90,19 +86,25 @@ class sequenced_index:
|
||||
#pragma parse_mfunc_templ off
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
/* cross-index access */
|
||||
|
||||
template <typename,typename,typename> friend class index_base;
|
||||
#endif
|
||||
|
||||
typedef typename SuperMeta::type super;
|
||||
|
||||
protected:
|
||||
typedef sequenced_index_node<
|
||||
typename super::node_type> node_type;
|
||||
typename super::index_node_type> index_node_type;
|
||||
|
||||
private:
|
||||
typedef typename node_type::impl_type node_impl_type;
|
||||
typedef typename index_node_type::impl_type node_impl_type;
|
||||
|
||||
public:
|
||||
/* types */
|
||||
|
||||
typedef typename node_type::value_type value_type;
|
||||
typedef typename index_node_type::value_type value_type;
|
||||
typedef tuples::null_type ctor_args;
|
||||
typedef typename super::final_allocator_type allocator_type;
|
||||
typedef value_type& reference;
|
||||
@@ -110,10 +112,9 @@ public:
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
typedef safe_mode::safe_iterator<
|
||||
bidir_node_iterator<node_type>,
|
||||
sequenced_index> iterator;
|
||||
bidir_node_iterator<index_node_type> > iterator;
|
||||
#else
|
||||
typedef bidir_node_iterator<node_type> iterator;
|
||||
typedef bidir_node_iterator<index_node_type> iterator;
|
||||
#endif
|
||||
|
||||
typedef iterator const_iterator;
|
||||
@@ -130,6 +131,9 @@ public:
|
||||
boost::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef typename
|
||||
boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef typename super::final_node_handle_type node_type;
|
||||
typedef detail::insert_return_type<
|
||||
iterator,node_type> insert_return_type;
|
||||
typedef TagList tag_list;
|
||||
|
||||
protected:
|
||||
@@ -155,17 +159,14 @@ protected:
|
||||
|
||||
private:
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
typedef safe_mode::safe_container<
|
||||
sequenced_index> safe_super;
|
||||
typedef safe_mode::safe_container<iterator> safe_container;
|
||||
#endif
|
||||
|
||||
typedef typename call_traits<value_type>::param_type value_param_type;
|
||||
|
||||
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
|
||||
* expansion.
|
||||
*/
|
||||
/* needed to avoid commas in some macros */
|
||||
|
||||
typedef std::pair<iterator,bool> emplace_return_type;
|
||||
typedef std::pair<iterator,bool> pair_return_type;
|
||||
|
||||
public:
|
||||
|
||||
@@ -218,9 +219,9 @@ public:
|
||||
/* iterators */
|
||||
|
||||
iterator begin()BOOST_NOEXCEPT
|
||||
{return make_iterator(node_type::from_impl(header()->next()));}
|
||||
{return make_iterator(index_node_type::from_impl(header()->next()));}
|
||||
const_iterator begin()const BOOST_NOEXCEPT
|
||||
{return make_iterator(node_type::from_impl(header()->next()));}
|
||||
{return make_iterator(index_node_type::from_impl(header()->next()));}
|
||||
iterator
|
||||
end()BOOST_NOEXCEPT{return make_iterator(header());}
|
||||
const_iterator
|
||||
@@ -244,12 +245,14 @@ public:
|
||||
|
||||
iterator iterator_to(const value_type& x)
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(boost::addressof(x)));
|
||||
return make_iterator(
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const value_type& x)const
|
||||
{
|
||||
return make_iterator(node_from_value<node_type>(boost::addressof(x)));
|
||||
return make_iterator(
|
||||
node_from_value<index_node_type>(boost::addressof(x)));
|
||||
}
|
||||
|
||||
/* capacity */
|
||||
@@ -285,7 +288,7 @@ public:
|
||||
/* modifiers */
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||
emplace_return_type,emplace_front,emplace_front_impl)
|
||||
pair_return_type,emplace_front,emplace_front_impl)
|
||||
|
||||
std::pair<iterator,bool> push_front(const value_type& x)
|
||||
{return insert(begin(),x);}
|
||||
@@ -294,7 +297,7 @@ public:
|
||||
void pop_front(){erase(begin());}
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||
emplace_return_type,emplace_back,emplace_back_impl)
|
||||
pair_return_type,emplace_back,emplace_back_impl)
|
||||
|
||||
std::pair<iterator,bool> push_back(const value_type& x)
|
||||
{return insert(end(),x);}
|
||||
@@ -303,7 +306,7 @@ public:
|
||||
void pop_back(){erase(--end());}
|
||||
|
||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
||||
emplace_return_type,emplace,emplace_impl,iterator,position)
|
||||
pair_return_type,emplace,emplace_impl,iterator,position)
|
||||
|
||||
std::pair<iterator,bool> insert(iterator position,const value_type& x)
|
||||
{
|
||||
@@ -350,6 +353,29 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
insert_return_type insert(const_iterator position,BOOST_RV_REF(node_type) nh)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
|
||||
if(p.second&&position.get_node()!=header()){
|
||||
relink(position.get_node(),p.first);
|
||||
}
|
||||
return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
|
||||
}
|
||||
|
||||
node_type extract(const_iterator position)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
return this->final_extract_(
|
||||
static_cast<final_node_type*>(position.get_node()));
|
||||
}
|
||||
|
||||
iterator erase(iterator position)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
@@ -451,20 +477,36 @@ public:
|
||||
|
||||
/* list operations */
|
||||
|
||||
void splice(iterator position,sequenced_index<SuperMeta,TagList>& x)
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(sequenced_index,Index,void)
|
||||
splice(iterator position,Index& x)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
iterator first=x.begin(),last=x.end();
|
||||
while(first!=last){
|
||||
if(insert(position,*first).second)first=x.erase(first);
|
||||
else ++first;
|
||||
if(x.end().get_node()==this->header()){ /* same container */
|
||||
BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(
|
||||
position==end(),safe_mode::inside_range);
|
||||
}
|
||||
else{
|
||||
external_splice(
|
||||
position,x,x.begin(),x.end(),
|
||||
boost::is_copy_constructible<value_type>());
|
||||
}
|
||||
}
|
||||
|
||||
void splice(iterator position,sequenced_index<SuperMeta,TagList>& x,iterator i)
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(sequenced_index,Index,void)
|
||||
splice(iterator position,BOOST_RV_REF(Index) x)
|
||||
{
|
||||
splice(position,static_cast<Index&>(x));
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||
sequenced_index,Index,pair_return_type)
|
||||
splice(
|
||||
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
@@ -472,30 +514,36 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
if(&x==this){
|
||||
if(position!=i)relink(position.get_node(),i.get_node());
|
||||
if(x.end().get_node()==this->header()){ /* same container */
|
||||
index_node_type* pn=position.get_node();
|
||||
index_node_type* in=static_cast<index_node_type*>(i.get_node());
|
||||
if(pn!=in)relink(pn,in);
|
||||
return std::pair<iterator,bool>(make_iterator(in),true);
|
||||
}
|
||||
else{
|
||||
if(insert(position,*i).second){
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
/* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following
|
||||
* workaround is needed. Left it for all compilers as it does no
|
||||
* harm.
|
||||
*/
|
||||
i.detach();
|
||||
x.erase(x.make_iterator(i.get_node()));
|
||||
#else
|
||||
x.erase(i);
|
||||
#endif
|
||||
|
||||
}
|
||||
std::pair<final_node_type*,bool> p=
|
||||
external_splice(
|
||||
position,x,i,boost::is_copy_constructible<value_type>());
|
||||
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
||||
}
|
||||
}
|
||||
|
||||
void splice(
|
||||
iterator position,sequenced_index<SuperMeta,TagList>& x,
|
||||
iterator first,iterator last)
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||
sequenced_index,Index,pair_return_type)
|
||||
splice(
|
||||
iterator position,BOOST_RV_REF(Index) x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||
{
|
||||
return splice(position,static_cast<Index&>(x),i);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(sequenced_index,Index,void)
|
||||
splice(
|
||||
iterator position,Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
||||
@@ -505,24 +553,32 @@ public:
|
||||
BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
|
||||
BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
if(&x==this){
|
||||
if(x.end().get_node()==this->header()){ /* same container */
|
||||
BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
|
||||
if(position!=last)relink(
|
||||
position.get_node(),first.get_node(),last.get_node());
|
||||
internal_splice(position,first,last);
|
||||
}
|
||||
else{
|
||||
while(first!=last){
|
||||
if(insert(position,*first).second)first=x.erase(first);
|
||||
else ++first;
|
||||
}
|
||||
external_splice(
|
||||
position,x,first,last,boost::is_copy_constructible<value_type>());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(sequenced_index,Index,void)
|
||||
splice(
|
||||
iterator position,BOOST_RV_REF(Index) x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||
{
|
||||
splice(position,static_cast<Index&>(x),first,last);
|
||||
}
|
||||
|
||||
void remove(value_param_type value)
|
||||
{
|
||||
sequenced_index_remove(
|
||||
*this,
|
||||
::boost::bind(std::equal_to<value_type>(),::boost::arg<1>(),value));
|
||||
::boost::bind<bool>(
|
||||
std::equal_to<value_type>(),::boost::arg<1>(),value));
|
||||
}
|
||||
|
||||
template<typename Predicate>
|
||||
@@ -604,16 +660,21 @@ public:
|
||||
void rearrange(InputIterator first)
|
||||
{
|
||||
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
||||
node_type* pos=header();
|
||||
index_node_type* pos=header();
|
||||
for(size_type s=size();s--;){
|
||||
const value_type& v=*first++;
|
||||
relink(pos,node_from_value<node_type>(&v));
|
||||
relink(pos,node_from_value<index_node_type>(&v));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
sequenced_index(const ctor_args_list& args_list,const allocator_type& al):
|
||||
super(args_list.get_tail(),al)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
empty_initialize();
|
||||
}
|
||||
@@ -622,7 +683,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
super(x)
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe_super()
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
@@ -634,7 +695,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
super(x,do_not_copy_elements_tag())
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
,safe_super()
|
||||
,safe(*this)
|
||||
#endif
|
||||
|
||||
{
|
||||
@@ -647,23 +708,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
iterator make_iterator(node_type* node){return iterator(node,this);}
|
||||
const_iterator make_iterator(node_type* node)const
|
||||
{return const_iterator(node,const_cast<sequenced_index*>(this));}
|
||||
iterator make_iterator(index_node_type* node)
|
||||
{return iterator(node,&safe);}
|
||||
const_iterator make_iterator(index_node_type* node)const
|
||||
{return const_iterator(node,const_cast<safe_container*>(&safe));}
|
||||
#else
|
||||
iterator make_iterator(node_type* node){return iterator(node);}
|
||||
const_iterator make_iterator(node_type* node)const
|
||||
iterator make_iterator(index_node_type* node){return iterator(node);}
|
||||
const_iterator make_iterator(index_node_type* node)const
|
||||
{return const_iterator(node);}
|
||||
#endif
|
||||
|
||||
void copy_(
|
||||
const sequenced_index<SuperMeta,TagList>& x,const copy_map_type& map)
|
||||
{
|
||||
node_type* org=x.header();
|
||||
node_type* cpy=header();
|
||||
index_node_type* org=x.header();
|
||||
index_node_type* cpy=header();
|
||||
do{
|
||||
node_type* next_org=node_type::from_impl(org->next());
|
||||
node_type* next_cpy=map.find(static_cast<final_node_type*>(next_org));
|
||||
index_node_type* next_org=index_node_type::from_impl(org->next());
|
||||
index_node_type* next_cpy=map.find(
|
||||
static_cast<final_node_type*>(next_org));
|
||||
cpy->next()=next_cpy->impl();
|
||||
next_cpy->prior()=cpy->impl();
|
||||
org=next_org;
|
||||
@@ -678,33 +741,36 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
value_param_type v,final_node_type*& x,Variant variant)
|
||||
{
|
||||
final_node_type* res=super::insert_(v,x,variant);
|
||||
if(res==x)link(static_cast<node_type*>(x));
|
||||
if(res==x)link(static_cast<index_node_type*>(x));
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Variant>
|
||||
final_node_type* insert_(
|
||||
value_param_type v,node_type* position,final_node_type*& x,Variant variant)
|
||||
value_param_type v,index_node_type* position,
|
||||
final_node_type*& x,Variant variant)
|
||||
{
|
||||
final_node_type* res=super::insert_(v,position,x,variant);
|
||||
if(res==x)link(static_cast<node_type*>(x));
|
||||
if(res==x)link(static_cast<index_node_type*>(x));
|
||||
return res;
|
||||
}
|
||||
|
||||
void erase_(node_type* x)
|
||||
template<typename Dst>
|
||||
void extract_(index_node_type* x,Dst dst)
|
||||
{
|
||||
unlink(x);
|
||||
super::erase_(x);
|
||||
super::extract_(x,dst.next());
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
detach_iterators(x);
|
||||
transfer_iterators(dst.get(),x);
|
||||
#endif
|
||||
}
|
||||
|
||||
void delete_all_nodes_()
|
||||
{
|
||||
for(node_type* x=node_type::from_impl(header()->next());x!=header();){
|
||||
node_type* y=node_type::from_impl(x->next());
|
||||
for(index_node_type* x=index_node_type::from_impl(header()->next());
|
||||
x!=header();){
|
||||
index_node_type* y=index_node_type::from_impl(x->next());
|
||||
this->final_delete_node_(static_cast<final_node_type*>(x));
|
||||
x=y;
|
||||
}
|
||||
@@ -716,35 +782,37 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
empty_initialize();
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::detach_dereferenceable_iterators();
|
||||
safe.detach_dereferenceable_iterators();
|
||||
#endif
|
||||
}
|
||||
|
||||
void swap_(sequenced_index<SuperMeta,TagList>& x)
|
||||
template<typename BoolConstant>
|
||||
void swap_(
|
||||
sequenced_index<SuperMeta,TagList>& x,BoolConstant swap_allocators)
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::swap(x);
|
||||
safe.swap(x.safe);
|
||||
#endif
|
||||
|
||||
super::swap_(x);
|
||||
super::swap_(x,swap_allocators);
|
||||
}
|
||||
|
||||
void swap_elements_(sequenced_index<SuperMeta,TagList>& x)
|
||||
{
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_super::swap(x);
|
||||
safe.swap(x.safe);
|
||||
#endif
|
||||
|
||||
super::swap_elements_(x);
|
||||
}
|
||||
|
||||
template<typename Variant>
|
||||
bool replace_(value_param_type v,node_type* x,Variant variant)
|
||||
bool replace_(value_param_type v,index_node_type* x,Variant variant)
|
||||
{
|
||||
return super::replace_(v,x,variant);
|
||||
}
|
||||
|
||||
bool modify_(node_type* x)
|
||||
bool modify_(index_node_type* x)
|
||||
{
|
||||
BOOST_TRY{
|
||||
if(!super::modify_(x)){
|
||||
@@ -770,12 +838,12 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
bool modify_rollback_(node_type* x)
|
||||
bool modify_rollback_(index_node_type* x)
|
||||
{
|
||||
return super::modify_rollback_(x);
|
||||
}
|
||||
|
||||
bool check_rollback_(node_type* x)const
|
||||
bool check_rollback_(index_node_type* x)const
|
||||
{
|
||||
return super::check_rollback_(x);
|
||||
}
|
||||
@@ -833,49 +901,57 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
||||
#endif
|
||||
|
||||
private:
|
||||
node_type* header()const{return this->final_header();}
|
||||
index_node_type* header()const{return this->final_header();}
|
||||
|
||||
void empty_initialize()
|
||||
{
|
||||
header()->prior()=header()->next()=header()->impl();
|
||||
}
|
||||
|
||||
void link(node_type* x)
|
||||
void link(index_node_type* x)
|
||||
{
|
||||
node_impl_type::link(x->impl(),header()->impl());
|
||||
}
|
||||
|
||||
static void unlink(node_type* x)
|
||||
static void unlink(index_node_type* x)
|
||||
{
|
||||
node_impl_type::unlink(x->impl());
|
||||
}
|
||||
|
||||
static void relink(node_type* position,node_type* x)
|
||||
static void relink(index_node_type* position,index_node_type* x)
|
||||
{
|
||||
node_impl_type::relink(position->impl(),x->impl());
|
||||
}
|
||||
|
||||
static void relink(node_type* position,node_type* first,node_type* last)
|
||||
static void relink(
|
||||
index_node_type* position,index_node_type* first,index_node_type* last)
|
||||
{
|
||||
node_impl_type::relink(
|
||||
position->impl(),first->impl(),last->impl());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
||||
void rearranger(node_type* position,node_type *x)
|
||||
void rearranger(index_node_type* position,index_node_type *x)
|
||||
{
|
||||
if(!position)position=header();
|
||||
node_type::increment(position);
|
||||
index_node_type::increment(position);
|
||||
if(position!=x)relink(position,x);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
void detach_iterators(node_type* x)
|
||||
void detach_iterators(index_node_type* x)
|
||||
{
|
||||
iterator it=make_iterator(x);
|
||||
safe_mode::detach_equivalent_iterators(it);
|
||||
}
|
||||
|
||||
template<typename Dst>
|
||||
void transfer_iterators(Dst& dst,index_node_type* x)
|
||||
{
|
||||
iterator it=make_iterator(x);
|
||||
safe_mode::transfer_equivalent_iterators(dst,it);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class InputIterator>
|
||||
@@ -945,12 +1021,116 @@ private:
|
||||
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
std::pair<final_node_type*,bool> external_splice(
|
||||
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i,
|
||||
boost::true_type /* copy-constructible value */)
|
||||
{
|
||||
if(get_allocator()==x.get_allocator()){
|
||||
return external_splice(position,x,i,boost::false_type());
|
||||
}
|
||||
else{
|
||||
/* backwards compatibility with old, non-transfer-based splice */
|
||||
|
||||
std::pair<iterator,bool> p=insert(position,*i);
|
||||
if(p.second)x.erase(i);
|
||||
return std::pair<final_node_type*,bool>(
|
||||
static_cast<final_node_type*>(p.first.get_node()),p.second);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
std::pair<final_node_type*,bool> external_splice(
|
||||
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i,
|
||||
boost::false_type /* copy-constructible value */)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
||||
std::pair<final_node_type*,bool> p=this->final_transfer_(
|
||||
x,static_cast<final_node_type*>(i.get_node()));
|
||||
if(p.second&&position.get_node()!=header()){
|
||||
relink(position.get_node(),p.first);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
void internal_splice(iterator position,Iterator first,Iterator last)
|
||||
{
|
||||
index_node_type* pn=position.get_node();
|
||||
while(first!=last){
|
||||
relink(pn,static_cast<index_node_type*>((first++).get_node()));
|
||||
}
|
||||
}
|
||||
|
||||
void internal_splice(iterator position,iterator first,iterator last)
|
||||
{
|
||||
index_node_type* pn=position.get_node();
|
||||
index_node_type* fn=static_cast<index_node_type*>(first.get_node());
|
||||
index_node_type* ln=static_cast<index_node_type*>(last.get_node());
|
||||
if(pn!=ln)relink(pn,fn,ln);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
void external_splice(
|
||||
iterator position,Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last,
|
||||
boost::true_type /* copy-constructible value */)
|
||||
{
|
||||
if(get_allocator()==x.get_allocator()){
|
||||
external_splice(position,x,first,last,boost::false_type());
|
||||
}
|
||||
else{
|
||||
/* backwards compatibility with old, non-transfer-based splice */
|
||||
|
||||
while(first!=last){
|
||||
if(insert(position,*first).second)first=x.erase(first);
|
||||
else ++first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
void external_splice(
|
||||
iterator position,Index& x,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||
BOOST_DEDUCED_TYPENAME Index::iterator last,
|
||||
boost::false_type /* copy-constructible value */)
|
||||
{
|
||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
||||
if(position==end()){
|
||||
this->final_transfer_range_(x,first,last);
|
||||
}
|
||||
else{
|
||||
iterator first_to_relink=end();
|
||||
--first_to_relink;
|
||||
BOOST_TRY{
|
||||
this->final_transfer_range_(x,first,last);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
++first_to_relink;
|
||||
relink(position.get_node(),first_to_relink.get_node(),header());
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
++first_to_relink;
|
||||
relink(position.get_node(),first_to_relink.get_node(),header());
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
||||
safe_container safe;
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
||||
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
||||
#pragma parse_mfunc_templ reset
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop) /* C4355 */
|
||||
#endif
|
||||
|
||||
/* comparison */
|
||||
|
||||
template<
|
||||
@@ -1057,12 +1237,18 @@ struct sequenced
|
||||
|
||||
/* Boost.Foreach compatibility */
|
||||
|
||||
namespace boost{
|
||||
namespace foreach{
|
||||
|
||||
template<typename>
|
||||
struct is_noncopyable;
|
||||
|
||||
template<typename SuperMeta,typename TagList>
|
||||
inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
||||
boost::multi_index::detail::sequenced_index<SuperMeta,TagList>*&,
|
||||
boost_foreach_argument_dependent_lookup_hack)
|
||||
{
|
||||
return 0;
|
||||
struct is_noncopyable<
|
||||
boost::multi_index::detail::sequenced_index<SuperMeta,TagList>
|
||||
>:boost::mpl::true_{};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
|
||||
|
||||
Reference in New Issue
Block a user