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 + -
显示快捷键?