1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/multi_index/detail/index_saver.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,135 @@
1.4 +/* Copyright 2003-2005 Joaquín M López Muñoz.
1.5 + * Distributed under the Boost Software License, Version 1.0.
1.6 + * (See accompanying file LICENSE_1_0.txt or copy at
1.7 + * http://www.boost.org/LICENSE_1_0.txt)
1.8 + *
1.9 + * See http://www.boost.org/libs/multi_index for library home page.
1.10 + */
1.11 +
1.12 +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP
1.13 +#define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP
1.14 +
1.15 +#if defined(_MSC_VER)&&(_MSC_VER>=1200)
1.16 +#pragma once
1.17 +#endif
1.18 +
1.19 +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
1.20 +#include <boost/multi_index/detail/index_matcher.hpp>
1.21 +#include <boost/noncopyable.hpp>
1.22 +#include <boost/serialization/nvp.hpp>
1.23 +#include <cstddef>
1.24 +
1.25 +namespace boost{
1.26 +
1.27 +namespace multi_index{
1.28 +
1.29 +namespace detail{
1.30 +
1.31 +/* index_saver accepts a base sequence of previously saved elements
1.32 + * and saves a possibly reordered subsequence in an efficient manner,
1.33 + * serializing only the information needed to rearrange the subsequence
1.34 + * based on the original order of the base.
1.35 + * multi_index_container is in charge of supplying the info about the
1.36 + * base sequence, and each index can subsequently save itself using the
1.37 + * const interface of index_saver.
1.38 + */
1.39 +
1.40 +template<typename Node,typename Allocator>
1.41 +class index_saver:private noncopyable
1.42 +{
1.43 +public:
1.44 + index_saver(const Allocator& al,std::size_t size):alg(al,size){}
1.45 +
1.46 + template<class Archive>
1.47 + void add(Node* node,Archive& ar,const unsigned int)
1.48 + {
1.49 + ar<<serialization::make_nvp("position",*node);
1.50 + alg.add(node);
1.51 + }
1.52 +
1.53 + template<class Archive>
1.54 + void add_track(Node* node,Archive& ar,const unsigned int)
1.55 + {
1.56 + ar<<serialization::make_nvp("position",*node);
1.57 + }
1.58 +
1.59 + template<typename IndexIterator,class Archive>
1.60 + void save(
1.61 + IndexIterator first,IndexIterator last,Archive& ar,
1.62 + const unsigned int)const
1.63 + {
1.64 + /* calculate ordered positions */
1.65 +
1.66 + alg.execute(first,last);
1.67 +
1.68 + /* Given a consecutive subsequence of displaced elements
1.69 + * x1,...,xn, the following information is serialized:
1.70 + *
1.71 + * p0,p1,...,pn,0
1.72 + *
1.73 + * where pi is a pointer to xi and p0 is a pointer to the element
1.74 + * preceding x1. Crealy, from this information is possible to
1.75 + * restore the original order on loading time. If x1 is the first
1.76 + * element in the sequence, the following is serialized instead:
1.77 + *
1.78 + * p1,p1,...,pn,0
1.79 + *
1.80 + * For each subsequence of n elements, n+2 pointers are serialized.
1.81 + * An optimization policy is applied: consider for instance the
1.82 + * sequence
1.83 + *
1.84 + * a,B,c,D
1.85 + *
1.86 + * where B and D are displaced, but c is in its correct position.
1.87 + * Applying the schema described above we would serialize 6 pointers:
1.88 + *
1.89 + * p(a),p(B),0
1.90 + * p(c),p(D),0
1.91 + *
1.92 + * but this can be reduced to 5 pointers by treating c as a displaced
1.93 + * element:
1.94 + *
1.95 + * p(a),p(B),p(c),p(D),0
1.96 + */
1.97 +
1.98 + std::size_t last_saved=3; /* distance to last pointer saved */
1.99 + for(IndexIterator it=first,prev=first;it!=last;prev=it++,++last_saved){
1.100 + if(!alg.is_ordered(get_node(it))){
1.101 + if(last_saved>1)save_node(get_node(prev),ar);
1.102 + save_node(get_node(it),ar);
1.103 + last_saved=0;
1.104 + }
1.105 + else if(last_saved==2)save_node(null_node(),ar);
1.106 + }
1.107 + if(last_saved<=2)save_node(null_node(),ar);
1.108 +
1.109 + /* marks the end of the serialization info for [first,last) */
1.110 +
1.111 + save_node(null_node(),ar);
1.112 + }
1.113 +
1.114 +private:
1.115 + template<typename IndexIterator>
1.116 + static Node* get_node(IndexIterator it)
1.117 + {
1.118 + return it.get_node();
1.119 + }
1.120 +
1.121 + static Node* null_node(){return 0;}
1.122 +
1.123 + template<typename Archive>
1.124 + static void save_node(Node* node,Archive& ar)
1.125 + {
1.126 + ar<<serialization::make_nvp("pointer",node);
1.127 + }
1.128 +
1.129 + index_matcher::algorithm<Node,Allocator> alg;
1.130 +};
1.131 +
1.132 +} /* namespace multi_index::detail */
1.133 +
1.134 +} /* namespace multi_index */
1.135 +
1.136 +} /* namespace boost */
1.137 +
1.138 +#endif