| [12] | 1 | //  boost quaternion.hpp header file | 
|---|
 | 2 |  | 
|---|
 | 3 | //  (C) Copyright Hubert Holin 2001. | 
|---|
 | 4 | //  Distributed under the Boost Software License, Version 1.0. (See | 
|---|
 | 5 | //  accompanying file LICENSE_1_0.txt or copy at | 
|---|
 | 6 | //  http://www.boost.org/LICENSE_1_0.txt) | 
|---|
 | 7 |  | 
|---|
 | 8 | // See http://www.boost.org for updates, documentation, and revision history. | 
|---|
 | 9 |  | 
|---|
 | 10 | #ifndef BOOST_QUATERNION_HPP | 
|---|
 | 11 | #define BOOST_QUATERNION_HPP | 
|---|
 | 12 |  | 
|---|
 | 13 |  | 
|---|
 | 14 | #include <complex> | 
|---|
 | 15 | #include <iosfwd>                                    // for the "<<" and ">>" operators | 
|---|
 | 16 | #include <sstream>                                    // for the "<<" operator | 
|---|
 | 17 |  | 
|---|
 | 18 | #include <boost/config.hpp> // for BOOST_NO_STD_LOCALE | 
|---|
 | 19 | #include <boost/detail/workaround.hpp> | 
|---|
 | 20 | #ifndef    BOOST_NO_STD_LOCALE | 
|---|
 | 21 |     #include <locale>                                    // for the "<<" operator | 
|---|
 | 22 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 23 |  | 
|---|
 | 24 | #include <valarray> | 
|---|
 | 25 |  | 
|---|
 | 26 |  | 
|---|
 | 27 |  | 
|---|
 | 28 | #include <boost/math/special_functions/sinc.hpp>    // for the Sinus cardinal | 
|---|
 | 29 | #include <boost/math/special_functions/sinhc.hpp>    // for the Hyperbolic Sinus cardinal | 
|---|
 | 30 |  | 
|---|
 | 31 |  | 
|---|
 | 32 | namespace boost | 
