ISO/ IEC JTC1/SC22/WG21 N1568

WG21 N1568=04-0008

PROPOSED ADDITIONS TO TR-1 TO IMPROVE
COMPATIBILITY WITH C99

P.J. Plauger
Dinkumware, Ltd.
pjp@dinkumware.com


1. General

This clause describes additions designed to bring the Standard C++
library in closer agreement with the library described in
ISO/IEC 9899:1999 Standard C, as corrected through 2003 (hereafter
C99, for short).

To avoid the need for language changes:

1) Any use of the type *long long* in C99 is replaced in this
clause by the type *_Longlong*, which behaves like a signed integer
type that occupies at least 64 bits. Any header containing a declaration
that uses *_Longlong* shall provide an idempotent definition of
*_Longlong*.

2) Any use of the type *unsigned long long* in C99 is replaced in this
clause by the type *_ULonglong*, which behaves like an unsigned integer
type with the same number of bits as *_Longlong*. Any header containing
a declaration that uses *_ULonglong* shall provide an idempotent
definition of *_ULonglong*.

3) Any use of the type qualifier *restrict* in C99 shall be omitted
in this clause.

2. Additions to header *<complex>*

2.1 Synopsis

namespace std {
	namespace tr1 {
template<class T>
	complex<T> acos(complex<T>& x);
template<class T>
	complex<T> asin(complex<T>& x);
template<class T>
	complex<T> atan(complex<T>& x);

template<class T>
	complex<T> acosh(complex<T>& x);
template<class T>
	complex<T> asinh(complex<T>& x);
template<class T>
	complex<T> atanh(complex<T>& x);
template<class T>
	complex<T> fabs(complex<T>& x);
	}
}

2.2 Function acos

Effects: Behaves the same as C99 function *cacos*,
defined in subclause 7.3.5.1.

2.3 Function asin

Effects: Behaves the same as C99 function *casin*,
defined in subclause 7.3.5.2.

2.4 Function atan

Effects: Behaves the same as C99 function *catan*,
defined in subclause 7.3.5.3.

2.5 Function acosh

Effects: Behaves the same as C99 function *cacosh*,
defined in subclause 7.3.6.1.

2.6 Function asinh

Effects: Behaves the same as C99 function *casinh*,
defined in subclause 7.3.6.2.

2.7 Function atanh

Effects: Behaves the same as C99 function *catanh*,
defined in subclause 7.3.6.3.

2.8 Function fabs

Effects: Behaves the same as C99 function *cabs*,
defined in subclause 7.3.8.1.

2.8 Additional Overloads

The following template functions shall have additional overloads:

	arg
	conj
	imag
	norm
	polar
	real

The additional overloads shall be sufficient to ensure:

	1. If the argument has type *long double*, then it is effectively cast
	to *complex<long double>*.

	2. Otherwise, if the argument has type *double* or an integer type,
	then it is effectively cast to *complex<double>*.

	3. Otherwise, if the argument has type *float*, then it is effectively
	cast to *complex<float>*.

Template function *pow* shall have additional overloads sufficient to
ensure, for a call with at least one argument of type *complex<T>*:

	1. If either argument has type *complex<long double>* or type *long
	double*, then both arguments are effectively cast to
	*complex<long double>*.

	2. Otherwise, if either argument has type *complex<double>*, *double*,
	or an integer type, then both arguments are effectively cast to
	*complex<double>*.

	3. Otherwise, if either argument has type *complex<float>* or *float*,
	then both arguments are effectively cast to *complex<float>*.

3. Header *<ccomplex>*

The header behaves as if it simply includes the header *<complex>*.

4. Header *<complex.h>"

The header behaves as if it includes the header *<ccomplex>*, and provides
sufficient *using* declarations to declare in the global namespace all
function and type names declared or defined in the neader *<complex>*.

5. Additions to header *<cctype>*

5.1 Synopsis

namespace std {
	namespace tr1 {
int isblank(int ch);
	}
}

5.2 Function isblank

