OSDN Git Service

2006-01-15 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / testsuite / testsuite_common_types.h
1 // -*- C++ -*-
2 // typelist for the C++ library testsuite. 
3 //
4 // Copyright (C) 2005 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 <ext/hash_map>
51 #include <ext/hash_set>
52 #include <tr1/unordered_map>
53 #include <tr1/unordered_set>
54
55 namespace __gnu_test
56 {
57   using __gnu_cxx::typelist;
58   using __gnu_cxx::transform;
59   using __gnu_cxx::append;
60
61   // All the allocators to test.
62   template<typename Tp, bool Thread>
63     struct allocator_policies
64     {
65       typedef Tp                                value_type;
66       typedef __gnu_cxx::new_allocator<Tp>              a1;
67       typedef __gnu_cxx::malloc_allocator<Tp>           a2;
68       typedef __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, Thread> pool_policy;
69       typedef __gnu_cxx::__mt_alloc<Tp, pool_policy>    a3;
70       typedef __gnu_cxx::bitmap_allocator<Tp>           a4;
71       typedef __gnu_cxx::__pool_alloc<Tp>               a5;
72       typedef typelist<_GLIBCXX_TYPELIST_CHAIN5(a1, a2, a3, a4, a5)> type;
73     };
74
75   // Typelists for vector, string, list, deque.
76   // XXX should just use template templates
77   template<typename Tp, bool Thread>
78     struct vectors
79     {
80       typedef Tp                                        value_type;
81
82       template<typename Tl>
83         struct vector_shell
84         {
85           typedef Tl                                    allocator_type;
86           typedef std::vector<value_type, allocator_type>       type;
87         };
88
89       typedef allocator_policies<value_type, Thread>    allocator_types;
90       typedef typename allocator_types::type            allocator_typelist;
91       typedef typename transform<allocator_typelist, vector_shell>::type type;
92     };
93
94   template<typename Tp, bool Thread>
95     struct lists
96     {
97       typedef Tp                                        value_type;
98
99       template<typename Tl>
100         struct list_shell
101         {
102           typedef Tl                                    allocator_type;
103           typedef std::list<value_type, allocator_type> type;
104         };
105
106       typedef allocator_policies<value_type, Thread>    allocator_types;
107       typedef typename allocator_types::type            allocator_typelist;
108       typedef typename transform<allocator_typelist, list_shell>::type type;
109     };
110
111   template<typename Tp, bool Thread>
112     struct deques
113     {
114       typedef Tp                                        value_type;
115
116       template<typename Tl>
117         struct deque_shell
118         {
119           typedef Tl                                    allocator_type;
120           typedef std::deque<value_type, allocator_type>        type;
121         };
122
123       typedef allocator_policies<value_type, Thread>    allocator_types;
124       typedef typename allocator_types::type            allocator_typelist;
125       typedef typename transform<allocator_typelist, deque_shell>::type type;
126     };
127
128   template<typename Tp, bool Thread>
129     struct strings
130     {
131       typedef Tp                                        value_type;
132
133       template<typename Tl>
134         struct string_shell
135         {
136           typedef Tl                                    allocator_type;
137           typedef std::char_traits<value_type>          traits_type;
138           typedef std::basic_string<value_type, traits_type, allocator_type>    type;
139         };
140
141       typedef allocator_policies<value_type, Thread>    allocator_types;
142       typedef typename allocator_types::type            allocator_typelist;
143       typedef typename transform<allocator_typelist, string_shell>::type type;
144     };
145
146   // A typelist of vector, list, deque, and string all instantiated
147   // with each of the allocator policies.
148   template<typename Tp, bool Thread>
149     struct sequence_containers
150     {
151       typedef Tp                                        value_type;
152
153       typedef typename vectors<value_type, Thread>::type vector_typelist;
154       typedef typename lists<value_type, Thread>::type   list_typelist;
155       typedef typename deques<value_type, Thread>::type  deque_typelist;
156       typedef typename strings<value_type, Thread>::type string_typelist;
157
158       typedef typename append<vector_typelist, list_typelist>::type a1;
159       typedef typename append<deque_typelist, string_typelist>::type a2;
160       typedef typename append<a1, a2>::type type;
161     };
162
163   // Typelists for map, set, hash_map, hash_set, unordered_set, unordered_map.
164   template<typename Tp, bool Thread>
165     struct maps
166     {
167       typedef Tp                                        value_type;
168       typedef Tp                                        key_type;
169       typedef std::pair<const key_type, value_type>     pair_type;
170       typedef std::less<key_type>                       compare_function;
171
172       template<typename Tl>
173         struct container
174         {
175           typedef Tl                                    allocator_type;
176           typedef std::map<key_type, value_type, compare_function, allocator_type>      type;
177         };
178
179       typedef allocator_policies<pair_type, Thread>     allocator_types;
180       typedef typename allocator_types::type            allocator_typelist;
181       typedef typename transform<allocator_typelist, container>::type type;
182     };
183
184   template<typename Tp, bool Thread>
185     struct hash_maps
186     {
187       typedef Tp                                        value_type;
188       typedef Tp                                        key_type;
189       typedef __gnu_cxx::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 __gnu_cxx::hash_map<key_type, value_type, hash_function, equality_function, allocator_type>   type;
197         };
198
199       typedef allocator_policies<value_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 unordered_maps
206     {
207       typedef Tp                                        value_type;
208       typedef Tp                                        key_type;
209       typedef std::pair<const key_type, value_type>     pair_type;
210       typedef std::tr1::hash<key_type>                  hash_function;
211       typedef std::equal_to<key_type>                   equality_function;
212
213       template<typename Tl>
214         struct container
215         {
216           typedef Tl                                    allocator_type;
217           typedef std::tr1::unordered_map<key_type, value_type, hash_function, equality_function, allocator_type>       type;
218         };
219
220       typedef allocator_policies<pair_type, Thread>     allocator_types;
221       typedef typename allocator_types::type            allocator_typelist;
222       typedef typename transform<allocator_typelist, container>::type type;
223     };
224
225   template<typename Tp, bool Thread>
226     struct sets
227     {
228       typedef Tp                                        value_type;
229       typedef Tp                                        key_type;
230       typedef std::less<key_type>                       compare_function;
231
232       template<typename Tl>
233         struct container
234         {
235           typedef Tl                                    allocator_type;
236           typedef std::set<key_type, compare_function, allocator_type>  type;
237         };
238
239       typedef allocator_policies<key_type, Thread>      allocator_types;
240       typedef typename allocator_types::type            allocator_typelist;
241       typedef typename transform<allocator_typelist, container>::type type;
242     };
243
244   template<typename Tp, bool Thread>
245     struct hash_sets
246     {
247       typedef Tp                                        value_type;
248       typedef Tp                                        key_type;
249       typedef __gnu_cxx::hash<key_type>                 hash_function;
250       typedef std::equal_to<key_type>                   equality_function;
251
252       template<typename Tl>
253         struct container
254         {
255           typedef Tl                                    allocator_type;
256           typedef __gnu_cxx::hash_set<key_type, hash_function, equality_function, allocator_type>       type;
257         };
258
259       typedef allocator_policies<key_type, Thread>      allocator_types;
260       typedef typename allocator_types::type            allocator_typelist;
261       typedef typename transform<allocator_typelist, container>::type type;
262     };
263
264   template<typename Tp, bool Thread>
265     struct unordered_sets
266     {
267       typedef Tp                                        value_type;
268       typedef Tp                                        key_type;
269       typedef std::tr1::hash<key_type>                  hash_function;
270       typedef std::equal_to<key_type>                   equality_function;
271
272       template<typename Tl>
273         struct container
274         {
275           typedef Tl                                    allocator_type;
276           typedef std::tr1::unordered_set<key_type, hash_function, equality_function, allocator_type>   type;
277         };
278
279       typedef allocator_policies<key_type, Thread>      allocator_types;
280       typedef typename allocator_types::type            allocator_typelist;
281       typedef typename transform<allocator_typelist, container>::type type;
282     };
283
284
285   // A typelist  of all associated  container types, with each  of the
286   // allocator policies.
287   template<typename Tp, bool Thread>
288     struct associative_containers
289     {
290       typedef Tp                                        value_type;
291
292       typedef typename maps<value_type, Thread>::type map_typelist;
293       typedef typename sets<value_type, Thread>::type set_typelist;
294       typedef typename hash_maps<value_type, Thread>::type hash_map_typelist;
295       typedef typename hash_sets<value_type, Thread>::type hash_set_typelist;
296       typedef typename unordered_maps<value_type, Thread>::type unordered_map_typelist;
297       typedef typename unordered_sets<value_type, Thread>::type unordered_set_typelist;
298
299       typedef typename append<map_typelist, hash_map_typelist>::type a1;
300       typedef typename append<a1, unordered_map_typelist>::type a2;
301       typedef typename append<set_typelist, hash_set_typelist>::type a3;
302       typedef typename append<a3, unordered_set_typelist>::type a4;
303       typedef typename append<a2, a4>::type type;
304     };
305
306 } // namespace __gnu_test
307
308
309 // Function template, function objects for the tests.
310 template<typename TestType>
311   struct value_type : public std::pair<const TestType, TestType>
312   {
313     inline value_type& operator++() 
314     { 
315       ++this->second;
316       return *this; 
317     }
318     
319     inline operator TestType() const { return this->second; }
320   };
321
322 template<typename Container, int Iter>
323   void
324   do_loop();
325
326 template<typename Container, int Iter>
327   void*
328   do_thread(void* p = NULL)
329   {
330     do_loop<Container, Iter>();
331     return p;
332   }
333
334 template<typename Container, int Iter, bool Thread>
335   void
336   test_container(const char* filename)
337   {
338     using namespace __gnu_test;
339     time_counter time;
340     resource_counter resource;
341     {
342       start_counters(time, resource);
343       if (!Thread)
344         {
345           // No threads, so run 4x.
346           do_loop<Container, Iter * 4>();
347         }
348       else
349         {
350 #if defined (_GLIBCXX_GCC_GTHR_POSIX_H) && !defined (NOTHREAD)
351           pthread_t  t1, t2, t3, t4;
352           pthread_create(&t1, 0, &do_thread<Container, Iter>, 0);
353           pthread_create(&t2, 0, &do_thread<Container, Iter>, 0);
354           pthread_create(&t3, 0, &do_thread<Container, Iter>, 0);
355           pthread_create(&t4, 0, &do_thread<Container, Iter>, 0);
356           
357           pthread_join(t1, NULL);
358           pthread_join(t2, NULL);
359           pthread_join(t3, NULL);
360           pthread_join(t4, NULL);
361 #endif
362         }
363       stop_counters(time, resource);
364
365       // Detailed text data.
366       Container obj;
367       int status;
368       std::ostringstream comment;
369       comment << "type: " << abi::__cxa_demangle(typeid(obj).name(),
370                                                  0, 0, &status);
371       report_header(filename, comment.str());
372       report_performance("", "", time, resource);
373
374       // Detailed data for visualization.
375       std::string vizfilename(filename);
376       vizfilename += ".dat";
377       write_viz_data(time, vizfilename.c_str());
378     }
379   }
380
381 template<bool Thread>
382   struct test_sequence
383   {
384     test_sequence(const char* filename) : _M_filename(filename) { }
385
386     template<class Container>
387       void
388       operator()(__gnu_cxx::detail::type_to_type<Container>)
389       {
390         const int i = 20000;
391         test_container<Container, i, Thread>(_M_filename); 
392       }
393
394   private:
395     const char* _M_filename;
396   };
397
398
399 inline std::string::size_type
400 sequence_find_container(std::string& type)
401 {
402   const std::string::size_type npos = std::string::npos;
403   std::string::size_type n1 = type.find("vector");
404   std::string::size_type n2 = type.find("list");
405   std::string::size_type n3 = type.find("deque");
406   std::string::size_type n4 = type.find("string");
407   
408   if (n1 != npos || n2 != npos || n3 != npos || n4 != npos)
409     return std::min(std::min(n1, n2), std::min(n3, n4));
410   else
411     throw std::runtime_error("sequence_find_container not found");
412 }
413
414 inline std::string::size_type
415 associative_find_container(std::string& type)
416 {
417   using std::string;
418   string::size_type n1 = type.find("map");
419   string::size_type n2 = type.find("set");
420   if (n1 != string::npos || n2 != string::npos)
421     return std::min(n1, n2);
422   else
423     throw std::runtime_error("associative_find_container not found");
424 }
425 #endif