OSDN Git Service

2008-04-10 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, 2006, 2007, 2008 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 <algorithm>
44
45 #include <vector>
46 #include <list>
47 #include <deque>
48 #include <string>
49
50 #include <map>
51 #include <set>
52 #include <tr1/functional>
53 #include <tr1/unordered_map>
54 #include <tr1/unordered_set>
55
56 #ifdef __GXX_EXPERIMENTAL_CXX0X__
57 #include <cstdatomic>
58 #endif
59
60 namespace __gnu_test
61 {
62   using __gnu_cxx::typelist::node;
63   using __gnu_cxx::typelist::transform;
64   using __gnu_cxx::typelist::append;
65
66   // All the allocators to test.
67   template<typename Tp, bool Thread>
68     struct allocator_policies
69     {
70       typedef Tp                                value_type;
71       typedef __gnu_cxx::new_allocator<Tp>              a1;
72       typedef __gnu_cxx::malloc_allocator<Tp>           a2;
73       typedef __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, Thread> pool_policy;
74       typedef __gnu_cxx::__mt_alloc<Tp, pool_policy>    a3;
75       typedef __gnu_cxx::bitmap_allocator<Tp>           a4;
76       typedef __gnu_cxx::__pool_alloc<Tp>               a5;
77       typedef node<_GLIBCXX_TYPELIST_CHAIN5(a1, a2, a3, a4, a5)> type;
78     };
79
80   // Typelists for vector, string, list, deque.
81   // XXX should just use template templates
82   template<typename Tp, bool Thread>
83     struct vectors
84     {
85       typedef Tp                                        value_type;
86
87       template<typename Tl>
88         struct vector_shell
89         {
90           typedef Tl                                    allocator_type;
91           typedef std::vector<value_type, allocator_type>       type;
92         };
93
94       typedef allocator_policies<value_type, Thread>    allocator_types;
95       typedef typename allocator_types::type            allocator_typelist;
96       typedef typename transform<allocator_typelist, vector_shell>::type type;
97     };
98
99   template<typename Tp, bool Thread>
100     struct lists
101     {
102       typedef Tp                                        value_type;
103
104       template<typename Tl>
105         struct list_shell
106         {
107           typedef Tl                                    allocator_type;
108           typedef std::list<value_type, allocator_type> type;
109         };
110
111       typedef allocator_policies<value_type, Thread>    allocator_types;
112       typedef typename allocator_types::type            allocator_typelist;
113       typedef typename transform<allocator_typelist, list_shell>::type type;
114     };
115
116   template<typename Tp, bool Thread>
117     struct deques
118     {
119       typedef Tp                                        value_type;
120
121       template<typename Tl>
122         struct deque_shell
123         {
124           typedef Tl                                    allocator_type;
125           typedef std::deque<value_type, allocator_type>        type;
126         };
127
128       typedef allocator_policies<value_type, Thread>    allocator_types;
129       typedef typename allocator_types::type            allocator_typelist;
130       typedef typename transform<allocator_typelist, deque_shell>::type type;
131     };
132
133   template<typename Tp, bool Thread>
134     struct strings
135     {
136       typedef Tp                                        value_type;
137
138       template<typename Tl>
139         struct string_shell
140         {
141           typedef Tl                                    allocator_type;
142           typedef std::char_traits<value_type>          traits_type;
143           typedef std::basic_string<value_type, traits_type, allocator_type>    type;
144         };
145
146       typedef allocator_policies<value_type, Thread>    allocator_types;
147       typedef typename allocator_types::type            allocator_typelist;
148       typedef typename transform<allocator_typelist, string_shell>::type type;
149     };
150
151   // A typelist of vector, list, deque, and string all instantiated
152   // with each of the allocator policies.
153   template<typename Tp, bool Thread>
154     struct sequence_containers
155     {
156       typedef Tp                                        value_type;
157
158       typedef typename vectors<value_type, Thread>::type vector_typelist;
159       typedef typename lists<value_type, Thread>::type   list_typelist;
160       typedef typename deques<value_type, Thread>::type  deque_typelist;
161       typedef typename strings<value_type, Thread>::type string_typelist;
162
163       typedef typename append<vector_typelist, list_typelist>::type a1;
164       typedef typename append<deque_typelist, string_typelist>::type a2;
165       typedef typename append<a1, a2>::type type;
166     };
167
168   // Typelists for map, set, unordered_set, unordered_map.
169   template<typename Tp, bool Thread>
170     struct maps
171     {
172       typedef Tp                                        value_type;
173       typedef Tp                                        key_type;
174       typedef std::pair<const key_type, value_type>     pair_type;
175       typedef std::less<key_type>                       compare_function;
176
177       template<typename Tl>
178         struct container
179         {
180           typedef Tl                                    allocator_type;
181           typedef std::map<key_type, value_type, compare_function, allocator_type>      type;
182         };
183
184       typedef allocator_policies<pair_type, Thread>     allocator_types;
185       typedef typename allocator_types::type            allocator_typelist;
186       typedef typename transform<allocator_typelist, container>::type type;
187     };
188
189   template<typename Tp, bool Thread>
190     struct unordered_maps
191     {
192       typedef Tp                                        value_type;
193       typedef Tp                                        key_type;
194       typedef std::pair<const key_type, value_type>     pair_type;
195       typedef std::tr1::hash<key_type>                  hash_function;
196       typedef std::equal_to<key_type>                   equality_function;
197
198       template<typename Tl>
199         struct container
200         {
201           typedef Tl                                    allocator_type;
202           typedef std::tr1::unordered_map<key_type, value_type, hash_function, equality_function, allocator_type>       type;
203         };
204
205       typedef allocator_policies<pair_type, Thread>     allocator_types;
206       typedef typename allocator_types::type            allocator_typelist;
207       typedef typename transform<allocator_typelist, container>::type type;
208     };
209
210   template<typename Tp, bool Thread>
211     struct sets
212     {
213       typedef Tp                                        value_type;
214       typedef Tp                                        key_type;
215       typedef std::less<key_type>                       compare_function;
216
217       template<typename Tl>
218         struct container
219         {
220           typedef Tl                                    allocator_type;
221           typedef std::set<key_type, compare_function, allocator_type>  type;
222         };
223
224       typedef allocator_policies<key_type, Thread>      allocator_types;
225       typedef typename allocator_types::type            allocator_typelist;
226       typedef typename transform<allocator_typelist, container>::type type;
227     };
228
229   template<typename Tp, bool Thread>
230     struct unordered_sets
231     {
232       typedef Tp                                        value_type;
233       typedef Tp                                        key_type;
234       typedef std::tr1::hash<key_type>                  hash_function;
235       typedef std::equal_to<key_type>                   equality_function;
236
237       template<typename Tl>
238         struct container
239         {
240           typedef Tl                                    allocator_type;
241           typedef std::tr1::unordered_set<key_type, hash_function, equality_function, allocator_type>   type;
242         };
243
244       typedef allocator_policies<key_type, Thread>      allocator_types;
245       typedef typename allocator_types::type            allocator_typelist;
246       typedef typename transform<allocator_typelist, container>::type type;
247     };
248
249
250   // A typelist  of all associated  container types, with each  of the
251   // allocator policies.
252   template<typename Tp, bool Thread>
253     struct associative_containers
254     {
255       typedef Tp                                        value_type;
256
257       typedef typename maps<value_type, Thread>::type map_typelist;
258       typedef typename sets<value_type, Thread>::type set_typelist;
259       typedef typename unordered_maps<value_type, Thread>::type unordered_map_typelist;
260       typedef typename unordered_sets<value_type, Thread>::type unordered_set_typelist;
261
262       typedef typename append<map_typelist, unordered_map_typelist>::type a1;
263       typedef typename append<set_typelist, unordered_set_typelist>::type a2;
264       typedef typename append<a1, a2>::type type;
265     };
266
267   // A typelist of all integral types.
268   struct integral_types
269   {
270     typedef bool                a1;
271     typedef char                a2;
272     typedef signed char         a3;
273     typedef unsigned char       a4;
274     typedef short               a5;
275     typedef unsigned short      a6;
276     typedef int                 a7;
277     typedef unsigned int        a8;
278     typedef long                a9;
279     typedef unsigned long       a10;
280     typedef long long           a11;
281     typedef unsigned long long  a12;
282     typedef wchar_t             a13;
283     // typedef char16_t                 a14;
284     // typedef char16_t                 a15;
285
286     typedef node<_GLIBCXX_TYPELIST_CHAIN13(a1, a2, a3, a4, a5, a6, a7, a8, a9, 
287                                            a10, a11, a12, a13)> type;
288   };
289
290 #ifdef __GXX_EXPERIMENTAL_CXX0X__
291   template<typename Tp>
292     struct atomics
293     {
294       typedef Tp                        value_type;
295       typedef std::atomic<value_type>   type;
296     };
297
298   typedef transform<integral_types::type, atomics>::type atomics_tl;
299 #endif
300
301   // Generator to test assignment operator.
302   struct assignable
303   {
304     template<typename _T>
305       void 
306       operator()()
307       {
308         _T v1;
309         _T v2;
310         v1 = v2;
311       }
312   };
313
314   // Generator to test default constructor.
315   struct default_constructible
316   {
317     template<typename _T>
318       void 
319       operator()()
320       {
321         _T v;
322       }
323   };
324
325   // Generator to test copy constructor.
326   struct copy_constructible
327   {
328     template<typename _T>
329       void 
330       operator()()
331       {
332         _T v1;
333         _T v2(v1);
334       }
335   };
336
337   // Generator to test explicit value constructor.
338   struct explicit_value_constructible
339   {
340     template<typename _Ttype, typename _Tvalue>
341       void 
342       operator()()
343       {
344         _Tvalue a;
345         _Ttype v(a);
346       }
347   };
348
349 } // namespace __gnu_test
350
351
352 // Function template, function objects for the tests.
353 template<typename TestType>
354   struct value_type : public std::pair<const TestType, TestType>
355   {
356     inline value_type& operator++() 
357     { 
358       ++this->second;
359       return *this; 
360     }
361     
362     inline operator TestType() const { return this->second; }
363   };
364
365 template<typename Container, int Iter>
366   void
367   do_loop();
368
369 template<typename Container, int Iter>
370   void*
371   do_thread(void* p = NULL)
372   {
373     do_loop<Container, Iter>();
374     return p;
375   }
376
377 template<typename Container, int Iter, bool Thread>
378   void
379   test_container(const char* filename)
380   {
381     using namespace __gnu_test;
382     time_counter time;
383     resource_counter resource;
384     {
385       start_counters(time, resource);
386       if (!Thread)
387         {
388           // No threads, so run 4x.
389           do_loop<Container, Iter * 4>();
390         }
391       else
392         {
393 #if defined (_GLIBCXX_GCC_GTHR_POSIX_H) && !defined (NOTHREAD)
394           pthread_t  t1, t2, t3, t4;
395           pthread_create(&t1, 0, &do_thread<Container, Iter>, 0);
396           pthread_create(&t2, 0, &do_thread<Container, Iter>, 0);
397           pthread_create(&t3, 0, &do_thread<Container, Iter>, 0);
398           pthread_create(&t4, 0, &do_thread<Container, Iter>, 0);
399           
400           pthread_join(t1, NULL);
401           pthread_join(t2, NULL);
402           pthread_join(t3, NULL);
403           pthread_join(t4, NULL);
404 #endif
405         }
406       stop_counters(time, resource);
407
408       // Detailed text data.
409       Container obj;
410       int status;
411       std::ostringstream comment;
412       comment << "type: " << abi::__cxa_demangle(typeid(obj).name(),
413                                                  0, 0, &status);
414       report_header(filename, comment.str());
415       report_performance("", "", time, resource);
416
417       // Detailed data for visualization.
418       std::string vizfilename(filename);
419       vizfilename += ".dat";
420       write_viz_data(time, vizfilename.c_str());
421     }
422   }
423
424 template<bool Thread>
425   struct test_sequence
426   {
427     test_sequence(const char* filename) : _M_filename(filename) { }
428
429     template<class Container>
430       void
431       operator()(Container)
432       {
433         const int i = 20000;
434         test_container<Container, i, Thread>(_M_filename); 
435       }
436
437   private:
438     const char* _M_filename;
439   };
440
441
442 inline std::string::size_type
443 sequence_find_container(std::string& type)
444 {
445   const std::string::size_type npos = std::string::npos;
446   std::string::size_type n1 = type.find("vector");
447   std::string::size_type n2 = type.find("list");
448   std::string::size_type n3 = type.find("deque");
449   std::string::size_type n4 = type.find("string");
450   
451   if (n1 != npos || n2 != npos || n3 != npos || n4 != npos)
452     return std::min(std::min(n1, n2), std::min(n3, n4));
453   else
454     throw std::runtime_error("sequence_find_container not found");
455 }
456
457 inline std::string::size_type
458 associative_find_container(std::string& type)
459 {
460   using std::string;
461   string::size_type n1 = type.find("map");
462   string::size_type n2 = type.find("set");
463   if (n1 != string::npos || n2 != string::npos)
464     return std::min(n1, n2);
465   else
466     throw std::runtime_error("associative_find_container not found");
467 }
468 #endif