Function *isblank* behaves the same as C99 function *isblank*,
defined in subclause 7.4.1.3.

6. Additions to header *<ctype.h>*

The header behaves as if it includes the header *<cctype>*, and provides
sufficient additional *using* declarations to declare in the global
namespace the additional function name declared in the header *<cctype>*.

7. Header *<cfenv>*

7.1 Synopsis

namespace std {
	namespace tr1 {
	// types
typedef <object type> fenv_t;
typedef <integer type fexcept_t;

    // functions
int feclearexcept(int except);
int fegetexceptflag(fexcept_t *pflag, int except);
int feraiseexcept(int except);
int fesetexceptflag(const fexcept_t *pflag, int except);
int fetestexcept(int except);

int fegetround(void);
int fesetround(int mode);

int fegetenv(fenv_t *penv);
int feholdexcept(fenv_t *penv);
int fesetenv(const fenv_t *penv);
int feupdateenv(const fenv_t *penv);
	}
}

The header also defines the macros:

	FE_ALL_EXCEPT
	FE_DIVBYZERO
	FE_INEXACT
	FE_INVALID
	FE_OVERFLOW
	FE_UNDERFLOW

	FE_DOWNWARD
	FE_TONEAREST
	FE_TOWARDZERO
	FE_UPWARD

	FE_DFL_ENV

7.2 Definitions

The header defines all functions, types, and macros the same as
C99 subclause 7.6.

8. Header *<fenv.h>"

The header behaves as if it includes the header *<cfenv>*, and provides
sufficient *using* declarations to declare in the global namespace all
function and type names declared or defined in the header *<cfenv>*.

9. Additions to header *<cfloat>*

The header defines the macros:

	DECIMAL_DIG
	FLT_EVAL_METHOD

the same as C99 subclause 5.2.4.2.2.

10. Additions to header *<float.h>*

The header behaves as if it defines the additional macros defined in
*<cfloat>* by including the header *<cfloat>*.

11. Additions to header *<ios>*

11.1 Synopsis

namespace std {
	namespace tr1 {
ios_base& hexfloat(ios_base& str);
	}
}

11.2 Function *hexfloat*

ios_base& hexfloat(ios_base& str);

Effects: Calls *str.setf(ios_base::fixed | ios_base::scientific,
	ios_base::floatfield)*.

Returns: *str*.

[Note that adding the format flag hexfloat to class *ios_base*
cannot be done without invading namespace std, so only the named
manipulator is provided. Note also that the more obvious use of
ios_base::hex to specify hexadecimal floating-point format would
change the meaning of existing well defined programs. C++2003
gives no meaning to the combination of fixed and scientific.]

12. Header *<cinttypes>*

12.1 Synopsis

#include <cstdint>

namespace std {
	namespace tr1 {
	// types
typedef struct {
    intmax_t quot, rem;
    } imaxdiv_t;

    // functions
intmax_t imaxabs(intmax_t i);
intmax_t abs(intmax_t i);

imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);
imaxdiv_t div(intmax_t numer, intmax_t denom);

intmax_t strtoimax(const char * s, char **endptr, int base);
uintmax_t strtoumax(const char *s, char **endptr, int base);
intmax_t wcstoimax(const wchar_t *s, wchar_t **endptr, int base);
uintmax_t wcstoumax(const wchar_t *s, wchar_t **endptr, int base);
	}
}

The header also defines numerous macros of the form:

	PRI{d i o u x X}[FAST LEAST]{8 16 32 64}
	PRI{d i o u x X}{MAX PTR}
	SCN{d i o u x}[FAST LEAST]{8 16 32 64}
	SCN{d i o u x}{MAX PTR}

12.2 Definitions

The header defines all functions, types, and macros the same as
C99 subclause 7.8.

13. Header *<inttypes.h>"

The header behaves as if it includes the header *<cinttypes>*, and
provides sufficient *using* declarations to declare in the global
namespace all function and type names declared or defined in the
header *<cinttypes>*.

14. Additions to header *<climits>*

The header defines the macros:

	LLONG_MIN
	LLONG_MAX
	ULLONG_MAX

the same as C99 subclause 5.2.4.2.1.

15. Additions to header *<limits.h>*

The header behaves as if it defines the additional macros defined in
*<climits>* by including the header *<climits>*.

16. Additions to header *<locale>*

In subclause 22.2.2.2.2, Table 58 Floating-point conversions, after the line:

	floatfield == ios_base::scientific	%E

add the two lines:

	floatfield == ios_base::fixed | ios_base::scientific && !uppercase	%a
	floatfield == ios_base::fixed | ios_base::scientific	%A

[Note that the additional requirements on print and scan functions,
later in this clause, ensure that the print functions generate hexadecimal
floating-point fields with a *%a* or *%A* conversion specifier, and that the
scan functions match hexadecimal floating-point fields with a *%g* conversion
specifier.]

17. Additions to header *<cmath>*

17.1 Synopsis

namespace std {
	namespace tr1 {
	// types
typedef <floating-type> double_t;
typedef <floating-type> float_t;

	// functions
double acosh(double x);
float acoshf(float x);
long double acoshl(long double x);

double asinh(double x);
float asinhf(float x);
long double asinhl(long double x);

double atanh(double x);
float atanhf(float x);
long double atanhl(long double x);

double cbrt(double x);
float cbrtf(float x);
long double cbrtl(long double x);

double copysign(double x, double y);
float copysignf(float x, float y);
long double copysignl(long double x, long double y);

double erf(double x);
float erff(float x);
long double erfl(long double x);

double erfc(double x);
float erfcf(float x);
long double erfcl(long double x);

double exp2(double x);
float exp2f(float x);
long double exp2l(long double x);

double expm1(double x);
float expm1f(float x);
long double expm1l(long double x);

double fdim(double x, double y);
float fdimf(float x, float y);
long double fdiml(long double x, long double y);

double fma(double x, double y, double z);
float fmaf(float x, float y, float z);
long double fmal(long double x, long double y, long double z);

double fmax(double x, double y);
float fmaxf(float x, float y);
long double fmaxl(long double x, long double y);

double fmin(double x, double y);
float fminf(float x, float y);
long double fminl(long double x, long double y);

double hypot(double x, double y);
float hypotf(float x, float y);
long double hypotl(long double x, long double y);

int ilogb(double x);
int ilogbf(float x);
int ilogbl(long double x);

double lgamma(double x);
float lgammaf(float x);
long double lgammal(long double x);

long long llrint(double x);
long long llrintf(float x);
long long llrintl(long double x);

long long llround(double x);
long long llroundf(float x);
long long llroundl(long double x);

double log1p(double x);
float log1pf(float x);
long double log1pl(long double x);

double log2(double x);
float log2f(float x);
long double log2l(long double x);

double logb(double x);
float logbf(float x);
long double logbl(long double x);

long lrint(double x);
long lrintf(float x);
long lrintl(long double x);

long lround(double x);
long lroundf(float x);
long lroundl(long double x);

double nan(const char *str);
float nanf(const char *str);
long double nanl(const char *str);

double nearbyint(double x);
float nearbyintf(float x);
long double nearbyintl(long double x);

double nextafter(double x, double y);
float nextafterf(float x, float y);
long double nextafterl(long double x, long double y);

double nexttoward(double x, long double y);
float nexttowardf(float x, long double y);
long double nexttowardl(long double x, long double y);

double remainder(double x, double y);
float remainderf(float x, float y);
long double remainderl(long double x, long double y);

double remquo(double x, double y, int *pquo);
float remquof(float x, float y, int *pquo);
long double remquol(long double x, long double y, int *pquo);

double rint(double x);
float rintf(float x);
long double rintl(long double x);

double round(double x);
float roundf(float x);
long double roundl(long double x);

double scalbln(double x, long ex);
float scalblnf(float x, long ex);
long double scalblnl(long double x, long ex);

double scalbn(double x, int ex);
float scalbnf(float x, int ex);
long double scalbnl(long double x, int ex);

double tgamma(double x);
float tgammaf(float x);
long double tgammal(long double x);

double trunc(double x);
float truncf(float x);
long double truncl(long double x);

