1 
2 // Copyright Aleksey Gurtovoy 2003-2004
3 // Copyright David Abrahams 2003-2004
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // See http://www.boost.org/libs/mpl for documentation.
10 
11 // $Id$
12 // $Date$
13 // $Revision$
14 
15 #include <boost/mpl/map.hpp>
16 #include <boost/mpl/insert.hpp>
17 #include <boost/mpl/erase_key.hpp>
18 #include <boost/mpl/erase_key.hpp>
19 #include <boost/mpl/contains.hpp>
20 #include <boost/mpl/at.hpp>
21 #include <boost/mpl/clear.hpp>
22 #include <boost/mpl/has_key.hpp>
23 #include <boost/mpl/order.hpp>
24 #include <boost/mpl/size.hpp>
25 #include <boost/mpl/empty.hpp>
26 #include <boost/mpl/begin_end.hpp>
27 #include <boost/type_traits/is_same.hpp>
28 
29 #include <boost/mpl/aux_/test.hpp>
30 
31 
MPL_TEST_CASE()32 MPL_TEST_CASE()
33 {
34     typedef map2<
35           mpl::pair<int,unsigned>
36         , mpl::pair<char,unsigned char>
37         > m_;
38 
39     typedef erase_key<m_,char>::type m;
40 
41     MPL_ASSERT_RELATION( size<m>::type::value, ==, 1 );
42     MPL_ASSERT_NOT(( empty<m> ));
43     MPL_ASSERT(( is_same< clear<m>::type,map0<> > ));
44 
45     MPL_ASSERT(( is_same< at<m,int>::type,unsigned > ));
46     MPL_ASSERT(( is_same< at<m,char>::type,void_ > ));
47     MPL_ASSERT(( contains< m,mpl::pair<int,unsigned> > ));
48     MPL_ASSERT_NOT(( contains< m,mpl::pair<int,int> > ));
49     MPL_ASSERT_NOT(( contains< m,mpl::pair<char,unsigned char> > ));
50 
51     MPL_ASSERT_NOT(( has_key<m,char>::type ));
52     MPL_ASSERT(( has_key<m,int>::type ));
53 
54     MPL_ASSERT_NOT(( is_same< order<m,int>::type, void_ > ));
55     MPL_ASSERT(( is_same< order<m,char>::type,void_ > ));
56 
57     typedef begin<m>::type first;
58     typedef end<m>::type last;
59 
60     MPL_ASSERT(( is_same< deref<first>::type,mpl::pair<int,unsigned> > ));
61     MPL_ASSERT(( is_same< next<first>::type,last > ));
62 
63     typedef insert<m,mpl::pair<char,long> >::type m2;
64 
65     MPL_ASSERT_RELATION( size<m2>::type::value, ==, 2 );
66     MPL_ASSERT_NOT(( empty<m2>::type ));
67     MPL_ASSERT(( is_same< clear<m2>::type,map0<> > ));
68     MPL_ASSERT(( is_same< at<m2,int>::type,unsigned > ));
69     MPL_ASSERT(( is_same< at<m2,char>::type,long > ));
70 
71     MPL_ASSERT(( contains< m2,mpl::pair<int,unsigned> > ));
72     MPL_ASSERT_NOT(( contains< m2,mpl::pair<int,int> > ));
73     MPL_ASSERT_NOT(( contains< m2,mpl::pair<char,unsigned char> > ));
74     MPL_ASSERT(( contains< m2,mpl::pair<char,long> > ));
75 
76     MPL_ASSERT(( has_key<m2,char>::type ));
77     MPL_ASSERT_NOT(( has_key<m2,long>::type ));
78     MPL_ASSERT_NOT(( is_same< order<m2,int>::type, void_ > ));
79     MPL_ASSERT_NOT(( is_same< order<m2,char>::type, void_ > ));
80     MPL_ASSERT_NOT(( is_same< order<m2,char>::type, order<m2,int>::type > ));
81 
82     typedef begin<m2>::type first2;
83     typedef end<m2>::type last2;
84 
85     MPL_ASSERT(( is_same<deref<first2>::type,mpl::pair<int,unsigned> > ));
86     typedef next<first2>::type iter;
87     MPL_ASSERT(( is_same<deref<iter>::type,mpl::pair<char,long> > ));
88     MPL_ASSERT(( is_same< next<iter>::type,last2 > ));
89 
90     typedef insert<m2,mpl::pair<int,unsigned> >::type s2_1;
91     MPL_ASSERT(( is_same<m2,s2_1> ));
92 
93     typedef insert<m2,mpl::pair<long,unsigned> >::type m3;
94     MPL_ASSERT_RELATION( size<m3>::type::value, ==, 3 );
95     MPL_ASSERT(( has_key<m3,long>::type ));
96     MPL_ASSERT(( has_key<m3,int>::type ));
97     MPL_ASSERT(( has_key<m3,char>::type ));
98     MPL_ASSERT(( contains< m3,mpl::pair<long,unsigned> > ));
99     MPL_ASSERT(( contains< m3,mpl::pair<int,unsigned> > ));
100 
101     typedef insert<m,mpl::pair<char,long> >::type m1;
102     MPL_ASSERT_RELATION( size<m1>::type::value, ==, 2 );
103     MPL_ASSERT(( is_same< at<m1,int>::type,unsigned > ));
104     MPL_ASSERT(( is_same< at<m1,char>::type,long > ));
105 
106     MPL_ASSERT(( contains< m1,mpl::pair<int,unsigned> > ));
107     MPL_ASSERT_NOT(( contains< m1,mpl::pair<int,int> > ));
108     MPL_ASSERT_NOT(( contains< m1,mpl::pair<char,unsigned char> > ));
109     MPL_ASSERT(( contains< m1,mpl::pair<char,long> > ));
110 
111     MPL_ASSERT(( is_same< m1,m2 > ));
112 
113     typedef erase_key<m1,char>::type m_1;
114     MPL_ASSERT(( is_same<m,m_1> ));
115     MPL_ASSERT_RELATION( size<m_1>::type::value, ==, 1 );
116     MPL_ASSERT(( is_same< at<m_1,char>::type,void_ > ));
117     MPL_ASSERT(( is_same< at<m_1,int>::type,unsigned > ));
118 
119     typedef erase_key<m3,char>::type m2_1;
120     MPL_ASSERT_RELATION( size<m2_1>::type::value, ==, 2 );
121     MPL_ASSERT(( is_same< at<m2_1,char>::type,void_ > ));
122     MPL_ASSERT(( is_same< at<m2_1,int>::type,unsigned > ));
123     MPL_ASSERT(( is_same< at<m2_1,long>::type,unsigned > ));
124 }
125 
MPL_TEST_CASE()126 MPL_TEST_CASE()
127 {
128     typedef map0<> m;
129 
130     MPL_ASSERT_RELATION( size<m>::type::value, ==, 0 );
131     MPL_ASSERT(( empty<m>::type ));
132 
133     MPL_ASSERT(( is_same< clear<m>::type,map0<> > ));
134     MPL_ASSERT(( is_same< at<m,char>::type,void_ > ));
135 
136     MPL_ASSERT_NOT(( has_key<m,char>::type ));
137     MPL_ASSERT_NOT(( has_key<m,int>::type ));
138     MPL_ASSERT_NOT(( has_key<m,UDT>::type ));
139     MPL_ASSERT_NOT(( has_key<m,incomplete>::type ));
140 
141     MPL_ASSERT_NOT(( has_key<m,char const>::type ));
142     MPL_ASSERT_NOT(( has_key<m,int const>::type ));
143     MPL_ASSERT_NOT(( has_key<m,UDT const>::type ));
144     MPL_ASSERT_NOT(( has_key<m,incomplete const>::type ));
145 
146     MPL_ASSERT_NOT(( has_key<m,int*>::type ));
147     MPL_ASSERT_NOT(( has_key<m,UDT*>::type ));
148     MPL_ASSERT_NOT(( has_key<m,incomplete*>::type ));
149 
150     MPL_ASSERT_NOT(( has_key<m,int&>::type ));
151     MPL_ASSERT_NOT(( has_key<m,UDT&>::type ));
152     MPL_ASSERT_NOT(( has_key<m,incomplete&>::type ));
153 
154     typedef insert<m,mpl::pair<char,int> >::type m1;
155     MPL_ASSERT_RELATION( size<m1>::type::value, ==, 1 );
156     MPL_ASSERT(( is_same< at<m1,char>::type,int > ));
157 
158     typedef erase_key<m,char>::type m0_1;
159     MPL_ASSERT_RELATION( size<m0_1>::type::value, ==, 0 );
160     MPL_ASSERT(( is_same< at<m0_1,char>::type,void_ > ));
161 }
162 
163 // Use a template for testing so that GCC will show us the actual types involved
164 template <class M>
test()165 void test()
166 {
167     MPL_ASSERT_RELATION( size<M>::value, ==, 3 );
168 
169     typedef typename end<M>::type not_found;
170     BOOST_MPL_ASSERT_NOT(( is_same<BOOST_DEDUCED_TYPENAME find<M,mpl::pair<int,int*> >::type,not_found> ));
171     BOOST_MPL_ASSERT_NOT(( is_same<BOOST_DEDUCED_TYPENAME find<M,mpl::pair<long,long*> >::type,not_found> ));
172     BOOST_MPL_ASSERT_NOT(( is_same<BOOST_DEDUCED_TYPENAME find<M,mpl::pair<char,char*> >::type,not_found> ));
173     BOOST_MPL_ASSERT(( is_same<BOOST_DEDUCED_TYPENAME find<M,int>::type,not_found> ));
174 };
175 
MPL_TEST_CASE()176 MPL_TEST_CASE()
177 {
178     typedef map< mpl::pair<int,int*> > map_of_1_pair;
179     typedef begin<map_of_1_pair>::type iter_to_1_pair;
180 
181     BOOST_MPL_ASSERT((
182         is_same<
183              deref<iter_to_1_pair>::type
184            , mpl::pair<int,int*>
185         >
186     ));
187 
188     typedef map<
189         mpl::pair<int,int*>
190       , mpl::pair<long,long*>
191       , mpl::pair<char,char*>
192     > mymap;
193 
194     test<mymap>();
195     test<mymap::type>();
196 }
197 
MPL_TEST_CASE()198 MPL_TEST_CASE()
199 {
200     typedef mpl::erase_key<
201         mpl::map<
202             mpl::pair<char, double>
203           , mpl::pair<int, float>
204         >
205       , char
206     >::type int_to_float_map;
207 
208     typedef mpl::insert<
209         int_to_float_map
210       , mpl::pair<char, long>
211     >::type with_char_too;
212 
213     BOOST_MPL_ASSERT((
214         boost::is_same<
215             mpl::at<with_char_too, char>::type
216           , long
217         >
218     ));
219 }
220 
MPL_TEST_CASE()221 MPL_TEST_CASE()
222 {
223     typedef insert< map<>, pair<int,int> >::type little_map;
224 
225     MPL_ASSERT_RELATION(size<little_map>::value, ==, 1);
226     MPL_ASSERT_RELATION(size<little_map::type>::value, ==, 1);
227 }
228 
MPL_TEST_CASE()229 MPL_TEST_CASE()
230 {
231     typedef erase_key< map< pair<float,float>, pair<int,int> >, float >::type little_map;
232 
233     MPL_ASSERT_RELATION(size<little_map>::value, ==, 1);
234     MPL_ASSERT_RELATION(size<little_map::type>::value, ==, 1);
235 }
236