1 // -*- C++ -*- 2 // Utility subroutines for the C++ library testsuite. 3 // 4 // Copyright (C) 2000, 2001, 2002, 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 // This file provides the following: 32 // 33 // 1) VERIFY(), via DEBUG_ASSERT, from Brent Verner <brent@rcfile.org>. 34 // This file is included in the various testsuite programs to provide 35 // #define(able) assert() behavior for debugging/testing. It may be 36 // a suitable location for other furry woodland creatures as well. 37 // 38 // 2) set_memory_limits() 39 // set_memory_limits() uses setrlimit() to restrict dynamic memory 40 // allocation. We provide a default memory limit if none is passed by the 41 // calling application. The argument to set_memory_limits() is the 42 // limit in megabytes (a floating-point number). If _GLIBCPP_MEM_LIMITS is 43 // not #defined before including this header, then no limiting is attempted. 44 // 45 // 3) counter 46 // This is a POD with a static data member, gnu_counting_struct::count, 47 // which starts at zero, increments on instance construction, and decrements 48 // on instance destruction. "assert_count(n)" can be called to VERIFY() 49 // that the count equals N. 50 // 51 // 4) copy_tracker, from Stephen M. Webb <stephen@bregmasoft.com>. 52 // A class with nontrivial ctor/dtor that provides the ability to track the 53 // number of copy ctors and dtors, and will throw on demand during copy. 54 // 55 // 5) pod_char, pod_int, , abstract character classes and 56 // char_traits specializations for testing instantiations. 57 58 #ifndef _GLIBCPP_TESTSUITE_HOOKS_H 59 #define _GLIBCPP_TESTSUITE_HOOKS_H 60 61 #include <bits/c++config.h> 62 #include <bits/functexcept.h> 63 #include <cstddef> 64 #ifdef DEBUG_ASSERT 65 # include <cassert> 66 # define VERIFY(fn) assert(fn) 67 #else 68 # define VERIFY(fn) test &= (fn) 69 #endif 70 #include <list> 71 72 namespace __gnu_cxx_test 73 { 74 // All macros are defined in GLIBCPP_CONFIGURE_TESTSUITE and imported 75 // from c++config.h 76 77 // Set memory limits if possible, if not set to 0. 78 #ifndef _GLIBCPP_MEM_LIMITS 79 # define MEMLIMIT_MB 0 80 #else 81 # ifndef MEMLIMIT_MB 82 # define MEMLIMIT_MB 16.0 83 # endif 84 #endif 85 extern void 86 set_memory_limits(float __size = MEMLIMIT_MB); 87 88 // Simple callback structure for variable numbers of tests (all with 89 // same signature). Assume all unit tests are of the signature 90 // void test01(); 91 typedef void (*test_func) (void); 92 typedef std::list<test_func> func_callback; 93 94 // Run select unit tests after setting global locale. 95 void 96 run_tests_wrapped_locale(const char*, const func_callback&); 97 98 // Run select unit tests after setting environment variables. 99 void 100 run_tests_wrapped_env(const char*, const char*, const func_callback&); 101 102 // Test data types. 103 struct pod_char 104 { 105 unsigned char c; 106 }; 107 108 struct pod_int 109 { 110 int i; 111 }; 112 113 struct pod_unsigned_int 114 { 115 unsigned int i; 116 }; 117 118 struct pod_long 119 { 120 unsigned long i; 121 }; 122 123 struct state 124 { 125 unsigned long l; 126 unsigned long l2; 127 }; 128 129 // Counting. 130 struct counter 131 { 132 // Specifically and glaringly-obviously marked 'signed' so that when 133 // COUNT mistakenly goes negative, we can track the patterns of 134 // deletions more easily. 135 typedef signed int size_type; 136 static size_type count; countercounter137 counter() { ++count; } countercounter138 counter (const counter&) { ++count; } ~countercounter139 ~counter() { --count; } 140 }; 141 142 #define assert_count(n) VERIFY(__gnu_cxx_test::counter::count == n) 143 144 // A (static) class for counting copy constructors and possibly throwing an 145 // exception on a desired count. 146 class copy_constructor 147 { 148 public: 149 static unsigned int count()150 count() { return count_; } 151 152 static void mark_call()153 mark_call() 154 { 155 count_++; 156 if (count_ == throw_on_) 157 __throw_exception_again "copy constructor exception"; 158 } 159 160 static void reset()161 reset() 162 { 163 count_ = 0; 164 throw_on_ = 0; 165 } 166 167 static void throw_on(unsigned int count)168 throw_on(unsigned int count) { throw_on_ = count; } 169 170 private: 171 static unsigned int count_; 172 static unsigned int throw_on_; 173 }; 174 175 // A (static) class for counting assignment operator calls and 176 // possibly throwing an exception on a desired count. 177 class assignment_operator 178 { 179 public: 180 static unsigned int count()181 count() { return count_; } 182 183 static void mark_call()184 mark_call() 185 { 186 count_++; 187 if (count_ == throw_on_) 188 __throw_exception_again "assignment operator exception"; 189 } 190 191 static void reset()192 reset() 193 { 194 count_ = 0; 195 throw_on_ = 0; 196 } 197 198 static void throw_on(unsigned int count)199 throw_on(unsigned int count) { throw_on_ = count; } 200 201 private: 202 static unsigned int count_; 203 static unsigned int throw_on_; 204 }; 205 206 // A (static) class for tracking calls to an object's destructor. 207 class destructor 208 { 209 public: 210 static unsigned int count()211 count() { return _M_count; } 212 213 static void mark_call()214 mark_call() { _M_count++; } 215 216 static void reset()217 reset() { _M_count = 0; } 218 219 private: 220 static unsigned int _M_count; 221 }; 222 223 // An class of objects that can be used for validating various 224 // behaviours and guarantees of containers and algorithms defined in 225 // the standard library. 226 class copy_tracker 227 { 228 public: 229 // Creates a copy-tracking object with the given ID number. If 230 // "throw_on_copy" is set, an exception will be thrown if an 231 // attempt is made to copy this object. 232 copy_tracker(int id = next_id_--, bool throw_on_copy = false) id_(id)233 : id_(id) , throw_on_copy_(throw_on_copy) { } 234 235 // Copy-constructs the object, marking a call to the copy 236 // constructor and forcing an exception if indicated. copy_tracker(const copy_tracker & rhs)237 copy_tracker(const copy_tracker& rhs) 238 : id_(rhs.id()), throw_on_copy_(rhs.throw_on_copy_) 239 { 240 int kkk = throw_on_copy_; 241 if (throw_on_copy_) 242 copy_constructor::throw_on(copy_constructor::count() + 1); 243 copy_constructor::mark_call(); 244 } 245 246 // Assigns the value of another object to this one, tracking the 247 // number of times this member function has been called and if the 248 // other object is supposed to throw an exception when it is 249 // copied, well, make it so. 250 copy_tracker& 251 operator=(const copy_tracker& rhs) 252 { 253 id_ = rhs.id(); 254 if (rhs.throw_on_copy_) 255 assignment_operator::throw_on(assignment_operator::count() + 1); 256 assignment_operator::mark_call(); 257 } 258 ~copy_tracker()259 ~copy_tracker() 260 { destructor::mark_call(); } 261 262 int id()263 id() const { return id_; } 264 265 private: 266 int id_; 267 const bool throw_on_copy_; 268 269 public: 270 static void reset()271 reset() 272 { 273 copy_constructor::reset(); 274 assignment_operator::reset(); 275 destructor::reset(); 276 } 277 278 // for backwards-compatibility 279 static int copyCount()280 copyCount() 281 { return copy_constructor::count(); } 282 283 // for backwards-compatibility 284 static int dtorCount()285 dtorCount() 286 { return destructor::count(); } 287 288 private: 289 static int next_id_; 290 }; 291 292 inline bool 293 operator==(const copy_tracker& lhs, const copy_tracker& rhs) 294 { return lhs.id() == rhs.id(); } 295 }; // namespace __gnu_cxx_test 296 297 namespace std 298 { 299 template<class _CharT> 300 struct char_traits; 301 302 // char_traits specialization 303 template<> 304 struct char_traits<__gnu_cxx_test::pod_char> 305 { 306 typedef __gnu_cxx_test::pod_char char_type; 307 typedef __gnu_cxx_test::pod_int int_type; 308 typedef long pos_type; 309 typedef unsigned long off_type; 310 typedef __gnu_cxx_test::state state_type; 311 312 static void 313 assign(char_type& __c1, const char_type& __c2); 314 315 static bool 316 eq(const char_type& __c1, const char_type& __c2); 317 318 static bool 319 lt(const char_type& __c1, const char_type& __c2); 320 321 static int 322 compare(const char_type* __s1, const char_type* __s2, size_t __n); 323 324 static size_t 325 length(const char_type* __s); 326 327 static const char_type* 328 find(const char_type* __s, size_t __n, const char_type& __a); 329 330 static char_type* 331 move(char_type* __s1, const char_type* __s2, size_t __n); 332 333 static char_type* 334 copy(char_type* __s1, const char_type* __s2, size_t __n); 335 336 static char_type* 337 assign(char_type* __s, size_t __n, char_type __a); 338 339 static char_type 340 to_char_type(const int_type& __c); 341 342 static int_type 343 to_int_type(const char_type& __c); 344 345 static bool 346 eq_int_type(const int_type& __c1, const int_type& __c2); 347 348 static int_type 349 eof(); 350 351 static int_type 352 not_eof(const int_type& __c); 353 }; 354 } // namespace std 355 356 #endif // _GLIBCPP_TESTSUITE_HOOKS_H 357 358