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