|---|
 | 33 | { | 
|---|
 | 34 |     namespace math | 
|---|
 | 35 |     { | 
|---|
 | 36 | #if     BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 37 |         // gcc 2.95.x uses expression templates for valarray calculations, but | 
|---|
 | 38 |         // the result is not conforming. We need BOOST_GET_VALARRAY to get an | 
|---|
 | 39 |         // actual valarray result when we need to call a member function | 
|---|
 | 40 |     #define    BOOST_GET_VALARRAY(T,x)    ::std::valarray<T>(x) | 
|---|
 | 41 |         // gcc 2.95.x has an "std::ios" class that is similar to  | 
|---|
 | 42 |         // "std::ios_base", so we just use a #define | 
|---|
 | 43 |     #define    BOOST_IOS_BASE    ::std::ios | 
|---|
 | 44 |         // gcc 2.x ignores function scope using declarations, | 
|---|
 | 45 |         // put them in the scope of the enclosing namespace instead: | 
|---|
 | 46 |         using    ::std::valarray; | 
|---|
 | 47 |         using    ::std::sqrt; | 
|---|
 | 48 |         using    ::std::cos; | 
|---|
 | 49 |         using    ::std::sin; | 
|---|
 | 50 |         using    ::std::exp; | 
|---|
 | 51 |         using    ::std::cosh; | 
|---|
 | 52 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 53 |  | 
|---|
 | 54 | #define    BOOST_QUATERNION_ACCESSOR_GENERATOR(type)                    \ | 
|---|
 | 55 |             type                    real() const                        \ | 
|---|
 | 56 |             {                                                           \ | 
|---|
 | 57 |                 return(a);                                              \ | 
|---|
 | 58 |             }                                                           \ | 
|---|
 | 59 |                                                                         \ | 
|---|
 | 60 |             quaternion<type>        unreal() const                      \ | 
|---|
 | 61 |             {                                                           \ | 
|---|
 | 62 |                 return(quaternion<type>(static_cast<type>(0),b,c,d));   \ | 
|---|
 | 63 |             }                                                           \ | 
|---|
 | 64 |                                                                         \ | 
|---|
 | 65 |             type                    R_component_1() const               \ | 
|---|
 | 66 |             {                                                           \ | 
|---|
 | 67 |                 return(a);                                              \ | 
|---|
 | 68 |             }                                                           \ | 
|---|
 | 69 |                                                                         \ | 
|---|
 | 70 |             type                    R_component_2() const               \ | 
|---|
 | 71 |             {                                                           \ | 
|---|
 | 72 |                 return(b);                                              \ | 
|---|
 | 73 |             }                                                           \ | 
|---|
 | 74 |                                                                         \ | 
|---|
 | 75 |             type                    R_component_3() const               \ | 
|---|
 | 76 |             {                                                           \ | 
|---|
 | 77 |                 return(c);                                              \ | 
|---|
 | 78 |             }                                                           \ | 
|---|
 | 79 |                                                                         \ | 
|---|
 | 80 |             type                    R_component_4() const               \ | 
|---|
 | 81 |             {                                                           \ | 
|---|
 | 82 |                 return(d);                                              \ | 
|---|
 | 83 |             }                                                           \ | 
|---|
 | 84 |                                                                         \ | 
|---|
 | 85 |             ::std::complex<type>    C_component_1() const               \ | 
|---|
 | 86 |             {                                                           \ | 
|---|
 | 87 |                 return(::std::complex<type>(a,b));                      \ | 
|---|
 | 88 |             }                                                           \ | 
|---|
 | 89 |                                                                         \ | 
|---|
 | 90 |             ::std::complex<type>    C_component_2() const               \ | 
|---|
 | 91 |             {                                                           \ | 
|---|
 | 92 |                 return(::std::complex<type>(c,d));                      \ | 
|---|
 | 93 |             } | 
|---|
 | 94 |          | 
|---|
 | 95 |          | 
|---|
 | 96 | #define    BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(type)                               \ | 
|---|
 | 97 |             template<typename X>                                                            \ | 
|---|
 | 98 |             quaternion<type> &        operator = (quaternion<X> const  & a_affecter)        \ | 
|---|
 | 99 |             {                                                                               \ | 
|---|
 | 100 |                 a = static_cast<type>(a_affecter.R_component_1());                          \ | 
|---|
 | 101 |                 b = static_cast<type>(a_affecter.R_component_2());                          \ | 
|---|
 | 102 |                 c = static_cast<type>(a_affecter.R_component_3());                          \ | 
|---|
 | 103 |                 d = static_cast<type>(a_affecter.R_component_4());                          \ | 
|---|
 | 104 |                                                                                             \ | 
|---|
 | 105 |                 return(*this);                                                              \ | 
|---|
 | 106 |             }                                                                               \ | 
|---|
 | 107 |                                                                                             \ | 
|---|
 | 108 |             quaternion<type> &        operator = (quaternion<type> const & a_affecter)      \ | 
|---|
 | 109 |             {                                                                               \ | 
|---|
 | 110 |                 a = a_affecter.a;                                                           \ | 
|---|
 | 111 |                 b = a_affecter.b;                                                           \ | 
|---|
 | 112 |                 c = a_affecter.c;                                                           \ | 
|---|
 | 113 |                 d = a_affecter.d;                                                           \ | 
|---|
 | 114 |                                                                                             \ | 
|---|
 | 115 |                 return(*this);                                                              \ | 
|---|
 | 116 |             }                                                                               \ | 
|---|
 | 117 |                                                                                             \ | 
|---|
 | 118 |             quaternion<type> &        operator = (type const & a_affecter)                  \ | 
|---|
 | 119 |             {                                                                               \ | 
|---|
 | 120 |                 a = a_affecter;                                                             \ | 
|---|
 | 121 |                                                                                             \ | 
|---|
 | 122 |                 b = c = d = static_cast<type>(0);                                           \ | 
|---|
 | 123 |                                                                                             \ | 
|---|
 | 124 |                 return(*this);                                                              \ | 
|---|
 | 125 |             }                                                                               \ | 
|---|
 | 126 |                                                                                             \ | 
|---|
 | 127 |             quaternion<type> &        operator = (::std::complex<type> const & a_affecter)  \ | 
|---|
 | 128 |             {                                                                               \ | 
|---|
 | 129 |                 a = a_affecter.real();                                                      \ | 
|---|
 | 130 |                 b = a_affecter.imag();                                                      \ | 
|---|
 | 131 |                                                                                             \ | 
|---|
 | 132 |                 c = d = static_cast<type>(0);                                               \ | 
|---|
 | 133 |                                                                                             \ | 
|---|
 | 134 |                 return(*this);                                                              \ | 
|---|
 | 135 |             } | 
|---|
 | 136 |          | 
|---|
 | 137 |          | 
|---|
 | 138 | #define    BOOST_QUATERNION_MEMBER_DATA_GENERATOR(type)       \ | 
|---|
 | 139 |             type    a;                                        \ | 
|---|
 | 140 |             type    b;                                        \ | 
|---|
 | 141 |             type    c;                                        \ | 
|---|
 | 142 |             type    d; | 
|---|
 | 143 |          | 
|---|
 | 144 |          | 
|---|
 | 145 |         template<typename T> | 
|---|
 | 146 |         class quaternion | 
|---|
 | 147 |         { | 
|---|
 | 148 |         public: | 
|---|
 | 149 |              | 
|---|
 | 150 |             typedef T value_type; | 
|---|
 | 151 |              | 
|---|
 | 152 |              | 
|---|
 | 153 |             // constructor for H seen as R^4 | 
|---|
 | 154 |             // (also default constructor) | 
|---|
 | 155 |              | 
|---|
 | 156 |             explicit            quaternion( T const & requested_a = T(), | 
|---|
 | 157 |                                             T const & requested_b = T(), | 
|---|
 | 158 |                                             T const & requested_c = T(), | 
|---|
 | 159 |                                             T const & requested_d = T()) | 
|---|
 | 160 |             :   a(requested_a), | 
|---|
 | 161 |                 b(requested_b), | 
|---|
 | 162 |                 c(requested_c), | 
|---|
 | 163 |                 d(requested_d) | 
|---|
 | 164 |             { | 
|---|
 | 165 |                 // nothing to do! | 
|---|
 | 166 |             } | 
|---|
 | 167 |              | 
|---|
 | 168 |              | 
|---|
 | 169 |             // constructor for H seen as C^2 | 
|---|
 | 170 |                  | 
|---|
 | 171 |             explicit            quaternion( ::std::complex<T> const & z0, | 
|---|
 | 172 |                                             ::std::complex<T> const & z1 = ::std::complex<T>()) | 
|---|
 | 173 |             :   a(z0.real()), | 
|---|
 | 174 |                 b(z0.imag()), | 
|---|
 | 175 |                 c(z1.real()), | 
|---|
 | 176 |                 d(z1.imag()) | 
|---|
 | 177 |             { | 
|---|
 | 178 |                 // nothing to do! | 
|---|
 | 179 |             } | 
|---|
 | 180 |              | 
|---|
 | 181 |              | 
|---|
 | 182 |             // UNtemplated copy constructor | 
|---|
 | 183 |             // (this is taken care of by the compiler itself) | 
|---|
 | 184 |              | 
|---|
 | 185 |              | 
|---|
 | 186 |             // templated copy constructor | 
|---|
 | 187 |              | 
|---|
 | 188 |             template<typename X> | 
|---|
 | 189 |             explicit            quaternion(quaternion<X> const & a_recopier) | 
|---|
 | 190 |             :   a(static_cast<T>(a_recopier.R_component_1())), | 
|---|
 | 191 |                 b(static_cast<T>(a_recopier.R_component_2())), | 
|---|
 | 192 |                 c(static_cast<T>(a_recopier.R_component_3())), | 
|---|
 | 193 |                 d(static_cast<T>(a_recopier.R_component_4())) | 
|---|
 | 194 |             { | 
|---|
 | 195 |                 // nothing to do! | 
|---|
 | 196 |             } | 
|---|
 | 197 |              | 
|---|
 | 198 |              | 
|---|
 | 199 |             // destructor | 
|---|
 | 200 |             // (this is taken care of by the compiler itself) | 
|---|
 | 201 |              | 
|---|
 | 202 |              | 
|---|
 | 203 |             // accessors | 
|---|
 | 204 |             // | 
|---|
 | 205 |             // Note:    Like complex number, quaternions do have a meaningful notion of "real part", | 
|---|
 | 206 |             //            but unlike them there is no meaningful notion of "imaginary part". | 
|---|
 | 207 |             //            Instead there is an "unreal part" which itself is a quaternion, and usually | 
|---|
 | 208 |             //            nothing simpler (as opposed to the complex number case). | 
|---|
 | 209 |             //            However, for practicallity, there are accessors for the other components | 
|---|
 | 210 |             //            (these are necessary for the templated copy constructor, for instance). | 
|---|
 | 211 |              | 
|---|
 | 212 |             BOOST_QUATERNION_ACCESSOR_GENERATOR(T) | 
|---|
 | 213 |              | 
|---|
 | 214 |             // assignment operators | 
|---|
 | 215 |              | 
|---|
 | 216 |             BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(T) | 
|---|
 | 217 |              | 
|---|
 | 218 |             // other assignment-related operators | 
|---|
 | 219 |             // | 
|---|
 | 220 |             // NOTE:    Quaternion multiplication is *NOT* commutative; | 
|---|
 | 221 |             //            symbolically, "q *= rhs;" means "q = q * rhs;" | 
|---|
 | 222 |             //            and "q /= rhs;" means "q = q * inverse_of(rhs);" | 
|---|
 | 223 |              | 
|---|
 | 224 |             quaternion<T> &        operator += (T const & rhs) | 
|---|
 | 225 |             { | 
|---|
 | 226 |                 T    at = a + rhs;    // exception guard | 
|---|
 | 227 |                  | 
|---|
 | 228 |                 a = at; | 
|---|
 | 229 |                  | 
|---|
 | 230 |                 return(*this); | 
|---|
 | 231 |             } | 
|---|
 | 232 |              | 
|---|
 | 233 |              | 
|---|
 | 234 |             quaternion<T> &        operator += (::std::complex<T> const & rhs) | 
|---|
 | 235 |             { | 
|---|
 | 236 |                 T    at = a + rhs.real();    // exception guard | 
|---|
 | 237 |                 T    bt = b + rhs.imag();    // exception guard | 
|---|
 | 238 |                  | 
|---|
 | 239 |                 a = at;  | 
|---|
 | 240 |                 b = bt; | 
|---|
 | 241 |                  | 
|---|
 | 242 |                 return(*this); | 
|---|
 | 243 |             } | 
|---|
 | 244 |              | 
|---|
 | 245 |              | 
|---|
 | 246 |             template<typename X> | 
|---|
 | 247 |             quaternion<T> &        operator += (quaternion<X> const & rhs) | 
|---|
 | 248 |             { | 
|---|
 | 249 |                 T    at = a + static_cast<T>(rhs.R_component_1());    // exception guard | 
|---|
 | 250 |                 T    bt = b + static_cast<T>(rhs.R_component_2());    // exception guard | 
|---|
 | 251 |                 T    ct = c + static_cast<T>(rhs.R_component_3());    // exception guard | 
|---|
 | 252 |                 T    dt = d + static_cast<T>(rhs.R_component_4());    // exception guard | 
|---|
 | 253 |                  | 
|---|
 | 254 |                 a = at; | 
|---|
 | 255 |                 b = bt; | 
|---|
 | 256 |                 c = ct; | 
|---|
 | 257 |                 d = dt; | 
|---|
 | 258 |                  | 
|---|
 | 259 |                 return(*this); | 
|---|
 | 260 |             } | 
|---|
 | 261 |              | 
|---|
 | 262 |              | 
|---|
 | 263 |              | 
|---|
 | 264 |             quaternion<T> &        operator -= (T const & rhs) | 
|---|
 | 265 |             { | 
|---|
 | 266 |                 T    at = a - rhs;    // exception guard | 
|---|
 | 267 |                  | 
|---|
 | 268 |                 a = at; | 
|---|
 | 269 |                  | 
|---|
 | 270 |                 return(*this); | 
|---|
 | 271 |             } | 
|---|
 | 272 |              | 
|---|
 | 273 |              | 
|---|
 | 274 |             quaternion<T> &        operator -= (::std::complex<T> const & rhs) | 
|---|
 | 275 |             { | 
|---|
 | 276 |                 T    at = a - rhs.real();    // exception guard | 
|---|
 | 277 |                 T    bt = b - rhs.imag();    // exception guard | 
|---|
 | 278 |                  | 
|---|
 | 279 |                 a = at; | 
|---|
 | 280 |                 b = bt; | 
|---|
 | 281 |                  | 
|---|
 | 282 |                 return(*this); | 
|---|
 | 283 |             } | 
|---|
 | 284 |              | 
|---|
 | 285 |              | 
|---|
 | 286 |             template<typename X> | 
|---|
 | 287 |             quaternion<T> &        operator -= (quaternion<X> const & rhs) | 
|---|
 | 288 |             { | 
|---|
 | 289 |                 T    at = a - static_cast<T>(rhs.R_component_1());    // exception guard | 
|---|
 | 290 |                 T    bt = b - static_cast<T>(rhs.R_component_2());    // exception guard | 
|---|
 | 291 |                 T    ct = c - static_cast<T>(rhs.R_component_3());    // exception guard | 
|---|
 | 292 |                 T    dt = d - static_cast<T>(rhs.R_component_4());    // exception guard | 
|---|
 | 293 |                  | 
|---|
 | 294 |                 a = at; | 
|---|
 | 295 |                 b = bt; | 
|---|
 | 296 |                 c = ct; | 
|---|
 | 297 |                 d = dt; | 
|---|
 | 298 |                  | 
|---|
 | 299 |                 return(*this); | 
|---|
 | 300 |             } | 
|---|
 | 301 |              | 
|---|
 | 302 |              | 
|---|
 | 303 |             quaternion<T> &        operator *= (T const & rhs) | 
|---|
 | 304 |             { | 
|---|
 | 305 |                 T    at = a * rhs;    // exception guard | 
|---|
 | 306 |                 T    bt = b * rhs;    // exception guard | 
|---|
 | 307 |                 T    ct = c * rhs;    // exception guard | 
|---|
 | 308 |                 T    dt = d * rhs;    // exception guard | 
|---|
 | 309 |                  | 
|---|
 | 310 |                 a = at; | 
|---|
 | 311 |                 b = bt; | 
|---|
 | 312 |                 c = ct; | 
|---|
 | 313 |                 d = dt; | 
|---|
 | 314 |                  | 
|---|
 | 315 |                 return(*this); | 
|---|
 | 316 |             } | 
|---|
 | 317 |              | 
|---|
 | 318 |              | 
|---|
 | 319 |             quaternion<T> &        operator *= (::std::complex<T> const & rhs) | 
|---|
 | 320 |             { | 
|---|
 | 321 |                 T    ar = rhs.real(); | 
|---|
 | 322 |                 T    br = rhs.imag(); | 
|---|
 | 323 |                  | 
|---|
 | 324 |                 T    at = +a*ar-b*br; | 
|---|
 | 325 |                 T    bt = +a*br+b*ar; | 
|---|
 | 326 |                 T    ct = +c*ar+d*br; | 
|---|
 | 327 |                 T    dt = -c*br+d*ar; | 
|---|
 | 328 |                  | 
|---|
 | 329 |                 a = at; | 
|---|
 | 330 |                 b = bt; | 
|---|
 | 331 |                 c = ct; | 
|---|
 | 332 |                 d = dt; | 
|---|
 | 333 |                  | 
|---|
 | 334 |                 return(*this); | 
|---|
 | 335 |             } | 
|---|
 | 336 |              | 
|---|
 | 337 |              | 
|---|
 | 338 |             template<typename X> | 
|---|
 | 339 |             quaternion<T> &        operator *= (quaternion<X> const & rhs) | 
|---|
 | 340 |             { | 
|---|
 | 341 |                 T    ar = static_cast<T>(rhs.R_component_1()); | 
|---|
 | 342 |                 T    br = static_cast<T>(rhs.R_component_2()); | 
|---|
 | 343 |                 T    cr = static_cast<T>(rhs.R_component_3()); | 
|---|
 | 344 |                 T    dr = static_cast<T>(rhs.R_component_4()); | 
|---|
 | 345 |                  | 
|---|
 | 346 |                 T    at = +a*ar-b*br-c*cr-d*dr; | 
|---|
 | 347 |                 T    bt = +a*br+b*ar+c*dr-d*cr;    //(a*br+ar*b)+(c*dr-cr*d); | 
|---|
 | 348 |                 T    ct = +a*cr-b*dr+c*ar+d*br;    //(a*cr+ar*c)+(d*br-dr*b); | 
|---|
 | 349 |                 T    dt = +a*dr+b*cr-c*br+d*ar;    //(a*dr+ar*d)+(b*cr-br*c); | 
|---|
 | 350 |                  | 
|---|
 | 351 |                 a = at; | 
|---|
 | 352 |                 b = bt; | 
|---|
 | 353 |                 c = ct; | 
|---|
 | 354 |                 d = dt; | 
|---|
 | 355 |                  | 
|---|
 | 356 |                 return(*this); | 
|---|
 | 357 |             } | 
|---|
 | 358 |              | 
|---|
 | 359 |              | 
|---|
 | 360 |              | 
|---|
 | 361 |             quaternion<T> &        operator /= (T const & rhs) | 
|---|
 | 362 |             { | 
|---|
 | 363 |                 T    at = a / rhs;    // exception guard | 
|---|
 | 364 |                 T    bt = b / rhs;    // exception guard | 
|---|
 | 365 |                 T    ct = c / rhs;    // exception guard | 
|---|
 | 366 |                 T    dt = d / rhs;    // exception guard | 
|---|
 | 367 |                  | 
|---|
 | 368 |                 a = at; | 
|---|
 | 369 |                 b = bt; | 
|---|
 | 370 |                 c = ct; | 
|---|
 | 371 |                 d = dt; | 
|---|
 | 372 |                  | 
|---|
 | 373 |                 return(*this); | 
|---|
 | 374 |             } | 
|---|
 | 375 |              | 
|---|
 | 376 |              | 
|---|
 | 377 |             quaternion<T> &        operator /= (::std::complex<T> const & rhs) | 
|---|
 | 378 |             { | 
|---|
 | 379 |                 T    ar = rhs.real(); | 
|---|
 | 380 |                 T    br = rhs.imag(); | 
|---|
 | 381 |                  | 
|---|
 | 382 |                 T    denominator = ar*ar+br*br; | 
|---|
 | 383 |                  | 
|---|
 | 384 |                 T    at = (+a*ar+b*br)/denominator;    //(a*ar+b*br)/denominator; | 
|---|
 | 385 |                 T    bt = (-a*br+b*ar)/denominator;    //(ar*b-a*br)/denominator; | 
|---|
 | 386 |                 T    ct = (+c*ar-d*br)/denominator;    //(ar*c-d*br)/denominator; | 
|---|
 | 387 |                 T    dt = (+c*br+d*ar)/denominator;    //(ar*d+br*c)/denominator; | 
|---|
 | 388 |                  | 
|---|
 | 389 |                 a = at; | 
|---|
 | 390 |                 b = bt; | 
|---|
 | 391 |                 c = ct; | 
|---|
 | 392 |                 d = dt; | 
|---|
 | 393 |                  | 
|---|
 | 394 |                 return(*this); | 
|---|
 | 395 |             } | 
|---|
 | 396 |              | 
|---|
 | 397 |              | 
|---|
 | 398 |             template<typename X> | 
|---|
 | 399 |             quaternion<T> &        operator /= (quaternion<X> const & rhs) | 
|---|
 | 400 |             { | 
|---|
 | 401 |                 T    ar = static_cast<T>(rhs.R_component_1()); | 
|---|
 | 402 |                 T    br = static_cast<T>(rhs.R_component_2()); | 
|---|
 | 403 |                 T    cr = static_cast<T>(rhs.R_component_3()); | 
|---|
 | 404 |                 T    dr = static_cast<T>(rhs.R_component_4()); | 
|---|
 | 405 |                  | 
|---|
 | 406 |                 T    denominator = ar*ar+br*br+cr*cr+dr*dr; | 
|---|
 | 407 |                  | 
|---|
 | 408 |                 T    at = (+a*ar+b*br+c*cr+d*dr)/denominator;    //(a*ar+b*br+c*cr+d*dr)/denominator; | 
|---|
 | 409 |                 T    bt = (-a*br+b*ar-c*dr+d*cr)/denominator;    //((ar*b-a*br)+(cr*d-c*dr))/denominator; | 
|---|
 | 410 |                 T    ct = (-a*cr+b*dr+c*ar-d*br)/denominator;    //((ar*c-a*cr)+(dr*b-d*br))/denominator; | 
|---|
 | 411 |                 T    dt = (-a*dr-b*cr+c*br+d*ar)/denominator;    //((ar*d-a*dr)+(br*c-b*cr))/denominator; | 
|---|
 | 412 |                  | 
|---|
 | 413 |                 a = at; | 
|---|
 | 414 |                 b = bt; | 
|---|
 | 415 |                 c = ct; | 
|---|
 | 416 |                 d = dt; | 
|---|
 | 417 |                  | 
|---|
 | 418 |                 return(*this); | 
|---|
 | 419 |             } | 
|---|
 | 420 |              | 
|---|
 | 421 |              | 
|---|
 | 422 |         protected: | 
|---|
 | 423 |              | 
|---|
 | 424 |             BOOST_QUATERNION_MEMBER_DATA_GENERATOR(T) | 
|---|
 | 425 |              | 
|---|
 | 426 |              | 
|---|
 | 427 |         private: | 
|---|
 | 428 |              | 
|---|
 | 429 |         }; | 
|---|
 | 430 |          | 
|---|
 | 431 |          | 
|---|
 | 432 |         // declaration of quaternion specialization | 
|---|
 | 433 |          | 
|---|
 | 434 |         template<>    class quaternion<float>; | 
|---|
 | 435 |         template<>    class quaternion<double>; | 
|---|
 | 436 |         template<>    class quaternion<long double>; | 
|---|
 | 437 |          | 
|---|
 | 438 |          | 
|---|
 | 439 |         // helper templates for converting copy constructors (declaration) | 
|---|
 | 440 |          | 
|---|
 | 441 |         namespace detail | 
|---|
 | 442 |         { | 
|---|
 | 443 |              | 
|---|
 | 444 |             template<   typename T, | 
|---|
 | 445 |                         typename U | 
|---|
 | 446 |                     > | 
|---|
 | 447 |             quaternion<T>    quaternion_type_converter(quaternion<U> const & rhs); | 
|---|
 | 448 |         } | 
|---|
 | 449 |          | 
|---|
 | 450 |          | 
|---|
 | 451 |         // implementation of quaternion specialization | 
|---|
 | 452 |          | 
|---|
 | 453 |          | 
|---|
 | 454 | #define    BOOST_QUATERNION_CONSTRUCTOR_GENERATOR(type)                                                 \ | 
|---|
 | 455 |             explicit            quaternion( type const & requested_a = static_cast<type>(0),            \ | 
|---|
 | 456 |                                             type const & requested_b = static_cast<type>(0),            \ | 
|---|
 | 457 |                                             type const & requested_c = static_cast<type>(0),            \ | 
|---|
 | 458 |                                             type const & requested_d = static_cast<type>(0))            \ | 
|---|
 | 459 |             :   a(requested_a),                                                                         \ | 
|---|
 | 460 |                 b(requested_b),                                                                         \ | 
|---|
 | 461 |                 c(requested_c),                                                                         \ | 
|---|
 | 462 |                 d(requested_d)                                                                          \ | 
|---|
 | 463 |             {                                                                                           \ | 
|---|
 | 464 |             }                                                                                           \ | 
|---|
 | 465 |                                                                                                         \ | 
|---|
 | 466 |             explicit            quaternion( ::std::complex<type> const & z0,                            \ | 
|---|
 | 467 |                                             ::std::complex<type> const & z1 = ::std::complex<type>())   \ | 
|---|
 | 468 |             :   a(z0.real()),                                                                           \ | 
|---|
 | 469 |                 b(z0.imag()),                                                                           \ | 
|---|
 | 470 |                 c(z1.real()),                                                                           \ | 
|---|
 | 471 |                 d(z1.imag())                                                                            \ | 
|---|
 | 472 |             {                                                                                           \ | 
|---|
 | 473 |             } | 
|---|
 | 474 |          | 
|---|
 | 475 |          | 
|---|
 | 476 | #define    BOOST_QUATERNION_MEMBER_ADD_GENERATOR_1(type)             \ | 
|---|
 | 477 |             quaternion<type> &        operator += (type const & rhs) \ | 
|---|
 | 478 |             {                                                        \ | 
|---|
 | 479 |                 a += rhs;                                            \ | 
|---|
 | 480 |                                                                      \ | 
|---|
 | 481 |                 return(*this);                                       \ | 
|---|
 | 482 |             } | 
|---|
 | 483 |      | 
|---|
 | 484 | #define    BOOST_QUATERNION_MEMBER_ADD_GENERATOR_2(type)                             \ | 
|---|
 | 485 |             quaternion<type> &        operator += (::std::complex<type> const & rhs) \ | 
|---|
 | 486 |             {                                                                        \ | 
|---|
 | 487 |                 a += rhs.real();                                                     \ | 
|---|
 | 488 |                 b += rhs.imag();                                                     \ | 
|---|
 | 489 |                                                                                      \ | 
|---|
 | 490 |                 return(*this);                                                       \ | 
|---|
 | 491 |             } | 
|---|
 | 492 |      | 
|---|
 | 493 | #define    BOOST_QUATERNION_MEMBER_ADD_GENERATOR_3(type)                      \ | 
|---|
 | 494 |             template<typename X>                                              \ | 
|---|
 | 495 |             quaternion<type> &        operator += (quaternion<X> const & rhs) \ | 
|---|
 | 496 |             {                                                                 \ | 
|---|
 | 497 |                 a += static_cast<type>(rhs.R_component_1());                  \ | 
|---|
 | 498 |                 b += static_cast<type>(rhs.R_component_2());                  \ | 
|---|
 | 499 |                 c += static_cast<type>(rhs.R_component_3());                  \ | 
|---|
 | 500 |                 d += static_cast<type>(rhs.R_component_4());                  \ | 
|---|
 | 501 |                                                                               \ | 
|---|
 | 502 |                 return(*this);                                                \ | 
|---|
 | 503 |             } | 
|---|
 | 504 |      | 
|---|
 | 505 | #define    BOOST_QUATERNION_MEMBER_SUB_GENERATOR_1(type)             \ | 
|---|
 | 506 |             quaternion<type> &        operator -= (type const & rhs) \ | 
|---|
 | 507 |             {                                                        \ | 
|---|
 | 508 |                 a -= rhs;                                            \ | 
|---|
 | 509 |                                                                      \ | 
|---|
 | 510 |                 return(*this);                                       \ | 
|---|
 | 511 |             } | 
|---|
 | 512 |      | 
|---|
 | 513 | #define    BOOST_QUATERNION_MEMBER_SUB_GENERATOR_2(type)                             \ | 
|---|
 | 514 |             quaternion<type> &        operator -= (::std::complex<type> const & rhs) \ | 
|---|
 | 515 |             {                                                                        \ | 
|---|
 | 516 |                 a -= rhs.real();                                                     \ | 
|---|
 | 517 |                 b -= rhs.imag();                                                     \ | 
|---|
 | 518 |                                                                                      \ | 
|---|
 | 519 |                 return(*this);                                                       \ | 
|---|
 | 520 |             } | 
|---|
 | 521 |      | 
|---|
 | 522 | #define    BOOST_QUATERNION_MEMBER_SUB_GENERATOR_3(type)                      \ | 
|---|
 | 523 |             template<typename X>                                              \ | 
|---|
 | 524 |             quaternion<type> &        operator -= (quaternion<X> const & rhs) \ | 
|---|
 | 525 |             {                                                                 \ | 
|---|
 | 526 |                 a -= static_cast<type>(rhs.R_component_1());                  \ | 
|---|
 | 527 |                 b -= static_cast<type>(rhs.R_component_2());                  \ | 
|---|
 | 528 |                 c -= static_cast<type>(rhs.R_component_3());                  \ | 
|---|
 | 529 |                 d -= static_cast<type>(rhs.R_component_4());                  \ | 
|---|
 | 530 |                                                                               \ | 
|---|
 | 531 |                 return(*this);                                                \ | 
|---|
 | 532 |             } | 
|---|
 | 533 |      | 
|---|
 | 534 | #define    BOOST_QUATERNION_MEMBER_MUL_GENERATOR_1(type)             \ | 
|---|
 | 535 |             quaternion<type> &        operator *= (type const & rhs) \ | 
|---|
 | 536 |             {                                                        \ | 
|---|
 | 537 |                 a *= rhs;                                            \ | 
|---|
 | 538 |                 b *= rhs;                                            \ | 
|---|
 | 539 |                 c *= rhs;                                            \ | 
|---|
 | 540 |                 d *= rhs;                                            \ | 
|---|
 | 541 |                                                                      \ | 
|---|
 | 542 |                 return(*this);                                       \ | 
|---|
 | 543 |             } | 
|---|
 | 544 |      | 
|---|
 | 545 | #define    BOOST_QUATERNION_MEMBER_MUL_GENERATOR_2(type)                             \ | 
|---|
 | 546 |             quaternion<type> &        operator *= (::std::complex<type> const & rhs) \ | 
|---|
 | 547 |             {                                                                        \ | 
|---|
 | 548 |                 type    ar = rhs.real();                                             \ | 
|---|
 | 549 |                 type    br = rhs.imag();                                             \ | 
|---|
 | 550 |                                                                                      \ | 
|---|
 | 551 |                 type    at = +a*ar-b*br;                                             \ | 
|---|
 | 552 |                 type    bt = +a*br+b*ar;                                             \ | 
|---|
 | 553 |                 type    ct = +c*ar+d*br;                                             \ | 
|---|
 | 554 |                 type    dt = -c*br+d*ar;                                             \ | 
|---|
 | 555 |                                                                                      \ | 
|---|
 | 556 |                 a = at;                                                              \ | 
|---|
 | 557 |                 b = bt;                                                              \ | 
|---|
 | 558 |                 c = ct;                                                              \ | 
|---|
 | 559 |                 d = dt;                                                              \ | 
|---|
 | 560 |                                                                                      \ | 
|---|
 | 561 |                 return(*this);                                                       \ | 
|---|
 | 562 |             } | 
|---|
 | 563 |      | 
|---|
 | 564 | #define    BOOST_QUATERNION_MEMBER_MUL_GENERATOR_3(type)                      \ | 
|---|
 | 565 |             template<typename X>                                              \ | 
|---|
 | 566 |             quaternion<type> &        operator *= (quaternion<X> const & rhs) \ | 
|---|
 | 567 |             {                                                                 \ | 
|---|
 | 568 |                 type    ar = static_cast<type>(rhs.R_component_1());          \ | 
|---|
 | 569 |                 type    br = static_cast<type>(rhs.R_component_2());          \ | 
|---|
 | 570 |                 type    cr = static_cast<type>(rhs.R_component_3());          \ | 
|---|
 | 571 |                 type    dr = static_cast<type>(rhs.R_component_4());          \ | 
|---|
 | 572 |                                                                               \ | 
|---|
 | 573 |                 type    at = +a*ar-b*br-c*cr-d*dr;                            \ | 
|---|
 | 574 |                 type    bt = +a*br+b*ar+c*dr-d*cr;                            \ | 
|---|
 | 575 |                 type    ct = +a*cr-b*dr+c*ar+d*br;                            \ | 
|---|
 | 576 |                 type    dt = +a*dr+b*cr-c*br+d*ar;                            \ | 
|---|
 | 577 |                                                                               \ | 
|---|
 | 578 |                 a = at;                                                       \ | 
|---|
 | 579 |                 b = bt;                                                       \ | 
|---|
 | 580 |                 c = ct;                                                       \ | 
|---|
 | 581 |                 d = dt;                                                       \ | 
|---|
 | 582 |                                                                               \ | 
|---|
 | 583 |                 return(*this);                                                \ | 
|---|
 | 584 |             } | 
|---|
 | 585 |      | 
|---|
 | 586 | // There is quite a lot of repetition in the code below. This is intentional. | 
|---|
 | 587 | // The last conditional block is the normal form, and the others merely | 
|---|
 | 588 | // consist of workarounds for various compiler deficiencies. Hopefuly, when | 
|---|
 | 589 | // more compilers are conformant and we can retire support for those that are | 
|---|
 | 590 | // not, we will be able to remove the clutter. This is makes the situation | 
|---|
 | 591 | // (painfully) explicit. | 
|---|
 | 592 |      | 
|---|
 | 593 | #define    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_1(type)             \ | 
|---|
 | 594 |             quaternion<type> &        operator /= (type const & rhs) \ | 
|---|
 | 595 |             {                                                        \ | 
|---|
 | 596 |                 a /= rhs;                                            \ | 
|---|
 | 597 |                 b /= rhs;                                            \ | 
|---|
 | 598 |                 c /= rhs;                                            \ | 
|---|
 | 599 |                 d /= rhs;                                            \ | 
|---|
 | 600 |                                                                      \ | 
|---|
 | 601 |                 return(*this);                                       \ | 
|---|
 | 602 |             } | 
|---|
 | 603 |  | 
|---|
 | 604 | #if defined(__GNUC__) && (__GNUC__ < 3) | 
|---|
 | 605 |     #define    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2(type)                                            \ | 
|---|
 | 606 |             quaternion<type> &        operator /= (::std::complex<type> const & rhs)                    \ | 
|---|
 | 607 |             {                                                                                           \ | 
|---|
 | 608 |                 using    ::std::valarray;                                                               \ | 
|---|
 | 609 |                                                                                                         \ | 
|---|
 | 610 |                 valarray<type>    tr(2);                                                                \ | 
|---|
 | 611 |                                                                                                         \ | 
|---|
 | 612 |                 tr[0] = rhs.real();                                                                     \ | 
|---|
 | 613 |                 tr[1] = rhs.imag();                                                                     \ | 
|---|
 | 614 |                                                                                                         \ | 
|---|
 | 615 |                 type            mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();  \ | 
|---|
 | 616 |                                                                                                         \ | 
|---|
 | 617 |                 tr *= mixam;                                                                            \ | 
|---|
 | 618 |                                                                                                         \ | 
|---|
 | 619 |                 valarray<type>    tt(4);                                                                \ | 
|---|
 | 620 |                                                                                                         \ | 
|---|
 | 621 |                 tt[0] = +a*tr[0]+b*tr[1];                                                               \ | 
|---|
 | 622 |                 tt[1] = -a*tr[1]+b*tr[0];                                                               \ | 
|---|
 | 623 |                 tt[2] = +c*tr[0]-d*tr[1];                                                               \ | 
|---|
 | 624 |                 tt[3] = +c*tr[1]+d*tr[0];                                                               \ | 
|---|
 | 625 |                                                                                                         \ | 
|---|
 | 626 |                 tr *= tr;                                                                               \ | 
|---|
 | 627 |                                                                                                         \ | 
|---|
 | 628 |                 tt *= (mixam/tr.sum());                                                                 \ | 
|---|
 | 629 |                                                                                                         \ | 
|---|
 | 630 |                 a = tt[0];                                                                              \ | 
|---|
 | 631 |                 b = tt[1];                                                                              \ | 
|---|
 | 632 |                 c = tt[2];                                                                              \ | 
|---|
 | 633 |                 d = tt[3];                                                                              \ | 
|---|
 | 634 |                                                                                                         \ | 
|---|
 | 635 |                 return(*this);                                                                          \ | 
|---|
 | 636 |             } | 
|---|
 | 637 | #elif    defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | 
|---|
 | 638 |     #define    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2(type)                         \ | 
|---|
 | 639 |             quaternion<type> &        operator /= (::std::complex<type> const & rhs) \ | 
|---|
 | 640 |             {                                                                        \ | 
|---|
 | 641 |                 using    ::std::valarray;                                            \ | 
|---|
 | 642 |                 using    ::std::abs;                                                 \ | 
|---|
 | 643 |                                                                                      \ | 
|---|
 | 644 |                 valarray<type>    tr(2);                                             \ | 
|---|
 | 645 |                                                                                      \ | 
|---|
 | 646 |                 tr[0] = rhs.real();                                                  \ | 
|---|
 | 647 |                 tr[1] = rhs.imag();                                                  \ | 
|---|
 | 648 |                                                                                      \ | 
|---|
 | 649 |                 type            mixam = static_cast<type>(1)/(abs(tr).max)();        \ | 
|---|
 | 650 |                                                                                      \ | 
|---|
 | 651 |                 tr *= mixam;                                                         \ | 
|---|
 | 652 |                                                                                      \ | 
|---|
 | 653 |                 valarray<type>    tt(4);                                             \ | 
|---|
 | 654 |                                                                                      \ | 
|---|
 | 655 |                 tt[0] = +a*tr[0]+b*tr[1];                                            \ | 
|---|
 | 656 |                 tt[1] = -a*tr[1]+b*tr[0];                                            \ | 
|---|
 | 657 |                 tt[2] = +c*tr[0]-d*tr[1];                                            \ | 
|---|
 | 658 |                 tt[3] = +c*tr[1]+d*tr[0];                                            \ | 
|---|
 | 659 |                                                                                      \ | 
|---|
 | 660 |                 tr *= tr;                                                            \ | 
|---|
 | 661 |                                                                                      \ | 
|---|
 | 662 |                 tt *= (mixam/tr.sum());                                              \ | 
|---|
 | 663 |                                                                                      \ | 
|---|
 | 664 |                 a = tt[0];                                                           \ | 
|---|
 | 665 |                 b = tt[1];                                                           \ | 
|---|
 | 666 |                 c = tt[2];                                                           \ | 
|---|
 | 667 |                 d = tt[3];                                                           \ | 
|---|
 | 668 |                                                                                      \ | 
|---|
 | 669 |                 return(*this);                                                       \ | 
|---|
 | 670 |             } | 
|---|
 | 671 | #else | 
|---|
 | 672 |     #define    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2(type)                         \ | 
|---|
 | 673 |             quaternion<type> &        operator /= (::std::complex<type> const & rhs) \ | 
|---|
 | 674 |             {                                                                        \ | 
|---|
 | 675 |                 using    ::std::valarray;                                            \ | 
|---|
 | 676 |                                                                                      \ | 
|---|
 | 677 |                 valarray<type>    tr(2);                                             \ | 
|---|
 | 678 |                                                                                      \ | 
|---|
 | 679 |                 tr[0] = rhs.real();                                                  \ | 
|---|
 | 680 |                 tr[1] = rhs.imag();                                                  \ | 
|---|
 | 681 |                                                                                      \ | 
|---|
 | 682 |                 type            mixam = static_cast<type>(1)/(abs(tr).max)();        \ | 
|---|
 | 683 |                                                                                      \ | 
|---|
 | 684 |                 tr *= mixam;                                                         \ | 
|---|
 | 685 |                                                                                      \ | 
|---|
 | 686 |                 valarray<type>    tt(4);                                             \ | 
|---|
 | 687 |                                                                                      \ | 
|---|
 | 688 |                 tt[0] = +a*tr[0]+b*tr[1];                                            \ | 
|---|
 | 689 |                 tt[1] = -a*tr[1]+b*tr[0];                                            \ | 
|---|
 | 690 |                 tt[2] = +c*tr[0]-d*tr[1];                                            \ | 
|---|
 | 691 |                 tt[3] = +c*tr[1]+d*tr[0];                                            \ | 
|---|
 | 692 |                                                                                      \ | 
|---|
 | 693 |                 tr *= tr;                                                            \ | 
|---|
 | 694 |                                                                                      \ | 
|---|
 | 695 |                 tt *= (mixam/tr.sum());                                              \ | 
|---|
 | 696 |                                                                                      \ | 
|---|
 | 697 |                 a = tt[0];                                                           \ | 
|---|
 | 698 |                 b = tt[1];                                                           \ | 
|---|
 | 699 |                 c = tt[2];                                                           \ | 
|---|
 | 700 |                 d = tt[3];                                                           \ | 
|---|
 | 701 |                                                                                      \ | 
|---|
 | 702 |                 return(*this);                                                       \ | 
|---|
 | 703 |             } | 
|---|
 | 704 | #endif /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | 
|---|
 | 705 |      | 
|---|
 | 706 | #if defined(__GNUC__) && (__GNUC__ < 3) | 
|---|
 | 707 |     #define    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3(type)                                            \ | 
|---|
 | 708 |             template<typename X>                                                                        \ | 
|---|
 | 709 |             quaternion<type> &        operator /= (quaternion<X> const & rhs)                           \ | 
|---|
 | 710 |             {                                                                                           \ | 
|---|
 | 711 |                 using    ::std::valarray;                                                               \ | 
|---|
 | 712 |                                                                                                         \ | 
|---|
 | 713 |                 valarray<type>    tr(4);                                                                \ | 
|---|
 | 714 |                                                                                                         \ | 
|---|
 | 715 |                 tr[0] = static_cast<type>(rhs.R_component_1());                                         \ | 
|---|
 | 716 |                 tr[1] = static_cast<type>(rhs.R_component_2());                                         \ | 
|---|
 | 717 |                 tr[2] = static_cast<type>(rhs.R_component_3());                                         \ | 
|---|
 | 718 |                 tr[3] = static_cast<type>(rhs.R_component_4());                                         \ | 
|---|
 | 719 |                                                                                                         \ | 
|---|
 | 720 |                 type            mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();  \ | 
|---|
 | 721 |                                                                                                         \ | 
|---|
 | 722 |                 tr *= mixam;                                                                            \ | 
|---|
 | 723 |                                                                                                         \ | 
|---|
 | 724 |                 valarray<type>    tt(4);                                                                \ | 
|---|
 | 725 |                                                                                                         \ | 
|---|
 | 726 |                 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                                               \ | 
|---|
 | 727 |                 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                                               \ | 
|---|
 | 728 |                 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                                               \ | 
|---|
 | 729 |                 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                                               \ | 
|---|
 | 730 |                                                                                                         \ | 
|---|
 | 731 |                 tr *= tr;                                                                               \ | 
|---|
 | 732 |                                                                                                         \ | 
|---|
 | 733 |                 tt *= (mixam/tr.sum());                                                                 \ | 
|---|
 | 734 |                                                                                                         \ | 
|---|
 | 735 |                 a = tt[0];                                                                              \ | 
|---|
 | 736 |                 b = tt[1];                                                                              \ | 
|---|
 | 737 |                 c = tt[2];                                                                              \ | 
|---|
 | 738 |                 d = tt[3];                                                                              \ | 
|---|
 | 739 |                                                                                                         \ | 
|---|
 | 740 |                 return(*this);                                                                          \ | 
|---|
 | 741 |             } | 
|---|
 | 742 | #elif    defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | 
|---|
 | 743 |     #define    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3(type)                  \ | 
|---|
 | 744 |             template<typename X>                                              \ | 
|---|
 | 745 |             quaternion<type> &        operator /= (quaternion<X> const & rhs) \ | 
|---|
 | 746 |             {                                                                 \ | 
|---|
 | 747 |                 using    ::std::valarray;                                     \ | 
|---|
 | 748 |                 using    ::std::abs;                                          \ | 
|---|
 | 749 |                                                                               \ | 
|---|
 | 750 |                 valarray<type>    tr(4);                                      \ | 
|---|
 | 751 |                                                                               \ | 
|---|
 | 752 |                 tr[0] = static_cast<type>(rhs.R_component_1());               \ | 
|---|
 | 753 |                 tr[1] = static_cast<type>(rhs.R_component_2());               \ | 
|---|
 | 754 |                 tr[2] = static_cast<type>(rhs.R_component_3());               \ | 
|---|
 | 755 |                 tr[3] = static_cast<type>(rhs.R_component_4());               \ | 
|---|
 | 756 |                                                                               \ | 
|---|
 | 757 |                 type            mixam = static_cast<type>(1)/(abs(tr).max)(); \ | 
|---|
 | 758 |                                                                               \ | 
|---|
 | 759 |                 tr *= mixam;                                                  \ | 
|---|
 | 760 |                                                                               \ | 
|---|
 | 761 |                 valarray<type>    tt(4);                                      \ | 
|---|
 | 762 |                                                                               \ | 
|---|
 | 763 |                 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                     \ | 
|---|
 | 764 |                 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                     \ | 
|---|
 | 765 |                 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                     \ | 
|---|
 | 766 |                 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                     \ | 
|---|
 | 767 |                                                                               \ | 
|---|
 | 768 |                 tr *= tr;                                                     \ | 
|---|
 | 769 |                                                                               \ | 
|---|
 | 770 |                 tt *= (mixam/tr.sum());                                       \ | 
|---|
 | 771 |                                                                               \ | 
|---|
 | 772 |                 a = tt[0];                                                    \ | 
|---|
 | 773 |                 b = tt[1];                                                    \ | 
|---|
 | 774 |                 c = tt[2];                                                    \ | 
|---|
 | 775 |                 d = tt[3];                                                    \ | 
|---|
 | 776 |                                                                               \ | 
|---|
 | 777 |                 return(*this);                                                \ | 
|---|
 | 778 |             } | 
|---|
 | 779 | #else | 
|---|
 | 780 |     #define    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3(type)                  \ | 
|---|
 | 781 |             template<typename X>                                              \ | 
|---|
 | 782 |             quaternion<type> &        operator /= (quaternion<X> const & rhs) \ | 
|---|
 | 783 |             {                                                                 \ | 
|---|
 | 784 |                 using    ::std::valarray;                                     \ | 
|---|
 | 785 |                                                                               \ | 
|---|
 | 786 |                 valarray<type>    tr(4);                                      \ | 
|---|
 | 787 |                                                                               \ | 
|---|
 | 788 |                 tr[0] = static_cast<type>(rhs.R_component_1());               \ | 
|---|
 | 789 |                 tr[1] = static_cast<type>(rhs.R_component_2());               \ | 
|---|
 | 790 |                 tr[2] = static_cast<type>(rhs.R_component_3());               \ | 
|---|
 | 791 |                 tr[3] = static_cast<type>(rhs.R_component_4());               \ | 
|---|
 | 792 |                                                                               \ | 
|---|
 | 793 |                 type            mixam = static_cast<type>(1)/(abs(tr).max)(); \ | 
|---|
 | 794 |                                                                               \ | 
|---|
 | 795 |                 tr *= mixam;                                                  \ | 
|---|
 | 796 |                                                                               \ | 
|---|
 | 797 |                 valarray<type>    tt(4);                                      \ | 
|---|
 | 798 |                                                                               \ | 
|---|
 | 799 |                 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                     \ | 
|---|
 | 800 |                 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                     \ | 
|---|
 | 801 |                 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                     \ | 
|---|
 | 802 |                 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                     \ | 
|---|
 | 803 |                                                                               \ | 
|---|
 | 804 |                 tr *= tr;                                                     \ | 
|---|
 | 805 |                                                                               \ | 
|---|
 | 806 |                 tt *= (mixam/tr.sum());                                       \ | 
|---|
 | 807 |                                                                               \ | 
|---|
 | 808 |                 a = tt[0];                                                    \ | 
|---|
 | 809 |                 b = tt[1];                                                    \ | 
|---|
 | 810 |                 c = tt[2];                                                    \ | 
|---|
 | 811 |                 d = tt[3];                                                    \ | 
|---|
 | 812 |                                                                               \ | 
|---|
 | 813 |                 return(*this);                                                \ | 
|---|
 | 814 |             } | 
|---|
 | 815 | #endif /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | 
|---|
 | 816 |      | 
|---|
 | 817 | #define    BOOST_QUATERNION_MEMBER_ADD_GENERATOR(type)   \ | 
|---|
 | 818 |         BOOST_QUATERNION_MEMBER_ADD_GENERATOR_1(type)    \ | 
|---|
 | 819 |         BOOST_QUATERNION_MEMBER_ADD_GENERATOR_2(type)    \ | 
|---|
 | 820 |         BOOST_QUATERNION_MEMBER_ADD_GENERATOR_3(type) | 
|---|
 | 821 |          | 
|---|
 | 822 | #define    BOOST_QUATERNION_MEMBER_SUB_GENERATOR(type)   \ | 
|---|
 | 823 |         BOOST_QUATERNION_MEMBER_SUB_GENERATOR_1(type)    \ | 
|---|
 | 824 |         BOOST_QUATERNION_MEMBER_SUB_GENERATOR_2(type)    \ | 
|---|
 | 825 |         BOOST_QUATERNION_MEMBER_SUB_GENERATOR_3(type) | 
|---|
 | 826 |          | 
|---|
 | 827 | #define    BOOST_QUATERNION_MEMBER_MUL_GENERATOR(type)   \ | 
|---|
 | 828 |         BOOST_QUATERNION_MEMBER_MUL_GENERATOR_1(type)    \ | 
|---|
 | 829 |         BOOST_QUATERNION_MEMBER_MUL_GENERATOR_2(type)    \ | 
|---|
 | 830 |         BOOST_QUATERNION_MEMBER_MUL_GENERATOR_3(type) | 
|---|
 | 831 |          | 
|---|
 | 832 | #define    BOOST_QUATERNION_MEMBER_DIV_GENERATOR(type)   \ | 
|---|
 | 833 |         BOOST_QUATERNION_MEMBER_DIV_GENERATOR_1(type)    \ | 
|---|
 | 834 |         BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2(type)    \ | 
|---|
 | 835 |         BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3(type) | 
|---|
 | 836 |          | 
|---|
 | 837 | #define    BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR(type)   \ | 
|---|
 | 838 |         BOOST_QUATERNION_MEMBER_ADD_GENERATOR(type)            \ | 
|---|
 | 839 |         BOOST_QUATERNION_MEMBER_SUB_GENERATOR(type)            \ | 
|---|
 | 840 |         BOOST_QUATERNION_MEMBER_MUL_GENERATOR(type)            \ | 
|---|
 | 841 |         BOOST_QUATERNION_MEMBER_DIV_GENERATOR(type) | 
|---|
 | 842 |          | 
|---|
 | 843 |          | 
|---|
 | 844 |         template<> | 
|---|
 | 845 |         class quaternion<float> | 
|---|
 | 846 |         { | 
|---|
 | 847 |         public: | 
|---|
 | 848 |              | 
|---|
 | 849 |             typedef float value_type; | 
|---|
 | 850 |              | 
|---|
 | 851 |             BOOST_QUATERNION_CONSTRUCTOR_GENERATOR(float) | 
|---|
 | 852 |              | 
|---|
 | 853 |             // UNtemplated copy constructor | 
|---|
 | 854 |             // (this is taken care of by the compiler itself) | 
|---|
 | 855 |              | 
|---|
 | 856 |             // explicit copy constructors (precision-loosing converters) | 
|---|
 | 857 |              | 
|---|
 | 858 |             explicit            quaternion(quaternion<double> const & a_recopier) | 
|---|
 | 859 |             { | 
|---|
 | 860 |                 *this = detail::quaternion_type_converter<float, double>(a_recopier); | 
|---|
 | 861 |             } | 
|---|
 | 862 |              | 
|---|
 | 863 |             explicit            quaternion(quaternion<long double> const & a_recopier) | 
|---|
 | 864 |             { | 
|---|
 | 865 |                 *this = detail::quaternion_type_converter<float, long double>(a_recopier); | 
|---|
 | 866 |             } | 
|---|
 | 867 |              | 
|---|
 | 868 |             // destructor | 
|---|
 | 869 |             // (this is taken care of by the compiler itself) | 
|---|
 | 870 |              | 
|---|
 | 871 |             // accessors | 
|---|
 | 872 |             // | 
|---|
 | 873 |             // Note:    Like complex number, quaternions do have a meaningful notion of "real part", | 
|---|
 | 874 |             //            but unlike them there is no meaningful notion of "imaginary part". | 
|---|
 | 875 |             //            Instead there is an "unreal part" which itself is a quaternion, and usually | 
|---|
 | 876 |             //            nothing simpler (as opposed to the complex number case). | 
|---|
 | 877 |             //            However, for practicallity, there are accessors for the other components | 
|---|
 | 878 |             //            (these are necessary for the templated copy constructor, for instance). | 
|---|
 | 879 |              | 
|---|
 | 880 |             BOOST_QUATERNION_ACCESSOR_GENERATOR(float) | 
|---|
 | 881 |              | 
|---|
 | 882 |             // assignment operators | 
|---|
 | 883 |              | 
|---|
 | 884 |             BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(float) | 
|---|
 | 885 |              | 
|---|
 | 886 |             // other assignment-related operators | 
|---|
 | 887 |             // | 
|---|
 | 888 |             // NOTE:    Quaternion multiplication is *NOT* commutative; | 
|---|
 | 889 |             //            symbolically, "q *= rhs;" means "q = q * rhs;" | 
|---|
 | 890 |             //            and "q /= rhs;" means "q = q * inverse_of(rhs);" | 
|---|
 | 891 |              | 
|---|
 | 892 |             BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR(float) | 
|---|
 | 893 |              | 
|---|
 | 894 |              | 
|---|
 | 895 |         protected: | 
|---|
 | 896 |              | 
|---|
 | 897 |             BOOST_QUATERNION_MEMBER_DATA_GENERATOR(float) | 
|---|
 | 898 |              | 
|---|
 | 899 |              | 
|---|
 | 900 |         private: | 
|---|
 | 901 |              | 
|---|
 | 902 |         }; | 
|---|
 | 903 |          | 
|---|
 | 904 |          | 
|---|
 | 905 |         template<> | 
|---|
 | 906 |         class quaternion<double> | 
|---|
 | 907 |         { | 
|---|
 | 908 |         public: | 
|---|
 | 909 |              | 
|---|
 | 910 |             typedef double value_type; | 
|---|
 | 911 |              | 
|---|
 | 912 |             BOOST_QUATERNION_CONSTRUCTOR_GENERATOR(double) | 
|---|
 | 913 |              | 
|---|
 | 914 |             // UNtemplated copy constructor | 
|---|
 | 915 |             // (this is taken care of by the compiler itself) | 
|---|
 | 916 |              | 
|---|
 | 917 |             // converting copy constructor | 
|---|
 | 918 |              | 
|---|
 | 919 |             explicit                quaternion(quaternion<float> const & a_recopier) | 
|---|
 | 920 |             { | 
|---|
 | 921 |                 *this = detail::quaternion_type_converter<double, float>(a_recopier); | 
|---|
 | 922 |             } | 
|---|
 | 923 |              | 
|---|
 | 924 |             // explicit copy constructors (precision-loosing converters) | 
|---|
 | 925 |              | 
|---|
 | 926 |             explicit                quaternion(quaternion<long double> const & a_recopier) | 
|---|
 | 927 |             { | 
|---|
 | 928 |                 *this = detail::quaternion_type_converter<double, long double>(a_recopier); | 
|---|
 | 929 |             } | 
|---|
 | 930 |              | 
|---|
 | 931 |             // destructor | 
|---|
 | 932 |             // (this is taken care of by the compiler itself) | 
|---|
 | 933 |              | 
|---|
 | 934 |             // accessors | 
|---|
 | 935 |             // | 
|---|
 | 936 |             // Note:    Like complex number, quaternions do have a meaningful notion of "real part", | 
|---|
 | 937 |             //            but unlike them there is no meaningful notion of "imaginary part". | 
|---|
 | 938 |             //            Instead there is an "unreal part" which itself is a quaternion, and usually | 
|---|
 | 939 |             //            nothing simpler (as opposed to the complex number case). | 
|---|
 | 940 |             //            However, for practicallity, there are accessors for the other components | 
|---|
 | 941 |             //            (these are necessary for the templated copy constructor, for instance). | 
|---|
 | 942 |              | 
|---|
 | 943 |             BOOST_QUATERNION_ACCESSOR_GENERATOR(double) | 
|---|
 | 944 |              | 
|---|
 | 945 |             // assignment operators | 
|---|
 | 946 |              | 
|---|
 | 947 |             BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(double) | 
|---|
 | 948 |              | 
|---|
 | 949 |             // other assignment-related operators | 
|---|
 | 950 |             // | 
|---|
 | 951 |             // NOTE:    Quaternion multiplication is *NOT* commutative; | 
|---|
 | 952 |             //            symbolically, "q *= rhs;" means "q = q * rhs;" | 
|---|
 | 953 |             //            and "q /= rhs;" means "q = q * inverse_of(rhs);" | 
|---|
 | 954 |              | 
|---|
 | 955 |             BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR(double) | 
|---|
 | 956 |              | 
|---|
 | 957 |              | 
|---|
 | 958 |         protected: | 
|---|
 | 959 |              | 
|---|
 | 960 |             BOOST_QUATERNION_MEMBER_DATA_GENERATOR(double) | 
|---|
 | 961 |              | 
|---|
 | 962 |              | 
|---|
 | 963 |         private: | 
|---|
 | 964 |              | 
|---|
 | 965 |         }; | 
|---|
 | 966 |          | 
|---|
 | 967 |          | 
|---|
 | 968 |         template<> | 
|---|
 | 969 |         class quaternion<long double> | 
|---|
 | 970 |         { | 
|---|
 | 971 |         public: | 
|---|
 | 972 |              | 
|---|
 | 973 |             typedef long double value_type; | 
|---|
 | 974 |              | 
|---|
 | 975 |             BOOST_QUATERNION_CONSTRUCTOR_GENERATOR(long double) | 
|---|
 | 976 |              | 
|---|
 | 977 |             // UNtemplated copy constructor | 
|---|
 | 978 |             // (this is taken care of by the compiler itself) | 
|---|
 | 979 |              | 
|---|
 | 980 |             // converting copy constructors | 
|---|
 | 981 |              | 
|---|
 | 982 |             explicit                    quaternion(quaternion<float> const & a_recopier) | 
|---|
 | 983 |             { | 
|---|
 | 984 |                 *this = detail::quaternion_type_converter<long double, float>(a_recopier); | 
|---|
 | 985 |             } | 
|---|
 | 986 |              | 
|---|
 | 987 |             explicit                    quaternion(quaternion<double> const & a_recopier) | 
|---|
 | 988 |             { | 
|---|
 | 989 |                 *this = detail::quaternion_type_converter<long double, double>(a_recopier); | 
|---|
 | 990 |             } | 
|---|
 | 991 |              | 
|---|
 | 992 |             // destructor | 
|---|
 | 993 |             // (this is taken care of by the compiler itself) | 
|---|
 | 994 |              | 
|---|
 | 995 |             // accessors | 
|---|
 | 996 |             // | 
|---|
 | 997 |             // Note:    Like complex number, quaternions do have a meaningful notion of "real part", | 
|---|
 | 998 |             //            but unlike them there is no meaningful notion of "imaginary part". | 
|---|
 | 999 |             //            Instead there is an "unreal part" which itself is a quaternion, and usually | 
|---|
 | 1000 |             //            nothing simpler (as opposed to the complex number case). | 
|---|
 | 1001 |             //            However, for practicallity, there are accessors for the other components | 
|---|
 | 1002 |             //            (these are necessary for the templated copy constructor, for instance). | 
|---|
 | 1003 |              | 
|---|
 | 1004 |             BOOST_QUATERNION_ACCESSOR_GENERATOR(long double) | 
|---|
 | 1005 |              | 
|---|
 | 1006 |             // assignment operators | 
|---|
 | 1007 |              | 
|---|
 | 1008 |             BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(long double) | 
|---|
 | 1009 |              | 
|---|
 | 1010 |             // other assignment-related operators | 
|---|
 | 1011 |             // | 
|---|
 | 1012 |             // NOTE:    Quaternion multiplication is *NOT* commutative; | 
|---|
 | 1013 |             //            symbolically, "q *= rhs;" means "q = q * rhs;" | 
|---|
 | 1014 |             //            and "q /= rhs;" means "q = q * inverse_of(rhs);" | 
|---|
 | 1015 |              | 
|---|
 | 1016 |             BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR(long double) | 
|---|
 | 1017 |              | 
|---|
 | 1018 |              | 
|---|
 | 1019 |         protected: | 
|---|
 | 1020 |              | 
|---|
 | 1021 |             BOOST_QUATERNION_MEMBER_DATA_GENERATOR(long double) | 
|---|
 | 1022 |              | 
|---|
 | 1023 |              | 
|---|
 | 1024 |         private: | 
|---|
 | 1025 |              | 
|---|
 | 1026 |         }; | 
|---|
 | 1027 |          | 
|---|
 | 1028 |          | 
|---|
 | 1029 | #undef    BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR | 
|---|
 | 1030 | #undef    BOOST_QUATERNION_MEMBER_ADD_GENERATOR | 
|---|
 | 1031 | #undef    BOOST_QUATERNION_MEMBER_SUB_GENERATOR | 
|---|
 | 1032 | #undef    BOOST_QUATERNION_MEMBER_MUL_GENERATOR | 
|---|
 | 1033 | #undef    BOOST_QUATERNION_MEMBER_DIV_GENERATOR | 
|---|
 | 1034 | #undef    BOOST_QUATERNION_MEMBER_ADD_GENERATOR_1 | 
|---|
 | 1035 | #undef    BOOST_QUATERNION_MEMBER_ADD_GENERATOR_2 | 
|---|
 | 1036 | #undef    BOOST_QUATERNION_MEMBER_ADD_GENERATOR_3 | 
|---|
 | 1037 | #undef    BOOST_QUATERNION_MEMBER_SUB_GENERATOR_1 | 
|---|
 | 1038 | #undef    BOOST_QUATERNION_MEMBER_SUB_GENERATOR_2 | 
|---|
 | 1039 | #undef    BOOST_QUATERNION_MEMBER_SUB_GENERATOR_3 | 
|---|
 | 1040 | #undef    BOOST_QUATERNION_MEMBER_MUL_GENERATOR_1 | 
|---|
 | 1041 | #undef    BOOST_QUATERNION_MEMBER_MUL_GENERATOR_2 | 
|---|
 | 1042 | #undef    BOOST_QUATERNION_MEMBER_MUL_GENERATOR_3 | 
|---|
 | 1043 | #undef    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_1 | 
|---|
 | 1044 | #undef    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2 | 
|---|
 | 1045 | #undef    BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3 | 
|---|
 | 1046 |          | 
|---|
 | 1047 | #undef    BOOST_QUATERNION_CONSTRUCTOR_GENERATOR | 
|---|
 | 1048 |          | 
|---|
 | 1049 |          | 
|---|
 | 1050 | #undef    BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR | 
|---|
 | 1051 |          | 
|---|
 | 1052 | #undef    BOOST_QUATERNION_MEMBER_DATA_GENERATOR | 
|---|
 | 1053 |          | 
|---|
 | 1054 | #undef    BOOST_QUATERNION_ACCESSOR_GENERATOR | 
|---|
 | 1055 |          | 
|---|
 | 1056 |          | 
|---|
 | 1057 |         // operators | 
|---|
 | 1058 |          | 
|---|
 | 1059 | #define    BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op)      \ | 
|---|
 | 1060 |         {                                                    \ | 
|---|
 | 1061 |             quaternion<T>    res(lhs);                       \ | 
|---|
 | 1062 |             res op##= rhs;                                   \ | 
|---|
 | 1063 |             return(res);                                     \ | 
|---|
 | 1064 |         } | 
|---|
 | 1065 |          | 
|---|
 | 1066 | #define    BOOST_QUATERNION_OPERATOR_GENERATOR_1_L(op)                                                  \ | 
|---|
 | 1067 |         template<typename T>                                                                            \ | 
|---|
 | 1068 |         inline quaternion<T>    operator op (T const & lhs, quaternion<T> const & rhs)                  \ | 
|---|
 | 1069 |         BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op) | 
|---|
 | 1070 |          | 
|---|
 | 1071 | #define    BOOST_QUATERNION_OPERATOR_GENERATOR_1_R(op)                                                  \ | 
|---|
 | 1072 |         template<typename T>                                                                            \ | 
|---|
 | 1073 |         inline quaternion<T>    operator op (quaternion<T> const & lhs, T const & rhs)                  \ | 
|---|
 | 1074 |         BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op) | 
