|
Boost : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-01-23 17:31:44
Hello,
Please find below a patch to boost/math/quaternion.hpp that allows it to
compile and run properly on GCC 2.95.3. I also verified that the changes do
not affect a more conforming platform (GCC 3.0.3). I'll summarize the changes
I made to get this working:
- Include <boost/config.hpp> to figure out what we're running on
- Only include <locale> if BOOST_NO_STD_LOCALE is not defined
- include <sstream> always - it's used internally for I/O, and we can't do
without it.
- include <boost/limits.hpp> instead of <limits>
- Added the BOOST_GET_VALARRAY macro. GCC 2.95.x's standard library uses
expression templates for valarray computation, so an expression like
abs(some_valarray_variable).max() will fail because max() isn't defined
within the expression template. BOOST_GET_VALARRAY is a simple workaround for
this that will evaluate the expression template to a temporary that max() can
be executed on.
- GCC 2.95.x's standard library has ostream and istream, but not
basic_ostream<...> and basic_istream<...>, so the input and output operators
have been changed to use ostream and istream (only for GCC 2.95.x, of course)
and to assume we are dealing with characters. ctype<charT>::narrow calls are
eliminated when compiling with GCC 2.95.x.
- When there is no locale support, don't imbue() the stringstreams with the
incoming istream's locale.
- GCC 2.95.x doesn't have a class ios_base, but instead has a class ios
that is very similar; use ios instead of ios_base for GCC 2.95.x.
If the above workarounds are acceptable, I can commit them to CVS.
Octonions will require similar modifications -- I'll write those up and post
them later.
Doug
Index: quaternion.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/math/quaternion.hpp,v
retrieving revision 1.4
diff -c -3 -p -r1.4 quaternion.hpp
*** quaternion.hpp 2002/01/12 13:29:30 1.4
--- quaternion.hpp 2002/01/23 22:18:02
***************
*** 10,18 ****
--- 10,23 ----
#ifndef BOOST_QUATERNION_HPP
#define BOOST_QUATERNION_HPP
+ #include <boost/config.hpp>
#include <complex>
#include <iosfwd> // for the "<<" and ">>"
operators
+ #include <sstream>
+ #ifndef BOOST_NO_STD_LOCALE
#include <locale> // for the "<<" operator
+ #endif // ndef BOOST_NO_STD_LOCALE
+
#include <valarray>
#include <boost/math/special_functions/sinc.hpp> // for the Sinus
cardinal
*************** namespace boost
*** 24,29 ****
--- 29,38 ----
namespace math
{
#if defined(__GNUC__) && (__GNUC__ < 3)
+ // gcc 2.95.x uses expression templates for valarray calculations,
but
+ // the result is not conforming. We need BOOST_GET_VALARRAY to get
an
+ // actual valarray result when we need to call a member function
+ # define BOOST_GET_VALARRAY(T, x) valarray<T>(x)
// gcc 2.x ignores function scope using declarations,
// put them in the scope of the enclosing namespace instead:
using ::std::valarray;
*************** namespace boost
*** 32,39 ****
using ::std::sin;
using ::std::exp;
using ::std::cosh;
#endif
!
#define BOOST_QUATERNION_ACCESSOR_GENERATOR(type) \
type real() const \
{ \
--- 41,50 ----
using ::std::sin;
using ::std::exp;
using ::std::cosh;
+ #else
+ # define BOOST_GET_VALARRAY(T, x) x
#endif
!
#define BOOST_QUATERNION_ACCESSOR_GENERATOR(type) \
type real() const \
{ \
*************** namespace boost
*** 123,130 ****
type b; \
type c; \
type d;
-
template<typename T>
class quaternion
{
--- 134,143 ----
type b; \
type c; \
type d;
+
+ template<typename T> class quaternion;
+
template<typename T>
class quaternion
{
*************** namespace boost
*** 572,578 ****
tr[0] = rhs.real();
\
tr[1] = rhs.imag();
\
\
! type mixam = static_cast<type>(1)/abs(tr).max();
\
\
tr *= mixam;
\
\
--- 585,591 ----
tr[0] = rhs.real();
\
tr[1] = rhs.imag();
\
\
! type mixam =
static_cast<type>(1)/BOOST_GET_VALARRAY(type, abs(tr)).max(); \
\
tr *= mixam;
\
\
*************** namespace boost
*** 608,614 ****
tr[2] = static_cast<type>(rhs.R_component_3());
\
tr[3] = static_cast<type>(rhs.R_component_4());
\
\
! type mixam = static_cast<type>(1)/abs(tr).max();
\
\
tr *= mixam;
\
\
--- 621,627 ----
tr[2] = static_cast<type>(rhs.R_component_3());
\
tr[3] = static_cast<type>(rhs.R_component_4());
\
\
! type mixam =
static_cast<type>(1)/BOOST_GET_VALARRAY(type, abs(tr)).max(); \
\
tr *= mixam;
\
\
*************** namespace boost
*** 1055,1288 ****
// a
// (a), (a,b), (a,b,c), (a,b,c,d)
// (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)),
((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b),(c,d))
!
template<typename T, typename charT, class traits>
::std::basic_istream<charT,traits> & operator >> (
::std::basic_istream<charT,traits> & is,
quaternion<T> & q)
{
! const ::std::ctype<charT> & ct = ::std::use_facet<
::std::ctype<charT> >(is.getloc());
!
! T a = T();
! T b = T();
! T c = T();
! T d = T();
!
! ::std::complex<T> u = ::std::complex<T>();
! ::std::complex<T> v = ::std::complex<T>();
!
! charT ch = charT();
! char cc;
!
! is >> ch; // get the
first lexeme
!
! if (!is.good()) goto finish;
!
! cc = ct.narrow(ch, char());
!
! if (cc == '(') // read "(",
possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)), ((a)), ((a),c),
((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
! {
! is >> ch; // get the
second lexeme
!
! if (!is.good()) goto finish;
!
! cc = ct.narrow(ch, char());
!
! if (cc == '(') // read "((",
possible: ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c),
((a,b),(c)), ((a,b,),(c,d,))
{
! is.putback(ch);
!
! is >> u; // we extract
the first and second components
! a = u.real();
! b = u.imag();
! if (!is.good()) goto finish;
! is >> ch; // get the
next lexeme
! if (!is.good()) goto finish;
! cc = ct.narrow(ch, char());
!
! if (cc == ')') // format:
((a)) or ((a,b))
{
! q = quaternion<T>(a,b);
}
! else if (cc == ',') // read "((a),"
or "((a,b),", possible: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c),
((a,b),(c)), ((a,b,),(c,d,))
{
! is >> v; // we extract
the third and fourth components
! c = v.real();
! d = v.imag();
!
! if (!is.good()) goto finish;
!
! is >> ch; // get the
last lexeme
! if (!is.good()) goto finish;
! cc = ct.narrow(ch, char());
! if (cc == ')') // format:
((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)) or ((a,b,),(c,d,))
{
! q = quaternion<T>(a,b,c,d);
}
! else // error
{
! is.setstate(::std::ios_base::failbit);
}
}
! else // error
{
! is.setstate(::std::ios_base::failbit);
}
}
! else // read "(a", possible:
(a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d))
{
! is.putback(ch);
!
! is >> a; // we extract
the first component
! if (!is.good()) goto finish;
! is >> ch; // get the
third lexeme
! if (!is.good()) goto finish;
! cc = ct.narrow(ch, char());
! if (cc == ')') // format: (a)
{
! q = quaternion<T>(a);
}
! else if (cc == ',') // read "(a,",
possible: (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d))
{
! is >> ch; // get the
fourth lexeme
! if (!is.good()) goto finish;
! cc = ct.narrow(ch, char());
!
! if (cc == '(') // read "(a,(",
possible: (a,(c)), (a,(c,d))
{
! is.putback(ch);
! is >> v; // we extract
the third and fourth component
! c = v.real();
! d = v.imag();
! if (!is.good()) goto finish;
! is >> ch; // get the
ninth lexeme
! if (!is.good()) goto finish;
! cc = ct.narrow(ch, char());
! if (cc == ')') // format:
(a,(c)) or (a,(c,d))
{
! q = quaternion<T>(a,b,c,d);
}
! else // error
{
! is.setstate(::std::ios_base::failbit);
}
}
! else // read "(a,b",
possible: (a,b), (a,b,c), (a,b,c,d)
{
! is.putback(ch);
! is >> b; // we extract
the second component
! if (!is.good()) goto finish;
! is >> ch; // get the
fifth lexeme
! if (!is.good()) goto finish;
! cc = ct.narrow(ch, char());
!
! if (cc == ')') // format:
(a,b)
{
! q = quaternion<T>(a,b);
}
! else if (cc == ',') // read "(a,b,",
possible: (a,b,c), (a,b,c,d)
{
! is >> c; // we extract
the third component
!
! if (!is.good()) goto finish;
!
! is >> ch; // get the
seventh lexeme
! if (!is.good()) goto finish;
! cc = ct.narrow(ch, char());
! if (cc == ')') // format:
(a,b,c)
{
! q = quaternion<T>(a,b,c);
}
! else if (cc == ',') // read
"(a,b,c,", possible: (a,b,c,d)
{
! is >> d; // we extract
the fourth component
!
! if (!is.good()) goto finish;
! is >> ch; // get the
ninth lexeme
! if (!is.good()) goto finish;
! cc = ct.narrow(ch, char());
!
! if (cc == ')') // format:
(a,b,c,d)
{
! q = quaternion<T>(a,b,c,d);
}
! else // error
{
!
is.setstate(::std::ios_base::failbit);
}
}
! else // error
{
! is.setstate(::std::ios_base::failbit);
}
}
! else // error
{
! is.setstate(::std::ios_base::failbit);
}
}
}
! else // error
{
! is.setstate(::std::ios_base::failbit);
}
}
}
! else // format: a
{
! is.putback(ch);
! is >> a; // we extract
the first component
! if (!is.good()) goto finish;
! q = quaternion<T>(a);
}
! finish:
! return(is);
}
!
template<typename T, typename charT, class traits>
::std::basic_ostream<charT,traits> & operator << (
::std::basic_ostream<charT,traits> & os,
quaternion<T> const & q)
{
::std::basic_ostringstream<charT,traits> s;
!
s.flags(os.flags());
s.imbue(os.getloc());
s.precision(os.precision());
s << '(' << q.R_component_1() << ','
--- 1068,1382 ----
// a
// (a), (a,b), (a,b,c), (a,b,c,d)
// (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)),
((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b),(c,d))
! #if defined(__GNUC__) && __GNUC__ < 3
! template<typename T>
! std::istream& operator>>(std::istream& is, quaternion<T>& q)
! #else
template<typename T, typename charT, class traits>
::std::basic_istream<charT,traits> & operator >> (
::std::basic_istream<charT,traits> & is,
quaternion<T> & q)
+ #endif
{
! #ifndef BOOST_NO_STD_LOCALE
! const ::std::ctype<charT> & ct = ::std::use_facet<
::std::ctype<charT> >(is.getloc());
! #endif
!
! #if defined(__GNUC__) && __GNUC__ < 3
! typedef char charT;
! #endif
!
! T a = T();
! T b = T();
! T c = T();
! T d = T();
!
! ::std::complex<T> u = ::std::complex<T>();
! ::std::complex<T> v = ::std::complex<T>();
!
! charT ch = charT();
! char cc;
!
! is >> ch; // get the first
lexeme
!
! if (!is.good()) goto finish;
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
! if (cc == '(') // read "(",
possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)), ((a)), ((a),c),
((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
! {
! is >> ch; // get the
second lexeme
!
! if (!is.good()) goto finish;
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
! if (cc == '(') // read "((",
possible: ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c),
((a,b),(c)), ((a,b,),(c,d,))
{
! is.putback(ch);
! is >> u; // we extract the
first and second components
! a = u.real();
! b = u.imag();
! if (!is.good()) goto finish;
! is >> ch; // get the next
lexeme
! if (!is.good()) goto finish;
!
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
!
! if (cc == ')') // format: ((a))
or ((a,b))
{
! q = quaternion<T>(a,b);
}
! else if (cc == ',') // read "((a)," or
"((a,b),", possible: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)),
((a,b,),(c,d,))
{
! is >> v; // we extract the
third and fourth components
! c = v.real();
! d = v.imag();
! if (!is.good()) goto finish;
! is >> ch; // get the
last lexeme
! if (!is.good()) goto finish;
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
!
! if (cc == ')') // format:
((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)) or ((a,b,),(c,d,))
{
! q = quaternion<T>(a,b,c,d);
}
! else // error
{
! #if defined(__GNUC__) && __GNUC__ < 3
! is.setstate(std::ios::failbit);
! #else
! is.setstate(::std::ios_base::failbit);
! #endif
}
}
! else // error
{
! #if defined(__GNUC__) && __GNUC__ < 3
! is.setstate(std::ios::failbit);
! #else
! is.setstate(::std::ios_base::failbit);
! #endif
}
}
! else // read "(a", possible:
(a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d))
{
! is.putback(ch);
! is >> a; // we extract the
first component
! if (!is.good()) goto finish;
! is >> ch; // get the third
lexeme
! if (!is.good()) goto finish;
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
! if (cc == ')') // format: (a)
{
! q = quaternion<T>(a);
}
! else if (cc == ',') // read "(a,",
possible: (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d))
{
! is >> ch; // get the
fourth lexeme
! if (!is.good()) goto finish;
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
! if (cc == '(') // read "(a,(",
possible: (a,(c)), (a,(c,d))
{
! is.putback(ch);
! is >> v; // we extract the
third and fourth component
! c = v.real();
! d = v.imag();
! if (!is.good()) goto finish;
! is >> ch; // get the ninth
lexeme
! if (!is.good()) goto finish;
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
! if (cc == ')') // format:
(a,(c)) or (a,(c,d))
{
! q = quaternion<T>(a,b,c,d);
}
! else // error
{
! #if defined(__GNUC__) && __GNUC__ < 3
! is.setstate(std::ios::failbit);
! #else
! is.setstate(::std::ios_base::failbit);
! #endif
}
}
! else // read "(a,b", possible:
(a,b), (a,b,c), (a,b,c,d)
{
! is.putback(ch);
! is >> b; // we extract the
second component
! if (!is.good()) goto finish;
! is >> ch; // get the fifth
lexeme
! if (!is.good()) goto finish;
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
!
! if (cc == ')') // format: (a,b)
{
! q = quaternion<T>(a,b);
}
! else if (cc == ',') // read "(a,b,",
possible: (a,b,c), (a,b,c,d)
{
! is >> c; // we extract the
third component
! if (!is.good()) goto finish;
! is >> ch; // get the
seventh lexeme
! if (!is.good()) goto finish;
!
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
!
! if (cc == ')') // format:
(a,b,c)
{
! q = quaternion<T>(a,b,c);
}
! else if (cc == ',') // read "(a,b,c,",
possible: (a,b,c,d)
{
! is >> d; // we extract the
fourth component
! if (!is.good()) goto finish;
! is >> ch; // get the ninth
lexeme
! if (!is.good()) goto finish;
!
! #if defined(__GNUC__) && __GNUC__ < 3
! cc = ch;
! #else
! cc = ct.narrow(ch, char());
! #endif
!
! if (cc == ')') // format:
(a,b,c,d)
{
! q = quaternion<T>(a,b,c,d);
}
! else // error
{
! #if defined(__GNUC__) && __GNUC__ < 3
! is.setstate(std::ios::failbit);
! #else
! is.setstate(::std::ios_base::failbit);
! #endif
}
}
! else // error
{
! #if defined(__GNUC__) && __GNUC__ < 3
! is.setstate(std::ios::failbit);
! #else
! is.setstate(::std::ios_base::failbit);
! #endif
}
}
! else // error
{
! #if defined(__GNUC__) && __GNUC__ < 3
! is.setstate(std::ios::failbit);
! #else
! is.setstate(::std::ios_base::failbit);
! #endif
}
}
}
! else // error
{
! #if defined(__GNUC__) && __GNUC__ < 3
! is.setstate(std::ios::failbit);
! #else
! is.setstate(::std::ios_base::failbit);
! #endif
}
}
}
! else // format: a
{
! is.putback(ch);
! is >> a; // we extract the
first component
! if (!is.good()) goto finish;
! q = quaternion<T>(a);
}
! finish:
! return(is);
}
!
! #if defined(__GNUC__) && __GNUC__ < 3
! template<typename T>
! ::std::ostream& operator<<(::std::ostream& os, quaternion<T> const
& q)
! #else
template<typename T, typename charT, class traits>
::std::basic_ostream<charT,traits> & operator << (
::std::basic_ostream<charT,traits> & os,
quaternion<T> const & q)
+ #endif
{
+ #if defined(__GNUC__) && __GNUC__ < 3
+ ::std::ostringstream s;
+ #else
::std::basic_ostringstream<charT,traits> s;
! #endif
s.flags(os.flags());
+ #ifndef BOOST_NO_STD_LOCALE
s.imbue(os.getloc());
+ #endif
s.precision(os.precision());
s << '(' << q.R_component_1() << ','
*************** namespace boost
*** 1326,1332 ****
{
BOOST_QUATERNION_VALARRAY_LOADER
! return(abs(temp).max());
}
--- 1420,1426 ----
{
BOOST_QUATERNION_VALARRAY_LOADER
! return(BOOST_GET_VALARRAY(T, abs(temp)).max());
}
*************** namespace boost
*** 1335,1341 ****
{
BOOST_QUATERNION_VALARRAY_LOADER
! return(abs(temp).sum());
}
--- 1429,1435 ----
{
BOOST_QUATERNION_VALARRAY_LOADER
! return(BOOST_GET_VALARRAY(T, abs(temp)).sum());
}
*************** namespace boost
*** 1346,1352 ****
BOOST_QUATERNION_VALARRAY_LOADER
! T maxim = abs(temp).max(); // overflow protection
if (maxim == static_cast<T>(0))
{
--- 1440,1446 ----
BOOST_QUATERNION_VALARRAY_LOADER
! T maxim = BOOST_GET_VALARRAY(T, abs(temp)).max();
// overflow protection
if (maxim == static_cast<T>(0))
{
*************** namespace boost
*** 1615,1620 ****
}
}
}
!
#endif /* BOOST_QUATERNION_HPP */
--- 1709,1714 ----
}
}
}
! #undef BOOST_GET_VALARRAY
#endif /* BOOST_QUATERNION_HPP */
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk