Ticket #3298: join_map_test.cpp

File join_map_test.cpp, 4.4 KB (added by Marshall Galbraith <Marshall.Galbraith@…>, 13 years ago)

Example code that compiles with CYGWIN GCC 4.3.2 but now MSVC 9

Line 
1
2#include <boost/mpl/map.hpp>
3#include <boost/mpl/pair.hpp>
4#include <boost/mpl/erase_key.hpp>
5#include <boost/mpl/for_each.hpp>
6#include <boost/mpl/insert.hpp>
7#include <boost/mpl/begin_end.hpp>
8#include <boost/mpl/less.hpp>
9#include <boost/mpl/size.hpp>
10#include <boost/mpl/deref.hpp>
11#include <iostream>
12
13
14namespace mpl = boost::mpl;
15
16//=============================================================================
17//Template meta function that joins two maps (normally in a header file)
18template< class, class MapL, class MapR >
19struct join_maps_imp;
20
21//=============================================================================
22template< class MapL, class MapR >
23struct join_maps
24{
25 typedef typename join_maps_imp< typename mpl::less< typename mpl::size<MapL>::type
26 , typename mpl::size<MapR>::type >::type
27 , MapL
28 , MapR
29 >::type type;
30};
31
32//=============================================================================
33//MapR is smaller than MapL, so add R to L
34template< class MapL, class MapR >
35struct join_maps_imp<mpl::false_, MapL, MapR>
36{
37 typedef typename join_maps_imp<mpl::true_, MapR, MapL>::type type;
38};
39
40
41//=============================================================================
42namespace join_maps_detail
43{
44 //The loop
45 template<bool done, class iter, class end_iter, class OldMap>
46 struct next_elem
47 {
48 typedef typename mpl::deref< iter >::type MapElem;
49 typedef typename mpl::insert< OldMap, MapElem >::type NewMap;
50 typedef typename mpl::next<iter>::type next_iter;
51 typedef typename next_elem<boost::is_same<next_iter, end_iter>::value
52 , next_iter
53 , end_iter
54 , NewMap >::type type;
55 };
56
57 //Loop termination
58 template<class iter, class end_iter, class NewMap>
59 struct next_elem<true, iter, end_iter, NewMap >
60 {
61 typedef NewMap type;
62 };
63
64};
65
66//=============================================================================
67//MapL is smaller than MapR, so add L to R
68template< class MapL, class MapR >
69struct join_maps_imp<mpl::true_, MapL, MapR>
70{
71
72 //Initialize the loop
73 typedef typename mpl::begin<MapL>::type iter;
74 typedef typename mpl::end<MapL>::type end_iter;
75
76 typedef typename join_maps_detail::next_elem<false
77 , iter
78 , end_iter
79 , MapR>::type type;
80
81};
82
83//=============================================================================
84template<int i>
85struct print {};
86
87//=============================================================================
88template<int i>
89std::ostream& operator<<(std::ostream& out, const print<i>&)
90{
91 out << i;
92 return out;
93}
94
95//=============================================================================
96 struct map_printer
97 {
98 template <class T>
99 inline void operator() (T) const
100 {
101 std::cout << " " << typename T::second();
102 }
103 };
104
105/*###################################################################*/
106int main(int argc, const char* argv[])
107{
108 //Create a couple of maps using insert (this replicates the actual code)
109 typedef mpl::insert<mpl::map<>, mpl::pair< mpl::int_<0>, print<0> > >::type map0;
110 typedef mpl::insert<map0 , mpl::pair< mpl::int_<1>, print<1> > >::type map1;
111 typedef mpl::insert<map1 , mpl::pair< mpl::int_<2>, print<2> > >::type map2;
112
113 typedef mpl::insert<mpl::map<>, mpl::pair< mpl::int_<3>, print<3> > >::type map3;
114 typedef mpl::insert<map3 , mpl::pair< mpl::int_<4>, print<4> > >::type map4;
115 typedef mpl::insert<map4 , mpl::pair< mpl::int_<5>, print<5> > >::type map5;
116
117 //Erease a couple of keys
118 typedef mpl::erase_key<map2, mpl::int_<1> >::type map_erase1;
119 typedef mpl::erase_key<map5, mpl::int_<4> >::type map_erase2;
120
121 //Join the maps into a single map
122 typedef join_maps< map2 , map_erase2 >::type join1;
123 typedef join_maps< map_erase1, map5 >::type join2;
124 typedef join_maps< map_erase1, map_erase2 >::type join3;
125
126 //Print out the resuling maps
127 std::cout << std::endl;
128 boost::mpl::for_each< join1 >(map_printer()); //Works
129
130 std::cout << std::endl;
131 boost::mpl::for_each< join2 >(map_printer()); //Works
132
133 std::cout << std::endl;
134 boost::mpl::for_each< join3 >(map_printer()); //MSVC 9 error (works with CYGWIN GCC 4.3.2 )
135
136 std::cout << std::endl;
137
138}
139