2 * D compatible types that correspond to various basic types in associated
5 * Copyright: Copyright Sean Kelly 2005 - 2009.
6 * License: Distributed under the
7 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
8 * (See accompanying file LICENSE)
10 * Source: $(DRUNTIMESRC core/stdc/_config.d)
11 * Standards: ISO/IEC 9899:1999 (E)
14 /* NOTE: This file has been patched from the original DMD distribution to
15 * work with the GDC compiler.
17 module core
.stdc
.config
;
27 static if (isPosix
&& (void*).sizeof
> int.sizeof
)
29 alias ddoc_long
= long;
30 alias ddoc_ulong
= ulong;
34 alias ddoc_long
= int;
35 alias ddoc_ulong
= uint;
37 struct ddoc_complex(T
) { T re
; T im
; }
41 * Used for a signed integer type that corresponds in size to the associated
42 * C compiler's `long` type.
44 alias c_long
= ddoc_long
;
47 * Used for an unsigned integer type that corresponds in size to the associated
48 * C compiler's `unsigned long` type.
50 alias c_ulong
= ddoc_ulong
;
53 * Used for a signed integer type that corresponds in size and mangling to the associated
54 * C++ compiler's `long` type.
56 alias cpp_long
= c_long
;
59 * Used for an unsigned integer type that corresponds in size and mangling to the associated
60 * C++ compiler's `unsigned long` type.
62 alias cpp_ulong
= c_ulong
;
65 * Used for a signed integer type that corresponds in size and mangling to the associated
66 * C++ compiler's `long long` type.
68 alias cpp_longlong
= long;
71 * Used for an unsigned integer type that corresponds in size and mangling to the associated
72 * C++ compiler's `unsigned long long` type.
74 alias cpp_ulonglong
= ulong;
77 * Used for a floating point type that corresponds in size and mangling to the associated
78 * C++ compiler's `long double` type.
80 alias c_long_double
= real;
83 * Used for an unsigned integer type that corresponds in size and mangling to the associated
84 * C++ compiler's `size_t` type.
86 alias cpp_size_t
= size_t
;
89 * Used for a signed integer type that corresponds in size and mangling to the associated
90 * C++ compiler's `ptrdiff_t` type.
92 alias cpp_ptrdiff_t
= ptrdiff_t
;
95 * Used for a complex floating point type that corresponds in size and ABI to the associated
96 * C compiler's `_Complex float` type.
98 alias c_complex_float
= ddoc_complex
!float;
101 * Used for a complex floating point type that corresponds in size and ABI to the associated
102 * C compiler's `_Complex double` type.
104 alias c_complex_double
= ddoc_complex
!double;
107 * Used for a complex floating point type that corresponds in size and ABI to the associated
108 * C compiler's `_Complex long double` type.
110 alias c_complex_real
= ddoc_complex
!real;
121 else version (WatchOS
)
128 alias __builtin_clong c_long
;
129 alias __builtin_culong c_ulong
;
131 enum __c_long
: __builtin_clong
;
132 enum __c_ulong
: __builtin_culong
;
134 alias __c_long cpp_long
;
135 alias __c_ulong cpp_ulong
;
137 enum __c_longlong
: __builtin_clonglong
;
138 enum __c_ulonglong
: __builtin_culonglong
;
140 alias __c_longlong cpp_longlong
;
141 alias __c_ulonglong cpp_ulonglong
;
143 else version (Windows
)
146 enum __c_ulong
: uint;
151 alias __c_long cpp_long
;
152 alias __c_ulong cpp_ulong
;
154 alias long cpp_longlong
;
155 alias ulong cpp_ulonglong
;
159 static if ( (void*).sizeof
> int.sizeof
)
161 enum __c_longlong
: long;
162 enum __c_ulonglong
: ulong;
168 alias ulong cpp_ulong
;
170 alias __c_longlong cpp_longlong
;
171 alias __c_ulonglong cpp_ulonglong
;
176 enum __c_ulong
: uint;
181 alias __c_long cpp_long
;
182 alias __c_ulong cpp_ulong
;
184 alias long cpp_longlong
;
185 alias ulong cpp_ulonglong
;
190 static if ( (void*).sizeof
> int.sizeof
)
192 enum __c_longlong
: long;
193 enum __c_ulonglong
: ulong;
199 alias ulong cpp_ulong
;
201 alias __c_longlong cpp_longlong
;
202 alias __c_ulonglong cpp_ulonglong
;
207 enum __c_ulong
: uint;
212 alias __c_long cpp_long
;
213 alias __c_ulong cpp_ulong
;
215 alias long cpp_longlong
;
216 alias ulong cpp_ulonglong
;
221 alias c_long_double
= real;
223 alias c_long_double
= real; // 64-bit real for MSVC targets
227 alias c_long_double
= real;
228 else version (X86_64
)
229 alias c_long_double
= real;
231 else version (CRuntime_Microsoft
)
233 /* long double is 64 bits, not 80 bits, but is mangled differently
234 * than double. To distinguish double from long double, create a wrapper to represent
235 * long double, then recognize that wrapper specially in the compiler
236 * to generate the correct name mangling and correct function call/return
239 enum __c_long_double
: double;
241 alias __c_long_double c_long_double
;
243 else version (DigitalMars
)
247 alias real c_long_double
;
249 else version (X86_64
)
252 alias real c_long_double
;
253 else version (FreeBSD
)
254 alias real c_long_double
;
255 else version (OpenBSD
)
256 alias real c_long_double
;
257 else version (NetBSD
)
258 alias real c_long_double
;
259 else version (DragonFlyBSD
)
260 alias real c_long_double
;
261 else version (Solaris
)
262 alias real c_long_double
;
263 else version (Darwin
)
264 alias real c_long_double
;
268 static assert(is(c_long_double
), "c_long_double needs to be declared for this platform/architecture.");
272 alias cpp_size_t
= cpp_ulong
;
274 alias cpp_ptrdiff_t
= cpp_long
;
276 alias cpp_ptrdiff_t
= ptrdiff_t
;
280 alias cpp_size_t
= size_t
;
281 alias cpp_ptrdiff_t
= ptrdiff_t
;
284 /** ABI layout of native complex types.
287 if (is(T
== float) ||
is(T
== double) ||
is(T
== c_long_double
))
293 /+ https://issues.dlang.org/show_bug.cgi?id=23788 dmd codegen problem with constructors and _Complex!float
294 this(_Complex!float c) { re = c.re; im = c.im; }
295 this(_Complex!double c) { re = c.re; im = c.im; }
296 this(_Complex!c_long_double c) { re = c.re; im = c.im; }
298 this(T re, T im) { this.re = re; this.im = im; }
300 this(T re) { this.re = re; this.im = 0; }
304 if (is(R
== _Complex
!float) ||
is(R
== _Complex
!double) ||
is(R
== _Complex
!c_long_double
))
306 return R(this.re
, this.im
);
311 ref _Complex
opAssign(_Complex
!float c
) { re
= c
.re
; im
= c
.im
; return this; }
312 ref _Complex
opAssign(_Complex
!double c
) { re
= c
.re
; im
= c
.im
; return this; }
313 ref _Complex
opAssign(_Complex
!c_long_double c
) { re
= c
.re
; im
= c
.im
; return this; }
315 ref _Complex
opAssign(T t
) { re
= t
; im
= 0; return this; }
319 bool opEquals(_Complex
!float c
) { return re
== c
.re
&& im
== c
.im
; }
320 bool opEquals(_Complex
!double c
) { return re
== c
.re
&& im
== c
.im
; }
321 bool opEquals(_Complex
!c_long_double c
) { return re
== c
.re
&& im
== c
.im
; }
323 bool opEquals(T t
) { return re
== t
&& im
== 0; }
328 _Complex
opUnary(string op
)()
335 _Complex
opUnary(string op
)()
338 return _Complex(-re
, -im
);
343 // complex op complex
344 _Complex
!(CommonType
!(T
,R
)) opBinary(string op
, R
)(_Complex
!R z
)
346 alias C
= typeof(return);
347 auto w
= C(this.re
, this.im
);
348 return w
.opOpAssign
!(op
)(z
);
351 // complex op numeric
352 _Complex
!(CommonType
!(T
,R
)) opBinary(string op
, R
)(R r
)
353 if (is(R
: c_long_double
))
355 alias C
= typeof(return);
356 auto w
= C(this.re
, this.im
);
357 return w
.opOpAssign
!(op
)(r
);
360 // numeric + complex, numeric * complex
361 _Complex
!(CommonType
!(T
, R
)) opBinaryRight(string op
, R
)(R r
)
362 if ((op
== "+" || op
== "*") && is(R
: c_long_double
))
364 return opBinary
!(op
)(r
);
368 _Complex
!(CommonType
!(T
, R
)) opBinaryRight(string op
, R
)(R r
)
369 if (op
== "-" && is(R
: c_long_double
))
371 return _Complex(r
- re
, -im
);
375 _Complex
!(CommonType
!(T
, R
)) opBinaryRight(string op
, R
)(R r
)
376 if (op
== "/" && is(R
: c_long_double
))
378 import core
.math
: fabs;
379 typeof(return) w
= void;
380 if (fabs(re
) < fabs(im
))
382 immutable ratio
= re
/im
;
383 immutable rdivd
= r
/(re
*ratio
+ im
);
390 immutable ratio
= im
/re
;
391 immutable rdivd
= r
/(re
+ im
*ratio
);
400 // OP-ASSIGN OPERATORS
402 // complex += complex, complex -= complex
403 ref _Complex
opOpAssign(string op
, C
)(C z
)
404 if ((op
== "+" || op
== "-") && is(C R
== _Complex
!R
))
406 mixin ("re "~op
~"= z.re;");
407 mixin ("im "~op
~"= z.im;");
411 // complex *= complex
412 ref _Complex
opOpAssign(string op
, C
)(C z
)
413 if (op
== "*" && is(C R
== _Complex
!R
))
415 auto temp
= re
*z
.re
- im
*z
.im
;
416 im
= im
*z
.re
+ re
*z
.im
;
421 // complex /= complex
422 ref _Complex
opOpAssign(string op
, C
)(C z
)
423 if (op
== "/" && is(C R
== _Complex
!R
))
425 import core
.math
: fabs;
426 if (fabs(z
.re
) < fabs(z
.im
))
428 immutable ratio
= z
.re
/z
.im
;
429 immutable denom
= z
.re
*ratio
+ z
.im
;
431 immutable temp
= (re
*ratio
+ im
)/denom
;
432 im
= (im
*ratio
- re
)/denom
;
437 immutable ratio
= z
.im
/z
.re
;
438 immutable denom
= z
.re
+ z
.im
*ratio
;
440 immutable temp
= (re
+ im
*ratio
)/denom
;
441 im
= (im
- re
*ratio
)/denom
;
447 // complex += numeric, complex -= numeric
448 ref _Complex
opOpAssign(string op
, U
: T
)(U a
)
449 if (op
== "+" || op
== "-")
451 mixin ("re "~op
~"= a;");
455 // complex *= numeric, complex /= numeric
456 ref _Complex
opOpAssign(string op
, U
: T
)(U a
)
457 if (op
== "*" || op
== "/")
459 mixin ("re "~op
~"= a;");
460 mixin ("im "~op
~"= a;");
464 // Helper properties.
467 static @property epsilon()() { return _Complex(T
.epsilon
, T
.epsilon
); }
468 static @property infinity()() { return _Complex(T
.infinity
, T
.infinity
); }
469 static @property max()() { return _Complex(T
.max
, T
.max
); }
470 static @property min_normal()() { return _Complex(T
.min_normal
, T
.min_normal
); }
471 static @property nan()() { return _Complex(T
.nan
, T
.nan
); }
472 static @property dig()() { return T
.dig
; }
473 static @property mant_dig()() { return T
.mant_dig
; }
474 static @property max_10_exp()() { return T
.max_10_exp
; }
475 static @property max_exp()() { return T
.max_exp
; }
476 static @property min_10_exp()() { return T
.min_10_exp
; }
477 static @property min_exp()() { return T
.min_exp
; }
481 enum __c_complex_float
: _Complex
!float;
482 enum __c_complex_double
: _Complex
!double;
483 enum __c_complex_real
: _Complex
!c_long_double
;
485 alias c_complex_float
= __c_complex_float
;
486 alias c_complex_double
= __c_complex_double
;
487 alias c_complex_real
= __c_complex_real
;
489 private template CommonType(T
, R
)
491 // Special kludge for Microsoft c_long_double
492 static if (is(T
== c_long_double
))
493 alias CommonType
= T
;
494 else static if (is(R
== c_long_double
))
495 alias CommonType
= R
;
497 alias CommonType
= typeof(true ? T
.init
: R
.init
);
500 /************ unittests ****************/
506 alias _cfloat
= _Complex
!float;
507 alias _cdouble
= _Complex
!double;
508 alias _creal
= _Complex
!c_long_double
;
510 T
abs(T
)(T t
) => t
< 0 ?
-t
: t
;
513 @safe pure nothrow unittest
515 auto c1
= _cdouble(1.0, 1.0);
517 // Check unary operations.
518 auto c2
= _cdouble(0.5, 2.0);
522 assert((-c2
).re
== -(c2
.re
));
523 assert((-c2
).im
== -(c2
.im
));
524 assert(c2
== -(-c2
));
526 // Check complex-complex operations.
528 assert(cpc
.re
== c1
.re
+ c2
.re
);
529 assert(cpc
.im
== c1
.im
+ c2
.im
);
532 assert(cmc.re
== c1
.re
- c2
.re
);
533 assert(cmc.im
== c1
.im
- c2
.im
);
536 assert(ctc
== _cdouble(-1.5, 2.5));
539 assert(abs(cdc
.re
- 0.5882352941177) < 1e-12);
540 assert(abs(cdc
.im
- -0.3529411764706) < 1e-12);
542 // Check complex-real operations.
546 assert(cpr
.re
== c1
.re
+ a
);
547 assert(cpr
.im
== c1
.im
);
550 assert(cmr
.re
== c1
.re
- a
);
551 assert(cmr
.im
== c1
.im
);
554 assert(ctr
.re
== c1
.re
*a
);
555 assert(ctr
.im
== c1
.im
*a
);
558 assert(abs(cdr
.re
- 0.00810005184033) < 1e-12);
559 assert(abs(cdr
.im
- 0.00810005184033) < 1e-12);
565 assert(rmc
.re
== a
-c1
.re
);
566 assert(rmc
.im
== -c1
.im
);
572 assert(abs(rdc
.re
- 61.728) < 1e-12);
573 assert(abs(rdc
.im
- -61.728) < 1e-12);
576 assert(abs(rdc
.re
- 14.5242352941) < 1e-10);
577 assert(abs(rdc
.im
- -58.0969411765) < 1e-10);
579 // Check operations between different complex types.
580 auto cf
= _cfloat(1.0, 1.0);
581 auto cr
= _creal(1.0, 1.0);
582 auto c1pcf
= c1
+ cf
;
583 auto c1pcr
= c1
+ cr
;
584 static assert(is(typeof(c1pcf
) == _cdouble
));
585 static assert(is(typeof(c1pcr
) == _creal
));
586 assert(c1pcf
.re
== c1pcr
.re
);
587 assert(c1pcf
.im
== c1pcr
.im
);
593 assert(abs(c1c
.re
- 1.0) < 1e-10);
594 assert(abs(c1c
.im
- 0.0) < 1e-10);
598 assert(abs(c1c
.re
- 0.5882352941177) < 1e-12);
599 assert(abs(c1c
.im
- -0.3529411764706) < 1e-12);
602 assert(abs(c2c
.re
- 1.25) < 1e-11);
603 assert(abs(c2c
.im
- 0.75) < 1e-12);
607 assert(abs(c2c
.re
- 1.0) < 1e-11);
608 assert(abs(c2c
.im
- 0.0) < 1e-12);
611 @safe pure nothrow unittest
614 _cdouble a
= _cdouble(1, 0);
615 assert(a
.re
== 1 && a
.im
== 0);
616 _cdouble b
= _cdouble(1.0, 0);
617 assert(b
.re
== 1.0 && b
.im
== 0);
618 // _cdouble c = _creal(1.0, 2);
619 // assert(c.re == 1.0 && c.im == 2);
622 @safe pure nothrow unittest
624 // Assignments and comparisons
629 assert(z
.re
== 1.0 && z
.im
== 0.0);
633 assert(z
.re
== 2.0 && z
.im
== 0.0);
637 assert(z
.re
== 1.0 && z
.im
== 0.0);
639 auto w
= _creal(1.0, 1.0);
642 assert(z
.re
== 1.0 && z
.im
== 1.0);
644 auto c
= _cfloat(2.0, 2.0);
647 assert(z
.re
== 2.0 && z
.im
== 2.0);
653 // Returns the mangled name for the 64-bit time_t versions of
654 // functions affected by musl's transition to 64-bit time_t.
655 // https://musl.libc.org/time64.html
656 version (CRuntime_Musl
)
658 version (CRuntime_Musl_Pre_Time64
)
659 enum muslRedirTime64
= false;
662 // time_t was defined as a C long in older Musl versions.
663 enum muslRedirTime64
= (c_long
.sizeof
== 4);
667 enum muslRedirTime64
= false;
669 package(core
) template muslRedirTime64Mangle(string name
, string redirectedName
)
671 static if (muslRedirTime64
)
672 enum muslRedirTime64Mangle
= redirectedName
;
674 enum muslRedirTime64Mangle
= name
;