|---|
 | 1075 |          | 
|---|
 | 1076 | #define    BOOST_QUATERNION_OPERATOR_GENERATOR_2_L(op)                                                  \ | 
|---|
 | 1077 |         template<typename T>                                                                            \ | 
|---|
 | 1078 |         inline quaternion<T>    operator op (::std::complex<T> const & lhs, quaternion<T> const & rhs)  \ | 
|---|
 | 1079 |         BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op) | 
|---|
 | 1080 |          | 
|---|
 | 1081 | #define    BOOST_QUATERNION_OPERATOR_GENERATOR_2_R(op)                                                  \ | 
|---|
 | 1082 |         template<typename T>                                                                            \ | 
|---|
 | 1083 |         inline quaternion<T>    operator op (quaternion<T> const & lhs, ::std::complex<T> const & rhs)  \ | 
|---|
 | 1084 |         BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op) | 
|---|
 | 1085 |          | 
|---|
 | 1086 | #define    BOOST_QUATERNION_OPERATOR_GENERATOR_3(op)                                                    \ | 
|---|
 | 1087 |         template<typename T>                                                                            \ | 
|---|
 | 1088 |         inline quaternion<T>    operator op (quaternion<T> const & lhs, quaternion<T> const & rhs)      \ | 
|---|
 | 1089 |         BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op) | 
