Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
26.c.math.cpp
Go to the documentation of this file.
1
29// this may be the "native" header that comes with the compiler
30// do not assume that any of our stuff (i.e., macros) is available
31
32#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
33// Disable implicit inclusion to work around
34// a limitation in IBM's VisualAge 5.0.2.0 (see PR#26959)
35
36# define _RWSTD_NO_IMPLICIT_INCLUSION
37#endif
38
39#include <cstdlib>
40#include <cmath>
41
42#include <rw_any.h>
43#include <rw_driver.h>
44#include <rw_valcmp.h>
45
46
47// define function templates with the same signatures as
48// the required overloads; if the required overloads are
49// not defined, the corresponding specializations of the
50// function templates will be instantiated and called,
51// triggering an assertion
52
53#define FUN_1(name) \
54 template <class T> \
55 T name (T) { \
56 static const char* const tname = rw_any_t (T ()).type_name (); \
57 rw_assert (0, 0, __LINE__, "std::%s(%s) not declared\n", \
58 #name, tname); \
59 return T (); \
60 } typedef void unused_typedef
61
62#define FUN_2(name) \
63 template <class T> \
64 T name (T, T) { \
65 static const char* const tname = rw_any_t (T ()).type_name (); \
66 rw_assert (0, 0, __LINE__, "std::%s (%s, %s) not declared\n", \
67 #name, tname, tname); \
68 return T (); \
69 } typedef void unused_typedef
70
71#define FUN_2_PTR(name) \
72 template <class T> \
73 T name (T, T*) { \
74 static const char* const tname = rw_any_t (T ()).type_name (); \
75 rw_assert (0, 0, __LINE__, "std::%s (%s, %s*) not declared\n", \
76 #name, tname, tname); \
77 return T (); \
78 } typedef void unused_typedef
79
80#define FUN_2_INT(name) \
81 template <class T> \
82 T name (T, int) { \
83 static const char* const tname = rw_any_t (T ()).type_name (); \
84 rw_assert (0, 0, __LINE__, "std::%s (%s, int) not declared\n", \
85 #name, tname); \
86 return T (); \
87 } typedef void unused_typedef
88
89#define FUN_2_PINT(name) \
90 template <class T> \
91 T name (T, int*) { \
92 static const char* const tname = rw_any_t (T ()).type_name (); \
93 rw_assert (0, 0, __LINE__, "std::%s (%s, int*) not declared\n", \
94 #name, tname); \
95 return T (); \
96 } typedef void unused_typedef
97
98
100
101// abs() is not declared in the C header <math.h> but is required
102// to be declared in the C++ headers <math.h> and <cmath>
103FUN_1 (abs);
104FUN_1 (acos);
105FUN_1 (asin);
106FUN_1 (atan);
107FUN_2 (atan2);
108FUN_1 (ceil);
109FUN_1 (cos);
110FUN_1 (cosh);
111FUN_1 (div);
112FUN_1 (exp);
113FUN_1 (fabs);
114FUN_1 (floor);
115FUN_2 (fmod);
116FUN_2_PINT (frexp);
117FUN_2_INT (ldexp);
118FUN_1 (log);
119FUN_1 (log10);
120FUN_2_PTR (modf);
121FUN_2 (pow);
122FUN_2_INT (pow);
123FUN_1 (sin);
124FUN_1 (sinh);
125FUN_1 (sqrt);
126FUN_1 (tan);
127FUN_1 (tanh);
128
129} // namespace std
130
131
132// returns true if all `size' bytes starting at `s' are 0
133static bool
134check_bits (const char *s, std::size_t size)
135{
136 while (size-- && !s [size]);
137 return unsigned (-1) == size;
138}
139
140
141static void
142clear_bytes (void *pb, _RWSTD_SIZE_T size)
143{
144 for (_RWSTD_SIZE_T i = 0; i != size; ++i)
145 ((char*)pb)[i] = 0;
146}
147
148
149static void
150test_behavior ()
151{
152 union {
153 float f;
154 double d;
155
156#ifndef _RWSTD_NO_LONG_DOUBLE
157 long double l;
158#endif // _RWSTD_NO_LONG_DOUBLE
159
160 char buf [sizeof (long double) * 2];
161 } u;
162
163#if !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x530
164
165 // make sure functions do not overflow buffer
166 clear_bytes (u.buf, sizeof u);
167
168 const float f = std::modf (3.141592f, &u.f);
169
170 rw_assert ( 3000 == int (u.f * 1000) && 141592 == int (f * 1000000)
171 && check_bits (u.buf + sizeof (u.f), sizeof (u) - sizeof (u.f)),
172 __FILE__, __LINE__, "float std::modf (float)");
173
174#endif // SunPro > 5.3
175
176 clear_bytes (u.buf, sizeof u);
177 const double d = std::modf (3.1415926, &u.d);
178
179 rw_assert ( 3000 == int (u.d * 1000) && 1415926 == int (d * 10000000)
180 && check_bits (u.buf + sizeof (u.d), sizeof (u) - sizeof (u.d)),
181 __FILE__, __LINE__, "double std::modf (double)");
182
183#ifndef _RWSTD_NO_LONG_DOUBLE
184
185# if !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x530
186
187 clear_bytes (u.buf, sizeof u);
188 const long double l = std::modf (3.1415926L, &u.l);
189
190 rw_assert ( 3000 == int (u.l * 1000) && 1415926 == int (l * 10000000)
191 && check_bits (u.buf + sizeof (u.l), sizeof (u) - sizeof (u.l)),
192 __FILE__, __LINE__, "long double std::modf (long double)");
193
194# endif // SunPro > 5.3
195
196#endif // _RWSTD_NO_LONG_DOUBLE
197
198 // check overloads of std::pow()
199 for (int i = -10; i != 10; ++i) {
200
201 for (int j = -10; j != 10; ++j) {
202
203 if (-9 < j && j < 9) {
204 const float fi = float (i);
205 const float fj = float (j);
206
207 // verify that both versions are equivalent
208 const float xf = std::pow (fi, j);
209 const float yf = std::pow (fi, fj);
210
211 rw_assert (rw_equal (xf, yf) || (!i && j < 0),
212 0, __LINE__,
213 "std::pow (%d.0f, %d) = %g, "
214 "std::pow (%d,0f, %d.0f) = %g",
215 i, j, xf, i, j, yf);
216 }
217
218 const double id = double (i);
219 const double jd = double (j);
220
221 const double xd = std::pow (id, j);
222 const double yd = std::pow (id, jd);
223
224 rw_assert (rw_equal (xd, yd) || (!i && j < 0),
225 0, __LINE__,
226 "std::pow (%d.0, %d) = %g, "
227 "std::pow (%d.0, %d.0) = %g",
228 i, j, xd, i, j, yd);
229
230#ifndef _RWSTD_NO_LONG_DOUBLE
231
232 const long double il = _RWSTD_STATIC_CAST (long double, i);
233 const long double jl = _RWSTD_STATIC_CAST (long double, j);
234
235 const long double xl = std::pow (il, j);
236 const long double yl = std::pow (il, jl);
237
238 rw_assert (rw_equal (xl, yl) || (!i && j < 0),
239 0, __LINE__,
240 "std::pow (%d.0L, %d) = %Lg, "
241 "std::pow (%d.0L, %d.0L) = %Lg",
242 i, j, xl, i, j, yl);
243
244#endif // _RWSTD_NO_LONG_DOUBLE
245
246 }
247 }
248}
249
250
251static void
252test_declarations ()
253{
254 _USING (namespace std);
255
256 int i = 1;
257 long l = 1;
258
259 float f = 0.1;
260 double d = 0.1;
261
262#ifndef _RWSTD_NO_LONG_DOUBLE
263
264 long double ld = 0.1;
265
266# define CHECK_OVERLOADS(name) \
267 rw_info (0, 0, __LINE__, "std::%s() overloads ", #name); \
268 (void)name (f); \
269 (void)name (d); \
270 (void)name (ld)
271#else // if defined (_RWSTD_NO_LONG_DOUBLE)
272# define CHECK_OVERLOADS(name) \
273 rw_info (0, 0, __LINE__, "std::%s() overloads", #name); \
274 (void)name (f); \
275 (void)name (d)
276#endif // _RWSTD_NO_LONG_DOUBLE
277
278 CHECK_OVERLOADS (abs);
279 CHECK_OVERLOADS (acos);
280 CHECK_OVERLOADS (asin);
281 CHECK_OVERLOADS (atan);
282 CHECK_OVERLOADS (atan);
283 CHECK_OVERLOADS (ceil);
284 CHECK_OVERLOADS (cos);
285 CHECK_OVERLOADS (cosh);
286 CHECK_OVERLOADS (exp);
287 CHECK_OVERLOADS (fabs);
288 CHECK_OVERLOADS (floor);
289
290 rw_info (0, 0, __LINE__, "std::%s() overloads", "fmod");
291 (void)fmod (f, f); (void)fmod (d, d);
292
293 rw_info (0, 0, __LINE__, "std::%s() overloads", "frexp");
294 (void)frexp (f, &i); (void)frexp (d, &i);
295
296 rw_info (0, 0, __LINE__, "std::%s() overloads", "ldexp");
297 (void)ldexp (f, i); (void)ldexp (d, i);
298
299 CHECK_OVERLOADS (log);
300 CHECK_OVERLOADS (log10);
301
302 rw_info (0, 0, __LINE__, "std::%s() overloads", "modf");
303 (void)modf (f, &f); (void)modf (d, &d);
304
305 rw_info (0, 0, __LINE__, "std::%s() overloads", "pow");
306 (void)pow (f, f); (void)pow (d, d);
307 (void)pow (f, i); (void)pow (d, i);
308
309 CHECK_OVERLOADS (sin);
310 CHECK_OVERLOADS (sinh);
311 CHECK_OVERLOADS (sqrt);
312 CHECK_OVERLOADS (tan);
313 CHECK_OVERLOADS (tanh);
314
315#ifndef _RWSTD_NO_LONG_DOUBLE
316
317 (void)atan2 (ld, ld);
318 (void)fmod (ld, ld);
319 (void)frexp (ld, &i);
320 (void)ldexp (ld, i);
321 (void)modf (ld, &ld);
322 (void)pow (ld, ld);
323 (void)pow (ld, i);
324
325#endif // _RWSTD_NO_LONG_DOUBLE
326
327 rw_info (0, 0, __LINE__, "std::%s() overloads", "div");
328 (void)div (i, i);
329 (void)div (l, l);
330}
331
332
334static int no_declarations;
335static int no_behavior;
336
337
338int run_test (int, char*[])
339{
340 if (no_declarations)
341 rw_note (0, __FILE__, __LINE__, "test of declarations disabled");
342 else
343 test_declarations ();
344
345 if (no_behavior)
346 rw_note (0, __FILE__, __LINE__, "test of behavior disabled");
347 else
348 test_behavior ();
349
350 return 0;
351}
352
353
355int main (int argc, char *argv[])
356{
357 return rw_test (argc, argv, __FILE__,
358 "lib.c.math",
359 0 /* no comment */, run_test,
360 "|-no-declarations# |-no-behavior#",
361 &no_declarations, &no_behavior);
362}
#define i
Definition 17.names.cpp:126
#define u
Definition 17.names.cpp:137
#define d
Definition 17.names.cpp:115
#define f
Definition 17.names.cpp:119
#define buf
Definition 17.names.cpp:452
#define j
Definition 17.names.cpp:127
#define s
#define FUN_2_PINT(name)
Definition 26.c.math.cpp:89
int run_test(int, char *[])
#define FUN_2(name)
Definition 26.c.math.cpp:62
#define FUN_1(name)
Definition 26.c.math.cpp:53
#define FUN_2_INT(name)
Definition 26.c.math.cpp:80
#define FUN_2_PTR(name)
Definition 26.c.math.cpp:71
#define CHECK_OVERLOADS(name)
T abs(T t)
#define main
ldiv_t div(T, T)
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _USING(name)
Definition _defs.h:568
Definition json.h:5363
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
Definition driver.cpp:1681
_TEST_EXPORT int rw_note(int, const char *, int, const char *,...)
Definition driver.cpp:1664
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
int rw_equal(T x, T y)
Definition rw_valcmp.h:153