Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:07

0001 /* Copyright 2003-2023 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See http://www.boost.org/libs/multi_index for library home page.
0007  */
0008 
0009 #ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0017 #include <algorithm>
0018 #include <boost/core/noncopyable.hpp>
0019 #include <boost/core/serialization.hpp>
0020 #include <boost/multi_index/detail/auto_space.hpp>
0021 #include <boost/multi_index/detail/bad_archive_exception.hpp>
0022 #include <boost/multi_index/detail/raw_ptr.hpp>
0023 #include <boost/throw_exception.hpp> 
0024 #include <cstddef>
0025 
0026 namespace boost{
0027 
0028 namespace multi_index{
0029 
0030 namespace detail{
0031 
0032 /* Counterpart of index_saver (check index_saver.hpp for serialization
0033  * details.)
0034  * multi_index_container is in charge of supplying the info about
0035  * the base sequence, and each index can subsequently load itself using the
0036  * const interface of index_loader.
0037  */
0038 
0039 template<typename Node,typename FinalNode,typename Allocator>
0040 class index_loader:private noncopyable
0041 {
0042 public:
0043   index_loader(const Allocator& al,std::size_t size):
0044     spc(al,size),size_(size),n(0),sorted(false)
0045   {
0046   }
0047 
0048   template<class Archive>
0049   void add(Node* node,Archive& ar,const unsigned int)
0050   {
0051     ar>>core::make_nvp("position",*node);
0052     entries()[n++]=node;
0053   }
0054 
0055   template<class Archive>
0056   void add_track(Node* node,Archive& ar,const unsigned int)
0057   {
0058     ar>>core::make_nvp("position",*node);
0059   }
0060 
0061   /* A rearranger is passed two nodes, and is expected to
0062    * reposition the second after the first.
0063    * If the first node is 0, then the second should be moved
0064    * to the beginning of the sequence.
0065    */
0066 
0067   template<typename Rearranger,class Archive>
0068   void load(Rearranger r,Archive& ar,const unsigned int)const
0069   {
0070     FinalNode* prev=unchecked_load_node(ar);
0071     if(!prev)return;
0072 
0073     if(!sorted){
0074       std::sort(entries(),entries()+size_);
0075       sorted=true;
0076     }
0077 
0078     check_node(prev);
0079 
0080     for(;;){
0081       for(;;){
0082         FinalNode* node=load_node(ar);
0083         if(!node)break;
0084 
0085         if(node==prev)prev=0;
0086         r(prev,node);
0087 
0088         prev=node;
0089       }
0090       prev=load_node(ar);
0091       if(!prev)break;
0092     }
0093   }
0094 
0095 private:
0096   Node** entries()const{return raw_ptr<Node**>(spc.data());}
0097 
0098   /* We try to delay sorting as much as possible just in case it
0099    * is not necessary, hence this version of load_node.
0100    */
0101 
0102   template<class Archive>
0103   FinalNode* unchecked_load_node(Archive& ar)const
0104   {
0105     Node* node=0;
0106     ar>>core::make_nvp("pointer",node);
0107     return static_cast<FinalNode*>(node);
0108   }
0109 
0110   template<class Archive>
0111   FinalNode* load_node(Archive& ar)const
0112   {
0113     Node* node=0;
0114     ar>>core::make_nvp("pointer",node);
0115     check_node(node);
0116     return static_cast<FinalNode*>(node);
0117   }
0118 
0119   void check_node(Node* node)const
0120   {
0121     if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){
0122       throw_exception(bad_archive_exception());
0123     }
0124   }
0125 
0126   auto_space<Node*,Allocator> spc;
0127   std::size_t                 size_;
0128   std::size_t                 n;
0129   mutable bool                sorted;
0130 };
0131 
0132 } /* namespace multi_index::detail */
0133 
0134 } /* namespace multi_index */
0135 
0136 } /* namespace boost */
0137 
0138 #endif