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 | } |
106 | |