|---|
 | 1090 |          | 
|---|
 | 1091 | #define    BOOST_QUATERNION_OPERATOR_GENERATOR(op)     \ | 
|---|
 | 1092 |         BOOST_QUATERNION_OPERATOR_GENERATOR_1_L(op)    \ | 
|---|
 | 1093 |         BOOST_QUATERNION_OPERATOR_GENERATOR_1_R(op)    \ | 
|---|
 | 1094 |         BOOST_QUATERNION_OPERATOR_GENERATOR_2_L(op)    \ | 
|---|
 | 1095 |         BOOST_QUATERNION_OPERATOR_GENERATOR_2_R(op)    \ | 
|---|
 | 1096 |         BOOST_QUATERNION_OPERATOR_GENERATOR_3(op) | 
|---|
 | 1097 |          | 
|---|
 | 1098 |          | 
|---|
 | 1099 |         BOOST_QUATERNION_OPERATOR_GENERATOR(+) | 
|---|
 | 1100 |         BOOST_QUATERNION_OPERATOR_GENERATOR(-) | 
|---|
 | 1101 |         BOOST_QUATERNION_OPERATOR_GENERATOR(*) | 
|---|
 | 1102 |         BOOST_QUATERNION_OPERATOR_GENERATOR(/) | 
|---|
 | 1103 |  | 