	// C99 macros defined as C++ templates
template<class T>
	bool signbit(T x);

template<class T>
	bool fpclassify(T x);
template<class T>
	bool isfinite(T x);
template<class T>
	bool isinf(T x);
template<class T>
	bool isnan(T x);
template<class T>
	bool isnormal(T x);

template<class T>
	bool isgreater(T x, T y);
template<class T>
	bool isgreaterequal(T x, T y);
template<class T>
	bool isless(T x, T y);
template<class T>
	bool islessequal(T x, T y);
template<class T>
	bool islessgreater(T x, T y);
template<class T>
	bool isunordered(T x, T y);
	}
}

The header also defines the macros:

	FP_FAST_FMA
	FP_FAST_FMAF
	FP_FAST_FMAL

	FP_ILOGB0
	FP_ILOGBNAN

	FP_INFINITE
	FP_NAN
	FP_NORMAL
	FP_SUBNORMAL
	FP_ZERO

	HUGE_VALF
	HUGE_VALL

	INFINITY
	NAN

	MATH_ERRNO
	MATH_ERREXCEPT
	math_errhandling

17.2 Definitions

The header defines all of the above (non-template) functions,
types, and macros the same as C99 subclause 7.12.

17.3 Template function definitions

The template functions:

template<class T>
	bool signbit(T x);

template<class T>
	bool fpclassify(T x);
template<class T>
	bool isfinite(T x);
template<class T>
	bool isinf(T x);
template<class T>
	bool isnan(T x);
template<class T>
	bool isnormal(T x);

template<class T>
	bool isgreater(T x);
template<class T>
	bool isgreaterequal(T x);
template<class T>
	bool isless(T x);
template<class T>
	bool islessequal(T x);
template<class T>
	bool islessgreater(T x);
template<class T>
	bool isunordered(T x);

behave the same as C99 macros with corresponding names defined in C99
subclause 7.12.3 Classification macros and C99 subclause 7.12.14
Comparison macros.

17.4 Additional overloads

The following functions shall have additional overloads:

	acos
	acosh
	asin
	asinh
	atan
	atan2
	atanh
	cbrt
	ceil
	copysign
	cos
	cosh
	erf
	erfc
	exp
	exp2
	expm1
	fabs
	fdim
	floor
	fma
	fmax
	fmin
	fmod
	frexp
	hypot
	log
	ilogb
	ldexp
	lgamma
	llrint
	llround
	log10
	log1p
	logb
	lrint
	lround
	nearbyint
	nextafter
	nexttoward
	pow
	remainder
	remquo
	rint
	round
	scalbln
	scalbn
	sin
	sinh
	sqrt
	tan
	tanh
	tgamma
	trunc

Each of the above functions shall have an overload with all parameters of
type *double* replaced with *long double*. If the return type of the
above function is type *double*, the return type of the overload shall
be *long double*.

Each of the above functions shall also have an overload with all parameters
of type *double* replaced with *float*. If the return type of the above
function is type *double*, the return type of the overload shall be *float*.

Moreover, there shall be additional overloads sufficient to ensure:

	1. If any argument corresponding to a *double* parameter has type
	*long double*, then all arguments corresponding to *double* parameters
	are effectively cast to *long double*.

	2. Otherwise, if any argument corresponding to a *double* parameter has
	type *double* or an integer type, then all arguments corresponding to
	*double* parameters are effectively cast to *double*.

	3. Otherwise, all arguments corresponding to *double* parameters are
	effectively cast to *float*.

18. Additions to header *<math.h>"

The header behaves as if it includes the header *<cmath>*, and provides
sufficient additional *using* declarations to declare in the global
namespace all the additional template function, function, and type names
declared or defined in the header *<cmath>*.

19. Additions to header *<cstdarg>*

Add the function macro:

	va_copy(va_list dest, va_list src)

