epoc32/include/stdapis/boost/multi_index/detail/index_loader.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
williamr@2
     1
/* Copyright 2003-2005 Joaquín M López Muñoz.
williamr@2
     2
 * Distributed under the Boost Software License, Version 1.0.
williamr@2
     3
 * (See accompanying file LICENSE_1_0.txt or copy at
williamr@2
     4
 * http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     5
 *
williamr@2
     6
 * See http://www.boost.org/libs/multi_index for library home page.
williamr@2
     7
 */
williamr@2
     8
williamr@2
     9
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
williamr@2
    10
#define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
williamr@2
    11
williamr@2
    12
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
williamr@2
    13
#pragma once
williamr@2
    14
#endif
williamr@2
    15
williamr@2
    16
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
williamr@2
    17
#include <algorithm>
williamr@2
    18
#include <boost/archive/archive_exception.hpp>
williamr@2
    19
#include <boost/noncopyable.hpp>
williamr@2
    20
#include <boost/multi_index/detail/auto_space.hpp>
williamr@2
    21
#include <boost/serialization/nvp.hpp>
williamr@2
    22
#include <boost/throw_exception.hpp> 
williamr@2
    23
#include <cstddef>
williamr@2
    24
williamr@2
    25
namespace boost{
williamr@2
    26
williamr@2
    27
namespace multi_index{
williamr@2
    28
williamr@2
    29
namespace detail{
williamr@2
    30
williamr@2
    31
/* Counterpart of index_saver (check index_saver.hpp for serialization
williamr@2
    32
 * details.)* multi_index_container is in charge of supplying the info about
williamr@2
    33
 * the base sequence, and each index can subsequently load itself using the
williamr@2
    34
 * const interface of index_loader.
williamr@2
    35
 */
williamr@2
    36
williamr@2
    37
template<typename Node,typename FinalNode,typename Allocator>
williamr@2
    38
class index_loader:private noncopyable
williamr@2
    39
{
williamr@2
    40
public:
williamr@2
    41
  index_loader(const Allocator& al,std::size_t size):
williamr@2
    42
    spc(al,size),size_(size),n(0),sorted(false)
williamr@2
    43
  {
williamr@2
    44
  }
williamr@2
    45
williamr@2
    46
  template<class Archive>
williamr@2
    47
  void add(Node* node,Archive& ar,const unsigned int)
williamr@2
    48
  {
williamr@2
    49
    ar>>serialization::make_nvp("position",*node);
williamr@2
    50
    entries()[n++]=node;
williamr@2
    51
  }
williamr@2
    52
williamr@2
    53
  template<class Archive>
williamr@2
    54
  void add_track(Node* node,Archive& ar,const unsigned int)
williamr@2
    55
  {
williamr@2
    56
    ar>>serialization::make_nvp("position",*node);
williamr@2
    57
  }
williamr@2
    58
williamr@2
    59
  /* A rearranger is passed two nodes, and is expected to
williamr@2
    60
   * reposition the second after the first.
williamr@2
    61
   * If the first node is 0, then the second should be moved
williamr@2
    62
   * to the beginning of the sequence.
williamr@2
    63
   */
williamr@2
    64
williamr@2
    65
  template<typename Rearranger,class Archive>
williamr@2
    66
  void load(Rearranger r,Archive& ar,const unsigned int)const
williamr@2
    67
  {
williamr@2
    68
    FinalNode* prev=unchecked_load_node(ar);
williamr@2
    69
    if(!prev)return;
williamr@2
    70
williamr@2
    71
    if(!sorted){
williamr@2
    72
      std::sort(entries(),entries()+size_);
williamr@2
    73
      sorted=true;
williamr@2
    74
    }
williamr@2
    75
williamr@2
    76
    check_node(prev);
williamr@2
    77
williamr@2
    78
    for(;;){
williamr@2
    79
      for(;;){
williamr@2
    80
        FinalNode* node=load_node(ar);
williamr@2
    81
        if(!node)break;
williamr@2
    82
williamr@2
    83
        if(node==prev)prev=0;
williamr@2
    84
        r(prev,node);
williamr@2
    85
williamr@2
    86
        prev=node;
williamr@2
    87
      }
williamr@2
    88
      prev=load_node(ar);
williamr@2
    89
      if(!prev)break;
williamr@2
    90
    }
williamr@2
    91
  }
williamr@2
    92
williamr@2
    93
private:
williamr@2
    94
  Node** entries()const{return spc.data();}
williamr@2
    95
williamr@2
    96
  /* We try to delay sorting as much as possible just in case it
williamr@2
    97
   * is not necessary, hence this version of load_node.
williamr@2
    98
   */
williamr@2
    99
williamr@2
   100
  template<class Archive>
williamr@2
   101
  FinalNode* unchecked_load_node(Archive& ar)const
williamr@2
   102
  {
williamr@2
   103
    Node* node=0;
williamr@2
   104
    ar>>serialization::make_nvp("pointer",node);
williamr@2
   105
    return static_cast<FinalNode*>(node);
williamr@2
   106
  }
williamr@2
   107
williamr@2
   108
  template<class Archive>
williamr@2
   109
  FinalNode* load_node(Archive& ar)const
williamr@2
   110
  {
williamr@2
   111
    Node* node=0;
williamr@2
   112
    ar>>serialization::make_nvp("pointer",node);
williamr@2
   113
    check_node(node);
williamr@2
   114
    return static_cast<FinalNode*>(node);
williamr@2
   115
  }
williamr@2
   116
williamr@2
   117
  void check_node(Node* node)const
williamr@2
   118
  {
williamr@2
   119
    if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){
williamr@2
   120
      throw_exception(
williamr@2
   121
        archive::archive_exception(
williamr@2
   122
          archive::archive_exception::other_exception));
williamr@2
   123
    }
williamr@2
   124
  }
williamr@2
   125
williamr@2
   126
  auto_space<Node*,Allocator> spc;
williamr@2
   127
  std::size_t                 size_;
williamr@2
   128
  std::size_t                 n;
williamr@2
   129
  mutable bool                sorted;
williamr@2
   130
};
williamr@2
   131
williamr@2
   132
} /* namespace multi_index::detail */
williamr@2
   133
williamr@2
   134
} /* namespace multi_index */
williamr@2
   135
williamr@2
   136
} /* namespace boost */
williamr@2
   137
williamr@2
   138
#endif