mirror of
https://github.com/boostorg/container.git
synced 2025-08-03 06:24:26 +02:00
Added support for configurable tree-based associative containers. In addition to RB trees, AVL, Scapegoat and Splay trees are experimentally supported.
This commit is contained in:
@@ -290,6 +290,15 @@ template<class BoostClass, class StdClass>
|
||||
void launch_tests(const char *BoostContName, const char *StdContName)
|
||||
{
|
||||
try {
|
||||
std::cout << "**********************************************" << '\n';
|
||||
std::cout << "**********************************************" << '\n';
|
||||
std::cout << "**********************************************" << '\n';
|
||||
std::cout << '\n';
|
||||
std::cout << BoostContName << " .VS " << StdContName << '\n';
|
||||
std::cout << '\n';
|
||||
std::cout << "**********************************************" << '\n';
|
||||
std::cout << "**********************************************" << '\n';
|
||||
std::cout << "**********************************************" << '\n' << std::endl;
|
||||
fill_ranges();
|
||||
{
|
||||
std::cout << "Construct benchmark:" << BoostContName << std::endl;
|
||||
@@ -333,20 +342,36 @@ void launch_tests(const char *BoostContName, const char *StdContName)
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
//set vs std::set
|
||||
launch_tests< boost::container::set<int> , std::set<int> >
|
||||
("boost::container::set<int>", "std::set<int>");
|
||||
launch_tests< set<int> , std::set<int> >
|
||||
("set<int>", "std::set<int>");
|
||||
//set(RB) vs set(AVL)
|
||||
launch_tests< set<int>, set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<avl_tree> >::type > >
|
||||
("set<int>(RB)", "set<int>(AVL)");
|
||||
//set(RB) vs set(SG)
|
||||
launch_tests< set<int>, set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<scapegoat_tree> >::type > >
|
||||
("set<int>(RB)", "set<int>(SG)");
|
||||
launch_tests< set<int>, set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<splay_tree> >::type > >
|
||||
("set<int>(RB)", "set<int>(SP)");
|
||||
//set(sizeopt) vs set(!sizeopt)
|
||||
launch_tests< set<int>, set<int, std::less<int>, std::allocator<int>, tree_assoc_options< optimize_size<false> >::type > >
|
||||
("set<int>(sizeopt=true)", "set<int>(sizeopt=false)");
|
||||
//set(AVL,sizeopt) vs set(AVL,!sizeopt)
|
||||
launch_tests< set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<avl_tree> >::type >
|
||||
, set<int, std::less<int>, std::allocator<int>, tree_assoc_options< tree_type<avl_tree>, optimize_size<false> >::type > >
|
||||
("set<int>(AVL,sizeopt=true)", "set<int>(AVL,sizeopt=false)");
|
||||
//set vs set<..., allocator_v2>
|
||||
launch_tests< boost::container::set<int> , boost::container::set<int, std::less<int>, boost::container::allocator<int> > >
|
||||
("boost::container::set<int>", "boost::container::set<int, ..., boost::container::allocator<int>" );
|
||||
launch_tests< set<int> , set<int, std::less<int>, allocator<int> > >
|
||||
("set<int>", "set<int, ..., allocator<int>" );
|
||||
//multiset vs std::set
|
||||
launch_tests< boost::container::multiset<int> , std::multiset<int> >
|
||||
("boost::container::multiset<int>", "std::multiset<int>");
|
||||
launch_tests< multiset<int> , std::multiset<int> >
|
||||
("multiset<int>", "std::multiset<int>");
|
||||
//flat_set vs set
|
||||
launch_tests< boost::container::flat_set<int> , boost::container::set<int> >
|
||||
("boost::container::flat_set<int>", "boost::container::set<int>");
|
||||
launch_tests< flat_set<int> , set<int> >
|
||||
("flat_set<int>", "set<int>");
|
||||
//flat_multiset vs multiset
|
||||
launch_tests< boost::container::flat_multiset<int> , boost::container::multiset<int> >
|
||||
("boost::container::flat_multiset<int>", "boost::container::multiset<int>");
|
||||
launch_tests< flat_multiset<int> , multiset<int> >
|
||||
("flat_multiset<int>", "multiset<int>");
|
||||
return 0;
|
||||
}
|
||||
|
@@ -35,7 +35,9 @@ doxygen autodoc
|
||||
\"BOOST_RV_REF_BEG=\" \\
|
||||
\"BOOST_RV_REF_END=&&\" \\
|
||||
\"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\
|
||||
\"BOOST_FWD_REF(a)=a &&\""
|
||||
\"BOOST_FWD_REF(a)=a &&\" \\
|
||||
\"BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) = template<TYPE VALUE> struct OPTION_NAME{};\" \\
|
||||
\"BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) = template<class TYPE> struct OPTION_NAME{};\" "
|
||||
<xsl:param>"boost.doxygen.reftitle=Boost.Container Header Reference"
|
||||
;
|
||||
|
||||
|
@@ -549,6 +549,46 @@ times.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:configurable_tree_based_associative_containers Configurable tree-based associative ordered containers]
|
||||
|
||||
[classref boost::container::set set], [classref boost::container::multiset multiset],
|
||||
[classref boost::container::map map] and [classref boost::container::multimap multimap] associative containers
|
||||
are implemented as binary search trees which offer the needed complexity and stability guarantees required by the
|
||||
C++ standard for associative containers.
|
||||
|
||||
[*Boost.Container] offers the possibility to configure at compile time some parameters of the binary search tree
|
||||
implementation. This configuration is passed as the last template parameter and defined using the utility class
|
||||
[classref boost::container::tree_assoc_options tree_assoc_options].
|
||||
|
||||
The following parameters can be configured:
|
||||
|
||||
* The underlying [*tree implementation] type ([classref boost::container::tree_type tree_type]).
|
||||
By default these containers use a red-black tree but the user can use other tree types:
|
||||
* [@http://en.wikipedia.org/wiki/Red%E2%80%93black_tree Red-Black Tree]
|
||||
* [@http://en.wikipedia.org/wiki/Avl_trees AVL tree]
|
||||
* [@http://en.wikipedia.org/wiki/Scapegoat_tree Scapegoat tree]. In this case Insertion and Deletion
|
||||
are amortized O(log n) instead of O(log n).
|
||||
* [@http://en.wikipedia.org/wiki/Splay_tree Splay tree]. In this case Searches, Insertions and Deletions
|
||||
are amortized O(log n) instead of O(log n).
|
||||
|
||||
* Whether the [*size saving] mechanisms are used to implement the tree nodes
|
||||
([classref boost::container::optimize_size optimize_size]). By default this option is activated and is only
|
||||
meaningful to red-black and avl trees (in other cases, this option will be ignored).
|
||||
This option will try to put rebalancing metadata inside the "parent" pointer of the node if the pointer
|
||||
type has enough alignment. Usually, due to alignment issues, the metadata uses the size of a pointer yielding
|
||||
to four pointer size overhead per node, whereas activating this option usually leads to 3 pointer size overhead.
|
||||
Although some mask operations must be performed to extract
|
||||
data from this special "parent" pointer, in several systems this option also improves performance due to the
|
||||
improved cache usage produced by the node size reduction.
|
||||
|
||||
See the following example to see how [classref boost::container::tree_assoc_options tree_assoc_options] can be
|
||||
used to customize these containers:
|
||||
|
||||
[import ../example/doc_custom_tree.cpp]
|
||||
[doc_custom_tree]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:constant_time_range_splice Constant-time range splice for `(s)list`]
|
||||
|
||||
In the first C++ standard `list::size()` was not required to be constant-time,
|
||||
@@ -637,6 +677,11 @@ The following extended allocators are provided:
|
||||
to the system. The overhead can be very low (< 5% for small nodes) and it's nearly as fast as [classref boost::container::node_allocator node_allocator].
|
||||
It's also suitable for node containers.
|
||||
|
||||
Use them simply specifying the new allocator in the corresponding template argument of your favourite container:
|
||||
|
||||
[import ../example/doc_extended_allocators.cpp]
|
||||
[doc_extended_allocators]
|
||||
|
||||
[endsect]
|
||||
|
||||
[/
|
||||
@@ -880,6 +925,11 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
|
||||
* Added DlMalloc-based [link container.extended_functionality.extended_allocators Extended Allocators].
|
||||
|
||||
* [link container.extended_functionality.configurable_tree_based_associative_containers Improved configurability]
|
||||
of tree-based ordered associative containers. AVL, Scapegoat and Splay trees are now available
|
||||
to implement [classref boost::container::set set], [classref boost::container::multiset multiset],
|
||||
[classref boost::container::map map] and [classref boost::container::multimap multimap].
|
||||
|
||||
* Fixed bugs:
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9338 #9338: ['"VS2005 compiler errors in swap() definition after including container/memory_util.hpp"]].
|
||||
|
||||
|
@@ -21,7 +21,7 @@ rule test_all
|
||||
|
||||
for local fileb in [ glob doc_*.cpp ]
|
||||
{
|
||||
all_rules += [ run $(fileb)
|
||||
all_rules += [ run $(fileb) /boost/container//boost_container /boost/timer//boost_timer
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
|
64
example/doc_custom_tree.cpp
Normal file
64
example/doc_custom_tree.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
//[doc_custom_tree
|
||||
#include <boost/container/set.hpp>
|
||||
#include <cassert>
|
||||
|
||||
int main ()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
//First define several options
|
||||
//
|
||||
|
||||
//This option specifies an AVL tree based associative container
|
||||
typedef tree_assoc_options< tree_type<avl_tree> >::type AVLTree;
|
||||
|
||||
//This option specifies an AVL tree based associative container
|
||||
//disabling node size optimization.
|
||||
typedef tree_assoc_options< tree_type<avl_tree>
|
||||
, optimize_size<false> >::type AVLTreeNoSizeOpt;
|
||||
|
||||
//This option specifies an Splay tree based associative container
|
||||
typedef tree_assoc_options< tree_type<splay_tree> >::type SplayTree;
|
||||
|
||||
//Now define new tree-based associative containers
|
||||
//
|
||||
|
||||
//AVLTree based set container
|
||||
typedef set<int, std::less<int>, std::allocator<int>, AVLTree> AvlSet;
|
||||
|
||||
//AVLTree based set container without size optimization
|
||||
typedef set<int, std::less<int>, std::allocator<int>, AVLTreeNoSizeOpt> AvlSetNoSizeOpt;
|
||||
|
||||
//Splay tree based multiset container
|
||||
typedef multiset<int, std::less<int>, std::allocator<int>, SplayTree> SplayMultiset;
|
||||
|
||||
//Use them
|
||||
//
|
||||
AvlSet avl_set;
|
||||
avl_set.insert(0);
|
||||
assert(avl_set.find(0) != avl_set.end());
|
||||
|
||||
AvlSetNoSizeOpt avl_set_no_szopt;
|
||||
avl_set_no_szopt.insert(1);
|
||||
avl_set_no_szopt.insert(1);
|
||||
assert(avl_set_no_szopt.count(1) == 1);
|
||||
|
||||
SplayMultiset splay_mset;
|
||||
splay_mset.insert(2);
|
||||
splay_mset.insert(2);
|
||||
assert(splay_mset.count(2) == 2);
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
#include <boost/container/detail/config_end.hpp>
|
54
example/doc_extended_allocators.cpp
Normal file
54
example/doc_extended_allocators.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
//[doc_extended_allocators
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/container/list.hpp>
|
||||
#include <boost/container/set.hpp>
|
||||
|
||||
//"allocator" is a general purpose allocator that can reallocate
|
||||
//memory, something useful for vector and flat associative containers
|
||||
#include <boost/container/allocator.hpp>
|
||||
|
||||
//"adaptive_pool" is a node allocator, specially suited for
|
||||
//node-based containers
|
||||
#include <boost/container/adaptive_pool.hpp>
|
||||
|
||||
int main ()
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
//A vector that can reallocate memory to implement faster insertions
|
||||
vector<int, allocator<int> > extended_alloc_vector;
|
||||
|
||||
//A flat set that can reallocate memory to implement faster insertions
|
||||
flat_set<int, std::less<int>, allocator<int> > extended_alloc_flat_set;
|
||||
|
||||
//A list that can manages nodes to implement faster
|
||||
//range insertions and deletions
|
||||
list<int, adaptive_pool<int> > extended_alloc_list;
|
||||
|
||||
//A set that can recycle nodes to implement faster
|
||||
//range insertions and deletions
|
||||
set<int, std::less<int>, adaptive_pool<int> > extended_alloc_set;
|
||||
|
||||
//Now user them as always
|
||||
extended_alloc_vector.push_back(0);
|
||||
extended_alloc_flat_set.insert(0);
|
||||
extended_alloc_list.push_back(0);
|
||||
extended_alloc_set.insert(0);
|
||||
|
||||
//...
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
#include <boost/container/detail/config_end.hpp>
|
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
//! \file
|
||||
//! This header file forward declares the following classes:
|
||||
//! This header file forward declares the following containers:
|
||||
//! - boost::container::vector
|
||||
//! - boost::container::stable_vector
|
||||
//! - boost::container::static_vector
|
||||
@@ -33,11 +33,13 @@
|
||||
//! - boost::container::basic_string
|
||||
//! - boost::container::string
|
||||
//! - boost::container::wstring
|
||||
//!
|
||||
//! It forward declares the following allocators:
|
||||
//! - boost::container::allocator
|
||||
//! - boost::container::node_allocator
|
||||
//! - boost::container::adaptive_pool
|
||||
//!
|
||||
//! and defines the following types:
|
||||
//! And finally it defines the following types
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Standard predeclarations
|
||||
@@ -74,7 +76,7 @@ namespace container {
|
||||
|
||||
//! Enumeration used to configure ordered associative containers
|
||||
//! with a concrete tree implementation.
|
||||
enum tree_type
|
||||
enum tree_type_enum
|
||||
{
|
||||
red_black_tree,
|
||||
avl_tree,
|
||||
@@ -107,30 +109,35 @@ template <class T
|
||||
,class Allocator = std::allocator<T> >
|
||||
class slist;
|
||||
|
||||
template<tree_type_enum TreeType, bool OptimizeSize>
|
||||
struct tree_opt;
|
||||
|
||||
typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
|
||||
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key>
|
||||
,tree_type = red_black_tree >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class set;
|
||||
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<Key>
|
||||
,tree_type = red_black_tree >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class multiset;
|
||||
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> >
|
||||
,tree_type = red_black_tree >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class map;
|
||||
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = std::allocator<std::pair<const Key, T> >
|
||||
,tree_type = red_black_tree >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class multimap;
|
||||
|
||||
template <class Key
|
||||
@@ -198,6 +205,13 @@ template
|
||||
, std::size_t Version = 2>
|
||||
class node_allocator;
|
||||
|
||||
#else
|
||||
|
||||
//! Default options for tree-based associative containers
|
||||
//! - tree_type<red_black_tree>
|
||||
//! - optimize_size<true>
|
||||
typedef implementation_defined tree_assoc_defaults;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/options.hpp>
|
||||
|
||||
//
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/rbtree.hpp>
|
||||
@@ -90,13 +92,44 @@ struct tree_value_compare
|
||||
{ return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
};
|
||||
|
||||
template<class VoidPointer>
|
||||
struct intrusive_tree_hook
|
||||
template<class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct intrusive_tree_hook;
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::red_black_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
, container_detail::bi::optimize_size<true>
|
||||
, container_detail::bi::optimize_size<OptimizeSize>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::avl_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_avl_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
, container_detail::bi::optimize_size<OptimizeSize>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::scapegoat_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_bs_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class VoidPointer, bool OptimizeSize>
|
||||
struct intrusive_tree_hook<VoidPointer, boost::container::splay_tree, OptimizeSize>
|
||||
{
|
||||
typedef typename container_detail::bi::make_bs_set_base_hook
|
||||
< container_detail::bi::void_pointer<VoidPointer>
|
||||
, container_detail::bi::link_mode<container_detail::bi::normal_link>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
@@ -114,23 +147,23 @@ struct tree_internal_data_type< std::pair<T1, T2> >
|
||||
typedef pair<T1, T2> type;
|
||||
};
|
||||
|
||||
|
||||
//The node to be store in the tree
|
||||
template <class T, class VoidPointer>
|
||||
template <class T, class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct tree_node
|
||||
: public intrusive_tree_hook<VoidPointer>::type
|
||||
: public intrusive_tree_hook<VoidPointer, tree_type_value, OptimizeSize>::type
|
||||
{
|
||||
private:
|
||||
//BOOST_COPYABLE_AND_MOVABLE(tree_node)
|
||||
tree_node();
|
||||
|
||||
public:
|
||||
typedef typename intrusive_tree_hook<VoidPointer>::type hook_type;
|
||||
|
||||
typedef typename intrusive_tree_hook
|
||||
<VoidPointer, tree_type_value, OptimizeSize>::type hook_type;
|
||||
typedef T value_type;
|
||||
typedef typename tree_internal_data_type<T>::type internal_type;
|
||||
typedef typename tree_internal_data_type<T>::type internal_type;
|
||||
|
||||
typedef tree_node<T, VoidPointer> node_type;
|
||||
typedef tree_node< T, VoidPointer
|
||||
, tree_type_value, OptimizeSize> node_type;
|
||||
|
||||
T &get_data()
|
||||
{
|
||||
@@ -215,12 +248,67 @@ class push_back_functor
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template<class A, class ValueCompare, boost::container::tree_type tree_type_value>
|
||||
struct intrusive_tree_type;
|
||||
template< class NodeType, class NodeCompareType
|
||||
, class SizeType, class HookType
|
||||
, boost::container::tree_type_enum tree_type_value>
|
||||
struct intrusive_tree_dispatch;
|
||||
|
||||
template<class A, class ValueCompare>
|
||||
struct intrusive_tree_type<A, ValueCompare, boost::container::red_black_tree>
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::red_black_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_rbtree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::avl_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_avltree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::scapegoat_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_sgtree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeType, class NodeCompareType, class SizeType, class HookType>
|
||||
struct intrusive_tree_dispatch
|
||||
<NodeType, NodeCompareType, SizeType, HookType, boost::container::splay_tree>
|
||||
{
|
||||
typedef typename container_detail::bi::make_splaytree
|
||||
<NodeType
|
||||
,container_detail::bi::compare<NodeCompareType>
|
||||
,container_detail::bi::base_hook<HookType>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<SizeType>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class A, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
|
||||
struct intrusive_tree_type
|
||||
{
|
||||
private:
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::value_type value_type;
|
||||
typedef typename boost::container::
|
||||
@@ -228,16 +316,49 @@ struct intrusive_tree_type<A, ValueCompare, boost::container::red_black_tree>
|
||||
typedef typename boost::container::
|
||||
allocator_traits<A>::size_type size_type;
|
||||
typedef typename container_detail::tree_node
|
||||
<value_type, void_pointer> node_type;
|
||||
< value_type, void_pointer
|
||||
, tree_type_value, OptimizeSize> node_type;
|
||||
typedef node_compare<ValueCompare, node_type> node_compare_type;
|
||||
typedef typename container_detail::bi::make_rbtree
|
||||
<node_type
|
||||
,container_detail::bi::compare<node_compare_type>
|
||||
,container_detail::bi::base_hook<typename intrusive_tree_hook<void_pointer>::type>
|
||||
,container_detail::bi::constant_time_size<true>
|
||||
,container_detail::bi::size_type<size_type>
|
||||
>::type container_type;
|
||||
typedef container_type type ;
|
||||
//Deducing the hook type from node_type (e.g. node_type::hook_type) would
|
||||
//provoke an early instantiation of node_type that could ruin recursive
|
||||
//tree definitions, so retype the complete type to avoid any problem.
|
||||
typedef typename intrusive_tree_hook
|
||||
<void_pointer, tree_type_value
|
||||
, OptimizeSize>::type hook_type;
|
||||
public:
|
||||
typedef typename intrusive_tree_dispatch
|
||||
< node_type, node_compare_type
|
||||
, size_type, hook_type
|
||||
, tree_type_value>::type type;
|
||||
};
|
||||
|
||||
//Trait to detect manually rebalanceable tree types
|
||||
template<boost::container::tree_type_enum tree_type_value>
|
||||
struct is_manually_balanceable
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<> struct is_manually_balanceable<red_black_tree>
|
||||
{ static const bool value = false; };
|
||||
|
||||
template<> struct is_manually_balanceable<avl_tree>
|
||||
{ static const bool value = false; };
|
||||
|
||||
//Proxy traits to implement different operations depending on the
|
||||
//is_manually_balanceable<>::value
|
||||
template< boost::container::tree_type_enum tree_type_value
|
||||
, bool IsManuallyRebalanceable = is_manually_balanceable<tree_type_value>::value>
|
||||
struct intrusive_tree_proxy
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &) {}
|
||||
};
|
||||
|
||||
template<boost::container::tree_type_enum tree_type_value>
|
||||
struct intrusive_tree_proxy<tree_type_value, true>
|
||||
{
|
||||
template<class Icont>
|
||||
static void rebalance(Icont &c)
|
||||
{ c.rebalance(); }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
@@ -326,24 +447,25 @@ struct key_node_compare
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class KeyCompare, class A,
|
||||
boost::container::tree_type tree_type_value>
|
||||
class Options>
|
||||
class tree
|
||||
: protected container_detail::node_alloc_holder
|
||||
< A
|
||||
, typename container_detail::intrusive_tree_type
|
||||
< A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue> //ValComp
|
||||
, tree_type_value>::type
|
||||
, Options::tree_type, Options::optimize_size>::type
|
||||
>
|
||||
{
|
||||
typedef tree_value_compare
|
||||
<Key, Value, KeyCompare, KeyOfValue> ValComp;
|
||||
typedef typename container_detail::intrusive_tree_type
|
||||
< A, ValComp, tree_type_value>::type Icont;
|
||||
< A, ValComp, Options::tree_type
|
||||
, Options::optimize_size>::type Icont;
|
||||
typedef container_detail::node_alloc_holder
|
||||
<A, Icont> AllocHolder;
|
||||
typedef typename AllocHolder::NodePtr NodePtr;
|
||||
typedef tree < Key, Value, KeyOfValue
|
||||
, KeyCompare, A, tree_type_value> ThisType;
|
||||
, KeyCompare, A, Options> ThisType;
|
||||
typedef typename AllocHolder::NodeAlloc NodeAlloc;
|
||||
typedef typename AllocHolder::ValAlloc ValAlloc;
|
||||
typedef typename AllocHolder::Node Node;
|
||||
@@ -353,6 +475,7 @@ class tree
|
||||
typedef typename AllocHolder::allocator_v1 allocator_v1;
|
||||
typedef typename AllocHolder::allocator_v2 allocator_v2;
|
||||
typedef typename AllocHolder::alloc_version alloc_version;
|
||||
typedef intrusive_tree_proxy<Options::tree_type> intrusive_tree_proxy_t;
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(tree)
|
||||
|
||||
@@ -985,6 +1108,9 @@ class tree
|
||||
(const_iterator(ret.first), const_iterator(ret.second));
|
||||
}
|
||||
|
||||
void rebalance()
|
||||
{ intrusive_tree_proxy_t::rebalance(this->icont()); }
|
||||
|
||||
friend bool operator==(const tree& x, const tree& y)
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
|
@@ -39,22 +39,26 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A map is a kind of associative container that supports unique keys (contains at
|
||||
//! most one of each key value) and provides for fast retrieval of values of another
|
||||
//! type T based on the keys. The map class supports bidirectional iterators.
|
||||
//!
|
||||
//! A map satisfies all of the requirements of a container and of a reversible
|
||||
//! container and of an associative container. For a
|
||||
//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
|
||||
//! container and of an associative container. The <code>value_type</code> stored
|
||||
//! by this container is the value_type is std::pair<const Key, T>.
|
||||
//!
|
||||
//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//!
|
||||
//! Allocator is the allocator to allocate the value_types
|
||||
//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > >
|
||||
//! \tparam Key is the key_type of the map
|
||||
//! \tparam Value is the <code>mapped_type</code>
|
||||
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
||||
//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
|
||||
//! \tparam MapOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template < class Key, class T, class Compare = std::less<Key>
|
||||
, class Allocator = std::allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults >
|
||||
#else
|
||||
template <class Key, class T, class Compare, class Allocator, tree_type tree_type_value>
|
||||
template <class Key, class T, class Compare, class Allocator, class MapOptions>
|
||||
#endif
|
||||
class map
|
||||
{
|
||||
@@ -64,7 +68,7 @@ class map
|
||||
|
||||
typedef std::pair<const Key, T> value_type_impl;
|
||||
typedef container_detail::tree
|
||||
<Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator, tree_type_value> tree_t;
|
||||
<Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator, MapOptions> tree_t;
|
||||
typedef container_detail::pair <Key, T> movable_value_type_impl;
|
||||
typedef container_detail::tree_value_compare
|
||||
< Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
|
||||
@@ -744,26 +748,53 @@ class map
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return m_tree.equal_range(x); }
|
||||
|
||||
//! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear
|
||||
void rebalance()
|
||||
{ return m_tree.rebalance(); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const map& x, const map& y)
|
||||
{ return x.m_tree == y.m_tree; }
|
||||
|
||||
friend bool operator<(const map& x, const map& y)
|
||||
{ return x.m_tree < y.m_tree; }
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const map& x, const map& y)
|
||||
{ return !(x == y); }
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const map& x, const map& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const map& x, const map& y)
|
||||
{ return y < x; }
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const map& x, const map& y)
|
||||
{ return !(y < x); }
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const map& x, const map& y)
|
||||
{ return !(x < y); }
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(map& x, map& y)
|
||||
{ x.swap(y); }
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
@@ -814,23 +845,27 @@ namespace container {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A multimap is a kind of associative container that supports equivalent keys
|
||||
//! (possibly containing multiple copies of the same key value) and provides for
|
||||
//! fast retrieval of values of another type T based on the keys. The multimap class
|
||||
//! supports bidirectional iterators.
|
||||
//!
|
||||
//! A multimap satisfies all of the requirements of a container and of a reversible
|
||||
//! container and of an associative container. For a
|
||||
//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
|
||||
//! container and of an associative container. The <code>value_type</code> stored
|
||||
//! by this container is the value_type is std::pair<const Key, T>.
|
||||
//!
|
||||
//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//!
|
||||
//! Allocator is the allocator to allocate the value_types
|
||||
//!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>).
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > >
|
||||
//! \tparam Key is the key_type of the map
|
||||
//! \tparam Value is the <code>mapped_type</code>
|
||||
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
||||
//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
|
||||
//! \tparam MultiMapOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template < class Key, class T, class Compare = std::less<Key>
|
||||
, class Allocator = std::allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults>
|
||||
#else
|
||||
template <class Key, class T, class Compare, class Allocator, tree_type tree_type_value>
|
||||
template <class Key, class T, class Compare, class Allocator, class MultiMapOptions>
|
||||
#endif
|
||||
class multimap
|
||||
{
|
||||
@@ -840,7 +875,7 @@ class multimap
|
||||
|
||||
typedef std::pair<const Key, T> value_type_impl;
|
||||
typedef container_detail::tree
|
||||
<Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator, tree_type_value> tree_t;
|
||||
<Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator, MultiMapOptions> tree_t;
|
||||
typedef container_detail::pair <Key, T> movable_value_type_impl;
|
||||
typedef container_detail::tree_value_compare
|
||||
< Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
|
||||
@@ -1424,24 +1459,51 @@ class multimap
|
||||
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
|
||||
{ return m_tree.equal_range(x); }
|
||||
|
||||
//! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear
|
||||
void rebalance()
|
||||
{ return m_tree.rebalance(); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const multimap& x, const multimap& y)
|
||||
{ return x.m_tree == y.m_tree; }
|
||||
|
||||
friend bool operator<(const multimap& x, const multimap& y)
|
||||
{ return x.m_tree < y.m_tree; }
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const multimap& x, const multimap& y)
|
||||
{ return !(x == y); }
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const multimap& x, const multimap& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const multimap& x, const multimap& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const multimap& x, const multimap& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const multimap& x, const multimap& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(multimap& x, multimap& y)
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
72
include/boost/container/options.hpp
Normal file
72
include/boost/container/options.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
||||
#define BOOST_CONTAINER_OPTIONS_HPP
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/intrusive/pack_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<tree_type_enum TreeType, bool OptimizeSize>
|
||||
struct tree_opt
|
||||
{
|
||||
static const boost::container::tree_type_enum tree_type = TreeType;
|
||||
static const bool optimize_size = OptimizeSize;
|
||||
};
|
||||
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//!This option setter specifies the underlying tree type
|
||||
//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type)
|
||||
|
||||
//!This option setter specifies if node size is optimized
|
||||
//!storing rebalancing data masked into pointers for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
|
||||
|
||||
//! Helper metafunction to combine options into a single type to be used
|
||||
//! by \c boost::container::set, \c boost::container::multiset
|
||||
//! \c boost::container::map and \c boost::container::multimap.
|
||||
//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct tree_assoc_options
|
||||
{
|
||||
/// @cond
|
||||
typedef typename ::boost::intrusive::pack_options
|
||||
< tree_assoc_defaults,
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
typedef tree_opt<packed_options::tree_type, packed_options::optimize_size> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
@@ -35,6 +35,8 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A set is a kind of associative container that supports unique keys (contains at
|
||||
//! most one of each key value) and provides for fast retrieval of the keys themselves.
|
||||
//! Class set supports bidirectional iterators.
|
||||
@@ -42,10 +44,14 @@ namespace container {
|
||||
//! A set satisfies all of the requirements of a container and of a reversible container
|
||||
//! , and of an associative container. A set also provides most operations described in
|
||||
//! for unique keys.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
|
||||
//!
|
||||
//! \tparam Key is the type to be inserted in the set, which is also the key_type
|
||||
//! \tparam Compare is the comparison functor used to order keys
|
||||
//! \tparam Allocator is the allocator to be used to allocate memory for this container
|
||||
//! \tparam SetOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>, class SetOptions = tree_assoc_defaults >
|
||||
#else
|
||||
template <class Key, class Compare, class Allocator, tree_type tree_type_value>
|
||||
template <class Key, class Compare, class Allocator, class SetOptions>
|
||||
#endif
|
||||
class set
|
||||
{
|
||||
@@ -53,7 +59,7 @@ class set
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(set)
|
||||
typedef container_detail::tree
|
||||
< Key, Key, container_detail::identity<Key>, Compare, Allocator, tree_type_value> tree_t;
|
||||
< Key, Key, container_detail::identity<Key>, Compare, Allocator, SetOptions> tree_t;
|
||||
tree_t m_tree; // red-black tree representing set
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
@@ -589,24 +595,51 @@ class set
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
|
||||
{ return m_tree.equal_range(x); }
|
||||
|
||||
//! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear
|
||||
void rebalance()
|
||||
{ return m_tree.rebalance(); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const set& x, const set& y)
|
||||
{ return x.m_tree == y.m_tree; }
|
||||
|
||||
friend bool operator<(const set& x, const set& y)
|
||||
{ return x.m_tree < y.m_tree; }
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const set& x, const set& y)
|
||||
{ return !(x == y); }
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const set& x, const set& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const set& x, const set& y)
|
||||
{ return y < x; }
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const set& x, const set& y)
|
||||
{ return !(y < x); }
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const set& x, const set& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(set& x, set& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
@@ -628,8 +661,8 @@ class set
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class C, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::set<Key, C, Allocator> >
|
||||
template <class Key, class C, class SetOptions, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::set<Key, C, Allocator, SetOptions> >
|
||||
{
|
||||
static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
|
||||
};
|
||||
@@ -638,6 +671,8 @@ namespace container {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A multiset is a kind of associative container that supports equivalent keys
|
||||
//! (possibly contains multiple copies of the same key value) and provides for
|
||||
//! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
|
||||
@@ -645,10 +680,14 @@ namespace container {
|
||||
//! A multiset satisfies all of the requirements of a container and of a reversible
|
||||
//! container, and of an associative container). multiset also provides most operations
|
||||
//! described for duplicate keys.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
|
||||
//!
|
||||
//! \tparam Key is the type to be inserted in the set, which is also the key_type
|
||||
//! \tparam Compare is the comparison functor used to order keys
|
||||
//! \tparam Allocator is the allocator to be used to allocate memory for this container
|
||||
//! \tparam MultiSetOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>, class MultiSetOptions = tree_assoc_defaults >
|
||||
#else
|
||||
template <class Key, class Compare, class Allocator, tree_type tree_type_value>
|
||||
template <class Key, class Compare, class Allocator, class MultiSetOptions>
|
||||
#endif
|
||||
class multiset
|
||||
{
|
||||
@@ -656,7 +695,7 @@ class multiset
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(multiset)
|
||||
typedef container_detail::tree
|
||||
<Key, Key,container_detail::identity<Key>, Compare, Allocator, tree_type_value> tree_t;
|
||||
<Key, Key,container_detail::identity<Key>, Compare, Allocator, MultiSetOptions> tree_t;
|
||||
tree_t m_tree; // red-black tree representing multiset
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
@@ -1182,24 +1221,51 @@ class multiset
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
|
||||
{ return m_tree.equal_range(x); }
|
||||
|
||||
//! <b>Effects</b>: Rebalances the tree. It's a no-op for Red-Black and AVL trees.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear
|
||||
void rebalance()
|
||||
{ return m_tree.rebalance(); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const multiset& x, const multiset& y)
|
||||
{ return x.m_tree == y.m_tree; }
|
||||
|
||||
friend bool operator<(const multiset& x, const multiset& y)
|
||||
{ return x.m_tree < y.m_tree; }
|
||||
{ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const multiset& x, const multiset& y)
|
||||
{ return !(x == y); }
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const multiset& x, const multiset& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const multiset& x, const multiset& y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const multiset& x, const multiset& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const multiset& x, const multiset& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(multiset& x, multiset& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
@@ -1222,8 +1288,8 @@ class multiset
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class C, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::multiset<Key, C, Allocator> >
|
||||
template <class Key, class C, class Allocator, class MultiSetOptions>
|
||||
struct has_trivial_destructor_after_move<boost::container::multiset<Key, C, Allocator, MultiSetOptions> >
|
||||
{
|
||||
static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
|
||||
};
|
||||
|
@@ -1423,6 +1423,9 @@ class slist
|
||||
void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
|
||||
{ this->splice(p, static_cast<slist&>(x), first, last); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are equal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator==(const slist& x, const slist& y)
|
||||
{
|
||||
if(x.size() != y.size()){
|
||||
@@ -1440,26 +1443,41 @@ class slist
|
||||
return i1 == end1;
|
||||
}
|
||||
|
||||
friend bool operator<(const slist& x, const slist& y)
|
||||
{
|
||||
return std::lexicographical_compare
|
||||
(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns true if x and y are unequal
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator!=(const slist& x, const slist& y)
|
||||
{ return !(x == y); }
|
||||
{ return !(x == y); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<(const slist& x, const slist& y)
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>(const slist& x, const slist& y)
|
||||
{ return y < x; }
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or less than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator<=(const slist& x, const slist& y)
|
||||
{ return !(y < x); }
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Effects</b>: Returns true if x is equal or greater than y
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of elements in the container.
|
||||
friend bool operator>=(const slist& x, const slist& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Effects</b>: x.swap(y)
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
friend void swap(slist& x, slist& y)
|
||||
{ x.swap(y); }
|
||||
{ x.swap(y); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
@@ -131,6 +131,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scoped_allocator_usage_test
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_custom_tree", "doc_custom_tree.vcproj", "{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_extended_allocators", "doc_extended_allocators.vcproj", "{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -271,6 +279,14 @@ Global
|
||||
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
|
||||
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
|
||||
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
|
||||
{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}.Debug.ActiveCfg = Debug|Win32
|
||||
{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}.Debug.Build.0 = Debug|Win32
|
||||
{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}.Release.ActiveCfg = Release|Win32
|
||||
{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}.Release.Build.0 = Release|Win32
|
||||
{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}.Debug.ActiveCfg = Debug|Win32
|
||||
{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}.Debug.Build.0 = Debug|Win32
|
||||
{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}.Release.ActiveCfg = Release|Win32
|
||||
{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
@@ -128,6 +128,9 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\node_allocator.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\options.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\scoped_allocator.hpp">
|
||||
</File>
|
||||
|
134
proj/vc7ide/doc_custom_tree.vcproj
Normal file
134
proj/vc7ide/doc_custom_tree.vcproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="doc_custom_tree"
|
||||
ProjectGUID="{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/vector_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
ExceptionHandling="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_custom_tree_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/doc_custom_tree.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/doc_custom_tree"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_custom_tree.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4F4737BC-032A-5430-AC75-A32542AA2D1F}">
|
||||
<File
|
||||
RelativePath="..\..\example\doc_custom_tree.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
134
proj/vc7ide/doc_extended_allocators.vcproj
Normal file
134
proj/vc7ide/doc_extended_allocators.vcproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="doc_extended_allocators"
|
||||
ProjectGUID="{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/vector_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
ExceptionHandling="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_extended_allocators_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/doc_extended_allocators.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/doc_extended_allocators"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_extended_allocators.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{41737BFF-1543-AC75-62A0-35A32A2D72AF}">
|
||||
<File
|
||||
RelativePath="..\..\example\doc_extended_allocators.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@@ -3,7 +3,7 @@
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="doc_recursive_containers"
|
||||
ProjectGUID="{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}"
|
||||
ProjectGUID="{1B51C8B2-A832-F55A-4FA2-210AF9D43BD2}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
|
@@ -171,14 +171,15 @@ class map_propagate_test_wrapper
|
||||
< T, T, std::less<T>
|
||||
, typename boost::container::allocator_traits<A>::template
|
||||
portable_rebind_alloc< std::pair<const T, T> >::type
|
||||
, red_black_tree>
|
||||
//tree_assoc_defaults
|
||||
>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(map_propagate_test_wrapper)
|
||||
typedef boost::container::map
|
||||
< T, T, std::less<T>
|
||||
, typename boost::container::allocator_traits<A>::template
|
||||
portable_rebind_alloc< std::pair<const T, T> >::type
|
||||
, red_black_tree> Base;
|
||||
> Base;
|
||||
public:
|
||||
map_propagate_test_wrapper()
|
||||
: Base()
|
||||
@@ -203,7 +204,7 @@ class map_propagate_test_wrapper
|
||||
};
|
||||
|
||||
|
||||
template<class VoidAllocator>
|
||||
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
|
||||
struct GetAllocatorMap
|
||||
{
|
||||
template<class ValueType>
|
||||
@@ -214,6 +215,9 @@ struct GetAllocatorMap
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
|
||||
, typename boost::container::tree_assoc_options
|
||||
< boost::container::tree_type<tree_type_value>
|
||||
>::type
|
||||
> map_type;
|
||||
|
||||
typedef multimap< ValueType
|
||||
@@ -221,22 +225,25 @@ struct GetAllocatorMap
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
|
||||
, typename boost::container::tree_assoc_options
|
||||
< boost::container::tree_type<tree_type_value>
|
||||
>::type
|
||||
> multimap_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
|
||||
int test_map_variants()
|
||||
{
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<int>::map_type MyMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_int>::map_type MyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_and_copyable_int>::map_type MyCopyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::copyable_int>::map_type MyCopyMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<int>::map_type MyMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_int>::map_type MyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::map_type MyCopyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::map_type MyCopyMap;
|
||||
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<int>::multimap_type MyMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_int>::multimap_type MyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_and_copyable_int>::multimap_type MyCopyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::copyable_int>::multimap_type MyCopyMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<int>::multimap_type MyMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_int>::multimap_type MyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::multimap_type MyCopyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::multimap_type MyCopyMultiMap;
|
||||
|
||||
typedef std::map<int, int> MyStdMap;
|
||||
typedef std::multimap<int, int> MyStdMultiMap;
|
||||
@@ -298,34 +305,96 @@ int main ()
|
||||
test_move<multimap<recursive_multimap, recursive_multimap> >();
|
||||
}
|
||||
|
||||
if(test_map_variants< std::allocator<void> >()){
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_map_variants< std::allocator<void>, red_black_tree >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(test_map_variants< allocator<void> >()){
|
||||
// boost::container::allocator
|
||||
if(test_map_variants< allocator<void>, red_black_tree >()){
|
||||
std::cerr << "test_map_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(test_map_variants< node_allocator<void> >()){
|
||||
// boost::container::node_allocator
|
||||
if(test_map_variants< node_allocator<void>, red_black_tree >()){
|
||||
std::cerr << "test_map_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(test_map_variants< adaptive_pool<void> >()){
|
||||
// boost::container::adaptive_pool
|
||||
if(test_map_variants< adaptive_pool<void>, red_black_tree >()){
|
||||
std::cerr << "test_map_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Tree implementations
|
||||
////////////////////////////////////
|
||||
// AVL
|
||||
if(test_map_variants< std::allocator<void>, avl_tree >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void>, avl_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// SCAPEGOAT TREE
|
||||
if(test_map_variants< std::allocator<void>, scapegoat_tree >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void>, scapegoat_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// SPLAY TREE
|
||||
if(test_map_variants< std::allocator<void>, splay_tree >()){
|
||||
std::cerr << "test_map_variants< std::allocator<void>, splay_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
|
||||
if(!boost::container::test::test_emplace<map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
|
||||
return 1;
|
||||
if(!boost::container::test::test_emplace<multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<map_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Test optimize_size option
|
||||
////////////////////////////////////
|
||||
//
|
||||
// map
|
||||
//
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmap_size_optimized_no;
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmap_size_optimized_yes) < sizeof(rbmap_size_optimized_no));
|
||||
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmap_size_optimized_no;
|
||||
typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmap_size_optimized_yes) < sizeof(avlmap_size_optimized_no));
|
||||
//
|
||||
// multimap
|
||||
//
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmmap_size_optimized_no;
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmmap_size_optimized_yes) < sizeof(rbmmap_size_optimized_no));
|
||||
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmmap_size_optimized_no;
|
||||
typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int const*, int*> >
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmmap_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmmap_size_optimized_yes) < sizeof(avlmmap_size_optimized_no));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,13 @@
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
template<class T1, class T2, class T3, class T4>
|
||||
bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
|
||||
{
|
||||
@@ -33,6 +40,16 @@ namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
template<class C>
|
||||
void map_test_rebalanceable(C &, boost::container::container_detail::false_type)
|
||||
{}
|
||||
|
||||
template<class C>
|
||||
void map_test_rebalanceable(C &c, boost::container::container_detail::true_type)
|
||||
{
|
||||
c.rebalance();
|
||||
}
|
||||
|
||||
template<class MyBoostMap
|
||||
,class MyStdMap
|
||||
,class MyBoostMultiMap
|
||||
@@ -501,6 +518,19 @@ int map_test()
|
||||
return 1;
|
||||
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
|
||||
return 1;
|
||||
|
||||
map_test_rebalanceable(*boostmap
|
||||
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMap>::value>());
|
||||
if(!CheckEqualContainers(boostmap, stdmap)){
|
||||
std::cout << "Error in boostmap->rebalance()" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
map_test_rebalanceable(*boostmultimap
|
||||
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMultiMap>::value>());
|
||||
if(!CheckEqualContainers(boostmultimap, stdmultimap)){
|
||||
std::cout << "Error in boostmultimap->rebalance()" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//Compare count with std containers
|
||||
|
@@ -145,10 +145,12 @@ void test_move()
|
||||
|
||||
template<class T, class A>
|
||||
class set_propagate_test_wrapper
|
||||
: public boost::container::set<T, std::less<T>, A, red_black_tree>
|
||||
: public boost::container::set<T, std::less<T>, A
|
||||
//tree_assoc_defaults
|
||||
>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(set_propagate_test_wrapper)
|
||||
typedef boost::container::set<T, std::less<T>, A, red_black_tree> Base;
|
||||
typedef boost::container::set<T, std::less<T>, A > Base;
|
||||
public:
|
||||
set_propagate_test_wrapper()
|
||||
: Base()
|
||||
@@ -172,7 +174,7 @@ class set_propagate_test_wrapper
|
||||
{ this->Base::swap(x); }
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
|
||||
struct GetAllocatorSet
|
||||
{
|
||||
template<class ValueType>
|
||||
@@ -182,28 +184,34 @@ struct GetAllocatorSet
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
, typename boost::container::tree_assoc_options
|
||||
< boost::container::tree_type<tree_type_value>
|
||||
>::type
|
||||
> set_type;
|
||||
|
||||
typedef multiset < ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
, typename boost::container::tree_assoc_options
|
||||
< boost::container::tree_type<tree_type_value>
|
||||
>::type
|
||||
> multiset_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
|
||||
int test_set_variants()
|
||||
{
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<int>::set_type MySet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_int>::set_type MyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::copyable_int>::set_type MyCopySet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<int>::set_type MySet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_int>::set_type MyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::set_type MyCopySet;
|
||||
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<int>::multiset_type MyMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<int>::multiset_type MyMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
|
||||
typedef typename GetAllocatorSet<VoidAllocator, tree_type_value>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
|
||||
|
||||
typedef std::set<int> MyStdSet;
|
||||
typedef std::multiset<int> MyStdMultiSet;
|
||||
@@ -266,34 +274,95 @@ int main ()
|
||||
test_move<multiset<recursive_multiset> >();
|
||||
}
|
||||
|
||||
if(test_set_variants< std::allocator<void> >()){
|
||||
////////////////////////////////////
|
||||
// Testing allocator implementations
|
||||
////////////////////////////////////
|
||||
// std:allocator
|
||||
if(test_set_variants< std::allocator<void>, red_black_tree >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(test_set_variants< allocator<void> >()){
|
||||
// boost::container::allocator
|
||||
if(test_set_variants< allocator<void>, red_black_tree>()){
|
||||
std::cerr << "test_set_variants< allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(test_set_variants< node_allocator<void> >()){
|
||||
// boost::container::node_allocator
|
||||
if(test_set_variants< node_allocator<void>, red_black_tree>()){
|
||||
std::cerr << "test_set_variants< node_allocator<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(test_set_variants< adaptive_pool<void> >()){
|
||||
// boost::container::adaptive_pool
|
||||
if(test_set_variants< adaptive_pool<void>, red_black_tree>()){
|
||||
std::cerr << "test_set_variants< adaptive_pool<void> > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Tree implementations
|
||||
////////////////////////////////////
|
||||
// AVL
|
||||
if(test_set_variants< std::allocator<void>, avl_tree >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void>, avl_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// SCAPEGOAT TREE
|
||||
if(test_set_variants< std::allocator<void>, scapegoat_tree >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void>, scapegoat_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// SPLAY TREE
|
||||
if(test_set_variants< std::allocator<void>, splay_tree >()){
|
||||
std::cerr << "test_set_variants< std::allocator<void>, splay_tree > failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Emplace testing
|
||||
////////////////////////////////////
|
||||
const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
|
||||
if(!boost::container::test::test_emplace<set<test::EmplaceInt>, SetOptions>())
|
||||
return 1;
|
||||
if(!boost::container::test::test_emplace<multiset<test::EmplaceInt>, SetOptions>())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Allocator propagation testing
|
||||
////////////////////////////////////
|
||||
if(!boost::container::test::test_propagate_allocator<set_propagate_test_wrapper>())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Test optimize_size option
|
||||
////////////////////////////////////
|
||||
//
|
||||
// set
|
||||
//
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbset_size_optimized_no;
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbset_size_optimized_yes) < sizeof(rbset_size_optimized_no));
|
||||
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlset_size_optimized_no;
|
||||
typedef set< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlset_size_optimized_yes) < sizeof(avlset_size_optimized_no));
|
||||
//
|
||||
// multiset
|
||||
//
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmset_size_optimized_no;
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(rbmset_size_optimized_yes) < sizeof(rbmset_size_optimized_no));
|
||||
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmset_size_optimized_no;
|
||||
typedef multiset< int*, std::less<int*>, std::allocator<int*>
|
||||
, tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmset_size_optimized_yes;
|
||||
BOOST_STATIC_ASSERT(sizeof(avlmset_size_optimized_yes) < sizeof(avlmset_size_optimized_no));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -21,10 +21,28 @@
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
template<class C>
|
||||
void set_test_rebalanceable(C &, boost::container::container_detail::false_type)
|
||||
{}
|
||||
|
||||
template<class C>
|
||||
void set_test_rebalanceable(C &c, boost::container::container_detail::true_type)
|
||||
{
|
||||
c.rebalance();
|
||||
}
|
||||
|
||||
template<class MyBoostSet
|
||||
,class MyStdSet
|
||||
,class MyBoostMultiSet
|
||||
@@ -459,6 +477,18 @@ int set_test ()
|
||||
std::cout << "Error in boostmultiset->insert(boostmultiset->lower_bound(move_me2), boost::move(move_me2))" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
set_test_rebalanceable(*boostset
|
||||
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostSet>::value>());
|
||||
if(!CheckEqualContainers(boostset, stdset)){
|
||||
std::cout << "Error in boostset->rebalance()" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
set_test_rebalanceable(*boostmultiset
|
||||
, container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMultiSet>::value>());
|
||||
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
|
||||
std::cout << "Error in boostmultiset->rebalance()" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user