as defined in C99 subclause 7.15.1.2.

20. Additions to header *<stdarg.h>*

The header behaves as if it defines the additional macro defined in
*<cstdarg>* by including the header *<cstdarg>*.

21. The header *<cstdbool>*

The header simply defines the macro:

	__bool_true_false_are_defined

as defined in C99 subclause 7.16.

22. The header *<stdbool.h>*

The header behaves as if it defines the additional macro defined in
*<cstbool>* by including the header *<cstdbool>*.

23. The header *<cstdint>*

23.1 Synopsis

namespace std {
	namespace tr1 {
	typedef <signed integer type> int8_t;	// optional
	typedef <signed integer type> int16_t;	// optional
	typedef <signed integer type> int32_t;	// optional
	typedef <signed integer type> int64_t;	// optional

	typedef <signed integer type> int_fast8_t;
	typedef <signed integer type> int_fast16_t;
	typedef <signed integer type> int_fast32_t;
	typedef <signed integer type> int_fast64_t;

	typedef <signed integer type> int_least8_t;
	typedef <signed integer type> int_least16_t;
	typedef <signed integer type> int_least32_t;
	typedef <signed integer type> int_least64_t;

	typedef <signed integer type> intmax_t;
	typedef <signed integer type> intptr_t;

	typedef <unsigned integer type> uint8_t;	// optional
	typedef <unsigned integer type> uint16_t;	// optional
	typedef <unsigned integer type> uint32_t;	// optional
	typedef <unsigned integer type> uint64_t;	// optional

	typedef <unsigned integer type> uint_fast8_t;
	typedef <unsigned integer type> uint_fast16_t;
	typedef <unsigned integer type> uint_fast32_t;
	typedef <unsigned integer type> uint_fast64_t;

	typedef <unsigned integer type> uint_least8_t;
	typedef <unsigned integer type> uint_least16_t;
	typedef <unsigned integer type> uint_least32_t;
	typedef <unsigned integer type> uint_least64_t;

	typedef <unsigned integer type> uintmax_t;
	typedef <unsigned integer type> uintptr_t;
	}
}

The header also defines numerous macros of the form:

	INT[FAST LEAST]{8 16 32 64}_MIN
	[U]INT[FAST LEAST]{8 16 32 64}_MAX
	INT{MAX PTR}_MIN
	[U]INT{MAX PTR}_MAX
	{PTRDIFF SIG_ATOMIC WCHAR WINT}{_MAX _MIN}
	SIZE_MAX

plus function macros of the form:

	[U]INT{8 16 32 64 MAX}_C

23.2 Definitions

The header defines all functions, types, and macros the same as
C99 subclause 7.18.

24. The header *<stdint.h>*

The header behaves as if it includes the header *<cstdint>*, and provides
sufficient *using* declarations to declare in the global namespace all
type names defined in the header *<cstdint>*.

25. Additions to header *<cstdio>*

25.1 Synopsis

namespace std {
	namespace tr1 {
int snprintf(char *s, size_t n, const char *format, ...);
int vsnprintf(char *s, size_t n, const char *format, va_list ap);

int vfscanf(FILE *stream, const char *format, va_list ap);
int vscanf(const char *format, va_list ap);
int vsscanf(const char *s, const char *format, va_list ap);
	}
}

25.2 Definitions

The header defines all added functions the same as C99 subclause 7.19.

25.3 Additional formatted input/output conversion specifications

The formatted output functions shall support the additional conversion
specifications specified in C99 subclause 7.19.6.1.

The formatted input functions shall support the additional conversion
specifications specified in C99 subclause 7.19.6.2.

[Note: These include the conversion specifiers a (for hexadecimal
floating-point) and F, and the conversion qualifiers hh, h, ll, t,
and z (for various integer types). They also include the ability
to match and generate various text forms of infinity and NaN values.]

26. Additions to header *<stdio.h>*

The header behaves as if it includes the header *<cstdio>*, and provides
sufficient additional *using* declarations to declare in the global
namespace all added function names defined in the header *<cstdio>*.

