brintos

brintos / llvm-project-archived public Read only

0
0
Text · 217.1 KiB · 5d147df Raw
4251 lines · plain
1//    boost octonion.hpp header file2 3//  (C) Copyright Hubert Holin 2001.4//  Distributed under the Boost Software License, Version 1.0. (See5//  accompanying file LICENSE_1_0.txt or copy at6//  http://www.boost.org/LICENSE_1_0.txt)7 8// See http://www.boost.org for updates, documentation, and revision history.9 10 11#ifndef BOOST_OCTONION_HPP12#define BOOST_OCTONION_HPP13 14#include <boost/math/quaternion.hpp>15#include <valarray>16 17 18namespace boost19{20    namespace math21    {22 23#define    BOOST_OCTONION_ACCESSOR_GENERATOR(type)                      \24            type                        real() const                    \25            {                                                           \26                return(a);                                              \27            }                                                           \28                                                                        \29            octonion<type>                unreal() const                \30            {                                                           \31                return( octonion<type>(static_cast<type>(0),b,c,d,e,f,g,h));   \32            }                                                           \33                                                                        \34            type                            R_component_1() const       \35            {                                                           \36                return(a);                                              \37            }                                                           \38                                                                        \39            type                            R_component_2() const       \40            {                                                           \41                return(b);                                              \42            }                                                           \43                                                                        \44            type                            R_component_3() const       \45            {                                                           \46                return(c);                                              \47            }                                                           \48                                                                        \49            type                            R_component_4() const       \50            {                                                           \51                return(d);                                              \52            }                                                           \53                                                                        \54            type                            R_component_5() const       \55            {                                                           \56                return(e);                                              \57            }                                                           \58                                                                        \59            type                            R_component_6() const       \60            {                                                           \61                return(f);                                              \62            }                                                           \63                                                                        \64            type                            R_component_7() const       \65            {                                                           \66                return(g);                                              \67            }                                                           \68                                                                        \69            type                            R_component_8() const       \70            {                                                           \71                return(h);                                              \72            }                                                           \73                                                                        \74            ::std::complex<type>            C_component_1() const       \75            {                                                           \76                return(::std::complex<type>(a,b));                      \77            }                                                           \78                                                                        \79            ::std::complex<type>            C_component_2() const       \80            {                                                           \81                return(::std::complex<type>(c,d));                      \82            }                                                           \83                                                                        \84            ::std::complex<type>            C_component_3() const       \85            {                                                           \86                return(::std::complex<type>(e,f));                      \87            }                                                           \88                                                                        \89            ::std::complex<type>            C_component_4() const       \90            {                                                           \91                return(::std::complex<type>(g,h));                      \92            }                                                           \93                                                                        \94            ::boost::math::quaternion<type>    H_component_1() const    \95            {                                                           \96                return(::boost::math::quaternion<type>(a,b,c,d));       \97            }                                                           \98                                                                        \99            ::boost::math::quaternion<type>    H_component_2() const    \100            {                                                           \101                return(::boost::math::quaternion<type>(e,f,g,h));       \102            }103 104 105#define    BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(type)                                         \106            template<typename X>                                                                    \107            octonion<type> &        operator = (octonion<X> const & a_affecter)                     \108            {                                                                                       \109                a = static_cast<type>(a_affecter.R_component_1());                                  \110                b = static_cast<type>(a_affecter.R_component_2());                                  \111                c = static_cast<type>(a_affecter.R_component_3());                                  \112                d = static_cast<type>(a_affecter.R_component_4());                                  \113                e = static_cast<type>(a_affecter.R_component_5());                                  \114                f = static_cast<type>(a_affecter.R_component_6());                                  \115                g = static_cast<type>(a_affecter.R_component_7());                                  \116                h = static_cast<type>(a_affecter.R_component_8());                                  \117                                                                                                    \118                return(*this);                                                                      \119            }                                                                                       \120                                                                                                    \121            octonion<type> &        operator = (octonion<type> const & a_affecter)                  \122            {                                                                                       \123                a = a_affecter.a;                                                                   \124                b = a_affecter.b;                                                                   \125                c = a_affecter.c;                                                                   \126                d = a_affecter.d;                                                                   \127                e = a_affecter.e;                                                                   \128                f = a_affecter.f;                                                                   \129                g = a_affecter.g;                                                                   \130                h = a_affecter.h;                                                                   \131                                                                                                    \132                return(*this);                                                                      \133            }                                                                                       \134                                                                                                    \135            octonion<type> &        operator = (type const & a_affecter)                            \136            {                                                                                       \137                a = a_affecter;                                                                     \138                                                                                                    \139                b = c = d = e = f= g = h = static_cast<type>(0);                                    \140                                                                                                    \141                return(*this);                                                                      \142            }                                                                                       \143                                                                                                    \144            octonion<type> &        operator = (::std::complex<type> const & a_affecter)            \145            {                                                                                       \146                a = a_affecter.real();                                                              \147                b = a_affecter.imag();                                                              \148                                                                                                    \149                c = d = e = f = g = h = static_cast<type>(0);                                       \150                                                                                                    \151                return(*this);                                                                      \152            }                                                                                       \153                                                                                                    \154            octonion<type> &        operator = (::boost::math::quaternion<type> const & a_affecter) \155            {                                                                                       \156                a = a_affecter.R_component_1();                                                     \157                b = a_affecter.R_component_2();                                                     \158                c = a_affecter.R_component_3();                                                     \159                d = a_affecter.R_component_4();                                                     \160                                                                                                    \161                e = f = g = h = static_cast<type>(0);                                               \162                                                                                                    \163                return(*this);                                                                      \164            }165 166 167#define    BOOST_OCTONION_MEMBER_DATA_GENERATOR(type) \168            type    a;                                \169            type    b;                                \170            type    c;                                \171            type    d;                                \172            type    e;                                \173            type    f;                                \174            type    g;                                \175            type    h;                                \176 177        // LCOV_EXCL_START178        // No code coverage for the generic case, like std::complex,179        // the The behavior of octonion is unspecified if T is not180        // one of float, double or long double.181 182        template<typename T>183        class octonion184        {185        public:186 187            using value_type = T;188 189            // constructor for O seen as R^8190            // (also default constructor)191 192            explicit                octonion(   T const & requested_a = T(),193                                                T const & requested_b = T(),194                                                T const & requested_c = T(),195                                                T const & requested_d = T(),196                                                T const & requested_e = T(),197                                                T const & requested_f = T(),198                                                T const & requested_g = T(),199                                                T const & requested_h = T())200            :   a(requested_a),201                b(requested_b),202                c(requested_c),203                d(requested_d),204                e(requested_e),205                f(requested_f),206                g(requested_g),207                h(requested_h)208            {209                // nothing to do!210            }211 212 213            // constructor for H seen as C^4214 215            explicit                octonion(   ::std::complex<T> const & z0,216                                                ::std::complex<T> const & z1 = ::std::complex<T>(),217                                                ::std::complex<T> const & z2 = ::std::complex<T>(),218                                                ::std::complex<T> const & z3 = ::std::complex<T>())219            :   a(z0.real()),220                b(z0.imag()),221                c(z1.real()),222                d(z1.imag()),223                e(z2.real()),224                f(z2.imag()),225                g(z3.real()),226                h(z3.imag())227            {228                // nothing to do!229            }230 231 232            // constructor for O seen as H^2233 234            explicit                octonion(   ::boost::math::quaternion<T> const & q0,235                                                ::boost::math::quaternion<T> const & q1 = ::boost::math::quaternion<T>())236            :   a(q0.R_component_1()),237                b(q0.R_component_2()),238                c(q0.R_component_3()),239                d(q0.R_component_4()),240                e(q1.R_component_1()),241                f(q1.R_component_2()),242                g(q1.R_component_3()),243                h(q1.R_component_4())244            {245                // nothing to do!246            }247 248 249            // UNtemplated copy constructor250            octonion(const octonion&) = default;251 252 253            // templated copy constructor254 255            template<typename X>256            explicit                octonion(octonion<X> const & a_recopier)257            :   a(static_cast<T>(a_recopier.R_component_1())),258                b(static_cast<T>(a_recopier.R_component_2())),259                c(static_cast<T>(a_recopier.R_component_3())),260                d(static_cast<T>(a_recopier.R_component_4())),261                e(static_cast<T>(a_recopier.R_component_5())),262                f(static_cast<T>(a_recopier.R_component_6())),263                g(static_cast<T>(a_recopier.R_component_7())),264                h(static_cast<T>(a_recopier.R_component_8()))265            {266                // nothing to do!267            }268 269 270            // destructor271            ~octonion() = default;272 273 274            // accessors275            //276            // Note:    Like complex number, octonions do have a meaningful notion of "real part",277            //            but unlike them there is no meaningful notion of "imaginary part".278            //            Instead there is an "unreal part" which itself is an octonion, and usually279            //            nothing simpler (as opposed to the complex number case).280            //            However, for practicality, there are accessors for the other components281            //            (these are necessary for the templated copy constructor, for instance).282 283            BOOST_OCTONION_ACCESSOR_GENERATOR(T)284 285            // assignment operators286 287            BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(T)288 289            // other assignment-related operators290            //291            // NOTE:    Octonion multiplication is *NOT* commutative;292            //            symbolically, "q *= rhs;" means "q = q * rhs;"293            //            and "q /= rhs;" means "q = q * inverse_of(rhs);";294            //            octonion multiplication is also *NOT* associative295 296            octonion<T> &            operator += (T const & rhs)297            {298                T    at = a + rhs;    // exception guard299 300                a = at;301 302                return(*this);303            }304 305 306            octonion<T> &            operator += (::std::complex<T> const & rhs)307            {308                T    at = a + rhs.real();    // exception guard309                T    bt = b + rhs.imag();    // exception guard310 311                a = at;312                b = bt;313 314                return(*this);315            }316 317 318            octonion<T> &            operator += (::boost::math::quaternion<T> const & rhs)319            {320                T    at = a + rhs.R_component_1();    // exception guard321                T    bt = b + rhs.R_component_2();    // exception guard322                T    ct = c + rhs.R_component_3();    // exception guard323                T    dt = d + rhs.R_component_4();    // exception guard324 325                a = at;326                b = bt;327                c = ct;328                d = dt;329 330                return(*this);331            }332 333 334            template<typename X>335            octonion<T> &            operator += (octonion<X> const & rhs)336            {337                T    at = a + static_cast<T>(rhs.R_component_1());    // exception guard338                T    bt = b + static_cast<T>(rhs.R_component_2());    // exception guard339                T    ct = c + static_cast<T>(rhs.R_component_3());    // exception guard340                T    dt = d + static_cast<T>(rhs.R_component_4());    // exception guard341                T    et = e + static_cast<T>(rhs.R_component_5());    // exception guard342                T    ft = f + static_cast<T>(rhs.R_component_6());    // exception guard343                T    gt = g + static_cast<T>(rhs.R_component_7());    // exception guard344                T    ht = h + static_cast<T>(rhs.R_component_8());    // exception guard345 346                a = at;347                b = bt;348                c = ct;349                d = dt;350                e = et;351                f = ft;352                g = gt;353                h = ht;354 355                return(*this);356            }357 358 359 360            octonion<T> &            operator -= (T const & rhs)361            {362                T    at = a - rhs;    // exception guard363 364                a = at;365 366                return(*this);367            }368 369 370            octonion<T> &            operator -= (::std::complex<T> const & rhs)371            {372                T    at = a - rhs.real();    // exception guard373                T    bt = b - rhs.imag();    // exception guard374 375                a = at;376                b = bt;377 378                return(*this);379            }380 381 382            octonion<T> &            operator -= (::boost::math::quaternion<T> const & rhs)383            {384                T    at = a - rhs.R_component_1();    // exception guard385                T    bt = b - rhs.R_component_2();    // exception guard386                T    ct = c - rhs.R_component_3();    // exception guard387                T    dt = d - rhs.R_component_4();    // exception guard388 389                a = at;390                b = bt;391                c = ct;392                d = dt;393 394                return(*this);395            }396 397 398            template<typename X>399            octonion<T> &            operator -= (octonion<X> const & rhs)400            {401                T    at = a - static_cast<T>(rhs.R_component_1());    // exception guard402                T    bt = b - static_cast<T>(rhs.R_component_2());    // exception guard403                T    ct = c - static_cast<T>(rhs.R_component_3());    // exception guard404                T    dt = d - static_cast<T>(rhs.R_component_4());    // exception guard405                T    et = e - static_cast<T>(rhs.R_component_5());    // exception guard406                T    ft = f - static_cast<T>(rhs.R_component_6());    // exception guard407                T    gt = g - static_cast<T>(rhs.R_component_7());    // exception guard408                T    ht = h - static_cast<T>(rhs.R_component_8());    // exception guard409 410                a = at;411                b = bt;412                c = ct;413                d = dt;414                e = et;415                f = ft;416                g = gt;417                h = ht;418 419                return(*this);420            }421 422 423            octonion<T> &            operator *= (T const & rhs)424            {425                T    at = a * rhs;    // exception guard426                T    bt = b * rhs;    // exception guard427                T    ct = c * rhs;    // exception guard428                T    dt = d * rhs;    // exception guard429                T    et = e * rhs;    // exception guard430                T    ft = f * rhs;    // exception guard431                T    gt = g * rhs;    // exception guard432                T    ht = h * rhs;    // exception guard433 434                a = at;435                b = bt;436                c = ct;437                d = dt;438                e = et;439                f = ft;440                g = gt;441                h = ht;442 443                return(*this);444            }445 446 447            octonion<T> &            operator *= (::std::complex<T> const & rhs)448            {449                T    ar = rhs.real();450                T    br = rhs.imag();451 452                T    at = +a*ar-b*br;453                T    bt = +a*br+b*ar;454                T    ct = +c*ar+d*br;455                T    dt = -c*br+d*ar;456                T    et = +e*ar+f*br;457                T    ft = -e*br+f*ar;458                T    gt = +g*ar-h*br;459                T    ht = +g*br+h*ar;460 461                a = at;462                b = bt;463                c = ct;464                d = dt;465                e = et;466                f = ft;467                g = gt;468                h = ht;469 470                return(*this);471            }472 473 474            octonion<T> &            operator *= (::boost::math::quaternion<T> const & rhs)475            {476                T    ar = rhs.R_component_1();477                T    br = rhs.R_component_2();478                T    cr = rhs.R_component_2();479                T    dr = rhs.R_component_2();480 481                T    at = +a*ar-b*br-c*cr-d*dr;482                T    bt = +a*br+b*ar+c*dr-d*cr;483                T    ct = +a*cr-b*dr+c*ar+d*br;484                T    dt = +a*dr+b*cr-c*br+d*ar;485                T    et = +e*ar+f*br+g*cr+h*dr;486                T    ft = -e*br+f*ar-g*dr+h*cr;487                T    gt = -e*cr+f*dr+g*ar-h*br;488                T    ht = -e*dr-f*cr+g*br+h*ar;489 490                a = at;491                b = bt;492                c = ct;493                d = dt;494                e = et;495                f = ft;496                g = gt;497                h = ht;498 499                return(*this);500            }501 502 503            template<typename X>504            octonion<T> &            operator *= (octonion<X> const & rhs)505            {506                T    ar = static_cast<T>(rhs.R_component_1());507                T    br = static_cast<T>(rhs.R_component_2());508                T    cr = static_cast<T>(rhs.R_component_3());509                T    dr = static_cast<T>(rhs.R_component_4());510                T    er = static_cast<T>(rhs.R_component_5());511                T    fr = static_cast<T>(rhs.R_component_6());512                T    gr = static_cast<T>(rhs.R_component_7());513                T    hr = static_cast<T>(rhs.R_component_8());514 515                T    at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr;516                T    bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr;517                T    ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr;518                T    dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er;519                T    et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr;520                T    ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr;521                T    gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br;522                T    ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar;523 524                a = at;525                b = bt;526                c = ct;527                d = dt;528                e = et;529                f = ft;530                g = gt;531                h = ht;532 533                return(*this);534            }535 536 537            octonion<T> &            operator /= (T const & rhs)538            {539                T    at = a / rhs;    // exception guard540                T    bt = b / rhs;    // exception guard541                T    ct = c / rhs;    // exception guard542                T    dt = d / rhs;    // exception guard543                T    et = e / rhs;    // exception guard544                T    ft = f / rhs;    // exception guard545                T    gt = g / rhs;    // exception guard546                T    ht = h / rhs;    // exception guard547 548                a = at;549                b = bt;550                c = ct;551                d = dt;552                e = et;553                f = ft;554                g = gt;555                h = ht;556 557                return(*this);558            }559 560 561            octonion<T> &            operator /= (::std::complex<T> const & rhs)562            {563                T    ar = rhs.real();564                T    br = rhs.imag();565 566                T    denominator = ar*ar+br*br;567 568                T    at = (+a*ar-b*br)/denominator;569                T    bt = (-a*br+b*ar)/denominator;570                T    ct = (+c*ar-d*br)/denominator;571                T    dt = (+c*br+d*ar)/denominator;572                T    et = (+e*ar-f*br)/denominator;573                T    ft = (+e*br+f*ar)/denominator;574                T    gt = (+g*ar+h*br)/denominator;575                T    ht = (+g*br+h*ar)/denominator;576 577                a = at;578                b = bt;579                c = ct;580                d = dt;581                e = et;582                f = ft;583                g = gt;584                h = ht;585 586                return(*this);587            }588 589 590            octonion<T> &            operator /= (::boost::math::quaternion<T> const & rhs)591            {592                T    ar = rhs.R_component_1();593                T    br = rhs.R_component_2();594                T    cr = rhs.R_component_2();595                T    dr = rhs.R_component_2();596 597                T    denominator = ar*ar+br*br+cr*cr+dr*dr;598 599                T    at = (+a*ar+b*br+c*cr+d*dr)/denominator;600                T    bt = (-a*br+b*ar-c*dr+d*cr)/denominator;601                T    ct = (-a*cr+b*dr+c*ar-d*br)/denominator;602                T    dt = (-a*dr-b*cr+c*br+d*ar)/denominator;603                T    et = (+e*ar-f*br-g*cr-h*dr)/denominator;604                T    ft = (+e*br+f*ar+g*dr-h*cr)/denominator;605                T    gt = (+e*cr-f*dr+g*ar+h*br)/denominator;606                T    ht = (+e*dr+f*cr-g*br+h*ar)/denominator;607 608                a = at;609                b = bt;610                c = ct;611                d = dt;612                e = et;613                f = ft;614                g = gt;615                h = ht;616 617                return(*this);618            }619 620 621            template<typename X>622            octonion<T> &            operator /= (octonion<X> const & rhs)623            {624                T    ar = static_cast<T>(rhs.R_component_1());625                T    br = static_cast<T>(rhs.R_component_2());626                T    cr = static_cast<T>(rhs.R_component_3());627                T    dr = static_cast<T>(rhs.R_component_4());628                T    er = static_cast<T>(rhs.R_component_5());629                T    fr = static_cast<T>(rhs.R_component_6());630                T    gr = static_cast<T>(rhs.R_component_7());631                T    hr = static_cast<T>(rhs.R_component_8());632 633                T    denominator = ar*ar+br*br+cr*cr+dr*dr+er*er+fr*fr+gr*gr+hr*hr;634 635                T    at = (+a*ar+b*br+c*cr+d*dr+e*er+f*fr+g*gr+h*hr)/denominator;636                T    bt = (-a*br+b*ar-c*dr+d*cr-e*fr+f*er+g*hr-h*gr)/denominator;637                T    ct = (-a*cr+b*dr+c*ar-d*br-e*gr-f*hr+g*er+h*fr)/denominator;638                T    dt = (-a*dr-b*cr+c*br+d*ar-e*hr+f*gr-g*fr+h*er)/denominator;639                T    et = (-a*er+b*fr+c*gr+d*hr+e*ar-f*br-g*cr-h*dr)/denominator;640                T    ft = (-a*fr-b*er+c*hr-d*gr+e*br+f*ar+g*dr-h*cr)/denominator;641                T    gt = (-a*gr-b*hr-c*er+d*fr+e*cr-f*dr+g*ar+h*br)/denominator;642                T    ht = (-a*hr+b*gr-c*fr-d*er+e*dr+f*cr-g*br+h*ar)/denominator;643 644                a = at;645                b = bt;646                c = ct;647                d = dt;648                e = et;649                f = ft;650                g = gt;651                h = ht;652 653                return(*this);654            }655 656 657        protected:658 659            BOOST_OCTONION_MEMBER_DATA_GENERATOR(T)660 661 662        private:663 664        };665        // LCOV_EXCL_STOP666 667        // declaration of octonion specialization668 669        template<>    class octonion<float>;670        template<>    class octonion<double>;671        template<>    class octonion<long double>;672 673 674        // helper templates for converting copy constructors (declaration)675 676        namespace detail677        {678 679            template<   typename T,680                        typename U681                    >682            octonion<T>    octonion_type_converter(octonion<U> const & rhs);683        }684 685 686        // implementation of octonion specialization687 688 689#define    BOOST_OCTONION_CONSTRUCTOR_GENERATOR(type)                                                                               \690            explicit                    octonion(   type const & requested_a = static_cast<type>(0),                                \691                                                    type const & requested_b = static_cast<type>(0),                                \692                                                    type const & requested_c = static_cast<type>(0),                                \693                                                    type const & requested_d = static_cast<type>(0),                                \694                                                    type const & requested_e = static_cast<type>(0),                                \695                                                    type const & requested_f = static_cast<type>(0),                                \696                                                    type const & requested_g = static_cast<type>(0),                                \697                                                    type const & requested_h = static_cast<type>(0))                                \698            :   a(requested_a),                                                                                                     \699                b(requested_b),                                                                                                     \700                c(requested_c),                                                                                                     \701                d(requested_d),                                                                                                     \702                e(requested_e),                                                                                                     \703                f(requested_f),                                                                                                     \704                g(requested_g),                                                                                                     \705                h(requested_h)                                                                                                      \706            {                                                                                                                       \707            }                                                                                                                       \708                                                                                                                                    \709            explicit                    octonion(   ::std::complex<type> const & z0,                                                \710                                                    ::std::complex<type> const & z1 = ::std::complex<type>(),                       \711                                                    ::std::complex<type> const & z2 = ::std::complex<type>(),                       \712                                                    ::std::complex<type> const & z3 = ::std::complex<type>())                       \713            :   a(z0.real()),                                                                                                       \714                b(z0.imag()),                                                                                                       \715                c(z1.real()),                                                                                                       \716                d(z1.imag()),                                                                                                       \717                e(z2.real()),                                                                                                       \718                f(z2.imag()),                                                                                                       \719                g(z3.real()),                                                                                                       \720                h(z3.imag())                                                                                                        \721            {                                                                                                                       \722            }                                                                                                                       \723                                                                                                                                    \724            explicit                    octonion(   ::boost::math::quaternion<type> const & q0,                                     \725                                                    ::boost::math::quaternion<type> const & q1 = ::boost::math::quaternion<type>()) \726            :   a(q0.R_component_1()),                                                                                              \727                b(q0.R_component_2()),                                                                                              \728                c(q0.R_component_3()),                                                                                              \729                d(q0.R_component_4()),                                                                                              \730                e(q1.R_component_1()),                                                                                              \731                f(q1.R_component_2()),                                                                                              \732                g(q1.R_component_3()),                                                                                              \733                h(q1.R_component_4())                                                                                               \734            {                                                                                                                       \735            }736 737 738#define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type)                  \739            octonion<type> &            operator += (type const & rhs)  \740            {                                                           \741                a += rhs;                                               \742                                                                        \743                return(*this);                                          \744            }745 746#define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type)                                  \747            octonion<type> &            operator += (::std::complex<type> const & rhs)  \748            {                                                                           \749                a += rhs.real();                                                        \750                b += rhs.imag();                                                        \751                                                                                        \752                return(*this);                                                          \753            }754 755#define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type)                                              \756            octonion<type> &            operator += (::boost::math::quaternion<type> const & rhs)   \757            {                                                                                       \758                a += rhs.R_component_1();                                                           \759                b += rhs.R_component_2();                                                           \760                c += rhs.R_component_3();                                                           \761                d += rhs.R_component_4();                                                           \762                                                                                                    \763                return(*this);                                                                      \764            }765 766#define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type)                          \767            template<typename X>                                                \768            octonion<type> &            operator += (octonion<X> const & rhs)   \769            {                                                                   \770                a += static_cast<type>(rhs.R_component_1());                    \771                b += static_cast<type>(rhs.R_component_2());                    \772                c += static_cast<type>(rhs.R_component_3());                    \773                d += static_cast<type>(rhs.R_component_4());                    \774                e += static_cast<type>(rhs.R_component_5());                    \775                f += static_cast<type>(rhs.R_component_6());                    \776                g += static_cast<type>(rhs.R_component_7());                    \777                h += static_cast<type>(rhs.R_component_8());                    \778                                                                                \779                return(*this);                                                  \780            }781 782#define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type)                  \783            octonion<type> &            operator -= (type const & rhs)  \784            {                                                           \785                a -= rhs;                                               \786                                                                        \787                return(*this);                                          \788            }789 790#define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type)                                  \791            octonion<type> &            operator -= (::std::complex<type> const & rhs)  \792            {                                                                           \793                a -= rhs.real();                                                        \794                b -= rhs.imag();                                                        \795                                                                                        \796                return(*this);                                                          \797            }798 799#define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type)                                              \800            octonion<type> &            operator -= (::boost::math::quaternion<type> const & rhs)   \801            {                                                                                       \802                a -= rhs.R_component_1();                                                           \803                b -= rhs.R_component_2();                                                           \804                c -= rhs.R_component_3();                                                           \805                d -= rhs.R_component_4();                                                           \806                                                                                                    \807                return(*this);                                                                      \808            }809 810#define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type)                        \811            template<typename X>                                              \812            octonion<type> &            operator -= (octonion<X> const & rhs) \813            {                                                                 \814                a -= static_cast<type>(rhs.R_component_1());                  \815                b -= static_cast<type>(rhs.R_component_2());                  \816                c -= static_cast<type>(rhs.R_component_3());                  \817                d -= static_cast<type>(rhs.R_component_4());                  \818                e -= static_cast<type>(rhs.R_component_5());                  \819                f -= static_cast<type>(rhs.R_component_6());                  \820                g -= static_cast<type>(rhs.R_component_7());                  \821                h -= static_cast<type>(rhs.R_component_8());                  \822                                                                              \823                return(*this);                                                \824            }825 826#define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type)                   \827            octonion<type> &            operator *= (type const & rhs)   \828            {                                                            \829                a *= rhs;                                                \830                b *= rhs;                                                \831                c *= rhs;                                                \832                d *= rhs;                                                \833                e *= rhs;                                                \834                f *= rhs;                                                \835                g *= rhs;                                                \836                h *= rhs;                                                \837                                                                         \838                return(*this);                                           \839            }840 841#define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type)                                  \842            octonion<type> &            operator *= (::std::complex<type> const & rhs)  \843            {                                                                           \844                type    ar = rhs.real();                                                \845                type    br = rhs.imag();                                                \846                                                                                        \847                type    at = +a*ar-b*br;                                                \848                type    bt = +a*br+b*ar;                                                \849                type    ct = +c*ar+d*br;                                                \850                type    dt = -c*br+d*ar;                                                \851                type    et = +e*ar+f*br;                                                \852                type    ft = -e*br+f*ar;                                                \853                type    gt = +g*ar-h*br;                                                \854                type    ht = +g*br+h*ar;                                                \855                                                                                        \856                a = at;                                                                 \857                b = bt;                                                                 \858                c = ct;                                                                 \859                d = dt;                                                                 \860                e = et;                                                                 \861                f = ft;                                                                 \862                g = gt;                                                                 \863                h = ht;                                                                 \864                                                                                        \865                return(*this);                                                          \866            }867 868#define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type)                                                    \869            octonion<type> &            operator *= (::boost::math::quaternion<type> const & rhs)   \870            {                                                                                       \871                type    ar = rhs.R_component_1();                                                   \872                type    br = rhs.R_component_2();                                                   \873                type    cr = rhs.R_component_2();                                                   \874                type    dr = rhs.R_component_2();                                                   \875                                                                                                    \876                type    at = +a*ar-b*br-c*cr-d*dr;                                                  \877                type    bt = +a*br+b*ar+c*dr-d*cr;                                                  \878                type    ct = +a*cr-b*dr+c*ar+d*br;                                                  \879                type    dt = +a*dr+b*cr-c*br+d*ar;                                                  \880                type    et = +e*ar+f*br+g*cr+h*dr;                                                  \881                type    ft = -e*br+f*ar-g*dr+h*cr;                                                  \882                type    gt = -e*cr+f*dr+g*ar-h*br;                                                  \883                type    ht = -e*dr-f*cr+g*br+h*ar;                                                  \884                                                                                                    \885                a = at;                                                                             \886                b = bt;                                                                             \887                c = ct;                                                                             \888                d = dt;                                                                             \889                e = et;                                                                             \890                f = ft;                                                                             \891                g = gt;                                                                             \892                h = ht;                                                                             \893                                                                                                    \894                return(*this);                                                                      \895            }896 897#define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type)                          \898            template<typename X>                                                \899            octonion<type> &            operator *= (octonion<X> const & rhs)   \900            {                                                                   \901                type    ar = static_cast<type>(rhs.R_component_1());            \902                type    br = static_cast<type>(rhs.R_component_2());            \903                type    cr = static_cast<type>(rhs.R_component_3());            \904                type    dr = static_cast<type>(rhs.R_component_4());            \905                type    er = static_cast<type>(rhs.R_component_5());            \906                type    fr = static_cast<type>(rhs.R_component_6());            \907                type    gr = static_cast<type>(rhs.R_component_7());            \908                type    hr = static_cast<type>(rhs.R_component_8());            \909                                                                                \910                type    at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr;          \911                type    bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr;          \912                type    ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr;          \913                type    dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er;          \914                type    et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr;          \915                type    ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr;          \916                type    gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br;          \917                type    ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar;          \918                                                                                \919                a = at;                                                         \920                b = bt;                                                         \921                c = ct;                                                         \922                d = dt;                                                         \923                e = et;                                                         \924                f = ft;                                                         \925                g = gt;                                                         \926                h = ht;                                                         \927                                                                                \928                return(*this);                                                  \929            }930 931// There is quite a lot of repetition in the code below. This is intentional.932// The last conditional block is the normal form, and the others merely933// consist of workarounds for various compiler deficiencies. Hopefully, when934// more compilers are conformant and we can retire support for those that are935// not, we will be able to remove the clutter. This is makes the situation936// (painfully) explicit.937 938#define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type)                  \939            octonion<type> &            operator /= (type const & rhs)  \940            {                                                           \941                a /= rhs;                                               \942                b /= rhs;                                               \943                c /= rhs;                                               \944                d /= rhs;                                               \945                                                                        \946                return(*this);                                          \947            }948 949#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)950    #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)                              \951            octonion<type> &            operator /= (::std::complex<type> const & rhs)  \952            {                                                                           \953                using    ::std::valarray;                                               \954                using    ::std::abs;                                                    \955                                                                                        \956                valarray<type>    tr(2);                                                \957                                                                                        \958                tr[0] = rhs.real();                                                     \959                tr[1] = rhs.imag();                                                     \960                                                                                        \961                type            mixam = static_cast<type>(1)/(abs(tr).max)();           \962                                                                                        \963                tr *= mixam;                                                            \964                                                                                        \965                valarray<type>    tt(8);                                                \966                                                                                        \967                tt[0] = +a*tr[0]-b*tr[1];                                               \968                tt[1] = -a*tr[1]+b*tr[0];                                               \969                tt[2] = +c*tr[0]-d*tr[1];                                               \970                tt[3] = +c*tr[1]+d*tr[0];                                               \971                tt[4] = +e*tr[0]-f*tr[1];                                               \972                tt[5] = +e*tr[1]+f*tr[0];                                               \973                tt[6] = +g*tr[0]+h*tr[1];                                               \974                tt[7] = +g*tr[1]+h*tr[0];                                               \975                                                                                        \976                tr *= tr;                                                               \977                                                                                        \978                tt *= (mixam/tr.sum());                                                 \979                                                                                        \980                a = tt[0];                                                              \981                b = tt[1];                                                              \982                c = tt[2];                                                              \983                d = tt[3];                                                              \984                e = tt[4];                                                              \985                f = tt[5];                                                              \986                g = tt[6];                                                              \987                h = tt[7];                                                              \988                                                                                        \989                return(*this);                                                          \990            }991#else992    #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)                              \993            octonion<type> &            operator /= (::std::complex<type> const & rhs)  \994            {                                                                           \995                using    ::std::valarray;                                               \996                                                                                        \997                valarray<type>    tr(2);                                                \998                                                                                        \999                tr[0] = rhs.real();                                                     \1000                tr[1] = rhs.imag();                                                     \1001                                                                                        \1002                type            mixam = static_cast<type>(1)/(abs(tr).max)();           \1003                                                                                        \1004                tr *= mixam;                                                            \1005                                                                                        \1006                valarray<type>    tt(8);                                                \1007                                                                                        \1008                tt[0] = +a*tr[0]-b*tr[1];                                               \1009                tt[1] = -a*tr[1]+b*tr[0];                                               \1010                tt[2] = +c*tr[0]-d*tr[1];                                               \1011                tt[3] = +c*tr[1]+d*tr[0];                                               \1012                tt[4] = +e*tr[0]-f*tr[1];                                               \1013                tt[5] = +e*tr[1]+f*tr[0];                                               \1014                tt[6] = +g*tr[0]+h*tr[1];                                               \1015                tt[7] = +g*tr[1]+h*tr[0];                                               \1016                                                                                        \1017                tr *= tr;                                                               \1018                                                                                        \1019                tt *= (mixam/tr.sum());                                                 \1020                                                                                        \1021                a = tt[0];                                                              \1022                b = tt[1];                                                              \1023                c = tt[2];                                                              \1024                d = tt[3];                                                              \1025                e = tt[4];                                                              \1026                f = tt[5];                                                              \1027                g = tt[6];                                                              \1028                h = tt[7];                                                              \1029                                                                                        \1030                return(*this);                                                          \1031            }1032#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */1033 1034#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)1035    #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)                                           \1036            octonion<type> &            operator /= (::boost::math::quaternion<type> const & rhs)    \1037            {                                                                                        \1038                using    ::std::valarray;                                                            \1039                using    ::std::abs;                                                                 \1040                                                                                                     \1041                valarray<type>    tr(4);                                                             \1042                                                                                                     \1043                tr[0] = static_cast<type>(rhs.R_component_1());                                      \1044                tr[1] = static_cast<type>(rhs.R_component_2());                                      \1045                tr[2] = static_cast<type>(rhs.R_component_3());                                      \1046                tr[3] = static_cast<type>(rhs.R_component_4());                                      \1047                                                                                                     \1048                type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \1049                                                                                                     \1050                tr *= mixam;                                                                         \1051                                                                                                     \1052                valarray<type>    tt(8);                                                             \1053                                                                                                     \1054                tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                                            \1055                tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                                            \1056                tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                                            \1057                tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                                            \1058                tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];                                            \1059                tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];                                            \1060                tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];                                            \1061                tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];                                            \1062                                                                                                     \1063                tr *= tr;                                                                            \1064                                                                                                     \1065                tt *= (mixam/tr.sum());                                                              \1066                                                                                                     \1067                a = tt[0];                                                                           \1068                b = tt[1];                                                                           \1069                c = tt[2];                                                                           \1070                d = tt[3];                                                                           \1071                e = tt[4];                                                                           \1072                f = tt[5];                                                                           \1073                g = tt[6];                                                                           \1074                h = tt[7];                                                                           \1075                                                                                                     \1076                return(*this);                                                                       \1077            }1078#else1079    #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)                                           \1080            octonion<type> &            operator /= (::boost::math::quaternion<type> const & rhs)    \1081            {                                                                                        \1082                using    ::std::valarray;                                                            \1083                                                                                                     \1084                valarray<type>    tr(4);                                                             \1085                                                                                                     \1086                tr[0] = static_cast<type>(rhs.R_component_1());                                      \1087                tr[1] = static_cast<type>(rhs.R_component_2());                                      \1088                tr[2] = static_cast<type>(rhs.R_component_3());                                      \1089                tr[3] = static_cast<type>(rhs.R_component_4());                                      \1090                                                                                                     \1091                type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \1092                                                                                                     \1093                tr *= mixam;                                                                         \1094                                                                                                     \1095                valarray<type>    tt(8);                                                             \1096                                                                                                     \1097                tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                                            \1098                tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                                            \1099                tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                                            \1100                tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                                            \1101                tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];                                            \1102                tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];                                            \1103                tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];                                            \1104                tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];                                            \1105                                                                                                     \1106                tr *= tr;                                                                            \1107                                                                                                     \1108                tt *= (mixam/tr.sum());                                                              \1109                                                                                                     \1110                a = tt[0];                                                                           \1111                b = tt[1];                                                                           \1112                c = tt[2];                                                                           \1113                d = tt[3];                                                                           \1114                e = tt[4];                                                                           \1115                f = tt[5];                                                                           \1116                g = tt[6];                                                                           \1117                h = tt[7];                                                                           \1118                                                                                                     \1119                return(*this);                                                                       \1120            }1121#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */1122 1123#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)1124    #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)                                           \1125            template<typename X>                                                                     \1126            octonion<type> &            operator /= (octonion<X> const & rhs)                        \1127            {                                                                                        \1128                using    ::std::valarray;                                                            \1129                using    ::std::abs;                                                                 \1130                                                                                                     \1131                valarray<type>    tr(8);                                                             \1132                                                                                                     \1133                tr[0] = static_cast<type>(rhs.R_component_1());                                      \1134                tr[1] = static_cast<type>(rhs.R_component_2());                                      \1135                tr[2] = static_cast<type>(rhs.R_component_3());                                      \1136                tr[3] = static_cast<type>(rhs.R_component_4());                                      \1137                tr[4] = static_cast<type>(rhs.R_component_5());                                      \1138                tr[5] = static_cast<type>(rhs.R_component_6());                                      \1139                tr[6] = static_cast<type>(rhs.R_component_7());                                      \1140                tr[7] = static_cast<type>(rhs.R_component_8());                                      \1141                                                                                                     \1142                type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \1143                                                                                                     \1144                tr *= mixam;                                                                         \1145                                                                                                     \1146                valarray<type>    tt(8);                                                             \1147                                                                                                     \1148                tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7];            \1149                tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6];            \1150                tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5];            \1151                tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4];            \1152                tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];            \1153                tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];            \1154                tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];            \1155                tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];            \1156                                                                                                     \1157                tr *= tr;                                                                            \1158                                                                                                     \1159                tt *= (mixam/tr.sum());                                                              \1160                                                                                                     \1161                a = tt[0];                                                                           \1162                b = tt[1];                                                                           \1163                c = tt[2];                                                                           \1164                d = tt[3];                                                                           \1165                e = tt[4];                                                                           \1166                f = tt[5];                                                                           \1167                g = tt[6];                                                                           \1168                h = tt[7];                                                                           \1169                                                                                                     \1170                return(*this);                                                                       \1171            }1172#else1173    #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)                                           \1174            template<typename X>                                                                     \1175            octonion<type> &            operator /= (octonion<X> const & rhs)                        \1176            {                                                                                        \1177                using    ::std::valarray;                                                            \1178                                                                                                     \1179                valarray<type>    tr(8);                                                             \1180                                                                                                     \1181                tr[0] = static_cast<type>(rhs.R_component_1());                                      \1182                tr[1] = static_cast<type>(rhs.R_component_2());                                      \1183                tr[2] = static_cast<type>(rhs.R_component_3());                                      \1184                tr[3] = static_cast<type>(rhs.R_component_4());                                      \1185                tr[4] = static_cast<type>(rhs.R_component_5());                                      \1186                tr[5] = static_cast<type>(rhs.R_component_6());                                      \1187                tr[6] = static_cast<type>(rhs.R_component_7());                                      \1188                tr[7] = static_cast<type>(rhs.R_component_8());                                      \1189                                                                                                     \1190                type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \1191                                                                                                     \1192                tr *= mixam;                                                                         \1193                                                                                                     \1194                valarray<type>    tt(8);                                                             \1195                                                                                                     \1196                tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7];            \1197                tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6];            \1198                tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5];            \1199                tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4];            \1200                tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];            \1201                tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];            \1202                tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];            \1203                tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];            \1204                                                                                                     \1205                tr *= tr;                                                                            \1206                                                                                                     \1207                tt *= (mixam/tr.sum());                                                              \1208                                                                                                     \1209                a = tt[0];                                                                           \1210                b = tt[1];                                                                           \1211                c = tt[2];                                                                           \1212                d = tt[3];                                                                           \1213                e = tt[4];                                                                           \1214                f = tt[5];                                                                           \1215                g = tt[6];                                                                           \1216                h = tt[7];                                                                           \1217                                                                                                     \1218                return(*this);                                                                       \1219            }1220#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */1221 1222 1223#define    BOOST_OCTONION_MEMBER_ADD_GENERATOR(type)       \1224        BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type)        \1225        BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type)        \1226        BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type)        \1227        BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type)1228 1229#define    BOOST_OCTONION_MEMBER_SUB_GENERATOR(type)       \1230        BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type)        \1231        BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type)        \1232        BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type)        \1233        BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type)1234 1235#define    BOOST_OCTONION_MEMBER_MUL_GENERATOR(type)       \1236        BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type)        \1237        BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type)        \1238        BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type)        \1239        BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type)1240 1241#define    BOOST_OCTONION_MEMBER_DIV_GENERATOR(type)       \1242        BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type)        \1243        BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)        \1244        BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)        \1245        BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)1246 1247#define    BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(type) \1248        BOOST_OCTONION_MEMBER_ADD_GENERATOR(type)          \1249        BOOST_OCTONION_MEMBER_SUB_GENERATOR(type)          \1250        BOOST_OCTONION_MEMBER_MUL_GENERATOR(type)          \1251        BOOST_OCTONION_MEMBER_DIV_GENERATOR(type)1252 1253 1254        template<>1255        class octonion<float>1256        {1257        public:1258 1259            using value_type = float;1260 1261            BOOST_OCTONION_CONSTRUCTOR_GENERATOR(float)1262 1263            // UNtemplated copy constructor1264            octonion(const octonion&) = default;1265 1266            // explicit copy constructors (precision-losing converters)1267 1268            explicit                    octonion(octonion<double> const & a_recopier)1269            {1270                *this = detail::octonion_type_converter<float, double>(a_recopier);1271            }1272 1273            explicit                    octonion(octonion<long double> const & a_recopier)1274            {1275                *this = detail::octonion_type_converter<float, long double>(a_recopier);1276            }1277 1278            // destructor1279            ~octonion() = default;1280 1281            // accessors1282            //1283            // Note:    Like complex number, octonions do have a meaningful notion of "real part",1284            //            but unlike them there is no meaningful notion of "imaginary part".1285            //            Instead there is an "unreal part" which itself is an octonion, and usually1286            //            nothing simpler (as opposed to the complex number case).1287            //            However, for practicality, there are accessors for the other components1288            //            (these are necessary for the templated copy constructor, for instance).1289 1290            BOOST_OCTONION_ACCESSOR_GENERATOR(float)1291 1292            // assignment operators1293 1294            BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(float)1295 1296            // other assignment-related operators1297            //1298            // NOTE:    Octonion multiplication is *NOT* commutative;1299            //            symbolically, "q *= rhs;" means "q = q * rhs;"1300            //            and "q /= rhs;" means "q = q * inverse_of(rhs);";1301            //            octonion multiplication is also *NOT* associative1302 1303            BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(float)1304 1305 1306        protected:1307 1308            BOOST_OCTONION_MEMBER_DATA_GENERATOR(float)1309        };1310 1311 1312        template<>1313        class octonion<double>1314        {1315        public:1316 1317            using value_type = double;1318 1319            BOOST_OCTONION_CONSTRUCTOR_GENERATOR(double)1320 1321            // Untemplated copy constructor1322            octonion(const octonion&) = default;1323 1324            // converting copy constructor1325 1326            explicit                    octonion(octonion<float> const & a_recopier)1327            {1328                *this = detail::octonion_type_converter<double, float>(a_recopier);1329            }1330 1331            // explicit copy constructors (precision-losing converters)1332 1333            explicit                    octonion(octonion<long double> const & a_recopier)1334            {1335                *this = detail::octonion_type_converter<double, long double>(a_recopier);1336            }1337 1338            // destructor1339            // (this is taken care of by the compiler itself)1340 1341            // accessors1342            //1343            // Note:    Like complex number, octonions do have a meaningful notion of "real part",1344            //            but unlike them there is no meaningful notion of "imaginary part".1345            //            Instead there is an "unreal part" which itself is an octonion, and usually1346            //            nothing simpler (as opposed to the complex number case).1347            //            However, for practicality, there are accessors for the other components1348            //            (these are necessary for the templated copy constructor, for instance).1349 1350            BOOST_OCTONION_ACCESSOR_GENERATOR(double)1351 1352            // assignment operators1353 1354            BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(double)1355 1356            // other assignment-related operators1357            //1358            // NOTE:    Octonion multiplication is *NOT* commutative;1359            //            symbolically, "q *= rhs;" means "q = q * rhs;"1360            //            and "q /= rhs;" means "q = q * inverse_of(rhs);";1361            //            octonion multiplication is also *NOT* associative1362 1363            BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(double)1364 1365 1366        protected:1367 1368            BOOST_OCTONION_MEMBER_DATA_GENERATOR(double)1369        };1370 1371 1372        template<>1373        class octonion<long double>1374        {1375        public:1376 1377            using value_type = long double;1378 1379            BOOST_OCTONION_CONSTRUCTOR_GENERATOR(long double)1380 1381            // UNtemplated copy constructor1382            octonion(const octonion&) = default;1383 1384            // converting copy constructor1385 1386            explicit                            octonion(octonion<float> const & a_recopier)1387            {1388                *this = detail::octonion_type_converter<long double, float>(a_recopier);1389            }1390 1391 1392            explicit                            octonion(octonion<double> const & a_recopier)1393            {1394                *this = detail::octonion_type_converter<long double, double>(a_recopier);1395            }1396 1397 1398            // destructor1399            // (this is taken care of by the compiler itself)1400 1401            // accessors1402            //1403            // Note:    Like complex number, octonions do have a meaningful notion of "real part",1404            //            but unlike them there is no meaningful notion of "imaginary part".1405            //            Instead there is an "unreal part" which itself is an octonion, and usually1406            //            nothing simpler (as opposed to the complex number case).1407            //            However, for practicality, there are accessors for the other components1408            //            (these are necessary for the templated copy constructor, for instance).1409 1410            BOOST_OCTONION_ACCESSOR_GENERATOR(long double)1411 1412            // assignment operators1413 1414            BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(long double)1415 1416            // other assignment-related operators1417            //1418            // NOTE:    Octonion multiplication is *NOT* commutative;1419            //            symbolically, "q *= rhs;" means "q = q * rhs;"1420            //            and "q /= rhs;" means "q = q * inverse_of(rhs);";1421            //            octonion multiplication is also *NOT* associative1422 1423            BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(long double)1424 1425 1426        protected:1427 1428            BOOST_OCTONION_MEMBER_DATA_GENERATOR(long double)1429 1430 1431        private:1432 1433        };1434 1435 1436#undef    BOOST_OCTONION_CONSTRUCTOR_GENERATOR1437 1438#undef    BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR1439 1440#undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR1441#undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR1442#undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR1443#undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR1444 1445#undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_11446#undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_21447#undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_31448#undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_41449#undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_11450#undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_21451#undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_31452#undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_41453#undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_11454#undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_21455#undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_31456#undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_41457#undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_11458#undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_21459#undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_31460#undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_41461 1462 1463#undef    BOOST_OCTONION_MEMBER_DATA_GENERATOR1464 1465#undef    BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR1466 1467#undef    BOOST_OCTONION_ACCESSOR_GENERATOR1468 1469 1470        // operators1471 1472#define    BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) \1473        {                                             \1474            octonion<T>    res(lhs);                  \1475            res op##= rhs;                            \1476            return(res);                              \1477        }1478 1479#define    BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op)                                                                              \1480        template<typename T>                                                                                                      \1481        inline octonion<T>                        operator op (T const & lhs, octonion<T> const & rhs)                            \1482        BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)1483 1484#define    BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op)                                                                              \1485        template<typename T>                                                                                                      \1486        inline octonion<T>                        operator op (octonion<T> const & lhs, T const & rhs)                            \1487        BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)1488 1489#define    BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op)                                                                              \1490        template<typename T>                                                                                                      \1491        inline octonion<T>                        operator op (::std::complex<T> const & lhs, octonion<T> const & rhs)            \1492        BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)1493 1494#define    BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op)                                                                              \1495        template<typename T>                                                                                                      \1496        inline octonion<T>                        operator op (octonion<T> const & lhs, ::std::complex<T> const & rhs)            \1497        BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)1498 1499#define    BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op)                                                                              \1500        template<typename T>                                                                                                      \1501        inline octonion<T>                        operator op (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs) \1502        BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)1503 1504#define    BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op)                                                                              \1505        template<typename T>                                                                                                      \1506        inline octonion<T>                        operator op (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs) \1507        BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)1508 1509#define    BOOST_OCTONION_OPERATOR_GENERATOR_4(op)                                                                                \1510        template<typename T>                                                                                                      \1511        inline octonion<T>                        operator op (octonion<T> const & lhs, octonion<T> const & rhs)                  \1512        BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)1513 1514#define    BOOST_OCTONION_OPERATOR_GENERATOR(op)     \1515        BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op)    \1516        BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op)    \1517        BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op)    \1518        BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op)    \1519        BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op)    \1520        BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op)    \1521        BOOST_OCTONION_OPERATOR_GENERATOR_4(op)1522 1523 1524        BOOST_OCTONION_OPERATOR_GENERATOR(+)1525        BOOST_OCTONION_OPERATOR_GENERATOR(-)1526        BOOST_OCTONION_OPERATOR_GENERATOR(*)1527        BOOST_OCTONION_OPERATOR_GENERATOR(/)1528 1529 1530#undef    BOOST_OCTONION_OPERATOR_GENERATOR1531 1532#undef    BOOST_OCTONION_OPERATOR_GENERATOR_1_L1533#undef    BOOST_OCTONION_OPERATOR_GENERATOR_1_R1534#undef    BOOST_OCTONION_OPERATOR_GENERATOR_2_L1535#undef    BOOST_OCTONION_OPERATOR_GENERATOR_2_R1536#undef    BOOST_OCTONION_OPERATOR_GENERATOR_3_L1537#undef    BOOST_OCTONION_OPERATOR_GENERATOR_3_R1538#undef    BOOST_OCTONION_OPERATOR_GENERATOR_41539 1540#undef    BOOST_OCTONION_OPERATOR_GENERATOR_BODY1541 1542 1543        template<typename T>1544        inline octonion<T>                        operator + (octonion<T> const & o)1545        {1546            return(o);1547        }1548 1549 1550        template<typename T>1551        inline octonion<T>                        operator - (octonion<T> const & o)1552        {1553            return(octonion<T>(-o.R_component_1(),-o.R_component_2(),-o.R_component_3(),-o.R_component_4(),-o.R_component_5(),-o.R_component_6(),-o.R_component_7(),-o.R_component_8()));1554        }1555 1556 1557        template<typename T>1558        inline bool                                operator == (T const & lhs, octonion<T> const & rhs)1559        {1560            return(1561                        (rhs.R_component_1() == lhs)&&1562                        (rhs.R_component_2() == static_cast<T>(0))&&1563                        (rhs.R_component_3() == static_cast<T>(0))&&1564                        (rhs.R_component_4() == static_cast<T>(0))&&1565                        (rhs.R_component_5() == static_cast<T>(0))&&1566                        (rhs.R_component_6() == static_cast<T>(0))&&1567                        (rhs.R_component_7() == static_cast<T>(0))&&1568                        (rhs.R_component_8() == static_cast<T>(0))1569                    );1570        }1571 1572 1573        template<typename T>1574        inline bool                                operator == (octonion<T> const & lhs, T const & rhs)1575        {1576            return(1577                        (lhs.R_component_1() == rhs)&&1578                        (lhs.R_component_2() == static_cast<T>(0))&&1579                        (lhs.R_component_3() == static_cast<T>(0))&&1580                        (lhs.R_component_4() == static_cast<T>(0))&&1581                        (lhs.R_component_5() == static_cast<T>(0))&&1582                        (lhs.R_component_6() == static_cast<T>(0))&&1583                        (lhs.R_component_7() == static_cast<T>(0))&&1584                        (lhs.R_component_8() == static_cast<T>(0))1585                    );1586        }1587 1588 1589        template<typename T>1590        inline bool                                operator == (::std::complex<T> const & lhs, octonion<T> const & rhs)1591        {1592            return(1593                        (rhs.R_component_1() == lhs.real())&&1594                        (rhs.R_component_2() == lhs.imag())&&1595                        (rhs.R_component_3() == static_cast<T>(0))&&1596                        (rhs.R_component_4() == static_cast<T>(0))&&1597                        (rhs.R_component_5() == static_cast<T>(0))&&1598                        (rhs.R_component_6() == static_cast<T>(0))&&1599                        (rhs.R_component_7() == static_cast<T>(0))&&1600                        (rhs.R_component_8() == static_cast<T>(0))1601                    );1602        }1603 1604 1605        template<typename T>1606        inline bool                                operator == (octonion<T> const & lhs, ::std::complex<T> const & rhs)1607        {1608            return(1609                        (lhs.R_component_1() == rhs.real())&&1610                        (lhs.R_component_2() == rhs.imag())&&1611                        (lhs.R_component_3() == static_cast<T>(0))&&1612                        (lhs.R_component_4() == static_cast<T>(0))&&1613                        (lhs.R_component_5() == static_cast<T>(0))&&1614                        (lhs.R_component_6() == static_cast<T>(0))&&1615                        (lhs.R_component_7() == static_cast<T>(0))&&1616                        (lhs.R_component_8() == static_cast<T>(0))1617                    );1618        }1619 1620 1621        template<typename T>1622        inline bool                                operator == (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs)1623        {1624            return(1625                        (rhs.R_component_1() == lhs.R_component_1())&&1626                        (rhs.R_component_2() == lhs.R_component_2())&&1627                        (rhs.R_component_3() == lhs.R_component_3())&&1628                        (rhs.R_component_4() == lhs.R_component_4())&&1629                        (rhs.R_component_5() == static_cast<T>(0))&&1630                        (rhs.R_component_6() == static_cast<T>(0))&&1631                        (rhs.R_component_7() == static_cast<T>(0))&&1632                        (rhs.R_component_8() == static_cast<T>(0))1633                    );1634        }1635 1636 1637        template<typename T>1638        inline bool                                operator == (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs)1639        {1640            return(1641                        (lhs.R_component_1() == rhs.R_component_1())&&1642                        (lhs.R_component_2() == rhs.R_component_2())&&1643                        (lhs.R_component_3() == rhs.R_component_3())&&1644                        (lhs.R_component_4() == rhs.R_component_4())&&1645                        (lhs.R_component_5() == static_cast<T>(0))&&1646                        (lhs.R_component_6() == static_cast<T>(0))&&1647                        (lhs.R_component_7() == static_cast<T>(0))&&1648                        (lhs.R_component_8() == static_cast<T>(0))1649                    );1650        }1651 1652 1653        template<typename T>1654        inline bool                                operator == (octonion<T> const & lhs, octonion<T> const & rhs)1655        {1656            return(1657                        (rhs.R_component_1() == lhs.R_component_1())&&1658                        (rhs.R_component_2() == lhs.R_component_2())&&1659                        (rhs.R_component_3() == lhs.R_component_3())&&1660                        (rhs.R_component_4() == lhs.R_component_4())&&1661                        (rhs.R_component_5() == lhs.R_component_5())&&1662                        (rhs.R_component_6() == lhs.R_component_6())&&1663                        (rhs.R_component_7() == lhs.R_component_7())&&1664                        (rhs.R_component_8() == lhs.R_component_8())1665                    );1666        }1667 1668 1669#define    BOOST_OCTONION_NOT_EQUAL_GENERATOR \1670        {                                     \1671            return(!(lhs == rhs));            \1672        }1673 1674        template<typename T>1675        inline bool                                operator != (T const & lhs, octonion<T> const & rhs)1676        BOOST_OCTONION_NOT_EQUAL_GENERATOR1677 1678        template<typename T>1679        inline bool                                operator != (octonion<T> const & lhs, T const & rhs)1680        BOOST_OCTONION_NOT_EQUAL_GENERATOR1681 1682        template<typename T>1683        inline bool                                operator != (::std::complex<T> const & lhs, octonion<T> const & rhs)1684        BOOST_OCTONION_NOT_EQUAL_GENERATOR1685 1686        template<typename T>1687        inline bool                                operator != (octonion<T> const & lhs, ::std::complex<T> const & rhs)1688        BOOST_OCTONION_NOT_EQUAL_GENERATOR1689 1690        template<typename T>1691        inline bool                                operator != (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs)1692        BOOST_OCTONION_NOT_EQUAL_GENERATOR1693 1694        template<typename T>1695        inline bool                                operator != (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs)1696        BOOST_OCTONION_NOT_EQUAL_GENERATOR1697 1698        template<typename T>1699        inline bool                                operator != (octonion<T> const & lhs, octonion<T> const & rhs)1700        BOOST_OCTONION_NOT_EQUAL_GENERATOR1701 1702    #undef    BOOST_OCTONION_NOT_EQUAL_GENERATOR1703 1704        // LCOV_EXCL_START1705        // Something like 2,100 lines of input-streaming up to line 3,800 and beyond.1706 1707        // Note:    the default values in the constructors of the complex and quaternions make for1708        //            a very complex and ambiguous situation; we have made choices to disambiguate.1709        template<typename T, typename charT, class traits>1710        ::std::basic_istream<charT,traits> &    operator >> (    ::std::basic_istream<charT,traits> & is,1711                                                                octonion<T> & o)1712        {1713#ifdef     BOOST_NO_STD_LOCALE1714#else1715            const ::std::ctype<charT> & ct = ::std::use_facet< ::std::ctype<charT> >(is.getloc());1716#endif /* BOOST_NO_STD_LOCALE */1717 1718            T    a = T();1719            T    b = T();1720            T    c = T();1721            T    d = T();1722            T    e = T();1723            T    f = T();1724            T    g = T();1725            T    h = T();1726 1727            ::std::complex<T>    u = ::std::complex<T>();1728            ::std::complex<T>    v = ::std::complex<T>();1729            ::std::complex<T>    x = ::std::complex<T>();1730            ::std::complex<T>    y = ::std::complex<T>();1731 1732            ::boost::math::quaternion<T>    p = ::boost::math::quaternion<T>();1733            ::boost::math::quaternion<T>    q = ::boost::math::quaternion<T>();1734 1735            charT    ch = charT();1736            char    cc;1737 1738            is >> ch;                                        // get the first lexeme1739 1740            if    (!is.good())    goto finish;1741 1742#ifdef    BOOST_NO_STD_LOCALE1743            cc = ch;1744#else1745            cc = ct.narrow(ch, char());1746#endif /* BOOST_NO_STD_LOCALE */1747 1748            if    (cc == '(')                            // read "("1749            {1750                is >> ch;                                    // get the second lexeme1751 1752                if    (!is.good())    goto finish;1753 1754#ifdef    BOOST_NO_STD_LOCALE1755                cc = ch;1756#else1757                cc = ct.narrow(ch, char());1758#endif /* BOOST_NO_STD_LOCALE */1759 1760                if    (cc == '(')                                // read "(("1761                {1762                    is >> ch;                                    // get the third lexeme1763 1764                    if    (!is.good())    goto finish;1765 1766#ifdef    BOOST_NO_STD_LOCALE1767                    cc = ch;1768#else1769                    cc = ct.narrow(ch, char());1770#endif /* BOOST_NO_STD_LOCALE */1771 1772                    if    (cc == '(')                                // read "((("1773                    {1774                        is.putback(ch);1775 1776                        is >> u;                                // read "((u"1777 1778                        if    (!is.good())    goto finish;1779 1780                        is >> ch;                                // get the next lexeme1781 1782                        if    (!is.good())    goto finish;1783 1784#ifdef    BOOST_NO_STD_LOCALE1785                        cc = ch;1786#else1787                        cc = ct.narrow(ch, char());1788#endif /* BOOST_NO_STD_LOCALE */1789 1790                        if        (cc == ')')                        // read "((u)"1791                        {1792                            is >> ch;                                // get the next lexeme1793 1794                            if    (!is.good())    goto finish;1795 1796#ifdef    BOOST_NO_STD_LOCALE1797                            cc = ch;1798#else1799                            cc = ct.narrow(ch, char());1800#endif /* BOOST_NO_STD_LOCALE */1801 1802                            if        (cc == ')')                        // format: (((a))), (((a,b)))1803                            {1804                                o = octonion<T>(u);1805                            }1806                            else if    (cc == ',')                        // read "((u),"1807                            {1808                                p = ::boost::math::quaternion<T>(u);1809 1810                                is >> q;                                // read "((u),q"1811 1812                                if    (!is.good())    goto finish;1813 1814                                is >> ch;                                // get the next lexeme1815 1816                                if    (!is.good())    goto finish;1817 1818#ifdef    BOOST_NO_STD_LOCALE1819                                cc = ch;1820#else1821                                cc = ct.narrow(ch, char());1822#endif /* BOOST_NO_STD_LOCALE */1823 1824                                if        (cc == ')')                        // format: (((a)),q), (((a,b)),q)1825                                {1826                                    o = octonion<T>(p,q);1827                                }1828                                else                                    // error1829                                {1830                                    is.setstate(::std::ios_base::failbit);1831                                }1832                            }1833                            else                                    // error1834                            {1835                                is.setstate(::std::ios_base::failbit);1836                            }1837                        }1838                        else if    (cc ==',')                        // read "((u,"1839                        {1840                            is >> v;                                // read "((u,v"1841 1842                            if    (!is.good())    goto finish;1843 1844                            is >> ch;                                // get the next lexeme1845 1846                            if    (!is.good())    goto finish;1847 1848#ifdef    BOOST_NO_STD_LOCALE1849                            cc = ch;1850#else1851                            cc = ct.narrow(ch, char());1852#endif /* BOOST_NO_STD_LOCALE */1853 1854                            if        (cc == ')')                        // read "((u,v)"1855                            {1856                                p = ::boost::math::quaternion<T>(u,v);1857 1858                                is >> ch;                                // get the next lexeme1859 1860                                if    (!is.good())    goto finish;1861 1862#ifdef    BOOST_NO_STD_LOCALE1863                                cc = ch;1864#else1865                                cc = ct.narrow(ch, char());1866#endif /* BOOST_NO_STD_LOCALE */1867 1868                                if        (cc == ')')                        // format: (((a),v)), (((a,b),v))1869                                {1870                                    o = octonion<T>(p);1871                                }1872                                else if    (cc == ',')                        // read "((u,v),"1873                                {1874                                    is >> q;                                // read "(p,q"1875 1876                                    if    (!is.good())    goto finish;1877 1878                                    is >> ch;                                // get the next lexeme1879 1880                                    if    (!is.good())    goto finish;1881 1882#ifdef    BOOST_NO_STD_LOCALE1883                                    cc = ch;1884#else1885                                    cc = ct.narrow(ch, char());1886#endif /* BOOST_NO_STD_LOCALE */1887 1888                                    if        (cc == ')')                        // format: (((a),v),q), (((a,b),v),q)1889                                    {1890                                        o = octonion<T>(p,q);1891                                    }1892                                    else                                    // error1893                                    {1894                                        is.setstate(::std::ios_base::failbit);1895                                    }1896                                }1897                                else                                    // error1898                                {1899                                    is.setstate(::std::ios_base::failbit);1900                                }1901                            }1902                            else                                    // error1903                            {1904                                is.setstate(::std::ios_base::failbit);1905                            }1906                        }1907                        else                                    // error1908                        {1909                            is.setstate(::std::ios_base::failbit);1910                        }1911                    }1912                    else                                        // read "((a"1913                    {1914                        is.putback(ch);1915 1916                        is >> a;                                    // we extract the first component1917 1918                        if    (!is.good())    goto finish;1919 1920                        is >> ch;                                    // get the next lexeme1921 1922                        if    (!is.good())    goto finish;1923 1924#ifdef    BOOST_NO_STD_LOCALE1925                        cc = ch;1926#else1927                        cc = ct.narrow(ch, char());1928#endif /* BOOST_NO_STD_LOCALE */1929 1930                        if        (cc == ')')                            // read "((a)"1931                        {1932                            is >> ch;                                    // get the next lexeme1933 1934                            if    (!is.good())    goto finish;1935 1936#ifdef    BOOST_NO_STD_LOCALE1937                            cc = ch;1938#else1939                            cc = ct.narrow(ch, char());1940#endif /* BOOST_NO_STD_LOCALE */1941 1942                            if        (cc == ')')                            // read "((a))"1943                            {1944                                o = octonion<T>(a);1945                            }1946                            else if    (cc == ',')                            // read "((a),"1947                            {1948                                is >> ch;                                    // get the next lexeme1949 1950                                if    (!is.good())    goto finish;1951 1952#ifdef    BOOST_NO_STD_LOCALE1953                                cc = ch;1954#else1955                                cc = ct.narrow(ch, char());1956#endif /* BOOST_NO_STD_LOCALE */1957 1958                                if        (cc == '(')                            // read "((a),("1959                                {1960                                    is >> ch;                                    // get the next lexeme1961 1962                                    if    (!is.good())    goto finish;1963 1964#ifdef    BOOST_NO_STD_LOCALE1965                                    cc = ch;1966#else1967                                    cc = ct.narrow(ch, char());1968#endif /* BOOST_NO_STD_LOCALE */1969 1970                                    if        (cc == '(')                            // read "((a),(("1971                                    {1972                                        is.putback(ch);1973 1974                                        is.putback(ch);                                // we backtrack twice, with the same value!1975 1976                                        is >> q;                                    // read "((a),q"1977 1978                                        if    (!is.good())    goto finish;1979 1980                                        is >> ch;                                    // get the next lexeme1981 1982                                        if    (!is.good())    goto finish;1983 1984#ifdef    BOOST_NO_STD_LOCALE1985                                        cc = ch;1986#else1987                                        cc = ct.narrow(ch, char());1988#endif /* BOOST_NO_STD_LOCALE */1989 1990                                        if        (cc == ')')                            // read "((a),q)"1991                                        {1992                                            p = ::boost::math::quaternion<T>(a);1993 1994                                            o = octonion<T>(p,q);1995                                        }1996                                        else                                        // error1997                                        {1998                                            is.setstate(::std::ios_base::failbit);1999                                        }2000                                    }2001                                    else                                        // read "((a),(c" or "((a),(e"2002                                    {2003                                        is.putback(ch);2004 2005                                        is >> c;2006 2007                                        if    (!is.good())    goto finish;2008 2009                                        is >> ch;                                    // get the next lexeme2010 2011                                        if    (!is.good())    goto finish;2012 2013#ifdef    BOOST_NO_STD_LOCALE2014                                        cc = ch;2015#else2016                                        cc = ct.narrow(ch, char());2017#endif /* BOOST_NO_STD_LOCALE */2018 2019                                        if        (cc == ')')                            // read "((a),(c)" (ambiguity resolution)2020                                        {2021                                            is >> ch;                                    // get the next lexeme2022 2023                                            if    (!is.good())    goto finish;2024 2025#ifdef    BOOST_NO_STD_LOCALE2026                                            cc = ch;2027#else2028                                            cc = ct.narrow(ch, char());2029#endif /* BOOST_NO_STD_LOCALE */2030 2031                                            if        (cc == ')')                        // read "((a),(c))"2032                                            {2033                                                o = octonion<T>(a,b,c);2034                                            }2035                                            else if    (cc == ',')                        // read "((a),(c),"2036                                            {2037                                                u = ::std::complex<T>(a);2038 2039                                                v = ::std::complex<T>(c);2040 2041                                                is >> x;                            // read "((a),(c),x"2042 2043                                                if    (!is.good())    goto finish;2044 2045                                                is >> ch;                                // get the next lexeme2046 2047                                                if    (!is.good())    goto finish;2048 2049#ifdef    BOOST_NO_STD_LOCALE2050                                                cc = ch;2051#else2052                                                cc = ct.narrow(ch, char());2053#endif /* BOOST_NO_STD_LOCALE */2054 2055                                                if        (cc == ')')                        // read "((a),(c),x)"2056                                                {2057                                                    o = octonion<T>(u,v,x);2058                                                }2059                                                else if    (cc == ',')                        // read "((a),(c),x,"2060                                                {2061                                                    is >> y;                                // read "((a),(c),x,y"2062 2063                                                    if    (!is.good())    goto finish;2064 2065                                                    is >> ch;                                // get the next lexeme2066 2067                                                    if    (!is.good())    goto finish;2068 2069#ifdef    BOOST_NO_STD_LOCALE2070                                                    cc = ch;2071#else2072                                                    cc = ct.narrow(ch, char());2073#endif /* BOOST_NO_STD_LOCALE */2074 2075                                                    if        (cc == ')')                        // read "((a),(c),x,y)"2076                                                    {2077                                                        o = octonion<T>(u,v,x,y);2078                                                    }2079                                                    else                                    // error2080                                                    {2081                                                        is.setstate(::std::ios_base::failbit);2082                                                    }2083                                                }2084                                                else                                    // error2085                                                {2086                                                    is.setstate(::std::ios_base::failbit);2087                                                }2088                                            }2089                                            else                                    // error2090                                            {2091                                                is.setstate(::std::ios_base::failbit);2092                                            }2093                                        }2094                                        else if    (cc == ',')                            // read "((a),(c," or "((a),(e,"2095                                        {2096                                            is >> ch;                                // get the next lexeme2097 2098                                            if    (!is.good())    goto finish;2099 2100#ifdef    BOOST_NO_STD_LOCALE2101                                            cc = ch;2102#else2103                                            cc = ct.narrow(ch, char());2104#endif /* BOOST_NO_STD_LOCALE */2105 2106                                            if        (cc == '(')                        // read "((a),(e,(" (ambiguity resolution)2107                                            {2108                                                p = ::boost::math::quaternion<T>(a);2109 2110                                                x = ::std::complex<T>(c);                // "c" was actually "e"2111 2112                                                is.putback(ch);                            // we can only backtrace once2113 2114                                                is >> y;                                // read "((a),(e,y"2115 2116                                                if    (!is.good())    goto finish;2117 2118                                                is >> ch;                                // get the next lexeme2119 2120#ifdef    BOOST_NO_STD_LOCALE2121                                                cc = ch;2122#else2123                                                cc = ct.narrow(ch, char());2124#endif /* BOOST_NO_STD_LOCALE */2125 2126                                                if        (cc == ')')                        // read "((a),(e,y)"2127                                                {2128                                                    q = ::boost::math::quaternion<T>(x,y);2129 2130                                                    is >> ch;                                // get the next lexeme2131 2132#ifdef    BOOST_NO_STD_LOCALE2133                                                    cc = ch;2134#else2135                                                    cc = ct.narrow(ch, char());2136#endif /* BOOST_NO_STD_LOCALE */2137 2138                                                    if        (cc == ')')                        // read "((a),(e,y))"2139                                                    {2140                                                        o = octonion<T>(p,q);2141                                                    }2142                                                    else                                    // error2143                                                    {2144                                                        is.setstate(::std::ios_base::failbit);2145                                                    }2146                                                }2147                                                else                                    // error2148                                                {2149                                                    is.setstate(::std::ios_base::failbit);2150                                                }2151                                            }2152                                            else                                    // read "((a),(c,d" or "((a),(e,f"2153                                            {2154                                                is.putback(ch);2155 2156                                                is >> d;2157 2158                                                if    (!is.good())    goto finish;2159 2160                                                is >> ch;                                // get the next lexeme2161 2162                                                if    (!is.good())    goto finish;2163 2164#ifdef    BOOST_NO_STD_LOCALE2165                                                cc = ch;2166#else2167                                                cc = ct.narrow(ch, char());2168#endif /* BOOST_NO_STD_LOCALE */2169 2170                                                if        (cc == ')')                        // read "((a),(c,d)" (ambiguity resolution)2171                                                {2172                                                    is >> ch;                                // get the next lexeme2173 2174                                                    if    (!is.good())    goto finish;2175 2176#ifdef    BOOST_NO_STD_LOCALE2177                                                    cc = ch;2178#else2179                                                    cc = ct.narrow(ch, char());2180#endif /* BOOST_NO_STD_LOCALE */2181 2182                                                    if        (cc == ')')                        // read "((a),(c,d))"2183                                                    {2184                                                        o = octonion<T>(a,b,c,d);2185                                                    }2186                                                    else if    (cc == ',')                        // read "((a),(c,d),"2187                                                    {2188                                                        u = ::std::complex<T>(a);2189 2190                                                        v = ::std::complex<T>(c,d);2191 2192                                                        is >> x;                                // read "((a),(c,d),x"2193 2194                                                        if    (!is.good())    goto finish;2195 2196                                                        is >> ch;                                // get the next lexeme2197 2198                                                        if    (!is.good())    goto finish;2199 2200#ifdef    BOOST_NO_STD_LOCALE2201                                                        cc = ch;2202#else2203                                                        cc = ct.narrow(ch, char());2204#endif /* BOOST_NO_STD_LOCALE */2205 2206                                                        if        (cc == ')')                        // read "((a),(c,d),x)"2207                                                        {2208                                                            o = octonion<T>(u,v,x);2209                                                        }2210                                                        else if    (cc == ',')                        // read "((a),(c,d),x,"2211                                                        {2212                                                            is >> y;                                // read "((a),(c,d),x,y"2213 2214                                                            if    (!is.good())    goto finish;2215 2216                                                            is >> ch;                                // get the next lexeme2217 2218                                                            if    (!is.good())    goto finish;2219 2220#ifdef    BOOST_NO_STD_LOCALE2221                                                            cc = ch;2222#else2223                                                            cc = ct.narrow(ch, char());2224#endif /* BOOST_NO_STD_LOCALE */2225 2226                                                            if        (cc == ')')                        // read "((a),(c,d),x,y)"2227                                                            {2228                                                                o = octonion<T>(u,v,x,y);2229                                                            }2230                                                            else                                    // error2231                                                            {2232                                                                is.setstate(::std::ios_base::failbit);2233                                                            }2234                                                        }2235                                                        else                                    // error2236                                                        {2237                                                            is.setstate(::std::ios_base::failbit);2238                                                        }2239                                                    }2240                                                    else                                    // error2241                                                    {2242                                                        is.setstate(::std::ios_base::failbit);2243                                                    }2244                                                }2245                                                else if    (cc == ',')                        // read "((a),(e,f," (ambiguity resolution)2246                                                {2247                                                    p = ::boost::math::quaternion<T>(a);2248 2249                                                    is >> g;                                // read "((a),(e,f,g" (too late to backtrack)2250 2251                                                    if    (!is.good())    goto finish;2252 2253                                                    is >> ch;                                // get the next lexeme2254 2255                                                    if    (!is.good())    goto finish;2256 2257#ifdef    BOOST_NO_STD_LOCALE2258                                                    cc = ch;2259#else2260                                                    cc = ct.narrow(ch, char());2261#endif /* BOOST_NO_STD_LOCALE */2262 2263                                                    if        (cc == ')')                        // read "((a),(e,f,g)"2264                                                    {2265                                                        q = ::boost::math::quaternion<T>(c,d,g);        // "c" was actually "e", and "d" was actually "f"2266 2267                                                        is >> ch;                                // get the next lexeme2268 2269                                                        if    (!is.good())    goto finish;2270 2271#ifdef    BOOST_NO_STD_LOCALE2272                                                        cc = ch;2273#else2274                                                        cc = ct.narrow(ch, char());2275#endif /* BOOST_NO_STD_LOCALE */2276 2277                                                        if        (cc == ')')                        // read "((a),(e,f,g))"2278                                                        {2279                                                            o = octonion<T>(p,q);2280                                                        }2281                                                        else                                    // error2282                                                        {2283                                                            is.setstate(::std::ios_base::failbit);2284                                                        }2285                                                    }2286                                                    else if    (cc == ',')                        // read "((a),(e,f,g,"2287                                                    {2288                                                        is >> h;                                // read "((a),(e,f,g,h"2289 2290                                                        if    (!is.good())    goto finish;2291 2292                                                        is >> ch;                                // get the next lexeme2293 2294                                                        if    (!is.good())    goto finish;2295 2296#ifdef    BOOST_NO_STD_LOCALE2297                                                        cc = ch;2298#else2299                                                        cc = ct.narrow(ch, char());2300#endif /* BOOST_NO_STD_LOCALE */2301 2302                                                        if        (cc == ')')                        // read "((a),(e,f,g,h)"2303                                                        {2304                                                            q = ::boost::math::quaternion<T>(c,d,g,h);    // "c" was actually "e", and "d" was actually "f"2305 2306                                                            is >> ch;                                // get the next lexeme2307 2308                                                            if    (!is.good())    goto finish;2309 2310#ifdef    BOOST_NO_STD_LOCALE2311                                                            cc = ch;2312#else2313                                                            cc = ct.narrow(ch, char());2314#endif /* BOOST_NO_STD_LOCALE */2315 2316                                                            if        (cc == ')')                        // read "((a),(e,f,g,h))"2317                                                            {2318                                                                o = octonion<T>(p,q);2319                                                            }2320                                                            else                                    // error2321                                                            {2322                                                                is.setstate(::std::ios_base::failbit);2323                                                            }2324                                                        }2325                                                        else                                    // error2326                                                        {2327                                                            is.setstate(::std::ios_base::failbit);2328                                                        }2329                                                    }2330                                                    else                                    // error2331                                                    {2332                                                        is.setstate(::std::ios_base::failbit);2333                                                    }2334                                                }2335                                                else                                    // error2336                                                {2337                                                    is.setstate(::std::ios_base::failbit);2338                                                }2339                                            }2340                                        }2341                                        else                                        // error2342                                        {2343                                            is.setstate(::std::ios_base::failbit);2344                                        }2345                                    }2346                                }2347                                else                                        // read "((a),c" (ambiguity resolution)2348                                {2349                                    is.putback(ch);2350 2351                                    is >> c;                                    // we extract the third component2352 2353                                    if    (!is.good())    goto finish;2354 2355                                    is >> ch;                                    // get the next lexeme2356 2357                                    if    (!is.good())    goto finish;2358 2359#ifdef    BOOST_NO_STD_LOCALE2360                                    cc = ch;2361#else2362                                    cc = ct.narrow(ch, char());2363#endif /* BOOST_NO_STD_LOCALE */2364 2365                                    if        (cc == ')')                            // read "((a),c)"2366                                    {2367                                        o = octonion<T>(a,b,c);2368                                    }2369                                    else if    (cc == ',')                            // read "((a),c,"2370                                    {2371                                        is >> x;                                    // read "((a),c,x"2372 2373                                        if    (!is.good())    goto finish;2374 2375                                        is >> ch;                                    // get the next lexeme2376 2377                                        if    (!is.good())    goto finish;2378 2379#ifdef    BOOST_NO_STD_LOCALE2380                                        cc = ch;2381#else2382                                        cc = ct.narrow(ch, char());2383#endif /* BOOST_NO_STD_LOCALE */2384 2385                                        if        (cc == ')')                            // read "((a),c,x)"2386                                        {2387                                            o = octonion<T>(a,b,c,d,x.real(),x.imag());2388                                        }2389                                        else if    (cc == ',')                            // read "((a),c,x,"2390                                        {2391                                            is >> y;if    (!is.good())    goto finish;        // read "((a),c,x,y"2392 2393                                            is >> ch;                                    // get the next lexeme2394 2395                                            if    (!is.good())    goto finish;2396 2397#ifdef    BOOST_NO_STD_LOCALE2398                                            cc = ch;2399#else2400                                            cc = ct.narrow(ch, char());2401#endif /* BOOST_NO_STD_LOCALE */2402 2403                                            if        (cc == ')')                            // read "((a),c,x,y)"2404                                            {2405                                                o = octonion<T>(a,b,c,d,x.real(),x.imag(),y.real(),y.imag());2406                                            }2407                                            else                                        // error2408                                            {2409                                                is.setstate(::std::ios_base::failbit);2410                                            }2411                                        }2412                                        else                                        // error2413                                        {2414                                            is.setstate(::std::ios_base::failbit);2415                                        }2416                                    }2417                                    else                                        // error2418                                    {2419                                        is.setstate(::std::ios_base::failbit);2420                                    }2421                                }2422                            }2423                            else                                        // error2424                            {2425                                is.setstate(::std::ios_base::failbit);2426                            }2427                        }2428                        else if    (cc ==',')                            // read "((a,"2429                        {2430                            is >> ch;                                    // get the next lexeme2431 2432                            if    (!is.good())    goto finish;2433 2434#ifdef    BOOST_NO_STD_LOCALE2435                            cc = ch;2436#else2437                            cc = ct.narrow(ch, char());2438#endif /* BOOST_NO_STD_LOCALE */2439 2440                            if        (cc == '(')                            // read "((a,("2441                            {2442                                u = ::std::complex<T>(a);2443 2444                                is.putback(ch);                                // can only backtrack so much2445 2446                                is >> v;                                    // read "((a,v"2447 2448                                if    (!is.good())    goto finish;2449 2450                                is >> ch;                                    // get the next lexeme2451 2452                                if    (!is.good())    goto finish;2453 2454#ifdef    BOOST_NO_STD_LOCALE2455                                cc = ch;2456#else2457                                cc = ct.narrow(ch, char());2458#endif /* BOOST_NO_STD_LOCALE */2459 2460                                if        (cc == ')')                            // read "((a,v)"2461                                {2462                                    is >> ch;                                    // get the next lexeme2463 2464                                    if    (!is.good())    goto finish;2465 2466#ifdef    BOOST_NO_STD_LOCALE2467                                    cc = ch;2468#else2469                                    cc = ct.narrow(ch, char());2470#endif /* BOOST_NO_STD_LOCALE */2471 2472                                    if        (cc == ')')                            // read "((a,v))"2473                                    {2474                                        o = octonion<T>(u,v);2475                                    }2476                                    else if    (cc == ',')                            // read "((a,v),"2477                                    {2478                                        p = ::boost::math::quaternion<T>(u,v);2479 2480                                        is >> q;                                    // read "((a,v),q"2481 2482                                        if    (!is.good())    goto finish;2483 2484                                        is >> ch;                                    // get the next lexeme2485 2486                                        if    (!is.good())    goto finish;2487 2488#ifdef    BOOST_NO_STD_LOCALE2489                                        cc = ch;2490#else2491                                        cc = ct.narrow(ch, char());2492#endif /* BOOST_NO_STD_LOCALE */2493 2494                                        if        (cc == ')')                            // read "((a,v),q)"2495                                        {2496                                            o = octonion<T>(p,q);2497                                        }2498                                        else                                        // error2499                                        {2500                                            is.setstate(::std::ios_base::failbit);2501                                        }2502                                    }2503                                    else                                        // error2504                                    {2505                                        is.setstate(::std::ios_base::failbit);2506                                    }2507                                }2508                                else                                        // error2509                                {2510                                    is.setstate(::std::ios_base::failbit);2511                                }2512                            }2513                            else2514                            {2515                                is.putback(ch);2516 2517                                is >> b;                                    // read "((a,b"2518 2519                                if    (!is.good())    goto finish;2520 2521                                is >> ch;                                    // get the next lexeme2522 2523                                if    (!is.good())    goto finish;2524 2525#ifdef    BOOST_NO_STD_LOCALE2526                                cc = ch;2527#else2528                                cc = ct.narrow(ch, char());2529#endif /* BOOST_NO_STD_LOCALE */2530 2531                                if        (cc == ')')                            // read "((a,b)"2532                                {2533                                    is >> ch;                                    // get the next lexeme2534 2535                                    if    (!is.good())    goto finish;2536 2537#ifdef    BOOST_NO_STD_LOCALE2538                                    cc = ch;2539#else2540                                    cc = ct.narrow(ch, char());2541#endif /* BOOST_NO_STD_LOCALE */2542 2543                                    if        (cc == ')')                            // read "((a,b))"2544                                    {2545                                        o = octonion<T>(a,b);2546                                    }2547                                    else if    (cc == ',')                            // read "((a,b),"2548                                    {2549                                        is >> ch;                                    // get the next lexeme2550 2551                                        if    (!is.good())    goto finish;2552 2553#ifdef    BOOST_NO_STD_LOCALE2554                                        cc = ch;2555#else2556                                        cc = ct.narrow(ch, char());2557#endif /* BOOST_NO_STD_LOCALE */2558 2559                                        if        (cc == '(')                            // read "((a,b),("2560                                        {2561                                            is >> ch;                                    // get the next lexeme2562 2563                                            if    (!is.good())    goto finish;2564 2565#ifdef    BOOST_NO_STD_LOCALE2566                                            cc = ch;2567#else2568                                            cc = ct.narrow(ch, char());2569#endif /* BOOST_NO_STD_LOCALE */2570 2571                                            if        (cc == '(')                            // read "((a,b),(("2572                                            {2573                                                p = ::boost::math::quaternion<T>(a,b);2574 2575                                                is.putback(ch);2576 2577                                                is.putback(ch);                            // we backtrack twice, with the same value2578 2579                                                is >> q;                                // read "((a,b),q"2580 2581                                                if    (!is.good())    goto finish;2582 2583                                                is >> ch;                                    // get the next lexeme2584 2585                                                if    (!is.good())    goto finish;2586 2587#ifdef    BOOST_NO_STD_LOCALE2588                                                cc = ch;2589#else2590                                                cc = ct.narrow(ch, char());2591#endif /* BOOST_NO_STD_LOCALE */2592 2593                                                if        (cc == ')')                            // read "((a,b),q)"2594                                                {2595                                                    o = octonion<T>(p,q);2596                                                }2597                                                else                                        // error2598                                                {2599                                                    is.setstate(::std::ios_base::failbit);2600                                                }2601                                            }2602                                            else                                        // read "((a,b),(c" or "((a,b),(e"2603                                            {2604                                                is.putback(ch);2605 2606                                                is >> c;2607 2608                                                if    (!is.good())    goto finish;2609 2610                                                is >> ch;                                    // get the next lexeme2611 2612                                                if    (!is.good())    goto finish;2613 2614#ifdef    BOOST_NO_STD_LOCALE2615                                                cc = ch;2616#else2617                                                cc = ct.narrow(ch, char());2618#endif /* BOOST_NO_STD_LOCALE */2619 2620                                                if        (cc == ')')                            // read "((a,b),(c)" (ambiguity resolution)2621                                                {2622                                                    is >> ch;                                    // get the next lexeme2623 2624                                                    if    (!is.good())    goto finish;2625 2626#ifdef    BOOST_NO_STD_LOCALE2627                                                    cc = ch;2628#else2629                                                    cc = ct.narrow(ch, char());2630#endif /* BOOST_NO_STD_LOCALE */2631 2632                                                    if        (cc == ')')                            // read "((a,b),(c))"2633                                                    {2634                                                        o = octonion<T>(a,b,c);2635                                                    }2636                                                    else if    (cc == ',')                            // read "((a,b),(c),"2637                                                    {2638                                                        u = ::std::complex<T>(a,b);2639 2640                                                        v = ::std::complex<T>(c);2641 2642                                                        is >> x;                                    // read "((a,b),(c),x"2643 2644                                                        if    (!is.good())    goto finish;2645 2646                                                        is >> ch;                                    // get the next lexeme2647 2648                                                        if    (!is.good())    goto finish;2649 2650#ifdef    BOOST_NO_STD_LOCALE2651                                                        cc = ch;2652#else2653                                                        cc = ct.narrow(ch, char());2654#endif /* BOOST_NO_STD_LOCALE */2655 2656                                                        if        (cc == ')')                            // read "((a,b),(c),x)"2657                                                        {2658                                                            o = octonion<T>(u,v,x);2659                                                        }2660                                                        else if    (cc == ',')                            // read "((a,b),(c),x,"2661                                                        {2662                                                            is >> y;                                    // read "((a,b),(c),x,y"2663 2664                                                            if    (!is.good())    goto finish;2665 2666                                                            is >> ch;                                    // get the next lexeme2667 2668                                                            if    (!is.good())    goto finish;2669 2670#ifdef    BOOST_NO_STD_LOCALE2671                                                            cc = ch;2672#else2673                                                            cc = ct.narrow(ch, char());2674#endif /* BOOST_NO_STD_LOCALE */2675 2676                                                            if        (cc == ')')                            // read "((a,b),(c),x,y)"2677                                                            {2678                                                                o = octonion<T>(u,v,x,y);2679                                                            }2680                                                            else                                        // error2681                                                            {2682                                                                is.setstate(::std::ios_base::failbit);2683                                                            }2684                                                        }2685                                                        else                                        // error2686                                                        {2687                                                            is.setstate(::std::ios_base::failbit);2688                                                        }2689                                                    }2690                                                    else                                        // error2691                                                    {2692                                                        is.setstate(::std::ios_base::failbit);2693                                                    }2694                                                }2695                                                else if    (cc == ',')                            // read "((a,b),(c," or "((a,b),(e,"2696                                                {2697                                                    is >> ch;                                    // get the next lexeme2698 2699                                                    if    (!is.good())    goto finish;2700 2701#ifdef    BOOST_NO_STD_LOCALE2702                                                    cc = ch;2703#else2704                                                    cc = ct.narrow(ch, char());2705#endif /* BOOST_NO_STD_LOCALE */2706 2707                                                    if        (cc == '(')                            // read "((a,b),(e,(" (ambiguity resolution)2708                                                    {2709                                                        u = ::std::complex<T>(a,b);2710 2711                                                        x = ::std::complex<T>(c);                    // "c" is actually "e"2712 2713                                                        is.putback(ch);2714 2715                                                        is >> y;                                    // read "((a,b),(e,y"2716 2717                                                        if    (!is.good())    goto finish;2718 2719                                                        is >> ch;                                    // get the next lexeme2720 2721                                                        if    (!is.good())    goto finish;2722 2723#ifdef    BOOST_NO_STD_LOCALE2724                                                        cc = ch;2725#else2726                                                        cc = ct.narrow(ch, char());2727#endif /* BOOST_NO_STD_LOCALE */2728 2729                                                        if        (cc == ')')                            // read "((a,b),(e,y)"2730                                                        {2731                                                            is >> ch;                                    // get the next lexeme2732 2733                                                            if    (!is.good())    goto finish;2734 2735#ifdef    BOOST_NO_STD_LOCALE2736                                                            cc = ch;2737#else2738                                                            cc = ct.narrow(ch, char());2739#endif /* BOOST_NO_STD_LOCALE */2740 2741                                                            if        (cc == ')')                            // read "((a,b),(e,y))"2742                                                            {2743                                                                o = octonion<T>(u,v,x,y);2744                                                            }2745                                                            else                                        // error2746                                                            {2747                                                                is.setstate(::std::ios_base::failbit);2748                                                            }2749                                                        }2750                                                        else                                        // error2751                                                        {2752                                                            is.setstate(::std::ios_base::failbit);2753                                                        }2754                                                    }2755                                                    else                                        // read "((a,b),(c,d" or "((a,b),(e,f"2756                                                    {2757                                                        is.putback(ch);2758 2759                                                        is >> d;2760 2761                                                        if    (!is.good())    goto finish;2762 2763                                                        is >> ch;                                    // get the next lexeme2764 2765                                                        if    (!is.good())    goto finish;2766 2767#ifdef    BOOST_NO_STD_LOCALE2768                                                        cc = ch;2769#else2770                                                        cc = ct.narrow(ch, char());2771#endif /* BOOST_NO_STD_LOCALE */2772 2773                                                        if        (cc == ')')                            // read "((a,b),(c,d)" (ambiguity resolution)2774                                                        {2775                                                            u = ::std::complex<T>(a,b);2776 2777                                                            v = ::std::complex<T>(c,d);2778 2779                                                            is >> ch;                                    // get the next lexeme2780 2781                                                            if    (!is.good())    goto finish;2782 2783#ifdef    BOOST_NO_STD_LOCALE2784                                                            cc = ch;2785#else2786                                                            cc = ct.narrow(ch, char());2787#endif /* BOOST_NO_STD_LOCALE */2788 2789                                                            if        (cc == ')')                            // read "((a,b),(c,d))"2790                                                            {2791                                                                o = octonion<T>(u,v);2792                                                            }2793                                                            else if    (cc == ',')                            // read "((a,b),(c,d),"2794                                                            {2795                                                                is >> x;                                    // read "((a,b),(c,d),x2796 2797                                                                if    (!is.good())    goto finish;2798 2799                                                                is >> ch;                                    // get the next lexeme2800 2801                                                                if    (!is.good())    goto finish;2802 2803#ifdef    BOOST_NO_STD_LOCALE2804                                                                cc = ch;2805#else2806                                                                cc = ct.narrow(ch, char());2807#endif /* BOOST_NO_STD_LOCALE */2808 2809                                                                if        (cc == ')')                            // read "((a,b),(c,d),x)"2810                                                                {2811                                                                    o = octonion<T>(u,v,x);2812                                                                }2813                                                                else if    (cc == ',')                            // read "((a,b),(c,d),x,"2814                                                                {2815                                                                    is >> y;                                    // read "((a,b),(c,d),x,y"2816 2817                                                                    if    (!is.good())    goto finish;2818 2819                                                                    is >> ch;                                    // get the next lexeme2820 2821                                                                    if    (!is.good())    goto finish;2822 2823#ifdef    BOOST_NO_STD_LOCALE2824                                                                    cc = ch;2825#else2826                                                                    cc = ct.narrow(ch, char());2827#endif /* BOOST_NO_STD_LOCALE */2828 2829                                                                    if        (cc == ')')                            // read "((a,b),(c,d),x,y)"2830                                                                    {2831                                                                        o = octonion<T>(u,v,x,y);2832                                                                    }2833                                                                    else                                        // error2834                                                                    {2835                                                                        is.setstate(::std::ios_base::failbit);2836                                                                    }2837                                                                }2838                                                                else                                        // error2839                                                                {2840                                                                    is.setstate(::std::ios_base::failbit);2841                                                                }2842                                                            }2843                                                            else                                        // error2844                                                            {2845                                                                is.setstate(::std::ios_base::failbit);2846                                                            }2847                                                        }2848                                                        else if    (cc == ',')                            // read "((a,b),(e,f," (ambiguity resolution)2849                                                        {2850                                                            p = ::boost::math::quaternion<T>(a,b);                // too late to backtrack2851 2852                                                            is >> g;                                    // read "((a,b),(e,f,g"2853 2854                                                            if    (!is.good())    goto finish;2855 2856                                                            is >> ch;                                    // get the next lexeme2857 2858                                                            if    (!is.good())    goto finish;2859 2860#ifdef    BOOST_NO_STD_LOCALE2861                                                            cc = ch;2862#else2863                                                            cc = ct.narrow(ch, char());2864#endif /* BOOST_NO_STD_LOCALE */2865 2866                                                            if        (cc == ')')                            // read "((a,b),(e,f,g)"2867                                                            {2868                                                                is >> ch;                                    // get the next lexeme2869 2870                                                                if    (!is.good())    goto finish;2871 2872#ifdef    BOOST_NO_STD_LOCALE2873                                                                cc = ch;2874#else2875                                                                cc = ct.narrow(ch, char());2876#endif /* BOOST_NO_STD_LOCALE */2877 2878                                                                if        (cc == ')')                            // read "((a,b),(e,f,g))"2879                                                                {2880                                                                    q = ::boost::math::quaternion<T>(c,d,g);            // "c" is actually "e" and "d" is actually "f"2881 2882                                                                    o = octonion<T>(p,q);2883                                                                }2884                                                                else                                        // error2885                                                                {2886                                                                    is.setstate(::std::ios_base::failbit);2887                                                                }2888                                                            }2889                                                            else if    (cc == ',')                            // read "((a,b),(e,f,g,"2890                                                            {2891                                                                is >> h;                                    // read "((a,b),(e,f,g,h"2892 2893                                                                if    (!is.good())    goto finish;2894 2895                                                                is >> ch;                                    // get the next lexeme2896 2897                                                                if    (!is.good())    goto finish;2898 2899#ifdef    BOOST_NO_STD_LOCALE2900                                                                cc = ch;2901#else2902                                                                cc = ct.narrow(ch, char());2903#endif /* BOOST_NO_STD_LOCALE */2904 2905                                                                if        (cc == ')')                            // read "((a,b),(e,f,g,h)"2906                                                                {2907                                                                    is >> ch;                                    // get the next lexeme2908 2909                                                                    if    (!is.good())    goto finish;2910 2911#ifdef    BOOST_NO_STD_LOCALE2912                                                                    cc = ch;2913#else2914                                                                    cc = ct.narrow(ch, char());2915#endif /* BOOST_NO_STD_LOCALE */2916 2917                                                                    if        (cc == ')')                            // read ((a,b),(e,f,g,h))"2918                                                                    {2919                                                                        q = ::boost::math::quaternion<T>(c,d,g,h);            // "c" is actually "e" and "d" is actually "f"2920 2921                                                                        o = octonion<T>(p,q);2922                                                                    }2923                                                                    else                                        // error2924                                                                    {2925                                                                        is.setstate(::std::ios_base::failbit);2926                                                                    }2927                                                                }2928                                                                else                                        // error2929                                                                {2930                                                                    is.setstate(::std::ios_base::failbit);2931                                                                }2932                                                            }2933                                                            else                                        // error2934                                                            {2935                                                                is.setstate(::std::ios_base::failbit);2936                                                            }2937                                                        }2938                                                        else                                        // error2939                                                        {2940                                                            is.setstate(::std::ios_base::failbit);2941                                                        }2942                                                    }2943                                                }2944                                                else                                        // error2945                                                {2946                                                    is.setstate(::std::ios_base::failbit);2947                                                }2948                                            }2949                                        }2950                                        else                                        // error2951                                        {2952                                            is.setstate(::std::ios_base::failbit);2953                                        }2954                                    }2955                                    else                                        // error2956                                    {2957                                        is.setstate(::std::ios_base::failbit);2958                                    }2959                                }2960                                else if    (cc == ',')                            // read "((a,b,"2961                                {2962                                    is >> c;                                    // read "((a,b,c"2963 2964                                    if    (!is.good())    goto finish;2965 2966                                    is >> ch;                                    // get the next lexeme2967 2968                                    if    (!is.good())    goto finish;2969 2970#ifdef    BOOST_NO_STD_LOCALE2971                                    cc = ch;2972#else2973                                    cc = ct.narrow(ch, char());2974#endif /* BOOST_NO_STD_LOCALE */2975 2976                                    if        (cc == ')')                            // read "((a,b,c)"2977                                    {2978                                        is >> ch;                                    // get the next lexeme2979 2980                                        if    (!is.good())    goto finish;2981 2982#ifdef    BOOST_NO_STD_LOCALE2983                                        cc = ch;2984#else2985                                        cc = ct.narrow(ch, char());2986#endif /* BOOST_NO_STD_LOCALE */2987 2988                                        if        (cc == ')')                            // read "((a,b,c))"2989                                        {2990                                            o = octonion<T>(a,b,c);2991                                        }2992                                        else if    (cc == ',')                            // read "((a,b,c),"2993                                        {2994                                            p = ::boost::math::quaternion<T>(a,b,c);2995 2996                                            is >> q;                                    // read "((a,b,c),q"2997 2998                                            if    (!is.good())    goto finish;2999 3000                                            is >> ch;                                    // get the next lexeme3001 3002                                            if    (!is.good())    goto finish;3003 3004#ifdef    BOOST_NO_STD_LOCALE3005                                            cc = ch;3006#else3007                                            cc = ct.narrow(ch, char());3008#endif /* BOOST_NO_STD_LOCALE */3009 3010                                            if        (cc == ')')                            // read "((a,b,c),q)"3011                                            {3012                                                o = octonion<T>(p,q);3013                                            }3014                                            else                                        // error3015                                            {3016                                                is.setstate(::std::ios_base::failbit);3017                                            }3018                                        }3019                                        else                                        // error3020                                        {3021                                            is.setstate(::std::ios_base::failbit);3022                                        }3023                                    }3024                                    else if    (cc == ',')                            // read "((a,b,c,"3025                                    {3026                                        is >> d;                                    // read "((a,b,c,d"3027 3028                                        if    (!is.good())    goto finish;3029 3030                                        is >> ch;                                    // get the next lexeme3031 3032                                        if    (!is.good())    goto finish;3033 3034#ifdef    BOOST_NO_STD_LOCALE3035                                        cc = ch;3036#else3037                                        cc = ct.narrow(ch, char());3038#endif /* BOOST_NO_STD_LOCALE */3039 3040                                        if        (cc == ')')                            // read "((a,b,c,d)"3041                                        {3042                                            is >> ch;                                    // get the next lexeme3043 3044                                            if    (!is.good())    goto finish;3045 3046#ifdef    BOOST_NO_STD_LOCALE3047                                            cc = ch;3048#else3049                                            cc = ct.narrow(ch, char());3050#endif /* BOOST_NO_STD_LOCALE */3051 3052                                            if        (cc == ')')                            // read "((a,b,c,d))"3053                                            {3054                                                o = octonion<T>(a,b,c,d);3055                                            }3056                                            else if    (cc == ',')                            // read "((a,b,c,d),"3057                                            {3058                                                p = ::boost::math::quaternion<T>(a,b,c,d);3059 3060                                                is >> q;                                    // read "((a,b,c,d),q"3061 3062                                                if    (!is.good())    goto finish;3063 3064                                                is >> ch;                                    // get the next lexeme3065 3066                                                if    (!is.good())    goto finish;3067 3068#ifdef    BOOST_NO_STD_LOCALE3069                                                cc = ch;3070#else3071                                                cc = ct.narrow(ch, char());3072#endif /* BOOST_NO_STD_LOCALE */3073 3074                                                if        (cc == ')')                            // read "((a,b,c,d),q)"3075                                                {3076                                                    o = octonion<T>(p,q);3077                                                }3078                                                else                                        // error3079                                                {3080                                                    is.setstate(::std::ios_base::failbit);3081                                                }3082                                            }3083                                            else                                        // error3084                                            {3085                                                is.setstate(::std::ios_base::failbit);3086                                            }3087                                        }3088                                        else                                        // error3089                                        {3090                                            is.setstate(::std::ios_base::failbit);3091                                        }3092                                    }3093                                    else                                        // error3094                                    {3095                                        is.setstate(::std::ios_base::failbit);3096                                    }3097                                }3098                                else                                        // error3099                                {3100                                    is.setstate(::std::ios_base::failbit);3101                                }3102                            }3103                        }3104                        else                                        // error3105                        {3106                            is.setstate(::std::ios_base::failbit);3107                        }3108                    }3109                }3110                else                                        // read "(a"3111                {3112                    is.putback(ch);3113 3114                    is >> a;                                    // we extract the first component3115 3116                    if    (!is.good())    goto finish;3117 3118                    is >> ch;                                    // get the next lexeme3119 3120                    if    (!is.good())    goto finish;3121 3122#ifdef    BOOST_NO_STD_LOCALE3123                    cc = ch;3124#else3125                    cc = ct.narrow(ch, char());3126#endif /* BOOST_NO_STD_LOCALE */3127 3128                    if        (cc == ')')                            // read "(a)"3129                    {3130                        o = octonion<T>(a);3131                    }3132                    else if    (cc == ',')                            // read "(a,"3133                    {3134                        is >> ch;                                    // get the next lexeme3135 3136                        if    (!is.good())    goto finish;3137 3138#ifdef    BOOST_NO_STD_LOCALE3139                        cc = ch;3140#else3141                        cc = ct.narrow(ch, char());3142#endif /* BOOST_NO_STD_LOCALE */3143 3144                        if        (cc == '(')                            // read "(a,("3145                        {3146                            is >> ch;                                    // get the next lexeme3147 3148                            if    (!is.good())    goto finish;3149 3150#ifdef    BOOST_NO_STD_LOCALE3151                            cc = ch;3152#else3153                            cc = ct.narrow(ch, char());3154#endif /* BOOST_NO_STD_LOCALE */3155 3156                            if        (cc == '(')                            // read "(a,(("3157                            {3158                                p = ::boost::math::quaternion<T>(a);3159 3160                                is.putback(ch);3161 3162                                is.putback(ch);                                // we backtrack twice, with the same value3163 3164                                is >> q;                                    // read "(a,q"3165 3166                                if    (!is.good())    goto finish;3167 3168                                is >> ch;                                    // get the next lexeme3169 3170                                if    (!is.good())    goto finish;3171 3172#ifdef    BOOST_NO_STD_LOCALE3173                                cc = ch;3174#else3175                                cc = ct.narrow(ch, char());3176#endif /* BOOST_NO_STD_LOCALE */3177 3178                                if        (cc == ')')                            // read "(a,q)"3179                                {3180                                    o = octonion<T>(p,q);3181                                }3182                                else                                        // error3183                                {3184                                    is.setstate(::std::ios_base::failbit);3185                                }3186                            }3187                            else                                        // read "(a,(c" or "(a,(e"3188                            {3189                                is.putback(ch);3190 3191                                is >> c;3192 3193                                if    (!is.good())    goto finish;3194 3195                                is >> ch;                                    // get the next lexeme3196 3197                                if    (!is.good())    goto finish;3198 3199#ifdef    BOOST_NO_STD_LOCALE3200                                cc = ch;3201#else3202                                cc = ct.narrow(ch, char());3203#endif /* BOOST_NO_STD_LOCALE */3204 3205                                if        (cc == ')')                            // read "(a,(c)" (ambiguity resolution)3206                                {3207                                    is >> ch;                                    // get the next lexeme3208 3209                                    if    (!is.good())    goto finish;3210 3211#ifdef    BOOST_NO_STD_LOCALE3212                                    cc = ch;3213#else3214                                    cc = ct.narrow(ch, char());3215#endif /* BOOST_NO_STD_LOCALE */3216 3217                                    if        (cc == ')')                            // read "(a,(c))"3218                                    {3219                                        o = octonion<T>(a,b,c);3220                                    }3221                                    else if    (cc == ',')                            // read "(a,(c),"3222                                    {3223                                        u = ::std::complex<T>(a);3224 3225                                        v = ::std::complex<T>(c);3226 3227                                        is >> x;                                // read "(a,(c),x"3228 3229                                        if    (!is.good())    goto finish;3230 3231                                        is >> ch;                                    // get the next lexeme3232 3233                                        if    (!is.good())    goto finish;3234 3235#ifdef    BOOST_NO_STD_LOCALE3236                                        cc = ch;3237#else3238                                        cc = ct.narrow(ch, char());3239#endif /* BOOST_NO_STD_LOCALE */3240 3241                                        if        (cc == ')')                            // read "(a,(c),x)"3242                                        {3243                                            o = octonion<T>(u,v,x);3244                                        }3245                                        else if    (cc == ',')                            // read "(a,(c),x,"3246                                        {3247                                            is >> y;                                    // read "(a,(c),x,y"3248 3249                                            if    (!is.good())    goto finish;3250 3251                                            is >> ch;                                    // get the next lexeme3252 3253                                            if    (!is.good())    goto finish;3254 3255#ifdef    BOOST_NO_STD_LOCALE3256                                            cc = ch;3257#else3258                                            cc = ct.narrow(ch, char());3259#endif /* BOOST_NO_STD_LOCALE */3260 3261                                            if        (cc == ')')                            // read "(a,(c),x,y)"3262                                            {3263                                                o = octonion<T>(u,v,x,y);3264                                            }3265                                            else                                        // error3266                                            {3267                                                is.setstate(::std::ios_base::failbit);3268                                            }3269                                        }3270                                        else                                        // error3271                                        {3272                                            is.setstate(::std::ios_base::failbit);3273                                        }3274                                    }3275                                    else                                        // error3276                                    {3277                                        is.setstate(::std::ios_base::failbit);3278                                    }3279                                }3280                                else if    (cc == ',')                            // read "(a,(c," or "(a,(e,"3281                                {3282                                    is >> ch;                                    // get the next lexeme3283 3284                                    if    (!is.good())    goto finish;3285 3286#ifdef    BOOST_NO_STD_LOCALE3287                                    cc = ch;3288#else3289                                    cc = ct.narrow(ch, char());3290#endif /* BOOST_NO_STD_LOCALE */3291 3292                                    if        (cc == '(')                            // read "(a,(e,(" (ambiguity resolution)3293                                    {3294                                        u = ::std::complex<T>(a);3295 3296                                        x = ::std::complex<T>(c);                // "c" is actually "e"3297 3298                                        is.putback(ch);                            // we backtrack3299 3300                                        is >> y;                                // read "(a,(e,y"3301 3302                                        if    (!is.good())    goto finish;3303 3304                                        is >> ch;                                    // get the next lexeme3305 3306                                        if    (!is.good())    goto finish;3307 3308#ifdef    BOOST_NO_STD_LOCALE3309                                        cc = ch;3310#else3311                                        cc = ct.narrow(ch, char());3312#endif /* BOOST_NO_STD_LOCALE */3313 3314                                        if        (cc == ')')                            // read "(a,(e,y)"3315                                        {3316                                            is >> ch;                                    // get the next lexeme3317 3318                                            if    (!is.good())    goto finish;3319 3320#ifdef    BOOST_NO_STD_LOCALE3321                                            cc = ch;3322#else3323                                            cc = ct.narrow(ch, char());3324#endif /* BOOST_NO_STD_LOCALE */3325 3326                                            if        (cc == ')')                            // read "(a,(e,y))"3327                                            {3328                                                o = octonion<T>(u,v,x,y);3329                                            }3330                                            else                                        // error3331                                            {3332                                                is.setstate(::std::ios_base::failbit);3333                                            }3334                                        }3335                                        else                                        // error3336                                        {3337                                            is.setstate(::std::ios_base::failbit);3338                                        }3339                                    }3340                                    else                                        // read "(a,(c,d" or "(a,(e,f"3341                                    {3342                                        is.putback(ch);3343 3344                                        is >> d;3345 3346                                        if    (!is.good())    goto finish;3347 3348                                        is >> ch;                                    // get the next lexeme3349 3350                                        if    (!is.good())    goto finish;3351 3352#ifdef    BOOST_NO_STD_LOCALE3353                                        cc = ch;3354#else3355                                        cc = ct.narrow(ch, char());3356#endif /* BOOST_NO_STD_LOCALE */3357 3358                                        if        (cc == ')')                            // read "(a,(c,d)" (ambiguity resolution)3359                                        {3360                                            is >> ch;                                    // get the next lexeme3361 3362                                            if    (!is.good())    goto finish;3363 3364#ifdef    BOOST_NO_STD_LOCALE3365                                            cc = ch;3366#else3367                                            cc = ct.narrow(ch, char());3368#endif /* BOOST_NO_STD_LOCALE */3369 3370                                            if        (cc == ')')                            // read "(a,(c,d))"3371                                            {3372                                                o = octonion<T>(a,b,c,d);3373                                            }3374                                            else if    (cc == ',')                            // read "(a,(c,d),"3375                                            {3376                                                u = ::std::complex<T>(a);3377 3378                                                v = ::std::complex<T>(c,d);3379 3380                                                is >> x;                                // read "(a,(c,d),x"3381 3382                                                if    (!is.good())    goto finish;3383 3384                                                is >> ch;                                    // get the next lexeme3385 3386                                                if    (!is.good())    goto finish;3387 3388#ifdef    BOOST_NO_STD_LOCALE3389                                                cc = ch;3390#else3391                                                cc = ct.narrow(ch, char());3392#endif /* BOOST_NO_STD_LOCALE */3393 3394                                                if        (cc == ')')                            // read "(a,(c,d),x)"3395                                                {3396                                                    o = octonion<T>(u,v,x);3397                                                }3398                                                else if    (cc == ',')                            // read "(a,(c,d),x,"3399                                                {3400                                                    is >> y;                                    // read "(a,(c,d),x,y"3401 3402                                                    if    (!is.good())    goto finish;3403 3404                                                    is >> ch;                                    // get the next lexeme3405 3406                                                    if    (!is.good())    goto finish;3407 3408#ifdef    BOOST_NO_STD_LOCALE3409                                                    cc = ch;3410#else3411                                                    cc = ct.narrow(ch, char());3412#endif /* BOOST_NO_STD_LOCALE */3413 3414                                                    if        (cc == ')')                            // read "(a,(c,d),x,y)"3415                                                    {3416                                                        o = octonion<T>(u,v,x,y);3417                                                    }3418                                                    else                                        // error3419                                                    {3420                                                        is.setstate(::std::ios_base::failbit);3421                                                    }3422                                                }3423                                                else                                        // error3424                                                {3425                                                    is.setstate(::std::ios_base::failbit);3426                                                }3427                                            }3428                                            else                                        // error3429                                            {3430                                                is.setstate(::std::ios_base::failbit);3431                                            }3432                                        }3433                                        else if    (cc == ',')                            // read "(a,(e,f," (ambiguity resolution)3434                                        {3435                                            p = ::boost::math::quaternion<T>(a);3436 3437                                            is >> g;                                    // read "(a,(e,f,g"3438 3439                                            if    (!is.good())    goto finish;3440 3441                                            is >> ch;                                    // get the next lexeme3442 3443                                            if    (!is.good())    goto finish;3444 3445#ifdef    BOOST_NO_STD_LOCALE3446                                            cc = ch;3447#else3448                                            cc = ct.narrow(ch, char());3449#endif /* BOOST_NO_STD_LOCALE */3450 3451                                            if        (cc == ')')                            // read "(a,(e,f,g)"3452                                            {3453                                                is >> ch;                                    // get the next lexeme3454 3455                                                if    (!is.good())    goto finish;3456 3457#ifdef    BOOST_NO_STD_LOCALE3458                                                cc = ch;3459#else3460                                                cc = ct.narrow(ch, char());3461#endif /* BOOST_NO_STD_LOCALE */3462 3463                                                if        (cc == ')')                            // read "(a,(e,f,g))"3464                                                {3465                                                    q = ::boost::math::quaternion<T>(c,d,g);            // "c" is actually "e" and "d" is actually "f"3466 3467                                                    o = octonion<T>(p,q);3468                                                }3469                                                else                                        // error3470                                                {3471                                                    is.setstate(::std::ios_base::failbit);3472                                                }3473                                            }3474                                            else if    (cc == ',')                            // read "(a,(e,f,g,"3475                                            {3476                                                is >> h;                                    // read "(a,(e,f,g,h"3477 3478                                                if    (!is.good())    goto finish;3479 3480                                                is >> ch;                                    // get the next lexeme3481 3482                                                if    (!is.good())    goto finish;3483 3484#ifdef    BOOST_NO_STD_LOCALE3485                                                cc = ch;3486#else3487                                                cc = ct.narrow(ch, char());3488#endif /* BOOST_NO_STD_LOCALE */3489 3490                                                if        (cc == ')')                            // read "(a,(e,f,g,h)"3491                                                {3492                                                    is >> ch;                                    // get the next lexeme3493 3494                                                    if    (!is.good())    goto finish;3495 3496#ifdef    BOOST_NO_STD_LOCALE3497                                                    cc = ch;3498#else3499                                                    cc = ct.narrow(ch, char());3500#endif /* BOOST_NO_STD_LOCALE */3501 3502                                                    if        (cc == ')')                            // read "(a,(e,f,g,h))"3503                                                    {3504                                                        q = ::boost::math::quaternion<T>(c,d,g,h);            // "c" is actually "e" and "d" is actually "f"3505 3506                                                        o = octonion<T>(p,q);3507                                                    }3508                                                    else                                        // error3509                                                    {3510                                                        is.setstate(::std::ios_base::failbit);3511                                                    }3512                                                }3513                                                else                                        // error3514                                                {3515                                                    is.setstate(::std::ios_base::failbit);3516                                                }3517                                            }3518                                            else                                        // error3519                                            {3520                                                is.setstate(::std::ios_base::failbit);3521                                            }3522                                        }3523                                        else                                        // error3524                                        {3525                                            is.setstate(::std::ios_base::failbit);3526                                        }3527                                    }3528                                }3529                                else                                        // error3530                                {3531                                    is.setstate(::std::ios_base::failbit);3532                                }3533                            }3534                        }3535                        else                                        // read "(a,b" or "(a,c" (ambiguity resolution)3536                        {3537                            is.putback(ch);3538 3539                            is >> b;3540 3541                            if    (!is.good())    goto finish;3542 3543                            is >> ch;                                    // get the next lexeme3544 3545                            if    (!is.good())    goto finish;3546 3547#ifdef    BOOST_NO_STD_LOCALE3548                            cc = ch;3549#else3550                            cc = ct.narrow(ch, char());3551#endif /* BOOST_NO_STD_LOCALE */3552 3553                            if        (cc == ')')                            // read "(a,b)" (ambiguity resolution)3554                            {3555                                o = octonion<T>(a,b);3556                            }3557                            else if    (cc == ',')                            // read "(a,b," or "(a,c,"3558                            {3559                                is >> ch;                                    // get the next lexeme3560 3561                                if    (!is.good())    goto finish;3562 3563#ifdef    BOOST_NO_STD_LOCALE3564                                cc = ch;3565#else3566                                cc = ct.narrow(ch, char());3567#endif /* BOOST_NO_STD_LOCALE */3568 3569                                if        (cc == '(')                            // read "(a,c,(" (ambiguity resolution)3570                                {3571                                    u = ::std::complex<T>(a);3572 3573                                    v = ::std::complex<T>(b);                    // "b" is actually "c"3574 3575                                    is.putback(ch);                                // we backtrack3576 3577                                    is >> x;                                    // read "(a,c,x"3578 3579                                    if    (!is.good())    goto finish;3580 3581                                    is >> ch;                                    // get the next lexeme3582 3583                                    if    (!is.good())    goto finish;3584 3585#ifdef    BOOST_NO_STD_LOCALE3586                                    cc = ch;3587#else3588                                    cc = ct.narrow(ch, char());3589#endif /* BOOST_NO_STD_LOCALE */3590 3591                                    if        (cc == ')')                            // read "(a,c,x)"3592                                    {3593                                        o = octonion<T>(u,v,x);3594                                    }3595                                    else if    (cc == ',')                            // read "(a,c,x,"3596                                    {3597                                        is >> y;                                    // read "(a,c,x,y"                                    // read "(a,c,x"3598 3599                                        if    (!is.good())    goto finish;3600 3601                                        is >> ch;                                    // get the next lexeme3602 3603                                        if    (!is.good())    goto finish;3604 3605#ifdef    BOOST_NO_STD_LOCALE3606                                        cc = ch;3607#else3608                                        cc = ct.narrow(ch, char());3609#endif /* BOOST_NO_STD_LOCALE */3610 3611                                        if        (cc == ')')                            // read "(a,c,x,y)"3612                                        {3613                                            o = octonion<T>(u,v,x,y);3614                                        }3615                                        else                                        // error3616                                        {3617                                            is.setstate(::std::ios_base::failbit);3618                                        }3619                                    }3620                                    else                                        // error3621                                    {3622                                        is.setstate(::std::ios_base::failbit);3623                                    }3624                                }3625                                else                                        // read "(a,b,c" or "(a,c,e"3626                                {3627                                    is.putback(ch);3628 3629                                    is >> c;3630 3631                                    if    (!is.good())    goto finish;3632 3633                                    is >> ch;                                    // get the next lexeme3634 3635                                    if    (!is.good())    goto finish;3636 3637#ifdef    BOOST_NO_STD_LOCALE3638                                    cc = ch;3639#else3640                                    cc = ct.narrow(ch, char());3641#endif /* BOOST_NO_STD_LOCALE */3642 3643                                    if        (cc == ')')                            // read "(a,b,c)" (ambiguity resolution)3644                                    {3645                                        o = octonion<T>(a,b,c);3646                                    }3647                                    else if    (cc == ',')                            // read "(a,b,c," or "(a,c,e,"3648                                    {3649                                        is >> ch;                                    // get the next lexeme3650 3651                                        if    (!is.good())    goto finish;3652 3653#ifdef    BOOST_NO_STD_LOCALE3654                                        cc = ch;3655#else3656                                        cc = ct.narrow(ch, char());3657#endif /* BOOST_NO_STD_LOCALE */3658 3659                                        if        (cc == '(')                            // read "(a,c,e,(") (ambiguity resolution)3660                                        {3661                                            u = ::std::complex<T>(a);3662 3663                                            v = ::std::complex<T>(b);                    // "b" is actually "c"3664 3665                                            x = ::std::complex<T>(c);                    // "c" is actually "e"3666 3667                                            is.putback(ch);                                // we backtrack3668 3669                                            is >> y;                                    // read "(a,c,e,y"3670 3671                                            if    (!is.good())    goto finish;3672 3673                                            is >> ch;                                    // get the next lexeme3674 3675                                            if    (!is.good())    goto finish;3676 3677#ifdef    BOOST_NO_STD_LOCALE3678                                            cc = ch;3679#else3680                                            cc = ct.narrow(ch, char());3681#endif /* BOOST_NO_STD_LOCALE */3682 3683                                            if        (cc == ')')                            // read "(a,c,e,y)"3684                                            {3685                                                o = octonion<T>(u,v,x,y);3686                                            }3687                                            else                                        // error3688                                            {3689                                                is.setstate(::std::ios_base::failbit);3690                                            }3691                                        }3692                                        else                                        // read "(a,b,c,d" (ambiguity resolution)3693                                        {3694                                            is.putback(ch);                                // we backtrack3695 3696                                            is >> d;3697 3698                                            if    (!is.good())    goto finish;3699 3700                                            is >> ch;                                    // get the next lexeme3701 3702                                            if    (!is.good())    goto finish;3703 3704#ifdef    BOOST_NO_STD_LOCALE3705                                            cc = ch;3706#else3707                                            cc = ct.narrow(ch, char());3708#endif /* BOOST_NO_STD_LOCALE */3709 3710                                            if        (cc == ')')                            // read "(a,b,c,d)"3711                                            {3712                                                o = octonion<T>(a,b,c,d);3713                                            }3714                                            else if    (cc == ',')                            // read "(a,b,c,d,"3715                                            {3716                                                is >> e;                                    // read "(a,b,c,d,e"3717 3718                                                if    (!is.good())    goto finish;3719 3720                                                is >> ch;                                    // get the next lexeme3721 3722                                                if    (!is.good())    goto finish;3723 3724#ifdef    BOOST_NO_STD_LOCALE3725                                                cc = ch;3726#else3727                                                cc = ct.narrow(ch, char());3728#endif /* BOOST_NO_STD_LOCALE */3729 3730                                                if        (cc == ')')                            // read "(a,b,c,d,e)"3731                                                {3732                                                    o = octonion<T>(a,b,c,d,e);3733                                                }3734                                                else if    (cc == ',')                            // read "(a,b,c,d,e,"3735                                                {3736                                                    is >> f;                                    // read "(a,b,c,d,e,f"3737 3738                                                    if    (!is.good())    goto finish;3739 3740                                                    is >> ch;                                    // get the next lexeme3741 3742                                                    if    (!is.good())    goto finish;3743 3744#ifdef    BOOST_NO_STD_LOCALE3745                                                    cc = ch;3746#else3747                                                    cc = ct.narrow(ch, char());3748#endif /* BOOST_NO_STD_LOCALE */3749 3750                                                    if        (cc == ')')                            // read "(a,b,c,d,e,f)"3751                                                    {3752                                                        o = octonion<T>(a,b,c,d,e,f);3753                                                    }3754                                                    else if    (cc == ',')                            // read "(a,b,c,d,e,f,"3755                                                    {3756                                                        is >> g;                                    // read "(a,b,c,d,e,f,g"                                    // read "(a,b,c,d,e,f"3757 3758                                                        if    (!is.good())    goto finish;3759 3760                                                        is >> ch;                                    // get the next lexeme3761 3762                                                        if    (!is.good())    goto finish;3763 3764#ifdef    BOOST_NO_STD_LOCALE3765                                                        cc = ch;3766#else3767                                                        cc = ct.narrow(ch, char());3768#endif /* BOOST_NO_STD_LOCALE */3769 3770                                                        if        (cc == ')')                            // read "(a,b,c,d,e,f,g)"3771                                                        {3772                                                            o = octonion<T>(a,b,c,d,e,f,g);3773                                                        }3774                                                        else if    (cc == ',')                            // read "(a,b,c,d,e,f,g,"3775                                                        {3776                                                            is >> h;                                    // read "(a,b,c,d,e,f,g,h"                                    // read "(a,b,c,d,e,f,g"                                    // read "(a,b,c,d,e,f"3777 3778                                                            if    (!is.good())    goto finish;3779 3780                                                            is >> ch;                                    // get the next lexeme3781 3782                                                            if    (!is.good())    goto finish;3783 3784#ifdef    BOOST_NO_STD_LOCALE3785                                                            cc = ch;3786#else3787                                                            cc = ct.narrow(ch, char());3788#endif /* BOOST_NO_STD_LOCALE */3789 3790                                                            if        (cc == ')')                            // read "(a,b,c,d,e,f,g,h)"3791                                                            {3792                                                                o = octonion<T>(a,b,c,d,e,f,g,h);3793                                                            }3794                                                            else                                        // error3795                                                            {3796                                                                is.setstate(::std::ios_base::failbit);3797                                                            }3798                                                        }3799                                                        else                                        // error3800                                                        {3801                                                            is.setstate(::std::ios_base::failbit);3802                                                        }3803                                                    }3804                                                    else                                        // error3805                                                    {3806                                                        is.setstate(::std::ios_base::failbit);3807                                                    }3808                                                }3809                                                else                                        // error3810                                                {3811                                                    is.setstate(::std::ios_base::failbit);3812                                                }3813                                            }3814                                            else                                        // error3815                                            {3816                                                is.setstate(::std::ios_base::failbit);3817                                            }3818                                        }3819                                    }3820                                    else                                        // error3821                                    {3822                                        is.setstate(::std::ios_base::failbit);3823                                    }3824                                }3825                            }3826                            else                                        // error3827                            {3828                                is.setstate(::std::ios_base::failbit);3829                            }3830                        }3831                    }3832                    else                                        // error3833                    {3834                        is.setstate(::std::ios_base::failbit);3835                    }3836                }3837            }3838            else                                        // format:    a3839            {3840                is.putback(ch);3841 3842                is >> a;                                    // we extract the first component3843 3844                if    (!is.good())    goto finish;3845 3846                o = octonion<T>(a);3847            }3848 3849            finish:3850            return(is);3851        }3852        // LCOV_EXCL_STOP3853 3854 3855        template<typename T, typename charT, class traits>3856        ::std::basic_ostream<charT,traits> &    operator << (    ::std::basic_ostream<charT,traits> & os,3857                                                                octonion<T> const & o)3858        {3859            ::std::basic_ostringstream<charT,traits>    s;3860 3861            s.flags(os.flags());3862#ifdef    BOOST_NO_STD_LOCALE3863#else3864            s.imbue(os.getloc());3865#endif /* BOOST_NO_STD_LOCALE */3866            s.precision(os.precision());3867 3868            s << '('    << o.R_component_1() << ','3869                        << o.R_component_2() << ','3870                        << o.R_component_3() << ','3871                        << o.R_component_4() << ','3872                        << o.R_component_5() << ','3873                        << o.R_component_6() << ','3874                        << o.R_component_7() << ','3875                        << o.R_component_8() << ')';3876 3877            return os << s.str();3878        }3879 3880 3881        // values3882 3883        template<typename T>3884        inline T                                real(octonion<T> const & o)3885        {3886            return(o.real());3887        }3888 3889 3890        template<typename T>3891        inline octonion<T>                        unreal(octonion<T> const & o)3892        {3893            return(o.unreal());3894        }3895 3896 3897#define    BOOST_OCTONION_VALARRAY_LOADER   \3898            using    ::std::valarray;       \3899                                            \3900            valarray<T>    temp(8);         \3901                                            \3902            temp[0] = o.R_component_1();    \3903            temp[1] = o.R_component_2();    \3904            temp[2] = o.R_component_3();    \3905            temp[3] = o.R_component_4();    \3906            temp[4] = o.R_component_5();    \3907            temp[5] = o.R_component_6();    \3908            temp[6] = o.R_component_7();    \3909            temp[7] = o.R_component_8();3910 3911 3912        template<typename T>3913        inline T                                sup(octonion<T> const & o)3914        {3915#ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP3916            using    ::std::abs;3917#endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */3918 3919            BOOST_OCTONION_VALARRAY_LOADER3920 3921            return((abs(temp).max)());3922        }3923 3924 3925        template<typename T>3926        inline T                                l1(octonion<T> const & o)3927        {3928#ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP3929            using    ::std::abs;3930#endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */3931 3932            BOOST_OCTONION_VALARRAY_LOADER3933 3934            return(abs(temp).sum());3935        }3936 3937 3938        template<typename T>3939        inline T                                abs(const octonion<T> & o)3940        {3941#ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP3942            using    ::std::abs;3943#endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */3944 3945            using    ::std::sqrt;3946 3947            BOOST_OCTONION_VALARRAY_LOADER3948 3949            T            maxim = (abs(temp).max)();    // overflow protection3950 3951            if    (maxim == static_cast<T>(0))3952            {3953                return(maxim);3954            }3955            else3956            {3957                T    mixam = static_cast<T>(1)/maxim;    // prefer multiplications over divisions3958 3959                temp *= mixam;3960 3961                temp *= temp;3962 3963                return(maxim*sqrt(temp.sum()));3964            }3965 3966            //return(::std::sqrt(norm(o)));3967        }3968 3969 3970#undef    BOOST_OCTONION_VALARRAY_LOADER3971 3972 3973        // Note:    This is the Cayley norm, not the Euclidean norm...3974 3975        template<typename T>3976        inline T                                norm(octonion<T> const & o)3977        {3978            return(real(o*conj(o)));3979        }3980 3981 3982        template<typename T>3983        inline octonion<T>                        conj(octonion<T> const & o)3984        {3985            return(octonion<T>( +o.R_component_1(),3986                                -o.R_component_2(),3987                                -o.R_component_3(),3988                                -o.R_component_4(),3989                                -o.R_component_5(),3990                                -o.R_component_6(),3991                                -o.R_component_7(),3992                                -o.R_component_8()));3993        }3994 3995 3996        // Note:    There is little point, for the octonions, to introduce the equivalents3997        //            to the complex "arg" and the quaternionic "cylindropolar".3998 3999 4000        template<typename T>4001        inline octonion<T>                        spherical(T const & rho,4002                                                            T const & theta,4003                                                            T const & phi1,4004                                                            T const & phi2,4005                                                            T const & phi3,4006                                                            T const & phi4,4007                                                            T const & phi5,4008                                                            T const & phi6)4009        {4010            using ::std::cos;4011            using ::std::sin;4012 4013            //T    a = cos(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);4014            //T    b = sin(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);4015            //T    c = sin(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);4016            //T    d = sin(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);4017            //T    e = sin(phi3)*cos(phi4)*cos(phi5)*cos(phi6);4018            //T    f = sin(phi4)*cos(phi5)*cos(phi6);4019            //T    g = sin(phi5)*cos(phi6);4020            //T    h = sin(phi6);4021 4022            T    courrant = static_cast<T>(1);4023 4024            T    h = sin(phi6);4025 4026            courrant *= cos(phi6);4027 4028            T    g = sin(phi5)*courrant;4029 4030            courrant *= cos(phi5);4031 4032            T    f = sin(phi4)*courrant;4033 4034            courrant *= cos(phi4);4035 4036            T    e = sin(phi3)*courrant;4037 4038            courrant *= cos(phi3);4039 4040            T    d = sin(phi2)*courrant;4041 4042            courrant *= cos(phi2);4043 4044            T    c = sin(phi1)*courrant;4045 4046            courrant *= cos(phi1);4047 4048            T    b = sin(theta)*courrant;4049            T    a = cos(theta)*courrant;4050 4051            return(rho*octonion<T>(a,b,c,d,e,f,g,h));4052        }4053 4054 4055        template<typename T>4056        inline octonion<T>                        multipolar(T const & rho1,4057                                                             T const & theta1,4058                                                             T const & rho2,4059                                                             T const & theta2,4060                                                             T const & rho3,4061                                                             T const & theta3,4062                                                             T const & rho4,4063                                                             T const & theta4)4064        {4065            using ::std::cos;4066            using ::std::sin;4067 4068            T    a = rho1*cos(theta1);4069            T    b = rho1*sin(theta1);4070            T    c = rho2*cos(theta2);4071            T    d = rho2*sin(theta2);4072            T    e = rho3*cos(theta3);4073            T    f = rho3*sin(theta3);4074            T    g = rho4*cos(theta4);4075            T    h = rho4*sin(theta4);4076 4077            return(octonion<T>(a,b,c,d,e,f,g,h));4078        }4079 4080 4081        template<typename T>4082        inline octonion<T>                        cylindrical(T const & r,4083                                                              T const & angle,4084                                                              T const & h1,4085                                                              T const & h2,4086                                                              T const & h3,4087                                                              T const & h4,4088                                                              T const & h5,4089                                                              T const & h6)4090        {4091            using ::std::cos;4092            using ::std::sin;4093 4094            T    a = r*cos(angle);4095            T    b = r*sin(angle);4096 4097            return(octonion<T>(a,b,h1,h2,h3,h4,h5,h6));4098        }4099 4100 4101        template<typename T>4102        inline octonion<T>                        exp(octonion<T> const & o)4103        {4104            using    ::std::exp;4105            using    ::std::cos;4106 4107            using    ::boost::math::sinc_pi;4108 4109            T    u = exp(real(o));4110 4111            T    z = abs(unreal(o));4112 4113            T    w = sinc_pi(z);4114 4115            return(u*octonion<T>(cos(z),4116                w*o.R_component_2(), w*o.R_component_3(),4117                w*o.R_component_4(), w*o.R_component_5(),4118                w*o.R_component_6(), w*o.R_component_7(),4119                w*o.R_component_8()));4120        }4121 4122 4123        template<typename T>4124        inline octonion<T>                        cos(octonion<T> const & o)4125        {4126            using    ::std::sin;4127            using    ::std::cos;4128            using    ::std::cosh;4129 4130            using    ::boost::math::sinhc_pi;4131 4132            T    z = abs(unreal(o));4133 4134            T    w = -sin(o.real())*sinhc_pi(z);4135 4136            return(octonion<T>(cos(o.real())*cosh(z),4137                w*o.R_component_2(), w*o.R_component_3(),4138                w*o.R_component_4(), w*o.R_component_5(),4139                w*o.R_component_6(), w*o.R_component_7(),4140                w*o.R_component_8()));4141        }4142 4143 4144        template<typename T>4145        inline octonion<T>                        sin(octonion<T> const & o)4146        {4147            using    ::std::sin;4148            using    ::std::cos;4149            using    ::std::cosh;4150 4151            using    ::boost::math::sinhc_pi;4152 4153            T    z = abs(unreal(o));4154 4155            T    w = +cos(o.real())*sinhc_pi(z);4156 4157            return(octonion<T>(sin(o.real())*cosh(z),4158                w*o.R_component_2(), w*o.R_component_3(),4159                w*o.R_component_4(), w*o.R_component_5(),4160                w*o.R_component_6(), w*o.R_component_7(),4161                w*o.R_component_8()));4162        }4163 4164 4165        template<typename T>4166        inline octonion<T>                        tan(octonion<T> const & o)4167        {4168            return(sin(o)/cos(o));4169        }4170 4171 4172        template<typename T>4173        inline octonion<T>                        cosh(octonion<T> const & o)4174        {4175            return((exp(+o)+exp(-o))/static_cast<T>(2));4176        }4177 4178 4179        template<typename T>4180        inline octonion<T>                        sinh(octonion<T> const & o)4181        {4182            return((exp(+o)-exp(-o))/static_cast<T>(2));4183        }4184 4185 4186        template<typename T>4187        inline octonion<T>                        tanh(octonion<T> const & o)4188        {4189            return(sinh(o)/cosh(o));4190        }4191 4192 4193        template<typename T>4194        octonion<T>                                pow(octonion<T> const & o,4195                                                    int n)4196        {4197            if        (n > 1)4198            {4199                int    m = n>>1;4200 4201                octonion<T>    result = pow(o, m);4202 4203                result *= result;4204 4205                if    (n != (m<<1))4206                {4207                    result *= o; // n odd4208                }4209 4210                return(result);4211            }4212            else if    (n == 1)4213            {4214                return(o);4215            }4216            else if    (n == 0)4217            {4218                return(octonion<T>(static_cast<T>(1)));4219            }4220            else    /* n < 0 */4221            {4222                return(pow(octonion<T>(static_cast<T>(1))/o,-n));4223            }4224        }4225 4226 4227        // helper templates for converting copy constructors (definition)4228 4229        namespace detail4230        {4231 4232            template<   typename T,4233                        typename U4234                    >4235            octonion<T>    octonion_type_converter(octonion<U> const & rhs)4236            {4237                return(octonion<T>( static_cast<T>(rhs.R_component_1()),4238                                    static_cast<T>(rhs.R_component_2()),4239                                    static_cast<T>(rhs.R_component_3()),4240                                    static_cast<T>(rhs.R_component_4()),4241                                    static_cast<T>(rhs.R_component_5()),4242                                    static_cast<T>(rhs.R_component_6()),4243                                    static_cast<T>(rhs.R_component_7()),4244                                    static_cast<T>(rhs.R_component_8())));4245            }4246        }4247    }4248}4249 4250#endif /* BOOST_OCTONION_HPP */4251