OSDN Git Service

2007-10-11 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / testsuite / util / testsuite_common_types.h
1 // -*- C++ -*-
2 // typelist for the C++ library testsuite. 
3 //
4 // Copyright (C) 2005, 2007 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
21 //
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 #ifndef _TESTSUITE_COMMON_TYPES_H
32 #define _TESTSUITE_COMMON_TYPES_H 1
33
34 #include <testsuite_visualization.h>
35 #include <ext/typelist.h>
36
37 #include <ext/new_allocator.h>
38 #include <ext/malloc_allocator.h>
39 #include <ext/mt_allocator.h>
40 #include <ext/bitmap_allocator.h>
41 #include <ext/pool_allocator.h>
42
43 #include <vector>
44 #include <list>
45 #include <deque>
46 #include <string>
47
48 #include <map>
49 #include <set>
50 #include <tr1/functional>
51 #include <tr1/unordered_map>
52 #include <tr1/unordered_set>
53
54 namespace __gnu_test
55 {
56   using __gnu_cxx::typelist::node;
57   using __gnu_cxx::typelist::transform;
58   using __gnu_cxx::typelist::append;
59
60   // All the allocators to test.
61   template<typename Tp, bool Thread>
62     struct allocator_policies
63     {
64       typedef Tp                                value_type;
65       typedef __gnu_cxx::new_allocator<Tp>              a1;
66       typedef __gnu_cxx::malloc_allocator<Tp>           a2;
67       typedef __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, Thread> pool_policy;
68       typedef __gnu_cxx::__mt_alloc<Tp, pool_policy>    a3;
69       typedef __gnu_cxx::bitmap_allocator<Tp>           a4;
70       typedef __gnu_cxx::__pool_alloc<Tp>               a5;
71       typedef node<_GLIBCXX_TYPELIST_CHAIN5(a1, a2, a3, a4, a5)> type;
72     };
73
74   // Typelists for vector, string, list, deque.
75   // XXX should just use template templates
76   template<typename Tp, bool Thread>
77     struct vectors
78     {
79       typedef Tp                                        value_type;
80
81       template<typename Tl>
82         struct vector_shell
83         {
84           typedef Tl                                    allocator_type;
85           typedef std::vector<value_type, allocator_type>       type;
86         };
87
88       typedef allocator_policies<value_type, Thread>    allocator_types;
89       typedef typename allocator_types::type            allocator_typelist;
90       typedef typename transform<allocator_typelist, vector_shell>::type type;
91     };
92
93   template<typename Tp, bool Thread>
94     struct lists
95     {
96       typedef Tp                                        value_type;
97
98       template<typename Tl>
99         struct list_shell
100         {
101           typedef Tl                                    allocator_type;
102           typedef std::list<value_type, allocator_type> type;
103         };
104
105       typedef allocator_policies<value_type, Thread>    allocator_types;
106       typedef typename allocator_types::type            allocator_typelist;
107       typedef typename transform<allocator_typelist, list_shell>::type type;
108     };
109
110   template<typename Tp, bool Thread>
111     struct deques
112     {
113       typedef Tp                                        value_type;
114
115       template<typename Tl>
116         struct deque_shell
117         {
118           typedef Tl                                    allocator_type;
119           typedef std::deque<value_type, allocator_type>        type;
120         };
121
122       typedef allocator_policies<value_type, Thread>    allocator_types;
123       typedef typename allocator_types::type            allocator_typelist;
124       typedef typename transform<allocator_typelist, deque_shell>::type type;
125     };
126
127   template<typename Tp, bool Thread>
128     struct strings
129     {
130       typedef Tp                                        value_type;
131
132       template<typename Tl>
133         struct string_shell
134         {
135           typedef Tl                                    allocator_type;
136           typedef std::char_traits<value_type>          traits_type;
137           typedef std::basic_string<value_type, traits_type, allocator_type>    type;
138         };
139
140       typedef allocator_policies<value_type, Thread>    allocator_types;
141       typedef typename allocator_types::type            allocator_typelist;
142       typedef typename transform<allocator_typelist, string_shell>::type type;
143     };
144
145   // A typelist of vector, list, deque, and string all instantiated
146   // with each of the allocator policies.
147   template<typename Tp, bool Thread>
148     struct sequence_containers
149     {
150       typedef Tp                                        value_type;
151
152       typedef typename vectors<value_type, Thread>::type vector_typelist;
153       typedef typename lists<value_type, Thread>::type   list_typelist;
154       typedef typename deques<value_type, Thread>::type  deque_typelist;
155       typedef typename strings<value_type, Thread>::type string_typelist;
156
157       typedef typename append<vector_typelist, list_typelist>::type a1;
158       typedef typename append<deque_typelist, string_typelist>::type a2;
159       typedef typename append<a1, a2>::type type;
160     };
161
162   // Typelists for map, set, unordered_set, unordered_map.
163   template<typename Tp, bool Thread>
164     struct maps
165     {
166       typedef Tp                                        value_type;
167       typedef Tp                                        key_type;
168       typedef std::pair<const key_type, value_type>     pair_type;
169       typedef std::less<key_type>                       compare_function;
170
171       template<typename Tl>
172         struct container
173         {
174           typedef Tl                                    allocator_type;
175           typedef std::map<key_type, value_type, compare_function, allocator_type>      type;
176         };
177
178       typedef allocator_policies<pair_type, Thread>     allocator_types;
179       typedef typename allocator_types::type            allocator_typelist;
180       typedef typename transform<allocator_typelist, container>::type type;
181     };
182
183   template<typename Tp, bool Thread>
184     struct unordered_maps
185     {
186       typedef Tp                                        value_type;
187       typedef Tp                                        key_type;
188       typedef std::pair<const key_type, value_type>     pair_type;
189       typedef std::tr1::hash<key_type>                  hash_function;
190       typedef std::equal_to<key_type>                   equality_function;
191
192       template<typename Tl>
193         struct container
194         {
195           typedef Tl                                    allocator_type;
196           typedef std::tr1::unordered_map<key_type, value_type, hash_function, equality_function, allocator_type>       type;
197         };
198
199       typedef allocator_policies<pair_type, Thread>     allocator_types;
200       typedef typename allocator_types::type            allocator_typelist;
201       typedef typename transform<allocator_typelist, container>::type type;
202     };
203
204   template<typename Tp, bool Thread>
205     struct sets
206     {
207       typedef Tp                                        value_type;
208       typedef Tp                                        key_type;
209       typedef std::less<key_type>                       compare_function;
210
211       template<typename Tl>
212         struct container
213         {
214           typedef Tl                                    allocator_type;
215           typedef std::set<key_type, compare_function, allocator_type>  type;
216         };
217
218       typedef allocator_policies<key_type, Thread>      allocator_types;
219       typedef typename allocator_types::type            allocator_typelist;
220       typedef typename transform<allocator_typelist, container>::type type;
221     };
222
223   template<typename Tp, bool Thread>
224     struct unordered_sets
225     {
226       typedef Tp                                        value_type;
227       typedef Tp                                        key_type;
228       typedef std::tr1::hash<key_type>                  hash_function;
229       typedef std::equal_to<key_type>                   equality_function;
230
231       template<typename Tl>
232         struct container
233         {
234           typedef Tl                                    allocator_type;
235           typedef std::tr1::unordered_set<key_type, hash_function, equality_function, allocator_type>   type;
236         };
237
238       typedef allocator_policies<key_type, Thread>      allocator_types;
239       typedef typename allocator_types::type            allocator_typelist;
240       typedef typename transform<allocator_typelist, container>::type type;
241     };
242
243
244   // A typelist  of all associated  container types, with each  of the
245   // allocator policies.
246   template<typename Tp, bool Thread>
247     struct associative_containers
248     {
249       typedef Tp                                        value_type;
250
251       typedef typename maps<value_type, Thread>::type map_typelist;
252       typedef typename sets<value_type, Thread>::type set_typelist;
253       typedef typename unordered_maps<value_type, Thread>::type unordered_map_typelist;
254       typedef typename unordered_sets<value_type, Thread>::type unordered_set_typelist;
255
256       typedef typename append<map_typelist, unordered_map_typelist>::type a1;
257       typedef typename append<set_typelist, unordered_set_typelist>::type a2;
258       typedef typename append<a1, a2>::type type;
259     };
260
261 } // namespace __gnu_test
262
263
264 // Function template, function objects for the tests.
265 template<typename TestType>
266   struct value_type : public std::pair<const TestType, TestType>
267   {
268     inline value_type& operator++() 
269     { 
270       ++this->second;
271       return *this; 
272     }
273     
274     inline operator TestType() const { return this->second; }
275   };
276
277 template<typename Container, int Iter>
278   void
279   do_loop();
280
281 template<typename Container, int Iter>
282   void*
283   do_thread(void* p = NULL)
284   {
285     do_loop<Container, Iter>();
286     return p;
287   }
288
289 template<typename Container, int Iter, bool Thread>
290   void
291   test_container(const char* filename)
292   {
293     using namespace __gnu_test;
294     time_counter time;
295     resource_counter resource;
296     {
297       start_counters(time, resource);
298       if (!Thread)
299         {
300           // No threads, so run 4x.
301           do_loop<Container, Iter * 4>();
302         }
303       else
304         {
305 #if defined (_GLIBCXX_GCC_GTHR_POSIX_H) && !defined (NOTHREAD)
306           pthread_t  t1, t2, t3, t4;
307           pthread_create(&t1, 0, &do_thread<Container, Iter>, 0);
308           pthread_create(&t2, 0, &do_thread<Container, Iter>, 0);
309           pthread_create(&t3, 0, &do_thread<Container, Iter>, 0);
310           pthread_create(&t4, 0, &do_thread<Container, Iter>, 0);
311           
312           pthread_join(t1, NULL);
313           pthread_join(t2, NULL);
314           pthread_join(t3, NULL);
315           pthread_join(t4, NULL);
316 #endif
317         }
318       stop_counters(time, resource);
319
320       // Detailed text data.
321       Container obj;
322       int status;
323       std::ostringstream comment;
324       comment << "type: " << abi::__cxa_demangle(typeid(obj).name(),
325                                                  0, 0, &status);
326       report_header(filename, comment.str());
327       report_performance("", "", time, resource);
328
329       // Detailed data for visualization.
330       std::string vizfilename(filename);
331       vizfilename += ".dat";
332       write_viz_data(time, vizfilename.c_str());
333     }
334   }
335
336 template<bool Thread>
337   struct test_sequence
338   {
339     test_sequence(const char* filename) : _M_filename(filename) { }
340
341     template<class Container>
342       void
343       operator()(Container)
344       {
345         const int i = 20000;
346         test_container<Container, i, Thread>(_M_filename); 
347       }
348
349   private:
350     const char* _M_filename;
351   };
352
353
354 inline std::string::size_type
355 sequence_find_container(std::string& type)
356 {
357   const std::string::size_type npos = std::string::npos;
358   std::string::size_type n1 = type.find("vector");
359   std::string::size_type n2 = type.find("list");
360   std::string::size_type n3 = type.find("deque");
361   std::string::size_type n4 = type.find("string");
362   
363   if (n1 != npos || n2 != npos || n3 != npos || n4 != npos)
364     return std::min(std::min(n1, n2), std::min(n3, n4));
365   else
366     throw std::runtime_error("sequence_find_container not found");
367 }
368
369 inline std::string::size_type
370 associative_find_container(std::string& type)
371 {
372   using std::string;
373   string::size_type n1 = type.find("map");
374   string::size_type n2 = type.find("set");
375   if (n1 != string::npos || n2 != string::npos)
376     return std::min(n1, n2);
377   else
378     throw std::runtime_error("associative_find_container not found");
379 }
380 #endif