27. Additions to header *<cstdlib>*

27.1 Synopsis

namespace std {
	namespace tr1 {
	// types
typedef struct {
    _Longlong quot, rem;
    } lldiv_t;

	// functions
_Longlong llabs(long long i);
lldiv_t lldiv(_Longlong numer, _Longlong denom);

_Longlong atoll(const char *s);
_Longlong strtoll(const char *s, char **endptr, int base);
_ULonglong strtoull(const char *s, char **endptr, int base);

float strtof(const char *s, char **endptr);
long double strtold(const char *s, char **endptr);

	// overloads
_Longlong abs(_Longlong i);
lldiv_t div(_Longlong numer, _Longlong denom);
	}
}

27.2 Definitions

The header defines all added types and functions, other than the
overloads of *abs* and *div*, the same as C99 subclause 7.20.

27.3 Function abs

_Longlong abs(_Longlong i);

Effects: Behaves the same as C99 function *llabs*,
defined in subclause 7.20.6.1.

27.4 Function div

lldiv_t div(_Longlong numer, _Longlong denom);

Effects: Behaves the same as C99 function *lldiv*,
defined in subclause 7.20.6.2.

28. Additions to header *<stdlib.h>*

The header behaves as if it includes the header *<cstdlib>*, and provides
sufficient additional *using* declarations to declare in the global
namespace all added type and function names defined in the header *<cstdlib>*.

29. Header *<ctgmath>*

The header simply includes the headers *<ccomplex>* and *<cmath>*.

[Note that the overloads provided in C99 by magic macros are already
provided in *<ccomplex>* and *<cmath>* by "sufficient" additional overloads.]

30. Header *<tgmath.h>*

The header effectively includes the headers *<complex.h>* and *<math.h>*.

31. Additions to header *<ctime>*

The function *strftime* shall support the additional conversion
specifiers and modifiers specified in C99 subclause 7.23.3.4.

[Note: These include the conversion specifiers C, D, e, F, g, G, h,
r, R, t, T, u, V, and z, and the modifiers E and O.]

32. Additions to header *<cwchar>*

32.1 Synopsis

namespace std {
	namespace tr1 {
float wcstof(const wchar_t *nptr, wchar_t **endptr);
long double wcstold(const wchar_t *nptr, wchar_t **endptr);
_Longlong wcstoll(const wchar_t *nptr, wchar_t **endptr, int base);
_ULonglong wcstoull(const wchar_t *nptr, wchar_t **endptr, int base);

int vfwscanf(FILE *stream, const wchar_t *format, va_list arg);
int vswscanf(const wchar_t *s, const wchar_t *format, va_list arg);
int vwscanf(const wchar_t *format, va_list arg);
	}
}

Moreover, the function *wcsftime* shall support the additional conversion
specifiers and modifiers specified in C99 subclause 7.23.3.4.

32.2 Definitions

The header defines all added functions the same as C99 subclause 7.24.

32.3 Additional formatted wide input/output conversion specifications

The formatted wide output functions shall support the additional conversion
specifications specified in C99 subclause 7.24.2.1.

The formatted wide input functions shall support the additional conversion
specifications specified in C99 subclause 7.24.2.2.

[Note: These are essentially the same extensions as for the header
*<cstdio>*.]

33. Additions to header *<wchar.h>*

The header behaves as if it includes the header *<cwchar>*, and provides
sufficient additional *using* declarations to declare in the global
namespace all added function names defined in the header *<cwchar>*.

34. Additions to header *<cwctype>*

34.1 Synopsis

namespace std {
	namespace tr1 {
int isbwlank(wint_t ch);
	}
}

34.2 Function iswblank

Function *iswblank* behaves the same as C99 function *iswblank*,
defined in subclause 7.25.2.1.3.

35. Additions to header *<wctype.h>*

The header behaves as if it includes the header *<cwctype>*, and provides
sufficient additional *using* declarations to declare in the global
namespace the additional function name declared in the header *<cwctype>*.