Commit b39d0359 by Loren J. Rittle Committed by Loren J. Rittle

std_cmath.h (__gnu_cx::__c99_binding): New namespace.

	libstdc++/7680
	* include/c_std/std_cmath.h (__gnu_cx::__c99_binding): New namespace.
	Populate it with multiple legal ways to obtain the C99 float
	transcendentals.  Use them instead of direct global reference.
	(C99 FP capture): Guard usage with _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC.
	* docs/html/17_intro/porting.texi
	(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK): New macro.
	(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC): New macro.
	(_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC): New macro.
	* config/os/bsd/freebsd/os_defines.h
	(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK): New macro.
	(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC): New macro.
	* testsuite/26_numerics/c_math_dynamic.cc: New file.

From-SVN: r65624
parent 35a54b49
2003-04-15 Loren J. Rittle <ljrittle@acm.org>
libstdc++/7680
* include/c_std/std_cmath.h (__gnu_cx::__c99_binding): New namespace.
Populate it with multiple legal ways to obtain the C99 float
transcendentals. Use them instead of direct global reference.
(C99 FP capture): Guard usage with _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC.
* docs/html/17_intro/porting.texi
(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK): New macro.
(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC): New macro.
(_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC): New macro.
* config/os/bsd/freebsd/os_defines.h
(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK): New macro.
(_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC): New macro.
* testsuite/26_numerics/c_math_dynamic.cc: New file.
2003-04-14 Andreas Tobler <toa@pop.agri.ch> 2003-04-14 Andreas Tobler <toa@pop.agri.ch>
Benjamin Kosnik <bkoz@redhat.com> Benjamin Kosnik <bkoz@redhat.com>
......
...@@ -34,4 +34,7 @@ ...@@ -34,4 +34,7 @@
// System-specific #define, typedefs, corrections, etc, go here. This // System-specific #define, typedefs, corrections, etc, go here. This
// file will come before all others. // file will come before all others.
#define _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK 1
#define _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC defined _XOPEN_SOURCE
#endif #endif
...@@ -150,12 +150,27 @@ need to define. You will need to add them to the ...@@ -150,12 +150,27 @@ need to define. You will need to add them to the
target. It will not work to simply define these macros in target. It will not work to simply define these macros in
@file{os_defines.h}. @file{os_defines.h}.
At this time, there is one libstdc++-v3-specific macro which may be At this time, there are a few libstdc++-v3-specific macro which may be
defined. @code{_G_USING_THUNKS} may be defined to 0 to express that the defined. @code{_G_USING_THUNKS} may be defined to 0 to express that the
port doesn't use thunks (although it is unclear that this is still port doesn't use thunks (although it is unclear that this is still
useful since libio support isn't currently working and the g++ v3 ABI useful since libio support isn't currently working and the g++ v3 ABI
invalidates the assumption that some ports don't use thunks). invalidates the assumption that some ports don't use thunks).
@code{_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC} may be defined to an
expression that yields 0 if and only if the system headers
are exposing proper support for the related set of macros. If defined,
it must be 0 while bootstrapping the compiler/rebuilding the library.
@code{_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK} may be defined
to 1 to check the related set of function declarations found in system
headers against versions found in the library headers derived from
the standard.
@code{_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC} may be defined
to an expression that yields 0 if and only if the system headers
are exposing proper support for the related set of functions. If defined,
it must be 0 while bootstrapping the compiler/rebuilding the library.
Finally, you should bracket the entire file in an include-guard, like Finally, you should bracket the entire file in an include-guard, like
this: this:
......
// -*- C++ -*- C forwarding header. // -*- C++ -*- C forwarding header.
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
// Free Software Foundation, Inc. // Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // This file is part of the GNU ISO C++ Library. This library is free
...@@ -76,6 +76,91 @@ ...@@ -76,6 +76,91 @@
#undef tan #undef tan
#undef tanh #undef tanh
// ...and in the darkness bind them...
namespace __gnu_cxx
{
namespace __c99_binding
{
#if _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK || \
_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC
extern "C" float (acosf)(float);
extern "C" float (asinf)(float);
extern "C" float (atanf)(float);
extern "C" float (atan2f)(float, float);
extern "C" float (ceilf)(float);
extern "C" float (coshf)(float);
extern "C" float (expf)(float);
extern "C" float (floorf)(float);
extern "C" float (fmodf)(float, float);
extern "C" float (frexpf)(float, int*);
extern "C" float (ldexpf)(float, int);
extern "C" float (logf)(float);
extern "C" float (log10f)(float);
extern "C" float (modff)(float, float*);
extern "C" float (powf)(float, float);
extern "C" float (sinhf)(float);
extern "C" float (tanf)(float);
extern "C" float (tanhf)(float);
#endif
#if !_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC
#if _GLIBCPP_HAVE_ACOSF
using ::acosf;
#endif
#if _GLIBCPP_HAVE_ASINF
using ::asinf;
#endif
#if _GLIBCPP_HAVE_ATANF
using ::atanf;
#endif
#if _GLIBCPP_HAVE_ATAN2F
using ::atan2f;
#endif
#if _GLIBCPP_HAVE_CEILF
using ::ceilf;
#endif
#if _GLIBCPP_HAVE_COSHF
using ::coshf;
#endif
#if _GLIBCPP_HAVE_EXPF
using ::expf;
#endif
#if _GLIBCPP_HAVE_FLOORF
using ::floorf;
#endif
#if _GLIBCPP_HAVE_FMODF
using ::fmodf;
#endif
#if _GLIBCPP_HAVE_FREXPF
using ::frexpf;
#endif
#if _GLIBCPP_HAVE_LDEXPF
using ::ldexpf;
#endif
#if _GLIBCPP_HAVE_LOGF
using ::logf;
#endif
#if _GLIBCPP_HAVE_LOG10F
using ::log10f;
#endif
#if _GLIBCPP_HAVE_MODFF
using ::modff;
#endif
#if _GLIBCPP_HAVE_POWF
using ::powf;
#endif
#if _GLIBCPP_HAVE_SINHF
using ::sinhf;
#endif
#if _GLIBCPP_HAVE_TANF
using ::tanf;
#endif
#if _GLIBCPP_HAVE_TANHF
using ::tanhf;
#endif
#endif /* _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC */
}
}
namespace std namespace std
{ {
// Forward declaration of a helper function. This really should be // Forward declaration of a helper function. This really should be
...@@ -96,7 +181,7 @@ namespace std ...@@ -96,7 +181,7 @@ namespace std
#if _GLIBCPP_HAVE_ACOSF #if _GLIBCPP_HAVE_ACOSF
inline float inline float
acos(float __x) { return ::acosf(__x); } acos(float __x) { return __gnu_cxx::__c99_binding::acosf(__x); }
#else #else
inline float inline float
acos(float __x) { return ::acos(static_cast<double>(__x)); } acos(float __x) { return ::acos(static_cast<double>(__x)); }
...@@ -116,7 +201,7 @@ namespace std ...@@ -116,7 +201,7 @@ namespace std
#if _GLIBCPP_HAVE_ASINF #if _GLIBCPP_HAVE_ASINF
inline float inline float
asin(float __x) { return ::asinf(__x); } asin(float __x) { return __gnu_cxx::__c99_binding::asinf(__x); }
#else #else
inline float inline float
asin(float __x) { return ::asin(static_cast<double>(__x)); } asin(float __x) { return ::asin(static_cast<double>(__x)); }
...@@ -134,7 +219,7 @@ namespace std ...@@ -134,7 +219,7 @@ namespace std
#if _GLIBCPP_HAVE_ATANF #if _GLIBCPP_HAVE_ATANF
inline float inline float
atan(float __x) { return ::atanf(__x); } atan(float __x) { return __gnu_cxx::__c99_binding::atanf(__x); }
#else #else
inline float inline float
atan(float __x) { return ::atan(static_cast<double>(__x)); } atan(float __x) { return ::atan(static_cast<double>(__x)); }
...@@ -152,7 +237,7 @@ namespace std ...@@ -152,7 +237,7 @@ namespace std
#if _GLIBCPP_HAVE_ATAN2F #if _GLIBCPP_HAVE_ATAN2F
inline float inline float
atan2(float __y, float __x) { return ::atan2f(__y, __x); } atan2(float __y, float __x) { return __gnu_cxx::__c99_binding::atan2f(__y, __x); }
#else #else
inline float inline float
atan2(float __y, float __x) atan2(float __y, float __x)
...@@ -172,7 +257,7 @@ namespace std ...@@ -172,7 +257,7 @@ namespace std
#if _GLIBCPP_HAVE_CEILF #if _GLIBCPP_HAVE_CEILF
inline float inline float
ceil(float __x) { return ::ceilf(__x); } ceil(float __x) { return __gnu_cxx::__c99_binding::ceilf(__x); }
#else #else
inline float inline float
ceil(float __x) { return ::ceil(static_cast<double>(__x)); } ceil(float __x) { return ::ceil(static_cast<double>(__x)); }
...@@ -200,7 +285,7 @@ namespace std ...@@ -200,7 +285,7 @@ namespace std
#if _GLIBCPP_HAVE_COSHF #if _GLIBCPP_HAVE_COSHF
inline float inline float
cosh(float __x) { return ::coshf(__x); } cosh(float __x) { return __gnu_cxx::__c99_binding::coshf(__x); }
#else #else
inline float inline float
cosh(float __x) { return ::cosh(static_cast<double>(__x)); } cosh(float __x) { return ::cosh(static_cast<double>(__x)); }
...@@ -218,7 +303,7 @@ namespace std ...@@ -218,7 +303,7 @@ namespace std
#if _GLIBCPP_HAVE_EXPF #if _GLIBCPP_HAVE_EXPF
inline float inline float
exp(float __x) { return ::expf(__x); } exp(float __x) { return __gnu_cxx::__c99_binding::expf(__x); }
#else #else
inline float inline float
exp(float __x) { return ::exp(static_cast<double>(__x)); } exp(float __x) { return ::exp(static_cast<double>(__x)); }
...@@ -246,7 +331,7 @@ namespace std ...@@ -246,7 +331,7 @@ namespace std
#if _GLIBCPP_HAVE_FLOORF #if _GLIBCPP_HAVE_FLOORF
inline float inline float
floor(float __x) { return ::floorf(__x); } floor(float __x) { return __gnu_cxx::__c99_binding::floorf(__x); }
#else #else
inline float inline float
floor(float __x) { return ::floor(static_cast<double>(__x)); } floor(float __x) { return ::floor(static_cast<double>(__x)); }
...@@ -264,7 +349,7 @@ namespace std ...@@ -264,7 +349,7 @@ namespace std
#if _GLIBCPP_HAVE_FMODF #if _GLIBCPP_HAVE_FMODF
inline float inline float
fmod(float __x, float __y) { return ::fmodf(__x, __y); } fmod(float __x, float __y) { return __gnu_cxx::__c99_binding::fmodf(__x, __y); }
#else #else
inline float inline float
fmod(float __x, float __y) fmod(float __x, float __y)
...@@ -284,7 +369,7 @@ namespace std ...@@ -284,7 +369,7 @@ namespace std
#if _GLIBCPP_HAVE_FREXPF #if _GLIBCPP_HAVE_FREXPF
inline float inline float
frexp(float __x, int* __exp) { return ::frexpf(__x, __exp); } frexp(float __x, int* __exp) { return __gnu_cxx::__c99_binding::frexpf(__x, __exp); }
#else #else
inline float inline float
frexp(float __x, int* __exp) { return ::frexp(__x, __exp); } frexp(float __x, int* __exp) { return ::frexp(__x, __exp); }
...@@ -303,7 +388,7 @@ namespace std ...@@ -303,7 +388,7 @@ namespace std
#if _GLIBCPP_HAVE_LDEXPF #if _GLIBCPP_HAVE_LDEXPF
inline float inline float
ldexp(float __x, int __exp) { return ::ldexpf(__x, __exp); } ldexp(float __x, int __exp) { return __gnu_cxx::__c99_binding::ldexpf(__x, __exp); }
#else #else
inline float inline float
ldexp(float __x, int __exp) ldexp(float __x, int __exp)
...@@ -323,7 +408,7 @@ namespace std ...@@ -323,7 +408,7 @@ namespace std
#if _GLIBCPP_HAVE_LOGF #if _GLIBCPP_HAVE_LOGF
inline float inline float
log(float __x) { return ::logf(__x); } log(float __x) { return __gnu_cxx::__c99_binding::logf(__x); }
#else #else
inline float log(float __x) inline float log(float __x)
{ return ::log(static_cast<double>(__x)); } { return ::log(static_cast<double>(__x)); }
...@@ -341,7 +426,7 @@ namespace std ...@@ -341,7 +426,7 @@ namespace std
#if _GLIBCPP_HAVE_LOG10F #if _GLIBCPP_HAVE_LOG10F
inline float inline float
log10(float __x) { return ::log10f(__x); } log10(float __x) { return __gnu_cxx::__c99_binding::log10f(__x); }
#else #else
inline float inline float
log10(float __x) { return ::log10(static_cast<double>(__x)); } log10(float __x) { return ::log10(static_cast<double>(__x)); }
...@@ -359,7 +444,7 @@ namespace std ...@@ -359,7 +444,7 @@ namespace std
#if _GLIBCPP_HAVE_MODFF #if _GLIBCPP_HAVE_MODFF
inline float inline float
modf(float __x, float* __iptr) { return ::modff(__x, __iptr); } modf(float __x, float* __iptr) { return __gnu_cxx::__c99_binding::modff(__x, __iptr); }
#else #else
inline float inline float
modf(float __x, float* __iptr) modf(float __x, float* __iptr)
...@@ -398,7 +483,7 @@ namespace std ...@@ -398,7 +483,7 @@ namespace std
#if _GLIBCPP_HAVE_POWF #if _GLIBCPP_HAVE_POWF
inline float inline float
pow(float __x, float __y) { return ::powf(__x, __y); } pow(float __x, float __y) { return __gnu_cxx::__c99_binding::powf(__x, __y); }
#else #else
inline float inline float
pow(float __x, float __y) pow(float __x, float __y)
...@@ -440,7 +525,7 @@ namespace std ...@@ -440,7 +525,7 @@ namespace std
#if _GLIBCPP_HAVE_SINHF #if _GLIBCPP_HAVE_SINHF
inline float inline float
sinh(float __x) { return ::sinhf(__x); } sinh(float __x) { return __gnu_cxx::__c99_binding::sinhf(__x); }
#else #else
inline float inline float
sinh(float __x) { return ::sinh(static_cast<double>(__x)); } sinh(float __x) { return ::sinh(static_cast<double>(__x)); }
...@@ -468,7 +553,7 @@ namespace std ...@@ -468,7 +553,7 @@ namespace std
#if _GLIBCPP_HAVE_TANF #if _GLIBCPP_HAVE_TANF
inline float inline float
tan(float __x) { return ::tanf(__x); } tan(float __x) { return __gnu_cxx::__c99_binding::tanf(__x); }
#else #else
inline float inline float
tan(float __x) { return ::tan(static_cast<double>(__x)); } tan(float __x) { return ::tan(static_cast<double>(__x)); }
...@@ -486,7 +571,7 @@ namespace std ...@@ -486,7 +571,7 @@ namespace std
#if _GLIBCPP_HAVE_TANHF #if _GLIBCPP_HAVE_TANHF
inline float inline float
tanh(float __x) { return ::tanhf(__x); } tanh(float __x) { return __gnu_cxx::__c99_binding::tanhf(__x); }
#else #else
inline float inline float
tanh(float __x) { return ::tanh(static_cast<double>(__x)); } tanh(float __x) { return ::tanh(static_cast<double>(__x)); }
...@@ -503,6 +588,7 @@ namespace std ...@@ -503,6 +588,7 @@ namespace std
#if _GLIBCPP_USE_C99 #if _GLIBCPP_USE_C99
#if !_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC
// These are possible macros imported from C99-land. For strict // These are possible macros imported from C99-land. For strict
// conformance, remove possible C99-injected names from the global // conformance, remove possible C99-injected names from the global
// namespace, and sequester them in the __gnu_cxx extension namespace. // namespace, and sequester them in the __gnu_cxx extension namespace.
...@@ -561,6 +647,7 @@ namespace __gnu_cxx ...@@ -561,6 +647,7 @@ namespace __gnu_cxx
__capture_isunordered(_Tp __f1, _Tp __f2) __capture_isunordered(_Tp __f1, _Tp __f2)
{ return isunordered(__f1, __f2); } { return isunordered(__f1, __f2); }
} }
#endif /* _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC */
#endif #endif
#undef fpclassify #undef fpclassify
...@@ -577,6 +664,7 @@ namespace __gnu_cxx ...@@ -577,6 +664,7 @@ namespace __gnu_cxx
#undef isunordered #undef isunordered
#if _GLIBCPP_USE_C99 #if _GLIBCPP_USE_C99
#if !_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC
namespace __gnu_cxx namespace __gnu_cxx
{ {
template<typename _Tp> template<typename _Tp>
...@@ -647,6 +735,7 @@ namespace std ...@@ -647,6 +735,7 @@ namespace std
using __gnu_cxx::islessgreater; using __gnu_cxx::islessgreater;
using __gnu_cxx::isunordered; using __gnu_cxx::isunordered;
} }
#endif /* _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC */
#endif #endif
#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
......
// Inspired by libstdc++/7680 & 26_numerics/c_math.cc, 2003-04-12 ljr
// Copyright (C) 2003 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
// { dg-do link }
// { dg-options "-D_XOPEN_SOURCE" { target *-*-freebsd* } }
#include <cmath>
int
test01()
{
float a = 1.f;
float b;
std::modf(a, &b);
return 0;
}
int
test02 ()
{
float a = 0.0f;
float b = std::acos(b);
return 0;
}
int
main()
{
test01();
test02();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment