external_value_traits_test.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 240 行
CPP
240 行
///////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2007//// 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/list.hpp>#include <boost/intrusive/slist.hpp>#include <boost/intrusive/rbtree.hpp>#include <boost/intrusive/hashtable.hpp>#include <boost/pointer_to_other.hpp>#include <functional>#include <vector>using namespace boost::intrusive;class MyClass{ public: int int_; MyClass(int i = 0) : int_(i) {} friend bool operator > (const MyClass &l, const MyClass &r) { return l.int_ > r.int_; } friend bool operator == (const MyClass &l, const MyClass &r) { return l.int_ == r.int_; } friend std::size_t hash_value(const MyClass &v) { return boost::hash_value(v.int_); }};const int NumElements = 100;template<class NodeTraits>struct external_traits{ typedef NodeTraits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef MyClass value_type; typedef typename boost::pointer_to_other <node_ptr, MyClass>::type pointer; typedef typename boost::pointer_to_other <node_ptr, const MyClass>::type const_pointer; static const link_mode_type link_mode = normal_link; external_traits(pointer values, std::size_t NumElem) : values_(values), node_array_(NumElem) {} node_ptr to_node_ptr (value_type &value) { return (&node_array_[0]) + (&value - values_); } const_node_ptr to_node_ptr (const value_type &value) const { return &node_array_[0] + (&value - values_); } pointer to_value_ptr(node_ptr n) { return values_ + (n - &node_array_[0]); } const_pointer to_value_ptr(const_node_ptr n) const { return values_ + (n - &node_array_[0]); } pointer values_; std::vector<node> node_array_;};template<class NodeTraits>struct value_traits_proxy;template<class T>struct traits_holder : public T{};typedef value_traits_proxy<list_node_traits<void*> > list_value_traits_proxy;typedef value_traits_proxy<slist_node_traits<void*> > slist_value_traits_proxy;typedef value_traits_proxy<rbtree_node_traits<void*> > rbtree_value_traits_proxy;typedef value_traits_proxy<traits_holder<slist_node_traits<void*> > > hash_value_traits_proxy;struct uset_bucket_traits{ private: typedef unordered_bucket<value_traits<external_traits <traits_holder<slist_node_traits<void*> > > > >::type bucket_type; //Non-copyable uset_bucket_traits(const uset_bucket_traits &other); uset_bucket_traits & operator=(const uset_bucket_traits &other); public: static const std::size_t NumBuckets = 100; uset_bucket_traits(){} bucket_type * bucket_begin() const { return buckets_; } std::size_t bucket_count() const { return NumBuckets; } mutable bucket_type buckets_[NumBuckets];};struct bucket_traits_proxy{ static const bool external_bucket_traits = true; typedef uset_bucket_traits bucket_traits; template<class Container> bucket_traits &get_bucket_traits(Container &cont); template<class Container> const bucket_traits &get_bucket_traits(const Container &cont) const;};//Define a list that will store MyClass using the external hooktypedef list<MyClass, value_traits<list_value_traits_proxy> > List;//Define a slist that will store MyClass using the external hooktypedef slist<MyClass, value_traits<slist_value_traits_proxy> > Slist;//Define a rbtree that will store MyClass using the external hooktypedef rbtree< MyClass , value_traits<rbtree_value_traits_proxy> , compare<std::greater<MyClass> > > Rbtree;//Define a hashtable that will store MyClass using the external hooktypedef hashtable< MyClass , value_traits<hash_value_traits_proxy> , bucket_traits<bucket_traits_proxy> > Hash;template<class NodeTraits>struct value_traits_proxy{ static const bool external_value_traits = true; typedef external_traits<NodeTraits> value_traits; template<class Container> const value_traits &get_value_traits(const Container &cont) const; template<class Container> value_traits &get_value_traits(Container &cont);};struct ContainerHolder : public uset_bucket_traits , public List , public external_traits<list_node_traits<void*> > , public Slist , public external_traits<slist_node_traits<void*> > , public Rbtree , public external_traits<rbtree_node_traits<void*> > , public Hash , public external_traits<traits_holder<slist_node_traits<void*> > >{ static const std::size_t NumBucket = 100; ContainerHolder(MyClass *values, std::size_t num_elem) : uset_bucket_traits() , List() , external_traits<list_node_traits<void*> >(values, num_elem) , Slist() , external_traits<slist_node_traits<void*> >(values, num_elem) , Rbtree() , external_traits<rbtree_node_traits<void*> >(values, num_elem) , Hash(Hash::bucket_traits()) , external_traits<traits_holder<slist_node_traits<void*> > >(values, num_elem) {}};template<class NodeTraits>template<class Container>typename value_traits_proxy<NodeTraits>::value_traits & value_traits_proxy<NodeTraits>::get_value_traits(Container &cont){ return static_cast<value_traits&>(static_cast<ContainerHolder&>(cont)); }template<class NodeTraits>template<class Container>const typename value_traits_proxy<NodeTraits>::value_traits & value_traits_proxy<NodeTraits>::get_value_traits(const Container &cont) const{ return static_cast<const value_traits&>(static_cast<const ContainerHolder&>(cont)); }template<class Container>typename bucket_traits_proxy::bucket_traits & bucket_traits_proxy::get_bucket_traits(Container &cont){ return static_cast<bucket_traits&>(static_cast<ContainerHolder&>(cont)); }template<class Container>const typename bucket_traits_proxy::bucket_traits & bucket_traits_proxy::get_bucket_traits(const Container &cont) const{ return static_cast<const bucket_traits&>(static_cast<const ContainerHolder&>(cont)); }int main(){ MyClass values [NumElements]; //Create several MyClass objects, each one with a different value for(int i = 0; i < NumElements; ++i) values[i].int_ = i; ContainerHolder cont_holder(values, NumElements); List &my_list = static_cast<List &> (cont_holder); Slist &my_slist = static_cast<Slist &> (cont_holder); Rbtree &my_rbtree = static_cast<Rbtree &> (cont_holder); Hash &my_hash = static_cast<Hash &> (cont_holder); //Now insert them in containers for(MyClass * it(&values[0]), *itend(&values[NumElements]) ; it != itend; ++it){ my_list.push_front(*it); my_slist.push_front(*it); my_rbtree.insert_unique(*it); my_hash.insert_unique(*it); } //Now test containers { List::const_iterator list_it (my_list.cbegin()); Slist::const_iterator slist_it (my_slist.cbegin()); Rbtree::const_iterator rbtree_it (my_rbtree.cbegin()); Hash::const_iterator hash_it (my_hash.cbegin()); MyClass *it_val(&values[NumElements] - 1), *it_rbeg_val(&values[0]-1); //Test inserted objects for(; it_val != it_rbeg_val; --it_val, ++list_it, ++slist_it, ++rbtree_it){ if(&*list_it != &*it_val) return 1; if(&*slist_it != &*it_val) return 1; if(&*rbtree_it != &*it_val) return 1; hash_it = my_hash.find(*it_val); if(hash_it == my_hash.cend() || &*hash_it != &*it_val) return 1; } } return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?