|---|
 | 1104 |  | 
|---|
 | 1105 | #undef    BOOST_QUATERNION_OPERATOR_GENERATOR | 
|---|
 | 1106 |          | 
|---|
 | 1107 | #undef    BOOST_QUATERNION_OPERATOR_GENERATOR_1_L | 
|---|
 | 1108 | #undef    BOOST_QUATERNION_OPERATOR_GENERATOR_1_R | 
|---|
 | 1109 | #undef    BOOST_QUATERNION_OPERATOR_GENERATOR_2_L | 
|---|
 | 1110 | #undef    BOOST_QUATERNION_OPERATOR_GENERATOR_2_R | 
|---|
 | 1111 | #undef    BOOST_QUATERNION_OPERATOR_GENERATOR_3 | 
|---|
 | 1112 |  | 
|---|
 | 1113 | #undef    BOOST_QUATERNION_OPERATOR_GENERATOR_BODY | 
|---|
 | 1114 |          | 
|---|
 | 1115 |          | 
|---|
 | 1116 |         template<typename T> | 
|---|
 | 1117 |         inline quaternion<T>                    operator + (quaternion<T> const & q) | 
|---|
 | 1118 |         { | 
|---|
 | 1119 |             return(q); | 
|---|
 | 1120 |         } | 
|---|
 | 1121 |          | 
|---|
 | 1122 |          | 
|---|
 | 1123 |         template<typename T> | 
|---|
 | 1124 |         inline quaternion<T>                    operator - (quaternion<T> const & q) | 
|---|
 | 1125 |         { | 
|---|
 | 1126 |             return(quaternion<T>(-q.R_component_1(),-q.R_component_2(),-q.R_component_3(),-q.R_component_4())); | 
|---|
 | 1127 |         } | 
|---|
 | 1128 |          | 
|---|
 | 1129 |          | 
|---|
 | 1130 |         template<typename T> | 
|---|
 | 1131 |         inline bool                                operator == (T const & lhs, quaternion<T> const & rhs) | 
