williamr@2: /* Copyright 2003-2005 Joaquín M López Muñoz. williamr@2: * Distributed under the Boost Software License, Version 1.0. williamr@2: * (See accompanying file LICENSE_1_0.txt or copy at williamr@2: * http://www.boost.org/LICENSE_1_0.txt) williamr@2: * williamr@2: * See http://www.boost.org/libs/multi_index for library home page. williamr@2: */ williamr@2: williamr@2: #ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP williamr@2: #define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP williamr@2: williamr@2: #if defined(_MSC_VER)&&(_MSC_VER>=1200) williamr@2: #pragma once williamr@2: #endif williamr@2: williamr@2: #include /* keep it first to prevent nasty warns in MSVC */ williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: namespace boost{ williamr@2: williamr@2: namespace multi_index{ williamr@2: williamr@2: namespace detail{ williamr@2: williamr@2: /* Counterpart of index_saver (check index_saver.hpp for serialization williamr@2: * details.)* multi_index_container is in charge of supplying the info about williamr@2: * the base sequence, and each index can subsequently load itself using the williamr@2: * const interface of index_loader. williamr@2: */ williamr@2: williamr@2: template williamr@2: class index_loader:private noncopyable williamr@2: { williamr@2: public: williamr@2: index_loader(const Allocator& al,std::size_t size): williamr@2: spc(al,size),size_(size),n(0),sorted(false) williamr@2: { williamr@2: } williamr@2: williamr@2: template williamr@2: void add(Node* node,Archive& ar,const unsigned int) williamr@2: { williamr@2: ar>>serialization::make_nvp("position",*node); williamr@2: entries()[n++]=node; williamr@2: } williamr@2: williamr@2: template williamr@2: void add_track(Node* node,Archive& ar,const unsigned int) williamr@2: { williamr@2: ar>>serialization::make_nvp("position",*node); williamr@2: } williamr@2: williamr@2: /* A rearranger is passed two nodes, and is expected to williamr@2: * reposition the second after the first. williamr@2: * If the first node is 0, then the second should be moved williamr@2: * to the beginning of the sequence. williamr@2: */ williamr@2: williamr@2: template williamr@2: void load(Rearranger r,Archive& ar,const unsigned int)const williamr@2: { williamr@2: FinalNode* prev=unchecked_load_node(ar); williamr@2: if(!prev)return; williamr@2: williamr@2: if(!sorted){ williamr@2: std::sort(entries(),entries()+size_); williamr@2: sorted=true; williamr@2: } williamr@2: williamr@2: check_node(prev); williamr@2: williamr@2: for(;;){ williamr@2: for(;;){ williamr@2: FinalNode* node=load_node(ar); williamr@2: if(!node)break; williamr@2: williamr@2: if(node==prev)prev=0; williamr@2: r(prev,node); williamr@2: williamr@2: prev=node; williamr@2: } williamr@2: prev=load_node(ar); williamr@2: if(!prev)break; williamr@2: } williamr@2: } williamr@2: williamr@2: private: williamr@2: Node** entries()const{return spc.data();} williamr@2: williamr@2: /* We try to delay sorting as much as possible just in case it williamr@2: * is not necessary, hence this version of load_node. williamr@2: */ williamr@2: williamr@2: template williamr@2: FinalNode* unchecked_load_node(Archive& ar)const williamr@2: { williamr@2: Node* node=0; williamr@2: ar>>serialization::make_nvp("pointer",node); williamr@2: return static_cast(node); williamr@2: } williamr@2: williamr@2: template williamr@2: FinalNode* load_node(Archive& ar)const williamr@2: { williamr@2: Node* node=0; williamr@2: ar>>serialization::make_nvp("pointer",node); williamr@2: check_node(node); williamr@2: return static_cast(node); williamr@2: } williamr@2: williamr@2: void check_node(Node* node)const williamr@2: { williamr@2: if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){ williamr@2: throw_exception( williamr@2: archive::archive_exception( williamr@2: archive::archive_exception::other_exception)); williamr@2: } williamr@2: } williamr@2: williamr@2: auto_space spc; williamr@2: std::size_t size_; williamr@2: std::size_t n; williamr@2: mutable bool sorted; williamr@2: }; williamr@2: williamr@2: } /* namespace multi_index::detail */ williamr@2: williamr@2: } /* namespace multi_index */ williamr@2: williamr@2: } /* namespace boost */ williamr@2: williamr@2: #endif