* Deleted dependencies with <boost/pointer_cast.hpp> and <boost/pointer_to_other.hpp>. pointer_traits is used to obtain pointer-related types and operations.

* Added examples for derivation_value_traits and member_value_traits and updated configuration.
This commit is contained in:
Ion Gaztañaga
2014-06-05 23:35:43 +02:00
parent 1ad883bddd
commit 29aa25d8e9
12 changed files with 130 additions and 60 deletions

View File

@@ -3035,8 +3035,7 @@ Let's explain each type and function:
as `node_ptr`: If `node_ptr` is `node*`, `pointer` must be `value_type*`. If as `node_ptr`: If `node_ptr` is `node*`, `pointer` must be `value_type*`. If
`node_ptr` is `smart_ptr<node_traits::node>`, `pointer` must be `smart_ptr<value_type>`. `node_ptr` is `smart_ptr<node_traits::node>`, `pointer` must be `smart_ptr<value_type>`.
This can be generically achieved using `boost::intrusive::pointer_traits` (portable implementation of C++11 This can be generically achieved using `boost::intrusive::pointer_traits` (portable implementation of C++11
`std::pointer_traits`) or `boost::pointer_to_other` utility from [*Boost SmartPointers] `std::pointer_traits`).
defined in `<boost/pointer_to_other.hpp>`.
* [*['const_pointer]]: The type of a pointer to a `const value_type`. It must be the same pointer type * [*['const_pointer]]: The type of a pointer to a `const value_type`. It must be the same pointer type
as `node_ptr`: If `node_ptr` is `node*`, `const_pointer` must be `const value_type*`. If as `node_ptr`: If `node_ptr` is `node*`, `const_pointer` must be `const value_type*`. If
@@ -3101,14 +3100,7 @@ intrusive containers, so [*Boost.Intrusive] offers a templatized
[classref boost::intrusive::trivial_value_traits trivial_value_traits] class [classref boost::intrusive::trivial_value_traits trivial_value_traits] class
that does exactly what we want: that does exactly what we want:
[c++] [doc_value_traits_trivial]
#include <boost/intrusive/trivial_value_traits.hpp>
//Now we can define legacy_value_traits just with a single line
using namespace boost::intrusive;
typedef trivial_value_traits<legacy_node_traits, normal_link> legacy_value_traits;
Now we can just define the containers that will store the legacy abi objects and write Now we can just define the containers that will store the legacy abi objects and write
a little test: a little test:
@@ -3160,30 +3152,15 @@ The previous example can be further simplified using the
class to define a value traits class with a value that stores the class to define a value traits class with a value that stores the
`simple_node` as a base class: `simple_node` as a base class:
[c++] [import ../example/doc_derivation_value_traits.cpp]
[doc_derivation_value_traits_value_traits]
#include <boost/intrusive/derivation_value_traits.hpp>
//value_1, value_2, simple_node and simple_node_traits are defined
//as in the previous example...
//...
using namespace boost::intrusive;
//Now define the needed value traits using
typedef derivation_value_traits<value_1, simple_node_traits, normal_link> ValueTraits1;
typedef derivation_value_traits<value_2, simple_node_traits, normal_link> ValueTraits2;
//Now define the containers
typedef list <value1, value_traits<ValueTraits1> > Value1List;
typedef list <value2, value_traits<ValueTraits2> > Value2List;
We can even choose to store `simple_node` as a member of `value_1` and `value_2` We can even choose to store `simple_node` as a member of `value_1` and `value_2`
classes and use [classref boost::intrusive::member_value_traits member_value_traits] classes and use [classref boost::intrusive::member_value_traits member_value_traits]
to define the needed value traits classes: to define the needed value traits classes:
[import ../example/doc_advanced_value_traits2.cpp] [import ../example/doc_member_value_traits.cpp]
[doc_advanced_value_traits2_value_traits] [doc_member_value_traits_value_traits]
[endsect] [endsect]

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/derivation_value_traits.hpp>
#include <vector>
struct simple_node
{
simple_node *prev_;
simple_node *next_;
};
//Define the node traits. A single node_traits will be enough.
struct simple_node_traits
{
typedef simple_node node;
typedef node * node_ptr;
typedef const node * const_node_ptr;
static node *get_next(const node *n) { return n->next_; }
static void set_next(node *n, node *next) { n->next_ = next; }
static node *get_previous(const node *n) { return n->prev_; }
static void set_previous(node *n, node *prev) { n->prev_ = prev; }
};
//[doc_derivation_value_traits_value_traits
class base_1{};
class base_2{};
struct value_1 : public base_1, public simple_node
{
int id_;
simple_node node_;
};
struct value_2 : public base_1, public base_2, public simple_node
{
simple_node node_;
float id_;
};
using namespace boost::intrusive;
//Now define the needed value traits using derivation_value_traits
typedef derivation_value_traits<value_1, simple_node_traits, normal_link> ValueTraits1;
typedef derivation_value_traits<value_2, simple_node_traits, normal_link> ValueTraits2;
//Now define two intrusive lists. Both lists will use the same algorithms:
// circular_list_algorithms<simple_node_traits>
typedef list <value_1, value_traits<ValueTraits1> > Value1List;
typedef list <value_2, value_traits<ValueTraits2> > Value2List;
//]
//[doc_derivation_value_traits_test
int main()
{
typedef std::vector<value_1> Vect1;
typedef std::vector<value_2> Vect2;
//Create values, with a different internal number
Vect1 values1;
Vect2 values2;
for(int i = 0; i < 100; ++i){
value_1 v1; v1.id_ = i; values1.push_back(v1);
value_2 v2; v2.id_ = (float)i; values2.push_back(v2);
}
//Create the lists with the objects
Value1List list1(values1.begin(), values1.end());
Value2List list2(values2.begin(), values2.end());
//Now test both lists
Value1List::const_iterator bit1(list1.begin()), bitend1(list1.end());
Value2List::const_iterator bit2(list2.begin()), bitend2(list2.end());
Vect1::const_iterator it1(values1.begin()), itend1(values1.end());
Vect2::const_iterator it2(values2.begin()), itend2(values2.end());
//Test the objects inserted in our lists
for(; it1 != itend1; ++it1, ++bit1, ++it2, ++bit2){
if(&*bit1 != &*it1 || &*bit2 != &*it2) return false;
}
return 0;
}
//]

View File

@@ -36,7 +36,6 @@ typedef list<MyClass, MemberOption> MemberList;
int main() int main()
{ {
typedef std::vector<MyClass>::iterator VectIt; typedef std::vector<MyClass>::iterator VectIt;
typedef std::vector<MyClass>::reverse_iterator VectRit;
//Create several MyClass objects, each one with a different value //Create several MyClass objects, each one with a different value
std::vector<MyClass> values; std::vector<MyClass> values;

View File

@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// (C) Copyright Ion Gaztanaga 2006-2013 // (C) Copyright Ion Gaztanaga 2006-2014
// //
// Distributed under the Boost Software License, Version 1.0. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
@@ -32,7 +32,7 @@ struct simple_node_traits
static void set_previous(node *n, node *prev) { n->prev_ = prev; } static void set_previous(node *n, node *prev) { n->prev_ = prev; }
}; };
//[doc_advanced_value_traits2_value_traits //[doc_member_value_traits_value_traits
class base_1{}; class base_1{};
class base_2{}; class base_2{};
@@ -61,7 +61,7 @@ typedef list <value_1, value_traits<ValueTraits1> > Value1List;
typedef list <value_2, value_traits<ValueTraits2> > Value2List; typedef list <value_2, value_traits<ValueTraits2> > Value2List;
//] //]
//[doc_advanced_value_traits2_test //[doc_member_value_traits_test
int main() int main()
{ {
typedef std::vector<value_1> Vect1; typedef std::vector<value_1> Vect1;

View File

@@ -13,6 +13,9 @@
#include <boost/intrusive/link_mode.hpp> #include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/list.hpp> #include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp> #include <boost/intrusive/slist.hpp>
//<-
#include <boost/intrusive/trivial_value_traits.hpp>
//->
#include <vector> #include <vector>
//This node is the legacy type we can't modify and we want to insert in //This node is the legacy type we can't modify and we want to insert in
@@ -66,11 +69,21 @@ struct legacy_value_traits
//] //]
//[doc_value_traits_trivial
typedef bi::trivial_value_traits<legacy_node_traits, bi::normal_link> trivial_legacy_value_traits;
//]
//[doc_value_traits_test //[doc_value_traits_test
//Now define an intrusive list and slist that will store legacy_value objects //Now define an intrusive list and slist that will store legacy_value objects
typedef bi::value_traits<legacy_value_traits> ValueTraitsOption; typedef bi::value_traits<legacy_value_traits> ValueTraitsOption;
typedef bi::list<legacy_value, ValueTraitsOption> LegacyAbiList; typedef bi::value_traits<trivial_legacy_value_traits> TrivialValueTraitsOption;
typedef bi::slist<legacy_value, ValueTraitsOption> LegacyAbiSlist;
typedef bi::list<legacy_value, ValueTraitsOption> LegacyAbiList;
typedef bi::slist<legacy_value, ValueTraitsOption> LegacyAbiSlist;
typedef bi::list<legacy_value, TrivialValueTraitsOption> TrivialLegacyAbiList;
typedef bi::slist<legacy_value, TrivialValueTraitsOption> TrivialLegacyAbiSlist;
template<class List> template<class List>
bool test_list() bool test_list()
@@ -98,6 +111,8 @@ bool test_list()
int main() int main()
{ {
return test_list<LegacyAbiList>() && test_list<LegacyAbiSlist>() ? 0 : 1; return test_list<LegacyAbiList>() && test_list<LegacyAbiSlist>() &&
test_list<TrivialLegacyAbiList>() && test_list<TrivialLegacyAbiSlist>()
? 0 : 1;
} }
//] //]

View File

@@ -15,11 +15,8 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/link_mode.hpp> #include <boost/intrusive/link_mode.hpp>
#include <boost/pointer_cast.hpp> #include <boost/intrusive/pointer_traits.hpp>
#include <boost/pointer_to_other.hpp>
#include <iterator>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
@@ -41,8 +38,10 @@ struct derivation_value_traits
typedef typename node_traits::node node; typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer; typedef typename pointer_traits<node_ptr>::
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer; template rebind_pointer<value_type>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const value_type>::type const_pointer;
typedef typename boost::intrusive:: typedef typename boost::intrusive::
pointer_traits<pointer>::reference reference; pointer_traits<pointer>::reference reference;
typedef typename boost::intrusive:: typedef typename boost::intrusive::
@@ -57,18 +56,12 @@ struct derivation_value_traits
static pointer to_value_ptr(const node_ptr &n) static pointer to_value_ptr(const node_ptr &n)
{ {
// This still fails in gcc < 4.4 so forget about it return pointer_traits<pointer>::pointer_to(static_cast<reference>(*n));
// using ::boost::static_pointer_cast;
// return static_pointer_cast<value_type>(n));
return pointer(&static_cast<value_type&>(*n));
} }
static const_pointer to_value_ptr(const const_node_ptr &n) static const_pointer to_value_ptr(const const_node_ptr &n)
{ {
// This still fails in gcc < 4.4 so forget about it return pointer_traits<pointer>::pointer_to(static_cast<const_reference>(*n));
// using ::boost::static_pointer_cast;
// return static_pointer_cast<const value_type>(n));
return const_pointer(&static_cast<const value_type&>(*n));
} }
}; };

