epoc32/include/stdapis/boost/multi_index/detail/seq_index_node.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     1 /* Copyright 2003-2006 Joaquín M López Muñoz.
     2  * Distributed under the Boost Software License, Version 1.0.
     3  * (See accompanying file LICENSE_1_0.txt or copy at
     4  * http://www.boost.org/LICENSE_1_0.txt)
     5  *
     6  * See http://www.boost.org/libs/multi_index for library home page.
     7  */
     8 
     9 #ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP
    10 #define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP
    11 
    12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
    13 #pragma once
    14 #endif
    15 
    16 #include <algorithm>
    17 
    18 namespace boost{
    19 
    20 namespace multi_index{
    21 
    22 namespace detail{
    23 
    24 /* doubly-linked node for use by sequenced_index */
    25 
    26 struct sequenced_index_node_impl
    27 {
    28   sequenced_index_node_impl*& prior(){return prior_;}
    29   sequenced_index_node_impl*  prior()const{return prior_;}
    30   sequenced_index_node_impl*& next(){return next_;}
    31   sequenced_index_node_impl*  next()const{return next_;}
    32 
    33   /* interoperability with bidir_node_iterator */
    34 
    35   static void increment(sequenced_index_node_impl*& x){x=x->next();}
    36   static void decrement(sequenced_index_node_impl*& x){x=x->prior();}
    37 
    38   /* algorithmic stuff */
    39 
    40   static void link(
    41     sequenced_index_node_impl* x,sequenced_index_node_impl* header)
    42   {
    43     x->prior()=header->prior();
    44     x->next()=header;
    45     x->prior()->next()=x->next()->prior()=x;
    46   };
    47 
    48   static void unlink(sequenced_index_node_impl* x)
    49   {
    50     x->prior()->next()=x->next();
    51     x->next()->prior()=x->prior();
    52   }
    53 
    54   static void relink(
    55     sequenced_index_node_impl* position,sequenced_index_node_impl* x)
    56   {
    57     unlink(x);
    58     x->prior()=position->prior();
    59     x->next()=position;
    60     x->prior()->next()=x->next()->prior()=x;
    61   }
    62 
    63   static void relink(
    64     sequenced_index_node_impl* position,
    65     sequenced_index_node_impl* x,sequenced_index_node_impl* y)
    66   {
    67     /* position is assumed not to be in [x,y) */
    68 
    69     if(x!=y){
    70       sequenced_index_node_impl* z=y->prior();
    71       x->prior()->next()=y;
    72       y->prior()=x->prior();
    73       x->prior()=position->prior();
    74       z->next()=position;
    75       x->prior()->next()=x;
    76       z->next()->prior()=z;
    77     }
    78   }
    79 
    80   static void reverse(sequenced_index_node_impl* header)
    81   {
    82     sequenced_index_node_impl* x=header;
    83     do{
    84       sequenced_index_node_impl* y=x->next();
    85       std::swap(x->prior(),x->next());
    86       x=y;
    87     }while(x!=header);
    88   }
    89 
    90   static void swap(sequenced_index_node_impl* x,sequenced_index_node_impl* y)
    91   {
    92     /* This swap function does not exchange the header nodes,
    93      * but rather their pointers. This is *not* used for implementing
    94      * sequenced_index::swap.
    95      */
    96 
    97     if(x->next()!=x){
    98       if(y->next()!=y){
    99         std::swap(x->next(),y->next());
   100         std::swap(x->prior(),y->prior());
   101         x->next()->prior()=x->prior()->next()=x;
   102         y->next()->prior()=y->prior()->next()=y;
   103       }
   104       else{
   105         y->next()=x->next();
   106         y->prior()=x->prior();
   107         x->next()=x->prior()=x;
   108         y->next()->prior()=y->prior()->next()=y;
   109       }
   110     }
   111     else if(y->next()!=y){
   112       x->next()=y->next();
   113       x->prior()=y->prior();
   114       y->next()=y->prior()=y;
   115       x->next()->prior()=x->prior()->next()=x;
   116     }
   117   }
   118 
   119 private:
   120   sequenced_index_node_impl* prior_;
   121   sequenced_index_node_impl* next_;
   122 };
   123 
   124 template<typename Super>
   125 struct sequenced_index_node_trampoline:sequenced_index_node_impl{};
   126 
   127 template<typename Super>
   128 struct sequenced_index_node:Super,sequenced_index_node_trampoline<Super>
   129 {
   130   sequenced_index_node_impl*& prior(){return impl_type::prior();}
   131   sequenced_index_node_impl*  prior()const{return impl_type::prior();}
   132   sequenced_index_node_impl*& next(){return impl_type::next();}
   133   sequenced_index_node_impl*  next()const{return impl_type::next();}
   134 
   135   sequenced_index_node_impl*       impl()
   136     {return static_cast<impl_type*>(this);}
   137   const sequenced_index_node_impl* impl()const
   138     {return static_cast<const impl_type*>(this);}
   139 
   140   static sequenced_index_node* from_impl(sequenced_index_node_impl *x)
   141     {return static_cast<sequenced_index_node*>(static_cast<impl_type*>(x));}
   142   static const sequenced_index_node* from_impl(
   143     const sequenced_index_node_impl* x)
   144   {
   145     return static_cast<const sequenced_index_node*>(
   146       static_cast<const impl_type*>(x));
   147   }
   148 
   149   /* interoperability with bidir_node_iterator */
   150 
   151   static void increment(sequenced_index_node*& x)
   152   {
   153     sequenced_index_node_impl* xi=x->impl();
   154     impl_type::increment(xi);
   155     x=from_impl(xi);
   156   }
   157 
   158   static void decrement(sequenced_index_node*& x)
   159   {
   160     sequenced_index_node_impl* xi=x->impl();
   161     impl_type::decrement(xi);
   162     x=from_impl(xi);
   163   }
   164 
   165 private:
   166   typedef sequenced_index_node_trampoline<Super> impl_type;
   167 };
   168 
   169 } /* namespace multi_index::detail */
   170 
   171 } /* namespace multi_index */
   172 
   173 } /* namespace boost */
   174 
   175 #endif