|---|
 | 1132 |         { | 
|---|
 | 1133 |             return    ( | 
|---|
 | 1134 |                         (rhs.R_component_1() == lhs)&& | 
|---|
 | 1135 |                         (rhs.R_component_2() == static_cast<T>(0))&& | 
|---|
 | 1136 |                         (rhs.R_component_3() == static_cast<T>(0))&& | 
|---|
 | 1137 |                         (rhs.R_component_4() == static_cast<T>(0)) | 
|---|
 | 1138 |                     ); | 
|---|
 | 1139 |         } | 
|---|
 | 1140 |          | 
|---|
 | 1141 |          | 
|---|
 | 1142 |         template<typename T> | 
|---|
 | 1143 |         inline bool                                operator == (quaternion<T> const & lhs, T const & rhs) | 
|---|
 | 1144 |         { | 
|---|
 | 1145 |             return    ( | 
|---|
 | 1146 |                         (lhs.R_component_1() == rhs)&& | 
|---|
 | 1147 |                         (lhs.R_component_2() == static_cast<T>(0))&& | 
|---|
 | 1148 |                         (lhs.R_component_3() == static_cast<T>(0))&& | 
|---|
 | 1149 |                         (lhs.R_component_4() == static_cast<T>(0)) | 
|---|
 | 1150 |                     ); | 
|---|
 | 1151 |         } | 
|---|
 | 1152 |          | 
|---|
 | 1153 |          | 
|---|
 | 1154 |         template<typename T> | 
|---|
 | 1155 |         inline bool                                operator == (::std::complex<T> const & lhs, quaternion<T> const & rhs) | 
|---|
 | 1156 |         { | 
|---|
 | 1157 |             return    ( | 
|---|
 | 1158 |                         (rhs.R_component_1() == lhs.real())&& | 
|---|
 | 1159 |                         (rhs.R_component_2() == lhs.imag())&& | 
|---|
 | 1160 |                         (rhs.R_component_3() == static_cast<T>(0))&& | 
|---|
 | 1161 |                         (rhs.R_component_4() == static_cast<T>(0)) | 
|---|
 | 1162 |                     ); | 
|---|
 | 1163 |         } | 
|---|
 | 1164 |          | 
|---|
 | 1165 |          | 
|---|
 | 1166 |         template<typename T> | 
|---|
 | 1167 |         inline bool                                operator == (quaternion<T> const & lhs, ::std::complex<T> const & rhs) | 
|---|
 | 1168 |         { | 
|---|
 | 1169 |             return    ( | 
|---|
 | 1170 |                         (lhs.R_component_1() == rhs.real())&& | 
|---|
 | 1171 |                         (lhs.R_component_2() == rhs.imag())&& | 
|---|
 | 1172 |                         (lhs.R_component_3() == static_cast<T>(0))&& | 
|---|
 | 1173 |                         (lhs.R_component_4() == static_cast<T>(0)) | 
|---|
 | 1174 |                     ); | 
|---|
 | 1175 |         } | 
|---|
 | 1176 |          | 
|---|
 | 1177 |          | 
|---|
 | 1178 |         template<typename T> | 
|---|
 | 1179 |         inline bool                                operator == (quaternion<T> const & lhs, quaternion<T> const & rhs) | 
|---|
 | 1180 |         { | 
|---|
 | 1181 |             return    ( | 
|---|
 | 1182 |                         (rhs.R_component_1() == lhs.R_component_1())&& | 
|---|
 | 1183 |                         (rhs.R_component_2() == lhs.R_component_2())&& | 
|---|
 | 1184 |                         (rhs.R_component_3() == lhs.R_component_3())&& | 
|---|
 | 1185 |                         (rhs.R_component_4() == lhs.R_component_4()) | 
|---|
 | 1186 |                     ); | 
|---|
 | 1187 |         } | 
|---|
 | 1188 |          | 
|---|
 | 1189 |          | 
|---|
 | 1190 | #define    BOOST_QUATERNION_NOT_EQUAL_GENERATOR  \ | 
|---|
 | 1191 |         {                                        \ | 
|---|
 | 1192 |             return(!(lhs == rhs));               \ | 
|---|
 | 1193 |         } | 
|---|
 | 1194 |          | 
|---|
 | 1195 |         template<typename T> | 
|---|
 | 1196 |         inline bool                                operator != (T const & lhs, quaternion<T> const & rhs) | 
|---|
 | 1197 |         BOOST_QUATERNION_NOT_EQUAL_GENERATOR | 
|---|
 | 1198 |          | 
|---|
 | 1199 |         template<typename T> | 
|---|
 | 1200 |         inline bool                                operator != (quaternion<T> const & lhs, T const & rhs) | 
|---|
 | 1201 |         BOOST_QUATERNION_NOT_EQUAL_GENERATOR | 
|---|
 | 1202 |          | 
|---|
 | 1203 |         template<typename T> | 
|---|
 | 1204 |         inline bool                                operator != (::std::complex<T> const & lhs, quaternion<T> const & rhs) | 
|---|
 | 1205 |         BOOST_QUATERNION_NOT_EQUAL_GENERATOR | 
|---|
 | 1206 |          | 
|---|
 | 1207 |         template<typename T> | 
|---|
 | 1208 |         inline bool                                operator != (quaternion<T> const & lhs, ::std::complex<T> const & rhs) | 
|---|
 | 1209 |         BOOST_QUATERNION_NOT_EQUAL_GENERATOR | 
|---|
 | 1210 |          | 
|---|
 | 1211 |         template<typename T> | 
|---|
 | 1212 |         inline bool                                operator != (quaternion<T> const & lhs, quaternion<T> const & rhs) | 
|---|
 | 1213 |         BOOST_QUATERNION_NOT_EQUAL_GENERATOR | 
|---|
 | 1214 |          | 
|---|
 | 1215 | #undef    BOOST_QUATERNION_NOT_EQUAL_GENERATOR | 
|---|
 | 1216 |          | 
|---|
 | 1217 |          | 
|---|
 | 1218 |         // Note:    we allow the following formats, whith a, b, c, and d reals | 
|---|
 | 1219 |         //            a | 
|---|
 | 1220 |         //            (a), (a,b), (a,b,c), (a,b,c,d) | 
|---|
 | 1221 |         //            (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)) | 
|---|
 | 1222 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1223 |         template<typename T> | 
|---|
 | 1224 |         std::istream &                            operator >> (    ::std::istream & is, | 
|---|
 | 1225 |                                                                 quaternion<T> & q) | 
|---|
 | 1226 | #else | 
|---|
 | 1227 |         template<typename T, typename charT, class traits> | 
|---|
 | 1228 |         ::std::basic_istream<charT,traits> &    operator >> (    ::std::basic_istream<charT,traits> & is, | 
|---|
 | 1229 |                                                                 quaternion<T> & q) | 
|---|
 | 1230 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1231 |         { | 
|---|
 | 1232 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1233 |             typedef char    charT; | 
|---|
 | 1234 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1235 |              | 
|---|
 | 1236 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1237 | #else | 
|---|
 | 1238 |             const ::std::ctype<charT> & ct = ::std::use_facet< ::std::ctype<charT> >(is.getloc()); | 
|---|
 | 1239 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1240 |              | 
|---|
 | 1241 |             T    a = T(); | 
|---|
 | 1242 |             T    b = T(); | 
|---|
 | 1243 |             T    c = T(); | 
|---|
 | 1244 |             T    d = T(); | 
|---|
 | 1245 |              | 
|---|
 | 1246 |             ::std::complex<T>    u = ::std::complex<T>(); | 
|---|
 | 1247 |             ::std::complex<T>    v = ::std::complex<T>(); | 
|---|
 | 1248 |              | 
|---|
 | 1249 |             charT    ch = charT(); | 
|---|
 | 1250 |             char    cc; | 
|---|
 | 1251 |              | 
|---|
 | 1252 |             is >> ch;                                        // get the first lexeme | 
|---|
 | 1253 |              | 
|---|
 | 1254 |             if    (!is.good())    goto finish; | 
|---|
 | 1255 |              | 
|---|
 | 1256 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1257 |             cc = ch; | 
|---|
 | 1258 | #else | 
|---|
 | 1259 |             cc = ct.narrow(ch, char()); | 
|---|
 | 1260 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1261 |              | 
|---|
 | 1262 |             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,)) | 
|---|
 | 1263 |             { | 
|---|
 | 1264 |                 is >> ch;                                    // get the second lexeme | 
|---|
 | 1265 |                  | 
|---|
 | 1266 |                 if    (!is.good())    goto finish; | 
|---|
 | 1267 |                  | 
|---|
 | 1268 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1269 |                 cc = ch; | 
|---|
 | 1270 | #else | 
|---|
 | 1271 |                 cc = ct.narrow(ch, char()); | 
|---|
 | 1272 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1273 |                  | 
|---|
 | 1274 |                 if    (cc == '(')                        // read "((", possible: ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,)) | 
|---|
 | 1275 |                 { | 
|---|
 | 1276 |                     is.putback(ch); | 
|---|
 | 1277 |                      | 
|---|
 | 1278 |                     is >> u;                                // we extract the first and second components | 
|---|
 | 1279 |                     a = u.real(); | 
|---|
 | 1280 |                     b = u.imag(); | 
|---|
 | 1281 |                      | 
|---|
 | 1282 |                     if    (!is.good())    goto finish; | 
|---|
 | 1283 |                      | 
|---|
 | 1284 |                     is >> ch;                                // get the next lexeme | 
|---|
 | 1285 |                      | 
|---|
 | 1286 |                     if    (!is.good())    goto finish; | 
|---|
 | 1287 |                      | 
|---|
 | 1288 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1289 |                     cc = ch; | 
|---|
 | 1290 | #else | 
|---|
 | 1291 |                     cc = ct.narrow(ch, char()); | 
|---|
 | 1292 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1293 |                      | 
|---|
 | 1294 |                     if        (cc == ')')                    // format: ((a)) or ((a,b)) | 
|---|
 | 1295 |                     { | 
|---|
 | 1296 |                         q = quaternion<T>(a,b); | 
|---|
 | 1297 |                     } | 
|---|
 | 1298 |                     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,)) | 
|---|
 | 1299 |                     { | 
|---|
 | 1300 |                         is >> v;                            // we extract the third and fourth components | 
|---|
 | 1301 |                         c = v.real(); | 
|---|
 | 1302 |                         d = v.imag(); | 
|---|
 | 1303 |                          | 
|---|
 | 1304 |                         if    (!is.good())    goto finish; | 
|---|
 | 1305 |                          | 
|---|
 | 1306 |                         is >> ch;                                // get the last lexeme | 
|---|
 | 1307 |                          | 
|---|
 | 1308 |                         if    (!is.good())    goto finish; | 
|---|
 | 1309 |                          | 
|---|
 | 1310 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1311 |                         cc = ch; | 
|---|
 | 1312 | #else | 
|---|
 | 1313 |                         cc = ct.narrow(ch, char()); | 
|---|
 | 1314 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1315 |                          | 
|---|
 | 1316 |                         if    (cc == ')')                    // format: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)) or ((a,b,),(c,d,)) | 
|---|
 | 1317 |                         { | 
|---|
 | 1318 |                             q = quaternion<T>(a,b,c,d); | 
|---|
 | 1319 |                         } | 
|---|
 | 1320 |                         else                            // error | 
|---|
 | 1321 |                         { | 
|---|
 | 1322 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1323 |                             is.setstate(::std::ios::failbit); | 
|---|
 | 1324 | #else | 
|---|
 | 1325 |                             is.setstate(::std::ios_base::failbit); | 
|---|
 | 1326 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1327 |                         } | 
|---|
 | 1328 |                     } | 
|---|
 | 1329 |                     else                                // error | 
|---|
 | 1330 |                     { | 
|---|
 | 1331 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1332 |                         is.setstate(::std::ios::failbit); | 
|---|
 | 1333 | #else | 
|---|
 | 1334 |                         is.setstate(::std::ios_base::failbit); | 
|---|
 | 1335 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1336 |                     } | 
|---|
 | 1337 |                 } | 
|---|
 | 1338 |                 else                                // read "(a", possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)) | 