View File

@@ -19,7 +19,6 @@
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#include <cstddef> #include <cstddef>
#include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/detail/mpl.hpp>
#include <boost/pointer_cast.hpp>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {

View File

@@ -20,13 +20,11 @@
#include <boost/intrusive/circular_list_algorithms.hpp> #include <boost/intrusive/circular_list_algorithms.hpp>
#include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/utilities.hpp> #include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/slist.hpp> //remove-me #include <boost/intrusive/slist.hpp> //make_slist
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/trivial_value_traits.hpp> #include <boost/intrusive/trivial_value_traits.hpp>
#include <cstddef> #include <cstddef>
#include <climits> #include <climits>
#include <boost/type_traits/make_unsigned.hpp> #include <boost/type_traits/make_unsigned.hpp>
#include <boost/pointer_cast.hpp>
#include <boost/move/core.hpp> #include <boost/move/core.hpp>

View File

@@ -23,7 +23,6 @@
#include <boost/intrusive/detail/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include <boost/pointer_cast.hpp>
//General intrusive utilities //General intrusive utilities
#include <boost/intrusive/detail/hashtable_node.hpp> #include <boost/intrusive/detail/hashtable_node.hpp>
#include <boost/intrusive/detail/transform_iterator.hpp> #include <boost/intrusive/detail/transform_iterator.hpp>

View File

@@ -15,7 +15,6 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/link_mode.hpp> #include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>

View File

@@ -16,12 +16,10 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/pointer_cast.hpp>
#include <boost/intrusive/detail/utilities.hpp> #include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/slist_hook.hpp> #include <boost/intrusive/slist_hook.hpp>
#include <boost/intrusive/options.hpp> #include <boost/intrusive/options.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/generic_hook.hpp> #include <boost/intrusive/detail/generic_hook.hpp>
namespace boost { namespace boost {

View File

@@ -13,7 +13,6 @@
#include <boost/iterator.hpp> #include <boost/iterator.hpp>
#include <boost/intrusive/pointer_plus_bits.hpp> #include <boost/intrusive/pointer_plus_bits.hpp>
#include <boost/pointer_cast.hpp>
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#if (defined _MSC_VER) #if (defined _MSC_VER)