1// -*- C++ -*-
2// Utility subroutines for the C++ library testsuite.
3//
4// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
5// Free Software Foundation, Inc.
6//
7// This file is part of the GNU ISO C++ Library.  This library is free
8// software; you can redistribute it and/or modify it under the
9// terms of the GNU General Public License as published by the
10// Free Software Foundation; either version 2, or (at your option)
11// any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License along
19// with this library; see the file COPYING.  If not, write to the Free
20// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21// USA.
22//
23// As a special exception, you may use this file as part of a free software
24// library without restriction.  Specifically, if other files instantiate
25// templates or use macros or inline functions from this file, or you compile
26// this file and link it with other files to produce an executable, this
27// file does not by itself cause the resulting executable to be covered by
28// the GNU General Public License.  This exception does not however
29// invalidate any other reasons why the executable file might be covered by
30// the GNU General Public License.
31
32// This file provides the following:
33//
34// 1)  VERIFY(), via _GLIBCXX_ASSERT, from Brent Verner <brent@rcfile.org>.
35//   This file is included in the various testsuite programs to provide
36//   #define(able) assert() behavior for debugging/testing. It may be
37//   a suitable location for other furry woodland creatures as well.
38//
39// 2)  set_memory_limits()
40//   set_memory_limits() uses setrlimit() to restrict dynamic memory
41//   allocation.  We provide a default memory limit if none is passed by the
42//   calling application.  The argument to set_memory_limits() is the
43//   limit in megabytes (a floating-point number).  If _GLIBCXX_RES_LIMITS is
44//   not #defined before including this header, then no limiting is attempted.
45//
46// 3)  counter
47//   This is a POD with a static data member, gnu_counting_struct::count,
48//   which starts at zero, increments on instance construction, and decrements
49//   on instance destruction.  "assert_count(n)" can be called to VERIFY()
50//   that the count equals N.
51//
52// 4)  copy_tracker, from Stephen M. Webb <stephen@bregmasoft.com>.
53//   A class with nontrivial ctor/dtor that provides the ability to track the
54//   number of copy ctors and dtors, and will throw on demand during copy.
55
56#ifndef _GLIBCXX_TESTSUITE_HOOKS_H
57#define _GLIBCXX_TESTSUITE_HOOKS_H
58
59#include <bits/c++config.h>
60#include <bits/functexcept.h>
61#include <cstddef>
62#include <locale>
63#ifdef _GLIBCXX_HAVE_SYS_STAT_H
64#include <sys/stat.h>
65#endif
66
67#ifdef _GLIBCXX_ASSERT
68# include <cassert>
69# define VERIFY(fn) assert(fn)
70#else
71# define VERIFY(fn) test &= (fn)
72#endif
73
74#ifdef _GLIBCXX_HAVE_UNISTD_H
75# include <unistd.h>
76#else
77# define unlink(x)
78#endif
79
80namespace __gnu_test
81{
82  // All macros are defined in GLIBCXX_CONFIGURE_TESTSUITE and imported
83  // from c++config.h
84
85  // Set memory limits if possible, if not set to 0.
86#ifndef _GLIBCXX_RES_LIMITS
87#  define MEMLIMIT_MB 0
88#else
89# ifndef MEMLIMIT_MB
90#  define MEMLIMIT_MB 16.0
91# endif
92#endif
93  extern void
94  set_memory_limits(float __size = MEMLIMIT_MB);
95
96  extern void
97  set_file_limit(unsigned long __size);
98
99  // Check mangled name demangles (using __cxa_demangle) as expected.
100  void
101  verify_demangle(const char* mangled, const char* wanted);
102
103  // 17.3.2.1.2 - Bitmask types [lib.bitmask.types]
104  // bitmask_operators
105  template<typename bitmask_type>
106    void
107    bitmask_operators(bitmask_type a = bitmask_type(),
108		      bitmask_type b = bitmask_type())
109    {
110      a | b;
111      a & b;
112      a ^ b;
113      ~b;
114      a |= b; // set
115      a &= ~b; // clear
116      a ^= b;
117    }
118
119  // Simple callback structure for variable numbers of tests (all with
120  // same signature).  Assume all unit tests are of the signature
121  // void test01();
122  class func_callback
123  {
124  public:
125    typedef void (*test_type) (void);
126
127  private:
128    int		_M_size;
129    test_type	_M_tests[15];
130
131    func_callback&
132    operator=(const func_callback&);
133
134    func_callback(const func_callback&);
135
136  public:
137    func_callback(): _M_size(0) { };
138
139    int
140    size() const { return _M_size; }
141
142    const test_type*
143    tests() const { return _M_tests; }
144
145    void
146    push_back(test_type test)
147    {
148      _M_tests[_M_size] = test;
149      ++_M_size;
150    }
151  };
152
153
154  // Run select unit tests after setting global locale.
155  void
156  run_tests_wrapped_locale(const char*, const func_callback&);
157
158  // Run select unit tests after setting environment variables.
159  void
160  run_tests_wrapped_env(const char*, const char*, const func_callback&);
161
162
163  // For containers (23.1/3).
164  struct NonDefaultConstructible
165  {
166    NonDefaultConstructible(int) { }
167  };
168
169  inline bool
170  operator==(const NonDefaultConstructible&,
171	     const NonDefaultConstructible&)
172  { return false; }
173
174  inline bool
175  operator<(const NonDefaultConstructible&,
176	    const NonDefaultConstructible&)
177  { return false; }
178
179
180  // Counting.
181  struct counter
182  {
183    // Specifically and glaringly-obviously marked 'signed' so that when
184    // COUNT mistakenly goes negative, we can track the patterns of
185    // deletions more easily.
186    typedef  signed int     size_type;
187    static size_type   count;
188    counter() { ++count; }
189    counter (const counter&) { ++count; }
190    ~counter() { --count; }
191  };
192
193#define assert_count(n)   VERIFY(__gnu_test::counter::count == n)
194
195  // A (static) class for counting copy constructors and possibly throwing an
196  // exception on a desired count.
197  class copy_constructor
198  {
199  public:
200    static unsigned int
201    count() { return count_; }
202
203    static void
204    mark_call()
205    {
206      count_++;
207      if (count_ == throw_on_)
208	std::__throw_runtime_error("copy_constructor::mark_call");
209    }
210
211    static void
212    reset()
213    {
214      count_ = 0;
215      throw_on_ = 0;
216    }
217
218    static void
219    throw_on(unsigned int count) { throw_on_ = count; }
220
221  private:
222    static unsigned int count_;
223    static unsigned int throw_on_;
224  };
225
226  // A (static) class for counting assignment operator calls and
227  // possibly throwing an exception on a desired count.
228  class assignment_operator
229  {
230  public:
231    static unsigned int
232    count() { return count_; }
233
234    static void
235    mark_call()
236    {
237      count_++;
238      if (count_ == throw_on_)
239	std::__throw_runtime_error("assignment_operator::mark_call");
240    }
241
242    static void
243    reset()
244    {
245      count_ = 0;
246      throw_on_ = 0;
247    }
248
249    static void
250    throw_on(unsigned int count) { throw_on_ = count; }
251
252  private:
253    static unsigned int count_;
254    static unsigned int throw_on_;
255  };
256
257  // A (static) class for tracking calls to an object's destructor.
258  class destructor
259  {
260  public:
261    static unsigned int
262    count() { return _M_count; }
263
264    static void
265    mark_call() { _M_count++; }
266
267    static void
268    reset() { _M_count = 0; }
269
270  private:
271    static unsigned int _M_count;
272  };
273
274  // An class of objects that can be used for validating various
275  // behaviours and guarantees of containers and algorithms defined in
276  // the standard library.
277  class copy_tracker
278  {
279  public:
280    // Creates a copy-tracking object with the given ID number.  If
281    // "throw_on_copy" is set, an exception will be thrown if an
282    // attempt is made to copy this object.
283    copy_tracker(int id = next_id_--, bool throw_on_copy = false)
284    : id_(id) , throw_on_copy_(throw_on_copy) { }
285
286    // Copy-constructs the object, marking a call to the copy
287    // constructor and forcing an exception if indicated.
288    copy_tracker(const copy_tracker& rhs)
289    : id_(rhs.id()), throw_on_copy_(rhs.throw_on_copy_)
290    {
291      if (throw_on_copy_)
292	copy_constructor::throw_on(copy_constructor::count() + 1);
293      copy_constructor::mark_call();
294    }
295
296    // Assigns the value of another object to this one, tracking the
297    // number of times this member function has been called and if the
298    // other object is supposed to throw an exception when it is
299    // copied, well, make it so.
300    copy_tracker&
301    operator=(const copy_tracker& rhs)
302    {
303      id_ = rhs.id();
304      if (rhs.throw_on_copy_)
305        assignment_operator::throw_on(assignment_operator::count() + 1);
306      assignment_operator::mark_call();
307      return *this;
308    }
309
310    ~copy_tracker()
311    { destructor::mark_call(); }
312
313    int
314    id() const { return id_; }
315
316  private:
317    int   id_;
318    const bool  throw_on_copy_;
319
320  public:
321    static void
322    reset()
323    {
324      copy_constructor::reset();
325      assignment_operator::reset();
326      destructor::reset();
327    }
328
329    // for backwards-compatibility
330    static int
331    copyCount()
332    { return copy_constructor::count(); }
333
334    // for backwards-compatibility
335    static int
336    dtorCount()
337    { return destructor::count(); }
338
339  private:
340    static int next_id_;
341  };
342
343  inline bool
344  operator==(const copy_tracker& lhs, const copy_tracker& rhs)
345  { return lhs.id() == rhs.id(); }
346
347  // Class for checking required type conversions, implicit and
348  // explicit for given library data structures.
349  template<typename _Container>
350    struct conversion
351    {
352      typedef typename _Container::const_iterator const_iterator;
353
354      // Implicit conversion iterator to const_iterator.
355      static const_iterator
356      iterator_to_const_iterator()
357      {
358	_Container v;
359	const_iterator it = v.begin();
360	const_iterator end = v.end();
361	return it == end ? v.end() : it;
362      }
363    };
364
365  // A binary semaphore for use across multiple processes.
366  class semaphore
367  {
368  public:
369    // Creates a binary semaphore.  The semaphore is initially in the
370    // unsignaled state.
371    semaphore();
372
373    // Destroy the semaphore.
374    ~semaphore();
375
376    // Signal the semaphore.  If there are processes blocked in
377    // "wait", exactly one will be permitted to proceed.
378    void signal();
379
380    // Wait until the semaphore is signaled.
381    void wait();
382
383  private:
384    int sem_set_;
385
386    pid_t pid_;
387  };
388
389  // For use in 22_locale/time_get and time_put.
390  tm test_tm(int sec, int min, int hour, int mday, int mon,
391	     int year, int wday, int yday, int isdst);
392
393} // namespace __gnu_test
394
395#endif // _GLIBCXX_TESTSUITE_HOOKS_H
396
397