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:
Ion Gaztañaga
2014-01-03 13:26:57 +01:00
parent 2489010881
commit 01486761a6
21 changed files with 1193 additions and 155 deletions

View File

@@ -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;
}

View File

@@ -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"
;

View File

@@ -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"]].

View File

@@ -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

View 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>

View 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>

View File

@@ -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

View File

@@ -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()); }

View File

@@ -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); }
};

View 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

View File

@@ -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;
};

View File

@@ -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:

View File

@@ -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

View File

@@ -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>

View 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>

View 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>

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}
}
}