|---|
 | 1339 |                 { | 
|---|
 | 1340 |                     is.putback(ch); | 
|---|
 | 1341 |                      | 
|---|
 | 1342 |                     is >> a;                                // we extract the first component | 
|---|
 | 1343 |                      | 
|---|
 | 1344 |                     if    (!is.good())    goto finish; | 
|---|
 | 1345 |                      | 
|---|
 | 1346 |                     is >> ch;                                // get the third lexeme | 
|---|
 | 1347 |                      | 
|---|
 | 1348 |                     if    (!is.good())    goto finish; | 
|---|
 | 1349 |                      | 
|---|
 | 1350 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1351 |                     cc = ch; | 
|---|
 | 1352 | #else | 
|---|
 | 1353 |                     cc = ct.narrow(ch, char()); | 
|---|
 | 1354 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1355 |                      | 
|---|
 | 1356 |                     if        (cc == ')')                    // format: (a) | 
|---|
 | 1357 |                     { | 
|---|
 | 1358 |                         q = quaternion<T>(a); | 
|---|
 | 1359 |                     } | 
|---|
 | 1360 |                     else if    (cc == ',')                // read "(a,", possible: (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)) | 
|---|
 | 1361 |                     { | 
|---|
 | 1362 |                         is >> ch;                            // get the fourth lexeme | 
|---|
 | 1363 |                          | 
|---|
 | 1364 |                         if    (!is.good())    goto finish; | 
|---|
 | 1365 |                          | 
|---|
 | 1366 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1367 |                         cc = ch; | 
|---|
 | 1368 | #else | 
|---|
 | 1369 |                         cc = ct.narrow(ch, char()); | 
|---|
 | 1370 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1371 |                          | 
|---|
 | 1372 |                         if    (cc == '(')                // read "(a,(", possible: (a,(c)), (a,(c,d)) | 
|---|
 | 1373 |                         { | 
|---|
 | 1374 |                             is.putback(ch); | 
|---|
 | 1375 |                              | 
|---|
 | 1376 |                             is >> v;                        // we extract the third and fourth component | 
|---|
 | 1377 |                              | 
|---|
 | 1378 |                             c = v.real(); | 
|---|
 | 1379 |                             d = v.imag(); | 
|---|
 | 1380 |                              | 
|---|
 | 1381 |                             if    (!is.good())    goto finish; | 
|---|
 | 1382 |                              | 
|---|
 | 1383 |                             is >> ch;                        // get the ninth lexeme | 
|---|
 | 1384 |                              | 
|---|
 | 1385 |                             if    (!is.good())    goto finish; | 
|---|
 | 1386 |                              | 
|---|
 | 1387 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1388 |                             cc = ch; | 
|---|
 | 1389 | #else | 
|---|
 | 1390 |                             cc = ct.narrow(ch, char()); | 
|---|
 | 1391 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1392 |                              | 
|---|
 | 1393 |                             if    (cc == ')')                // format: (a,(c)) or (a,(c,d)) | 
|---|
 | 1394 |                             { | 
|---|
 | 1395 |                                 q = quaternion<T>(a,b,c,d); | 
|---|
 | 1396 |                             } | 
|---|
 | 1397 |                             else                        // error | 
|---|
 | 1398 |                             { | 
|---|
 | 1399 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1400 |                                 is.setstate(::std::ios::failbit); | 
|---|
 | 1401 | #else | 
|---|
 | 1402 |                                 is.setstate(::std::ios_base::failbit); | 
|---|
 | 1403 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1404 |                             } | 
|---|
 | 1405 |                         } | 
|---|
 | 1406 |                         else                        // read "(a,b", possible: (a,b), (a,b,c), (a,b,c,d) | 
|---|
 | 1407 |                         { | 
|---|
 | 1408 |                             is.putback(ch); | 
|---|
 | 1409 |                              | 
|---|
 | 1410 |                             is >> b;                        // we extract the second component | 
|---|
 | 1411 |                              | 
|---|
 | 1412 |                             if    (!is.good())    goto finish; | 
|---|
 | 1413 |                              | 
|---|
 | 1414 |                             is >> ch;                        // get the fifth lexeme | 
|---|
 | 1415 |                              | 
|---|
 | 1416 |                             if    (!is.good())    goto finish; | 
|---|
 | 1417 |                              | 
|---|
 | 1418 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1419 |                             cc = ch; | 
|---|
 | 1420 | #else | 
|---|
 | 1421 |                             cc = ct.narrow(ch, char()); | 
|---|
 | 1422 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1423 |                              | 
|---|
 | 1424 |                             if    (cc == ')')                // format: (a,b) | 
|---|
 | 1425 |                             { | 
|---|
 | 1426 |                                 q = quaternion<T>(a,b); | 
|---|
 | 1427 |                             } | 
|---|
 | 1428 |                             else if    (cc == ',')        // read "(a,b,", possible: (a,b,c), (a,b,c,d) | 
|---|
 | 1429 |                             { | 
|---|
 | 1430 |                                 is >> c;                    // we extract the third component | 
|---|
 | 1431 |                                  | 
|---|
 | 1432 |                                 if    (!is.good())    goto finish; | 
|---|
 | 1433 |                                  | 
|---|
 | 1434 |                                 is >> ch;                    // get the seventh lexeme | 
|---|
 | 1435 |                                  | 
|---|
 | 1436 |                                 if    (!is.good())    goto finish; | 
|---|
 | 1437 |                                  | 
|---|
 | 1438 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1439 |                                 cc = ch; | 
|---|
 | 1440 | #else | 
|---|
 | 1441 |                                 cc = ct.narrow(ch, char()); | 
|---|
 | 1442 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1443 |                                  | 
|---|
 | 1444 |                                 if        (cc == ')')        // format: (a,b,c) | 
|---|
 | 1445 |                                 { | 
|---|
 | 1446 |                                     q = quaternion<T>(a,b,c); | 
|---|
 | 1447 |                                 } | 
|---|
 | 1448 |                                 else if    (cc == ',')    // read "(a,b,c,", possible: (a,b,c,d) | 
|---|
 | 1449 |                                 { | 
|---|
 | 1450 |                                     is >> d;                // we extract the fourth component | 
|---|
 | 1451 |                                      | 
|---|
 | 1452 |                                     if    (!is.good())    goto finish; | 
|---|
 | 1453 |                                      | 
|---|
 | 1454 |                                     is >> ch;                // get the ninth lexeme | 
|---|
 | 1455 |                                      | 
|---|
 | 1456 |                                     if    (!is.good())    goto finish; | 
|---|
 | 1457 |                                      | 
|---|
 | 1458 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1459 |                                     cc = ch; | 
|---|
 | 1460 | #else | 
|---|
 | 1461 |                                     cc = ct.narrow(ch, char()); | 
|---|
 | 1462 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1463 |                                      | 
|---|
 | 1464 |                                     if    (cc == ')')        // format: (a,b,c,d) | 
|---|
 | 1465 |                                     { | 
|---|
 | 1466 |                                         q = quaternion<T>(a,b,c,d); | 
|---|
 | 1467 |                                     } | 
|---|
 | 1468 |                                     else                // error | 
|---|
 | 1469 |                                     { | 
|---|
 | 1470 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1471 |                                         is.setstate(::std::ios::failbit); | 
|---|
 | 1472 | #else | 
|---|
 | 1473 |                                         is.setstate(::std::ios_base::failbit); | 
|---|
 | 1474 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1475 |                                     } | 
|---|
 | 1476 |                                 } | 
|---|
 | 1477 |                                 else                    // error | 
|---|
 | 1478 |                                 { | 
|---|
 | 1479 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1480 |                                     is.setstate(::std::ios::failbit); | 
|---|
 | 1481 | #else | 
|---|
 | 1482 |                                     is.setstate(::std::ios_base::failbit); | 
|---|
 | 1483 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1484 |                                 } | 
|---|
 | 1485 |                             } | 
|---|
 | 1486 |                             else                        // error | 
|---|
 | 1487 |                             { | 
|---|
 | 1488 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1489 |                                 is.setstate(::std::ios::failbit); | 
|---|
 | 1490 | #else | 
|---|
 | 1491 |                                 is.setstate(::std::ios_base::failbit); | 
|---|
 | 1492 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1493 |                             } | 
|---|
 | 1494 |                         } | 
|---|
 | 1495 |                     } | 
|---|
 | 1496 |                     else                                // error | 
|---|
 | 1497 |                     { | 
|---|
 | 1498 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1499 |                         is.setstate(::std::ios::failbit); | 
|---|
 | 1500 | #else | 
|---|
 | 1501 |                         is.setstate(::std::ios_base::failbit); | 
|---|
 | 1502 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1503 |                     } | 
|---|
 | 1504 |                 } | 
|---|
 | 1505 |             } | 
|---|
 | 1506 |             else                                        // format:    a | 
|---|
 | 1507 |             { | 
|---|
 | 1508 |                 is.putback(ch); | 
|---|
 | 1509 |                  | 
|---|
 | 1510 |                 is >> a;                                    // we extract the first component | 
|---|
 | 1511 |                  | 
|---|
 | 1512 |                 if    (!is.good())    goto finish; | 
|---|
 | 1513 |                  | 
|---|
 | 1514 |                 q = quaternion<T>(a); | 
|---|
 | 1515 |             } | 
|---|
 | 1516 |              | 
|---|
 | 1517 |             finish: | 
|---|
 | 1518 |             return(is); | 
|---|
 | 1519 |         } | 
|---|
 | 1520 |          | 
|---|
 | 1521 |          | 
|---|
 | 1522 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1523 |         template<typename T> | 
|---|
 | 1524 |         ::std::ostream &                         operator << (    ::std::ostream & os, | 
|---|
 | 1525 |                                                                 quaternion<T> const & q) | 
|---|
 | 1526 | #else | 
|---|
 | 1527 |         template<typename T, typename charT, class traits> | 
|---|
 | 1528 |         ::std::basic_ostream<charT,traits> &    operator << (    ::std::basic_ostream<charT,traits> & os, | 
|---|
 | 1529 |                                                                 quaternion<T> const & q) | 
|---|
 | 1530 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1531 |         { | 
|---|
 | 1532 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1533 |             ::std::ostringstream                        s; | 
|---|
 | 1534 | #else | 
|---|
 | 1535 |             ::std::basic_ostringstream<charT,traits>    s; | 
|---|
 | 1536 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1537 |              | 
|---|
 | 1538 |             s.flags(os.flags()); | 
|---|
 | 1539 | #ifdef    BOOST_NO_STD_LOCALE | 
|---|
 | 1540 | #else | 
|---|
 | 1541 |             s.imbue(os.getloc()); | 
|---|
 | 1542 | #endif /* BOOST_NO_STD_LOCALE */ | 
|---|
 | 1543 |             s.precision(os.precision()); | 
|---|
 | 1544 |              | 
|---|
 | 1545 |             s << '('    << q.R_component_1() << ',' | 
|---|
 | 1546 |                         << q.R_component_2() << ',' | 
|---|
 | 1547 |                         << q.R_component_3() << ',' | 
|---|
 | 1548 |                         << q.R_component_4() << ')'; | 
|---|
 | 1549 |              | 
|---|
 | 1550 |             return os << s.str(); | 
|---|
 | 1551 |         } | 
|---|
 | 1552 |          | 
|---|
 | 1553 |          | 
|---|
 | 1554 |         // values | 
|---|
 | 1555 |          | 
|---|
 | 1556 |         template<typename T> | 
|---|
 | 1557 |         inline T                                real(quaternion<T> const & q) | 
|---|
 | 1558 |         { | 
|---|
 | 1559 |             return(q.real()); | 
|---|
 | 1560 |         } | 
|---|
 | 1561 |          | 
|---|
 | 1562 |          | 
|---|
 | 1563 |         template<typename T> | 
|---|
 | 1564 |         inline quaternion<T>                    unreal(quaternion<T> const & q) | 
|---|
 | 1565 |         { | 
|---|
 | 1566 |             return(q.unreal()); | 
|---|
 | 1567 |         } | 
|---|
 | 1568 |          | 
|---|
 | 1569 |          | 
|---|
 | 1570 | #define    BOOST_QUATERNION_VALARRAY_LOADER  \ | 
|---|
 | 1571 |             using    ::std::valarray;        \ | 
|---|
 | 1572 |                                              \ | 
|---|
 | 1573 |             valarray<T>    temp(4);          \ | 
|---|
 | 1574 |                                              \ | 
|---|
 | 1575 |             temp[0] = q.R_component_1();     \ | 
|---|
 | 1576 |             temp[1] = q.R_component_2();     \ | 
|---|
 | 1577 |             temp[2] = q.R_component_3();     \ | 
|---|
 | 1578 |             temp[3] = q.R_component_4(); | 
|---|
 | 1579 |          | 
|---|
 | 1580 |          | 
|---|
 | 1581 |         template<typename T> | 
|---|
 | 1582 |         inline T                                sup(quaternion<T> const & q) | 
|---|
 | 1583 |         { | 
|---|
 | 1584 | #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP | 
|---|
 | 1585 |             using    ::std::abs; | 
|---|
 | 1586 | #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | 
|---|
 | 1587 |              | 
|---|
 | 1588 |             BOOST_QUATERNION_VALARRAY_LOADER | 
|---|
 | 1589 |              | 
|---|
 | 1590 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1591 |             return((BOOST_GET_VALARRAY(T, abs(temp)).max)()); | 
|---|
 | 1592 | #else | 
|---|
 | 1593 |             return((abs(temp).max)()); | 
|---|
 | 1594 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1595 |         } | 
|---|
 | 1596 |          | 
|---|
 | 1597 |          | 
|---|
 | 1598 |         template<typename T> | 
|---|
 | 1599 |         inline T                                l1(quaternion<T> const & q) | 
|---|
 | 1600 |         { | 
|---|
 | 1601 | #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP | 
|---|
 | 1602 |             using    ::std::abs; | 
|---|
 | 1603 | #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | 
|---|
 | 1604 |              | 
|---|
 | 1605 |             BOOST_QUATERNION_VALARRAY_LOADER | 
|---|
 | 1606 |              | 
|---|
 | 1607 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1608 |             return(BOOST_GET_VALARRAY(T, abs(temp)).sum()); | 
|---|
 | 1609 | #else | 
|---|
 | 1610 |             return(abs(temp).sum()); | 
|---|
 | 1611 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1612 |         } | 
|---|
 | 1613 |          | 
|---|
 | 1614 |          | 
|---|
 | 1615 |         template<typename T> | 
|---|
 | 1616 |         inline T                                abs(quaternion<T> const & q) | 
|---|
 | 1617 |         { | 
|---|
 | 1618 | #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP | 
|---|
 | 1619 |             using    ::std::abs; | 
|---|
 | 1620 | #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | 
|---|
 | 1621 |              | 
|---|
 | 1622 |             using    ::std::sqrt; | 
|---|
 | 1623 |              | 
|---|
 | 1624 |             BOOST_QUATERNION_VALARRAY_LOADER | 
|---|
 | 1625 |              | 
|---|
 | 1626 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1627 |             T            maxim = (BOOST_GET_VALARRAY(T, abs(temp)).max)();    // overflow protection | 
|---|
 | 1628 | #else | 
|---|
 | 1629 |             T            maxim = (abs(temp).max)();    // overflow protection | 
|---|
 | 1630 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1631 |              | 
|---|
 | 1632 |             if    (maxim == static_cast<T>(0)) | 
|---|
 | 1633 |             { | 
|---|
 | 1634 |                 return(maxim); | 
|---|
 | 1635 |             } | 
|---|
 | 1636 |             else | 
|---|
 | 1637 |             { | 
|---|
 | 1638 |                 T    mixam = static_cast<T>(1)/maxim;    // prefer multiplications over divisions | 
|---|
 | 1639 |                  | 
|---|
 | 1640 |                 temp *= mixam; | 
|---|
 | 1641 |                  | 
|---|
 | 1642 |                 temp *= temp; | 
|---|
 | 1643 |                  | 
|---|
 | 1644 |                 return(maxim*sqrt(temp.sum())); | 
|---|
 | 1645 |             } | 
|---|
 | 1646 |              | 
|---|
 | 1647 |             //return(sqrt(norm(q))); | 
|---|
 | 1648 |         } | 
|---|
 | 1649 |          | 
|---|
 | 1650 |          | 
|---|
 | 1651 | #undef    BOOST_QUATERNION_VALARRAY_LOADER | 
|---|
 | 1652 |          | 
|---|
 | 1653 |          | 
|---|
 | 1654 |         // Note:    This is the Cayley norm, not the Euclidian norm... | 
|---|
 | 1655 |          | 
|---|
 | 1656 |         template<typename T> | 
|---|
 | 1657 |         inline T                                norm(quaternion<T>const  & q) | 
|---|
 | 1658 |         { | 
|---|
 | 1659 |             return(real(q*conj(q))); | 
|---|
 | 1660 |         } | 
|---|
 | 1661 |          | 
|---|
 | 1662 |          | 
|---|
 | 1663 |         template<typename T> | 
|---|
 | 1664 |         inline quaternion<T>                    conj(quaternion<T> const & q) | 
