Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / multi_index / test / test_serialization_template.hpp
1 /* Boost.MultiIndex serialization tests template.
2  *
3  * Copyright 2003-2013 Joaquin M Lopez Munoz.
4  * Distributed under the Boost Software License, Version 1.0.
5  * (See accompanying file LICENSE_1_0.txt or copy at
6  * http://www.boost.org/LICENSE_1_0.txt)
7  *
8  * See http://www.boost.org/libs/multi_index for library home page.
9  */
10
11 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
12 #include <boost/archive/text_oarchive.hpp>
13 #include <boost/archive/text_iarchive.hpp>
14 #include <boost/detail/lightweight_test.hpp>
15 #include <boost/mpl/size.hpp>
16 #include "pre_multi_index.hpp"
17 #include <boost/multi_index_container.hpp>
18 #include <string>
19 #include <sstream>
20 #include <vector>
21
22 template<int N>
23 struct all_indices_equal_helper
24 {
25   template<class MultiIndexContainer>
26   static bool compare(
27     const MultiIndexContainer& m1,const MultiIndexContainer& m2)
28   {
29     if(!(boost::multi_index::get<N>(m1)==boost::multi_index::get<N>(m2))){
30       return false;
31     }
32     return all_indices_equal_helper<N-1>::compare(m1,m2);
33   }
34 };
35
36 template<>
37 struct all_indices_equal_helper<0>
38 {
39   template<class MultiIndexContainer>
40   static bool compare(
41     const MultiIndexContainer&,const MultiIndexContainer&)
42   {
43     return true;
44   }
45 };
46
47 template<class MultiIndexContainer>
48 bool all_indices_equal(
49   const MultiIndexContainer& m1,const MultiIndexContainer& m2)
50 {
51   BOOST_STATIC_CONSTANT(int,
52     N=boost::mpl::size<
53     BOOST_DEDUCED_TYPENAME MultiIndexContainer::index_type_list>::type::value);
54
55   return all_indices_equal_helper<N-1>::compare(m1,m2);
56 }
57
58 template<class MultiIndexContainer>
59 void test_serialization(const MultiIndexContainer& m)
60 {
61   typedef typename MultiIndexContainer::iterator       iterator;
62   typedef typename MultiIndexContainer::const_iterator const_iterator;
63
64   std::ostringstream oss;
65   {
66     boost::archive::text_oarchive oa(oss);
67     oa<<m;
68
69     std::vector<const_iterator> its(m.size());
70     const_iterator              it_end=m.end();
71     for(const_iterator it=m.begin();it!=it_end;++it){
72       its.push_back(it);
73       oa<<const_cast<const const_iterator&>(its.back());
74     }
75     oa<<const_cast<const const_iterator&>(it_end);
76   }
77
78   MultiIndexContainer m2;
79   std::istringstream iss(oss.str());
80   boost::archive::text_iarchive ia(iss);
81   ia>>m2;
82   BOOST_TEST(all_indices_equal(m,m2));
83
84   iterator it_end=m2.end();
85   for(iterator it=m2.begin();it!=it_end;++it){
86     iterator it2;
87     ia>>it2;
88     BOOST_TEST(it==it2);
89
90     /* exercise safe mode with this (unchecked) iterator */
91     BOOST_TEST(*it==*it2);
92     m2.erase(it,it2);
93     m2.erase(it2,it2);
94     m2.erase(it2,it);
95     iterator it3(++it2);
96     iterator it4;
97     it4=--it2;
98     BOOST_TEST(it==it4);
99     BOOST_TEST(it==boost::multi_index::project<0>(m2,it4));
100   }
101   iterator it2;
102   ia>>it2;
103   BOOST_TEST(it_end==it2);
104   BOOST_TEST(it_end==boost::multi_index::project<0>(m2,it2));
105 }