epoc32/include/stdapis/boost/multi_index/detail/copy_map.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-2005 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_COPY_MAP_HPP
    10 #define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
    11 
    12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
    13 #pragma once
    14 #endif
    15 
    16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
    17 #include <algorithm>
    18 #include <boost/detail/no_exceptions_support.hpp>
    19 #include <boost/multi_index/detail/auto_space.hpp>
    20 #include <boost/noncopyable.hpp>
    21 #include <cstddef>
    22 #include <functional>
    23 
    24 namespace boost{
    25 
    26 namespace multi_index{
    27 
    28 namespace detail{
    29 
    30 /* copy_map is used as an auxiliary structure during copy_() operations.
    31  * When a container with n nodes is replicated, node_map holds the pairings
    32  * between original and copied nodes, and provides a fast way to find a
    33  * copied node from an original one.
    34  * The semantics of the class are not simple, and no attempt has been made
    35  * to enforce it: multi_index_container handles it right. On the other hand,
    36  * the const interface, which is the one provided to index implementations,
    37  * only allows for:
    38  *   - Enumeration of pairs of (original,copied) nodes (excluding the headers),
    39  *   - fast retrieval of copied nodes (including the headers.)
    40  */
    41 
    42 template <typename Node>
    43 struct copy_map_entry
    44 {
    45   copy_map_entry(Node* f,Node* s):first(f),second(s){}
    46 
    47   Node* first;
    48   Node* second;
    49 
    50   bool operator<(const copy_map_entry<Node>& x)const
    51   {
    52     return std::less<Node*>()(first,x.first);
    53   }
    54 };
    55 
    56 template <typename Node,typename Allocator>
    57 class copy_map:private noncopyable
    58 {
    59 public:
    60   typedef const copy_map_entry<Node>* const_iterator;
    61 
    62   copy_map(
    63     const Allocator& al,std::size_t size,Node* header_org,Node* header_cpy):
    64     al_(al),size_(size),spc(al_,size_),n(0),
    65     header_org_(header_org),header_cpy_(header_cpy),released(false)
    66   {}
    67 
    68   ~copy_map()
    69   {
    70     if(!released){
    71       for(std::size_t i=0;i<n;++i){
    72         boost::detail::allocator::destroy(&spc.data()[i].second->value());
    73         deallocate(spc.data()[i].second);
    74       }
    75     }
    76   }
    77 
    78   const_iterator begin()const{return spc.data();}
    79   const_iterator end()const{return spc.data()+n;}
    80 
    81   void clone(Node* node)
    82   {
    83     spc.data()[n].first=node;
    84     spc.data()[n].second=al_.allocate(1);
    85     BOOST_TRY{
    86       boost::detail::allocator::construct(
    87         &spc.data()[n].second->value(),node->value());
    88     }
    89     BOOST_CATCH(...){
    90       deallocate(spc.data()[n].second);
    91       BOOST_RETHROW;
    92     }
    93     BOOST_CATCH_END
    94     ++n;
    95 
    96     if(n==size_)std::sort(spc.data(),spc.data()+size_);
    97   }
    98 
    99   Node* find(Node* node)const
   100   {
   101     if(node==header_org_)return header_cpy_;
   102     return std::lower_bound(
   103       begin(),end(),copy_map_entry<Node>(node,0))->second;
   104   }
   105 
   106   void release()
   107   {
   108     released=true;
   109   }
   110 
   111 private:
   112   typename boost::detail::allocator::rebind_to<
   113     Allocator,Node>::type                       al_;
   114   std::size_t                                   size_;
   115   auto_space<copy_map_entry<Node>,Allocator>    spc;
   116   std::size_t                                   n;
   117   Node*                                         header_org_;
   118   Node*                                         header_cpy_;
   119   bool                                          released;
   120 
   121   void deallocate(Node* node)
   122   {
   123     al_.deallocate(node,1);
   124   }
   125 };
   126 
   127 } /* namespace multi_index::detail */
   128 
   129 } /* namespace multi_index */
   130 
   131 } /* namespace boost */
   132 
   133 #endif