|---|
 | 1665 |         { | 
|---|
 | 1666 |             return(quaternion<T>(   +q.R_component_1(), | 
|---|
 | 1667 |                                     -q.R_component_2(), | 
|---|
 | 1668 |                                     -q.R_component_3(), | 
|---|
 | 1669 |                                     -q.R_component_4())); | 
|---|
 | 1670 |         } | 
|---|
 | 1671 |          | 
|---|
 | 1672 |          | 
|---|
 | 1673 |         template<typename T> | 
|---|
 | 1674 |         inline quaternion<T>                    spherical(  T const & rho, | 
|---|
 | 1675 |                                                             T const & theta, | 
|---|
 | 1676 |                                                             T const & phi1, | 
|---|
 | 1677 |                                                             T const & phi2) | 
|---|
 | 1678 |         { | 
|---|
 | 1679 |             using ::std::cos; | 
|---|
 | 1680 |             using ::std::sin; | 
|---|
 | 1681 |              | 
|---|
 | 1682 |             //T    a = cos(theta)*cos(phi1)*cos(phi2); | 
|---|
 | 1683 |             //T    b = sin(theta)*cos(phi1)*cos(phi2); | 
|---|
 | 1684 |             //T    c = sin(phi1)*cos(phi2); | 
|---|
 | 1685 |             //T    d = sin(phi2); | 
|---|
 | 1686 |              | 
|---|
 | 1687 |             T    courrant = static_cast<T>(1); | 
|---|
 | 1688 |              | 
|---|
 | 1689 |             T    d = sin(phi2); | 
|---|
 | 1690 |              | 
|---|
 | 1691 |             courrant *= cos(phi2); | 
|---|
 | 1692 |              | 
|---|
 | 1693 |             T    c = sin(phi1)*courrant; | 
|---|
 | 1694 |              | 
|---|
 | 1695 |             courrant *= cos(phi1); | 
|---|
 | 1696 |              | 
|---|
 | 1697 |             T    b = sin(theta)*courrant; | 
|---|
 | 1698 |             T    a = cos(theta)*courrant; | 
|---|
 | 1699 |              | 
|---|
 | 1700 |             return(rho*quaternion<T>(a,b,c,d)); | 
|---|
 | 1701 |         } | 
|---|
 | 1702 |          | 
|---|
 | 1703 |          | 
|---|
 | 1704 |         template<typename T> | 
|---|
 | 1705 |         inline quaternion<T>                    semipolar(  T const & rho, | 
|---|
 | 1706 |                                                             T const & alpha, | 
|---|
 | 1707 |                                                             T const & theta1, | 
|---|
 | 1708 |                                                             T const & theta2) | 
|---|
 | 1709 |         { | 
|---|
 | 1710 |             using ::std::cos; | 
|---|
 | 1711 |             using ::std::sin; | 
|---|
 | 1712 |              | 
|---|
 | 1713 |             T    a = cos(alpha)*cos(theta1); | 
|---|
 | 1714 |             T    b = cos(alpha)*sin(theta1); | 
|---|
 | 1715 |             T    c = sin(alpha)*cos(theta2); | 
|---|
 | 1716 |             T    d = sin(alpha)*sin(theta2); | 
|---|
 | 1717 |              | 
|---|
 | 1718 |             return(rho*quaternion<T>(a,b,c,d)); | 
|---|
 | 1719 |         } | 
|---|
 | 1720 |          | 
|---|
 | 1721 |          | 
|---|
 | 1722 |         template<typename T> | 
|---|
 | 1723 |         inline quaternion<T>                    multipolar( T const & rho1, | 
|---|
 | 1724 |                                                             T const & theta1, | 
|---|
 | 1725 |                                                             T const & rho2, | 
|---|
 | 1726 |                                                             T const & theta2) | 
|---|
 | 1727 |         { | 
|---|
 | 1728 |             using ::std::cos; | 
|---|
 | 1729 |             using ::std::sin; | 
|---|
 | 1730 |              | 
|---|
 | 1731 |             T    a = rho1*cos(theta1); | 
|---|
 | 1732 |             T    b = rho1*sin(theta1); | 
|---|
 | 1733 |             T    c = rho2*cos(theta2); | 
|---|
 | 1734 |             T    d = rho2*sin(theta2); | 
|---|
 | 1735 |              | 
|---|
 | 1736 |             return(quaternion<T>(a,b,c,d)); | 
|---|
 | 1737 |         } | 
|---|
 | 1738 |          | 
|---|
 | 1739 |          | 
|---|
 | 1740 |         template<typename T> | 
|---|
 | 1741 |         inline quaternion<T>                    cylindrospherical(  T const & t, | 
|---|
 | 1742 |                                                                     T const & radius, | 
|---|
 | 1743 |                                                                     T const & longitude, | 
|---|
 | 1744 |                                                                     T const & latitude) | 
|---|
 | 1745 |         { | 
|---|
 | 1746 |             using ::std::cos; | 
|---|
 | 1747 |             using ::std::sin; | 
|---|
 | 1748 |              | 
|---|
 | 1749 |              | 
|---|
 | 1750 |              | 
|---|
 | 1751 |             T    b = radius*cos(longitude)*cos(latitude); | 
|---|
 | 1752 |             T    c = radius*sin(longitude)*cos(latitude); | 
|---|
 | 1753 |             T    d = radius*sin(latitude); | 
|---|
 | 1754 |              | 
|---|
 | 1755 |             return(quaternion<T>(t,b,c,d)); | 
|---|
 | 1756 |         } | 
|---|
 | 1757 |          | 
|---|
 | 1758 |          | 
|---|
 | 1759 |         template<typename T> | 
|---|
 | 1760 |         inline quaternion<T>                    cylindrical(T const & r, | 
|---|
 | 1761 |                                                             T const & angle, | 
|---|
 | 1762 |                                                             T const & h1, | 
|---|
 | 1763 |                                                             T const & h2) | 
|---|
 | 1764 |         { | 
|---|
 | 1765 |             using ::std::cos; | 
|---|
 | 1766 |             using ::std::sin; | 
|---|
 | 1767 |              | 
|---|
 | 1768 |             T    a = r*cos(angle); | 
|---|
 | 1769 |             T    b = r*sin(angle); | 
|---|
 | 1770 |              | 
|---|
 | 1771 |             return(quaternion<T>(a,b,h1,h2)); | 
|---|
 | 1772 |         } | 
|---|
 | 1773 |          | 
|---|
 | 1774 |          | 
|---|
 | 1775 |         // transcendentals | 
|---|
 | 1776 |         // (please see the documentation) | 
|---|
 | 1777 |          | 
|---|
 | 1778 |          | 
|---|
 | 1779 |         template<typename T> | 
|---|
 | 1780 |         inline quaternion<T>                    exp(quaternion<T> const & q) | 
|---|
 | 1781 |         { | 
|---|
 | 1782 |             using    ::std::exp; | 
|---|
 | 1783 |             using    ::std::cos; | 
|---|
 | 1784 |              | 
|---|
 | 1785 |             using    ::boost::math::sinc_pi; | 
|---|
 | 1786 |              | 
|---|
 | 1787 |             T    u = exp(real(q)); | 
|---|
 | 1788 |              | 
|---|
 | 1789 |             T    z = abs(unreal(q)); | 
|---|
 | 1790 |              | 
|---|
 | 1791 |             T    w = sinc_pi(z); | 
|---|
 | 1792 |              | 
|---|
 | 1793 |             return(u*quaternion<T>(cos(z), | 
|---|
 | 1794 |                 w*q.R_component_2(), w*q.R_component_3(), | 
|---|
 | 1795 |                 w*q.R_component_4())); | 
|---|
 | 1796 |         } | 
|---|
 | 1797 |          | 
|---|
 | 1798 |          | 
|---|
 | 1799 |         template<typename T> | 
|---|
 | 1800 |         inline quaternion<T>                    cos(quaternion<T> const & q) | 
|---|
 | 1801 |         { | 
|---|
 | 1802 |             using    ::std::sin; | 
|---|
 | 1803 |             using    ::std::cos; | 
|---|
 | 1804 |             using    ::std::cosh; | 
|---|
 | 1805 |              | 
|---|
 | 1806 |             using    ::boost::math::sinhc_pi; | 
|---|
 | 1807 |              | 
|---|
 | 1808 |             T    z = abs(unreal(q)); | 
|---|
 | 1809 |              | 
|---|
 | 1810 |             T    w = -sin(q.real())*sinhc_pi(z); | 
|---|
 | 1811 |              | 
|---|
 | 1812 |             return(quaternion<T>(cos(q.real())*cosh(z), | 
|---|
 | 1813 |                 w*q.R_component_2(), w*q.R_component_3(), | 
|---|
 | 1814 |                 w*q.R_component_4())); | 
|---|
 | 1815 |         } | 
|---|
 | 1816 |          | 
|---|
 | 1817 |          | 
|---|
 | 1818 |         template<typename T> | 
|---|
 | 1819 |         inline quaternion<T>                    sin(quaternion<T> const & q) | 
|---|
 | 1820 |         { | 
|---|
 | 1821 |             using    ::std::sin; | 
|---|
 | 1822 |             using    ::std::cos; | 
|---|
 | 1823 |             using    ::std::cosh; | 
|---|
 | 1824 |              | 
|---|
 | 1825 |             using    ::boost::math::sinhc_pi; | 
|---|
 | 1826 |              | 
|---|
 | 1827 |             T    z = abs(unreal(q)); | 
|---|
 | 1828 |              | 
|---|
 | 1829 |             T    w = +cos(q.real())*sinhc_pi(z); | 
|---|
 | 1830 |              | 
|---|
 | 1831 |             return(quaternion<T>(sin(q.real())*cosh(z), | 
|---|
 | 1832 |                 w*q.R_component_2(), w*q.R_component_3(), | 
|---|
 | 1833 |                 w*q.R_component_4())); | 
|---|
 | 1834 |         } | 
|---|
 | 1835 |          | 
|---|
 | 1836 |          | 
|---|
 | 1837 |         template<typename T> | 
|---|
 | 1838 |         inline quaternion<T>                    tan(quaternion<T> const & q) | 
|---|
 | 1839 |         { | 
|---|
 | 1840 |             return(sin(q)/cos(q)); | 
|---|
 | 1841 |         } | 
|---|
 | 1842 |          | 
|---|
 | 1843 |          | 
|---|
 | 1844 |         template<typename T> | 
|---|
 | 1845 |         inline quaternion<T>                    cosh(quaternion<T> const & q) | 
|---|
 | 1846 |         { | 
|---|
 | 1847 |             return((exp(+q)+exp(-q))/static_cast<T>(2)); | 
|---|
 | 1848 |         } | 
|---|
 | 1849 |          | 
|---|
 | 1850 |          | 
|---|
 | 1851 |         template<typename T> | 
|---|
 | 1852 |         inline quaternion<T>                    sinh(quaternion<T> const & q) | 
|---|
 | 1853 |         { | 
|---|
 | 1854 |             return((exp(+q)-exp(-q))/static_cast<T>(2)); | 
|---|
 | 1855 |         } | 
|---|
 | 1856 |          | 
|---|
 | 1857 |          | 
|---|
 | 1858 |         template<typename T> | 
|---|
 | 1859 |         inline quaternion<T>                    tanh(quaternion<T> const & q) | 
|---|
 | 1860 |         { | 
|---|
 | 1861 |             return(sinh(q)/cosh(q)); | 
|---|
 | 1862 |         } | 
|---|
 | 1863 |          | 
|---|
 | 1864 |          | 
|---|
 | 1865 |         template<typename T> | 
|---|
 | 1866 |         quaternion<T>                            pow(quaternion<T> const & q, | 
|---|
 | 1867 |                                                     int n) | 
|---|
 | 1868 |         { | 
|---|
 | 1869 |             if        (n > 1) | 
|---|
 | 1870 |             { | 
|---|
 | 1871 |                 int    m = n>>1; | 
|---|
 | 1872 |                  | 
|---|
 | 1873 |                 quaternion<T>    result = pow(q, m); | 
|---|
 | 1874 |                  | 
|---|
 | 1875 |                 result *= result; | 
|---|
 | 1876 |                  | 
|---|
 | 1877 |                 if    (n != (m<<1)) | 
|---|
 | 1878 |                 { | 
|---|
 | 1879 |                     result *= q; // n odd | 
|---|
 | 1880 |                 } | 
|---|
 | 1881 |                  | 
|---|
 | 1882 |                 return(result); | 
|---|
 | 1883 |             } | 
|---|
 | 1884 |             else if    (n == 1) | 
|---|
 | 1885 |             { | 
|---|
 | 1886 |                 return(q); | 
|---|
 | 1887 |             } | 
|---|
 | 1888 |             else if    (n == 0) | 
|---|
 | 1889 |             { | 
|---|
 | 1890 |                 return(quaternion<T>(1)); | 
|---|
 | 1891 |             } | 
|---|
 | 1892 |             else    /* n < 0 */ | 
|---|
 | 1893 |             { | 
|---|
 | 1894 |                 return(pow(quaternion<T>(1)/q,-n)); | 
|---|
 | 1895 |             } | 
|---|
 | 1896 |         } | 
|---|
 | 1897 |          | 
|---|
 | 1898 |          | 
|---|
 | 1899 |         // helper templates for converting copy constructors (definition) | 
|---|
 | 1900 |          | 
|---|
 | 1901 |         namespace detail | 
|---|
 | 1902 |         { | 
|---|
 | 1903 |              | 
|---|
 | 1904 |             template<   typename T, | 
|---|
 | 1905 |                         typename U | 
|---|
 | 1906 |                     > | 
|---|
 | 1907 |             quaternion<T>    quaternion_type_converter(quaternion<U> const & rhs) | 
|---|
 | 1908 |             { | 
|---|
 | 1909 |                 return(quaternion<T>(   static_cast<T>(rhs.R_component_1()), | 
|---|
 | 1910 |                                         static_cast<T>(rhs.R_component_2()), | 
|---|
 | 1911 |                                         static_cast<T>(rhs.R_component_3()), | 
|---|
 | 1912 |                                         static_cast<T>(rhs.R_component_4()))); | 
|---|
 | 1913 |             } | 
|---|
 | 1914 |         } | 
|---|
 | 1915 |     } | 
|---|
 | 1916 | } | 
|---|
 | 1917 |  | 
|---|
 | 1918 |  | 
|---|
 | 1919 | #if    BOOST_WORKAROUND(__GNUC__, < 3) | 
|---|
 | 1920 |     #undef    BOOST_GET_VALARRAY | 
|---|
 | 1921 | #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | 
|---|
 | 1922 |  | 
|---|
 | 1923 |  | 
|---|
 | 1924 | #endif /* BOOST_QUATERNION_HPP */ | 
|---|