epoc32/include/stdapis/boost/math/octonion.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     1 //    boost octonion.hpp header file
     2 
     3 //  (C) Copyright Hubert Holin 2001.
     4 //  Distributed under the Boost Software License, Version 1.0. (See
     5 //  accompanying file LICENSE_1_0.txt or copy at
     6 //  http://www.boost.org/LICENSE_1_0.txt)
     7 
     8 // See http://www.boost.org for updates, documentation, and revision history.
     9 
    10 
    11 #ifndef BOOST_OCTONION_HPP
    12 #define BOOST_OCTONION_HPP
    13 
    14 #include <boost/math/quaternion.hpp>
    15 
    16 
    17 namespace boost
    18 {
    19     namespace math
    20     {
    21 #if    BOOST_WORKAROUND(__GNUC__, < 3)
    22         // gcc 2.95.x uses expression templates for valarray calculations, but
    23         // the result is not conforming. We need BOOST_GET_VALARRAY to get an
    24         // actual valarray result when we need to call a member function
    25     #define    BOOST_GET_VALARRAY(T,x)    ::std::valarray<T>(x)
    26         // gcc 2.95.x has an "std::ios" class that is similar to 
    27         // "std::ios_base", so we just use a #define
    28     #define    BOOST_IOS_BASE    ::std::ios
    29         // gcc 2.x ignores function scope using declarations,
    30         // put them in the scope of the enclosing namespace instead:
    31         using    ::std::valarray;
    32         using    ::std::sqrt;
    33         using    ::std::cos;
    34         using    ::std::sin;
    35         using    ::std::exp;
    36         using    ::std::cosh;
    37 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
    38     
    39 #define    BOOST_OCTONION_ACCESSOR_GENERATOR(type)                      \
    40             type                        real() const                    \
    41             {                                                           \
    42                 return(a);                                              \
    43             }                                                           \
    44                                                                         \
    45             octonion<type>                unreal() const                \
    46             {                                                           \
    47                 return( octonion<type>(static_cast<type>(0),b,c,d,e,f,g,h));   \
    48             }                                                           \
    49                                                                         \
    50             type                            R_component_1() const       \
    51             {                                                           \
    52                 return(a);                                              \
    53             }                                                           \
    54                                                                         \
    55             type                            R_component_2() const       \
    56             {                                                           \
    57                 return(b);                                              \
    58             }                                                           \
    59                                                                         \
    60             type                            R_component_3() const       \
    61             {                                                           \
    62                 return(c);                                              \
    63             }                                                           \
    64                                                                         \
    65             type                            R_component_4() const       \
    66             {                                                           \
    67                 return(d);                                              \
    68             }                                                           \
    69                                                                         \
    70             type                            R_component_5() const       \
    71             {                                                           \
    72                 return(e);                                              \
    73             }                                                           \
    74                                                                         \
    75             type                            R_component_6() const       \
    76             {                                                           \
    77                 return(f);                                              \
    78             }                                                           \
    79                                                                         \
    80             type                            R_component_7() const       \
    81             {                                                           \
    82                 return(g);                                              \
    83             }                                                           \
    84                                                                         \
    85             type                            R_component_8() const       \
    86             {                                                           \
    87                 return(h);                                              \
    88             }                                                           \
    89                                                                         \
    90             ::std::complex<type>            C_component_1() const       \
    91             {                                                           \
    92                 return(::std::complex<type>(a,b));                      \
    93             }                                                           \
    94                                                                         \
    95             ::std::complex<type>            C_component_2() const       \
    96             {                                                           \
    97                 return(::std::complex<type>(c,d));                      \
    98             }                                                           \
    99                                                                         \
   100             ::std::complex<type>            C_component_3() const       \
   101             {                                                           \
   102                 return(::std::complex<type>(e,f));                      \
   103             }                                                           \
   104                                                                         \
   105             ::std::complex<type>            C_component_4() const       \
   106             {                                                           \
   107                 return(::std::complex<type>(g,h));                      \
   108             }                                                           \
   109                                                                         \
   110             ::boost::math::quaternion<type>    H_component_1() const    \
   111             {                                                           \
   112                 return(::boost::math::quaternion<type>(a,b,c,d));       \
   113             }                                                           \
   114                                                                         \
   115             ::boost::math::quaternion<type>    H_component_2() const    \
   116             {                                                           \
   117                 return(::boost::math::quaternion<type>(e,f,g,h));       \
   118             }
   119         
   120     
   121 #define    BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(type)                                         \
   122             template<typename X>                                                                    \
   123             octonion<type> &        operator = (octonion<X> const & a_affecter)                     \
   124             {                                                                                       \
   125                 a = static_cast<type>(a_affecter.R_component_1());                                  \
   126                 b = static_cast<type>(a_affecter.R_component_2());                                  \
   127                 c = static_cast<type>(a_affecter.R_component_3());                                  \
   128                 d = static_cast<type>(a_affecter.R_component_4());                                  \
   129                 e = static_cast<type>(a_affecter.R_component_5());                                  \
   130                 f = static_cast<type>(a_affecter.R_component_6());                                  \
   131                 g = static_cast<type>(a_affecter.R_component_7());                                  \
   132                 h = static_cast<type>(a_affecter.R_component_8());                                  \
   133                                                                                                     \
   134                 return(*this);                                                                      \
   135             }                                                                                       \
   136                                                                                                     \
   137             octonion<type> &        operator = (octonion<type> const & a_affecter)                  \
   138             {                                                                                       \
   139                 a = a_affecter.a;                                                                   \
   140                 b = a_affecter.b;                                                                   \
   141                 c = a_affecter.c;                                                                   \
   142                 d = a_affecter.d;                                                                   \
   143                 e = a_affecter.e;                                                                   \
   144                 f = a_affecter.f;                                                                   \
   145                 g = a_affecter.g;                                                                   \
   146                 h = a_affecter.h;                                                                   \
   147                                                                                                     \
   148                 return(*this);                                                                      \
   149             }                                                                                       \
   150                                                                                                     \
   151             octonion<type> &        operator = (type const & a_affecter)                            \
   152             {                                                                                       \
   153                 a = a_affecter;                                                                     \
   154                                                                                                     \
   155                 b = c = d = e = f= g = h = static_cast<type>(0);                                    \
   156                                                                                                     \
   157                 return(*this);                                                                      \
   158             }                                                                                       \
   159                                                                                                     \
   160             octonion<type> &        operator = (::std::complex<type> const & a_affecter)            \
   161             {                                                                                       \
   162                 a = a_affecter.real();                                                              \
   163                 b = a_affecter.imag();                                                              \
   164                                                                                                     \
   165                 c = d = e = f = g = h = static_cast<type>(0);                                       \
   166                                                                                                     \
   167                 return(*this);                                                                      \
   168             }                                                                                       \
   169                                                                                                     \
   170             octonion<type> &        operator = (::boost::math::quaternion<type> const & a_affecter) \
   171             {                                                                                       \
   172                 a = a_affecter.R_component_1();                                                     \
   173                 b = a_affecter.R_component_2();                                                     \
   174                 c = a_affecter.R_component_3();                                                     \
   175                 d = a_affecter.R_component_4();                                                     \
   176                                                                                                     \
   177                 e = f = g = h = static_cast<type>(0);                                               \
   178                                                                                                     \
   179                 return(*this);                                                                      \
   180             }
   181         
   182         
   183 #define    BOOST_OCTONION_MEMBER_DATA_GENERATOR(type) \
   184             type    a;                                \
   185             type    b;                                \
   186             type    c;                                \
   187             type    d;                                \
   188             type    e;                                \
   189             type    f;                                \
   190             type    g;                                \
   191             type    h;                                \
   192         
   193         
   194         template<typename T>
   195         class octonion
   196         {
   197         public:
   198             
   199             typedef T value_type;
   200             
   201             // constructor for O seen as R^8
   202             // (also default constructor)
   203             
   204             explicit                octonion(   T const & requested_a = T(),
   205                                                 T const & requested_b = T(),
   206                                                 T const & requested_c = T(),
   207                                                 T const & requested_d = T(),
   208                                                 T const & requested_e = T(),
   209                                                 T const & requested_f = T(),
   210                                                 T const & requested_g = T(),
   211                                                 T const & requested_h = T())
   212             :   a(requested_a),
   213                 b(requested_b),
   214                 c(requested_c),
   215                 d(requested_d),
   216                 e(requested_e),
   217                 f(requested_f),
   218                 g(requested_g),
   219                 h(requested_h)
   220             {
   221                 // nothing to do!
   222             }
   223             
   224             
   225             // constructor for H seen as C^4
   226                 
   227             explicit                octonion(   ::std::complex<T> const & z0,
   228                                                 ::std::complex<T> const & z1 = ::std::complex<T>(),
   229                                                 ::std::complex<T> const & z2 = ::std::complex<T>(),
   230                                                 ::std::complex<T> const & z3 = ::std::complex<T>())
   231             :   a(z0.real()),
   232                 b(z0.imag()),
   233                 c(z1.real()),
   234                 d(z1.imag()),
   235                 e(z2.real()),
   236                 f(z2.imag()),
   237                 g(z3.real()),
   238                 h(z3.imag())
   239             {
   240                 // nothing to do!
   241             }
   242             
   243             
   244             // constructor for O seen as H^2
   245                 
   246             explicit                octonion(   ::boost::math::quaternion<T> const & q0,
   247                                                 ::boost::math::quaternion<T> const & q1 = ::boost::math::quaternion<T>())
   248             :   a(q0.R_component_1()),
   249                 b(q0.R_component_2()),
   250                 c(q0.R_component_3()),
   251                 d(q0.R_component_4()),
   252                 e(q1.R_component_1()),
   253                 f(q1.R_component_2()),
   254                 g(q1.R_component_3()),
   255                 h(q1.R_component_4())
   256             {
   257                 // nothing to do!
   258             }
   259             
   260             
   261             // UNtemplated copy constructor
   262             // (this is taken care of by the compiler itself)
   263             
   264             
   265             // templated copy constructor
   266             
   267             template<typename X>
   268             explicit                octonion(octonion<X> const & a_recopier)
   269             :   a(static_cast<T>(a_recopier.R_component_1())),
   270                 b(static_cast<T>(a_recopier.R_component_2())),
   271                 c(static_cast<T>(a_recopier.R_component_3())),
   272                 d(static_cast<T>(a_recopier.R_component_4())),
   273                 e(static_cast<T>(a_recopier.R_component_5())),
   274                 f(static_cast<T>(a_recopier.R_component_6())),
   275                 g(static_cast<T>(a_recopier.R_component_7())),
   276                 h(static_cast<T>(a_recopier.R_component_8()))
   277             {
   278                 // nothing to do!
   279             }
   280             
   281             
   282             // destructor
   283             // (this is taken care of by the compiler itself)
   284             
   285             
   286             // accessors
   287             //
   288             // Note:    Like complex number, octonions do have a meaningful notion of "real part",
   289             //            but unlike them there is no meaningful notion of "imaginary part".
   290             //            Instead there is an "unreal part" which itself is an octonion, and usually
   291             //            nothing simpler (as opposed to the complex number case).
   292             //            However, for practicallity, there are accessors for the other components
   293             //            (these are necessary for the templated copy constructor, for instance).
   294             
   295             BOOST_OCTONION_ACCESSOR_GENERATOR(T)
   296             
   297             // assignment operators
   298             
   299             BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(T)
   300             
   301             // other assignment-related operators
   302             //
   303             // NOTE:    Octonion multiplication is *NOT* commutative;
   304             //            symbolically, "q *= rhs;" means "q = q * rhs;"
   305             //            and "q /= rhs;" means "q = q * inverse_of(rhs);";
   306             //            octonion multiplication is also *NOT* associative
   307             
   308             octonion<T> &            operator += (T const & rhs)
   309             {
   310                 T    at = a + rhs;    // exception guard
   311                 
   312                 a = at;
   313                 
   314                 return(*this);
   315             }
   316             
   317             
   318             octonion<T> &            operator += (::std::complex<T> const & rhs)
   319             {
   320                 T    at = a + rhs.real();    // exception guard
   321                 T    bt = b + rhs.imag();    // exception guard
   322                 
   323                 a = at; 
   324                 b = bt;
   325                 
   326                 return(*this);
   327             }
   328             
   329             
   330             octonion<T> &            operator += (::boost::math::quaternion<T> const & rhs)
   331             {
   332                 T    at = a + rhs.R_component_1();    // exception guard
   333                 T    bt = b + rhs.R_component_2();    // exception guard
   334                 T    ct = c + rhs.R_component_3();    // exception guard
   335                 T    dt = d + rhs.R_component_4();    // exception guard
   336                 
   337                 a = at; 
   338                 b = bt;
   339                 c = ct;
   340                 d = dt;
   341                 
   342                 return(*this);
   343             }
   344             
   345             
   346             template<typename X>
   347             octonion<T> &            operator += (octonion<X> const & rhs)
   348             {
   349                 T    at = a + static_cast<T>(rhs.R_component_1());    // exception guard
   350                 T    bt = b + static_cast<T>(rhs.R_component_2());    // exception guard
   351                 T    ct = c + static_cast<T>(rhs.R_component_3());    // exception guard
   352                 T    dt = d + static_cast<T>(rhs.R_component_4());    // exception guard
   353                 T    et = e + static_cast<T>(rhs.R_component_5());    // exception guard
   354                 T    ft = f + static_cast<T>(rhs.R_component_6());    // exception guard
   355                 T    gt = g + static_cast<T>(rhs.R_component_7());    // exception guard
   356                 T    ht = h + static_cast<T>(rhs.R_component_8());    // exception guard
   357                 
   358                 a = at;
   359                 b = bt;
   360                 c = ct;
   361                 d = dt;
   362                 e = et;
   363                 f = ft;
   364                 g = gt;
   365                 h = ht;
   366                 
   367                 return(*this);
   368             }
   369             
   370             
   371             
   372             octonion<T> &            operator -= (T const & rhs)
   373             {
   374                 T    at = a - rhs;    // exception guard
   375                 
   376                 a = at;
   377                 
   378                 return(*this);
   379             }
   380             
   381             
   382             octonion<T> &            operator -= (::std::complex<T> const & rhs)
   383             {
   384                 T    at = a - rhs.real();    // exception guard
   385                 T    bt = b - rhs.imag();    // exception guard
   386                 
   387                 a = at; 
   388                 b = bt;
   389                 
   390                 return(*this);
   391             }
   392             
   393             
   394             octonion<T> &            operator -= (::boost::math::quaternion<T> const & rhs)
   395             {
   396                 T    at = a - rhs.R_component_1();    // exception guard
   397                 T    bt = b - rhs.R_component_2();    // exception guard
   398                 T    ct = c - rhs.R_component_3();    // exception guard
   399                 T    dt = d - rhs.R_component_4();    // exception guard
   400                 
   401                 a = at; 
   402                 b = bt;
   403                 c = ct;
   404                 d = dt;
   405                 
   406                 return(*this);
   407             }
   408             
   409             
   410             template<typename X>
   411             octonion<T> &            operator -= (octonion<X> const & rhs)
   412             {
   413                 T    at = a - static_cast<T>(rhs.R_component_1());    // exception guard
   414                 T    bt = b - static_cast<T>(rhs.R_component_2());    // exception guard
   415                 T    ct = c - static_cast<T>(rhs.R_component_3());    // exception guard
   416                 T    dt = d - static_cast<T>(rhs.R_component_4());    // exception guard
   417                 T    et = e - static_cast<T>(rhs.R_component_5());    // exception guard
   418                 T    ft = f - static_cast<T>(rhs.R_component_6());    // exception guard
   419                 T    gt = g - static_cast<T>(rhs.R_component_7());    // exception guard
   420                 T    ht = h - static_cast<T>(rhs.R_component_8());    // exception guard
   421                 
   422                 a = at;
   423                 b = bt;
   424                 c = ct;
   425                 d = dt;
   426                 e = et;
   427                 f = ft;
   428                 g = gt;
   429                 h = ht;
   430                 
   431                 return(*this);
   432             }
   433             
   434             
   435             octonion<T> &            operator *= (T const & rhs)
   436             {
   437                 T    at = a * rhs;    // exception guard
   438                 T    bt = b * rhs;    // exception guard
   439                 T    ct = c * rhs;    // exception guard
   440                 T    dt = d * rhs;    // exception guard
   441                 T    et = e * rhs;    // exception guard
   442                 T    ft = f * rhs;    // exception guard
   443                 T    gt = g * rhs;    // exception guard
   444                 T    ht = h * rhs;    // exception guard
   445                 
   446                 a = at;
   447                 b = bt;
   448                 c = ct;
   449                 d = dt;
   450                 e = et;
   451                 f = ft;
   452                 g = gt;
   453                 h = ht;
   454                 
   455                 return(*this);
   456             }
   457             
   458             
   459             octonion<T> &            operator *= (::std::complex<T> const & rhs)
   460             {
   461                 T    ar = rhs.real();
   462                 T    br = rhs.imag();
   463                 
   464                 T    at = +a*ar-b*br;
   465                 T    bt = +a*br+b*ar;
   466                 T    ct = +c*ar+d*br;
   467                 T    dt = -c*br+d*ar;
   468                 T    et = +e*ar+f*br;
   469                 T    ft = -e*br+f*ar;
   470                 T    gt = +g*ar-h*br;
   471                 T    ht = +g*br+h*ar;
   472                 
   473                 a = at;
   474                 b = bt;
   475                 c = ct;
   476                 d = dt;
   477                 e = et;
   478                 f = ft;
   479                 g = gt;
   480                 h = ht;
   481                 
   482                 return(*this);
   483             }
   484             
   485             
   486             octonion<T> &            operator *= (::boost::math::quaternion<T> const & rhs)
   487             {
   488                 T    ar = rhs.R_component_1();
   489                 T    br = rhs.R_component_2();
   490                 T    cr = rhs.R_component_2();
   491                 T    dr = rhs.R_component_2();
   492                 
   493                 T    at = +a*ar-b*br-c*cr-d*dr;
   494                 T    bt = +a*br+b*ar+c*dr-d*cr;
   495                 T    ct = +a*cr-b*dr+c*ar+d*br;
   496                 T    dt = +a*dr+b*cr-c*br+d*ar;
   497                 T    et = +e*ar+f*br+g*cr+h*dr;
   498                 T    ft = -e*br+f*ar-g*dr+h*cr;
   499                 T    gt = -e*cr+f*dr+g*ar-h*br;
   500                 T    ht = -e*dr-f*cr+g*br+h*ar;
   501                 
   502                 a = at;
   503                 b = bt;
   504                 c = ct;
   505                 d = dt;
   506                 e = et;
   507                 f = ft;
   508                 g = gt;
   509                 h = ht;
   510                 
   511                 return(*this);
   512             }
   513             
   514             
   515             template<typename X>
   516             octonion<T> &            operator *= (octonion<X> const & rhs)
   517             {
   518                 T    ar = static_cast<T>(rhs.R_component_1());
   519                 T    br = static_cast<T>(rhs.R_component_2());
   520                 T    cr = static_cast<T>(rhs.R_component_3());
   521                 T    dr = static_cast<T>(rhs.R_component_4());
   522                 T    er = static_cast<T>(rhs.R_component_5());
   523                 T    fr = static_cast<T>(rhs.R_component_6());
   524                 T    gr = static_cast<T>(rhs.R_component_7());
   525                 T    hr = static_cast<T>(rhs.R_component_8());
   526                 
   527                 T    at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr;
   528                 T    bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr;
   529                 T    ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr;
   530                 T    dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er;
   531                 T    et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr;
   532                 T    ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr;
   533                 T    gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br;
   534                 T    ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar;
   535                 
   536                 a = at;
   537                 b = bt;
   538                 c = ct;
   539                 d = dt;
   540                 e = et;
   541                 f = ft;
   542                 g = gt;
   543                 h = ht;
   544                 
   545                 return(*this);
   546             }
   547             
   548             
   549             octonion<T> &            operator /= (T const & rhs)
   550             {
   551                 T    at = a / rhs;    // exception guard
   552                 T    bt = b / rhs;    // exception guard
   553                 T    ct = c / rhs;    // exception guard
   554                 T    dt = d / rhs;    // exception guard
   555                 T    et = e / rhs;    // exception guard
   556                 T    ft = f / rhs;    // exception guard
   557                 T    gt = g / rhs;    // exception guard
   558                 T    ht = h / rhs;    // exception guard
   559                 
   560                 a = at;
   561                 b = bt;
   562                 c = ct;
   563                 d = dt;
   564                 e = et;
   565                 f = ft;
   566                 g = gt;
   567                 h = ht;
   568                 
   569                 return(*this);
   570             }
   571             
   572             
   573             octonion<T> &            operator /= (::std::complex<T> const & rhs)
   574             {
   575                 T    ar = rhs.real();
   576                 T    br = rhs.imag();
   577                 
   578                 T    denominator = ar*ar+br*br;
   579                 
   580                 T    at = (+a*ar-b*br)/denominator;
   581                 T    bt = (-a*br+b*ar)/denominator;
   582                 T    ct = (+c*ar-d*br)/denominator;
   583                 T    dt = (+c*br+d*ar)/denominator;
   584                 T    et = (+e*ar-f*br)/denominator;
   585                 T    ft = (+e*br+f*ar)/denominator;
   586                 T    gt = (+g*ar+h*br)/denominator;
   587                 T    ht = (+g*br+h*ar)/denominator;
   588                 
   589                 a = at;
   590                 b = bt;
   591                 c = ct;
   592                 d = dt;
   593                 e = et;
   594                 f = ft;
   595                 g = gt;
   596                 h = ht;
   597                 
   598                 return(*this);
   599             }
   600             
   601             
   602             octonion<T> &            operator /= (::boost::math::quaternion<T> const & rhs)
   603             {
   604                 T    ar = rhs.R_component_1();
   605                 T    br = rhs.R_component_2();
   606                 T    cr = rhs.R_component_2();
   607                 T    dr = rhs.R_component_2();
   608                 
   609                 T    denominator = ar*ar+br*br+cr*cr+dr*dr;
   610                 
   611                 T    at = (+a*ar+b*br+c*cr+d*dr)/denominator;
   612                 T    bt = (-a*br+b*ar-c*dr+d*cr)/denominator;
   613                 T    ct = (-a*cr+b*dr+c*ar-d*br)/denominator;
   614                 T    dt = (-a*dr-b*cr+c*br+d*ar)/denominator;
   615                 T    et = (+e*ar-f*br-g*cr-h*dr)/denominator;
   616                 T    ft = (+e*br+f*ar+g*dr-h*cr)/denominator;
   617                 T    gt = (+e*cr-f*dr+g*ar+h*br)/denominator;
   618                 T    ht = (+e*dr+f*cr-g*br+h*ar)/denominator;
   619                 
   620                 a = at;
   621                 b = bt;
   622                 c = ct;
   623                 d = dt;
   624                 e = et;
   625                 f = ft;
   626                 g = gt;
   627                 h = ht;
   628                 
   629                 return(*this);
   630             }
   631             
   632             
   633             template<typename X>
   634             octonion<T> &            operator /= (octonion<X> const & rhs)
   635             {
   636                 T    ar = static_cast<T>(rhs.R_component_1());
   637                 T    br = static_cast<T>(rhs.R_component_2());
   638                 T    cr = static_cast<T>(rhs.R_component_3());
   639                 T    dr = static_cast<T>(rhs.R_component_4());
   640                 T    er = static_cast<T>(rhs.R_component_5());
   641                 T    fr = static_cast<T>(rhs.R_component_6());
   642                 T    gr = static_cast<T>(rhs.R_component_7());
   643                 T    hr = static_cast<T>(rhs.R_component_8());
   644                 
   645                 T    denominator = ar*ar+br*br+cr*cr+dr*dr+er*er+fr*fr+gr*gr+hr*hr;
   646                 
   647                 T    at = (+a*ar+b*br+c*cr+d*dr+e*er+f*fr+g*gr+h*hr)/denominator;
   648                 T    bt = (-a*br+b*ar-c*dr+d*cr-e*fr+f*er+g*hr-h*gr)/denominator;
   649                 T    ct = (-a*cr+b*dr+c*ar-d*br-e*gr-f*hr+g*er+h*fr)/denominator;
   650                 T    dt = (-a*dr-b*cr+c*br+d*ar-e*hr+f*gr-g*fr+h*er)/denominator;
   651                 T    et = (-a*er+b*fr+c*gr+d*hr+e*ar-f*br-g*cr-h*dr)/denominator;
   652                 T    ft = (-a*fr-b*er+c*hr-d*gr+e*br+f*ar+g*dr-h*cr)/denominator;
   653                 T    gt = (-a*gr-b*hr-c*er+d*fr+e*cr-f*dr+g*ar+h*br)/denominator;
   654                 T    ht = (-a*hr+b*gr-c*fr-d*er+e*dr+f*cr-g*br+h*ar)/denominator;
   655                 
   656                 a = at;
   657                 b = bt;
   658                 c = ct;
   659                 d = dt;
   660                 e = et;
   661                 f = ft;
   662                 g = gt;
   663                 h = ht;
   664                 
   665                 return(*this);
   666             }
   667             
   668             
   669         protected:
   670             
   671             BOOST_OCTONION_MEMBER_DATA_GENERATOR(T)
   672             
   673             
   674         private:
   675             
   676         };
   677         
   678         
   679         // declaration of octonion specialization
   680         
   681         template<>    class octonion<float>;
   682         template<>    class octonion<double>;
   683         template<>    class octonion<long double>;
   684         
   685         
   686         // helper templates for converting copy constructors (declaration)
   687         
   688         namespace detail
   689         {
   690             
   691             template<   typename T,
   692                         typename U
   693                     >
   694             octonion<T>    octonion_type_converter(octonion<U> const & rhs);
   695         }
   696         
   697         
   698         // implementation of octonion specialization
   699         
   700         
   701 #define    BOOST_OCTONION_CONSTRUCTOR_GENERATOR(type)                                                                               \
   702             explicit                    octonion(   type const & requested_a = static_cast<type>(0),                                \
   703                                                     type const & requested_b = static_cast<type>(0),                                \
   704                                                     type const & requested_c = static_cast<type>(0),                                \
   705                                                     type const & requested_d = static_cast<type>(0),                                \
   706                                                     type const & requested_e = static_cast<type>(0),                                \
   707                                                     type const & requested_f = static_cast<type>(0),                                \
   708                                                     type const & requested_g = static_cast<type>(0),                                \
   709                                                     type const & requested_h = static_cast<type>(0))                                \
   710             :   a(requested_a),                                                                                                     \
   711                 b(requested_b),                                                                                                     \
   712                 c(requested_c),                                                                                                     \
   713                 d(requested_d),                                                                                                     \
   714                 e(requested_e),                                                                                                     \
   715                 f(requested_f),                                                                                                     \
   716                 g(requested_g),                                                                                                     \
   717                 h(requested_h)                                                                                                      \
   718             {                                                                                                                       \
   719             }                                                                                                                       \
   720                                                                                                                                     \
   721             explicit                    octonion(   ::std::complex<type> const & z0,                                                \
   722                                                     ::std::complex<type> const & z1 = ::std::complex<type>(),                       \
   723                                                     ::std::complex<type> const & z2 = ::std::complex<type>(),                       \
   724                                                     ::std::complex<type> const & z3 = ::std::complex<type>())                       \
   725             :   a(z0.real()),                                                                                                       \
   726                 b(z0.imag()),                                                                                                       \
   727                 c(z1.real()),                                                                                                       \
   728                 d(z1.imag()),                                                                                                       \
   729                 e(z2.real()),                                                                                                       \
   730                 f(z2.imag()),                                                                                                       \
   731                 g(z3.real()),                                                                                                       \
   732                 h(z3.imag())                                                                                                        \
   733             {                                                                                                                       \
   734             }                                                                                                                       \
   735                                                                                                                                     \
   736             explicit                    octonion(   ::boost::math::quaternion<type> const & q0,                                     \
   737                                                     ::boost::math::quaternion<type> const & q1 = ::boost::math::quaternion<type>()) \
   738             :   a(q0.R_component_1()),                                                                                              \
   739                 b(q0.R_component_2()),                                                                                              \
   740                 c(q0.R_component_3()),                                                                                              \
   741                 d(q0.R_component_4()),                                                                                              \
   742                 e(q1.R_component_1()),                                                                                              \
   743                 f(q1.R_component_2()),                                                                                              \
   744                 g(q1.R_component_3()),                                                                                              \
   745                 h(q1.R_component_4())                                                                                               \
   746             {                                                                                                                       \
   747             }
   748         
   749     
   750 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type)                  \
   751             octonion<type> &            operator += (type const & rhs)  \
   752             {                                                           \
   753                 a += rhs;                                               \
   754                                                                         \
   755                 return(*this);                                          \
   756             }
   757     
   758 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type)                                  \
   759             octonion<type> &            operator += (::std::complex<type> const & rhs)  \
   760             {                                                                           \
   761                 a += rhs.real();                                                        \
   762                 b += rhs.imag();                                                        \
   763                                                                                         \
   764                 return(*this);                                                          \
   765             }
   766     
   767 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type)                                              \
   768             octonion<type> &            operator += (::boost::math::quaternion<type> const & rhs)   \
   769             {                                                                                       \
   770                 a += rhs.R_component_1();                                                           \
   771                 b += rhs.R_component_2();                                                           \
   772                 c += rhs.R_component_3();                                                           \
   773                 d += rhs.R_component_4();                                                           \
   774                                                                                                     \
   775                 return(*this);                                                                      \
   776             }
   777     
   778 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type)                          \
   779             template<typename X>                                                \
   780             octonion<type> &            operator += (octonion<X> const & rhs)   \
   781             {                                                                   \
   782                 a += static_cast<type>(rhs.R_component_1());                    \
   783                 b += static_cast<type>(rhs.R_component_2());                    \
   784                 c += static_cast<type>(rhs.R_component_3());                    \
   785                 d += static_cast<type>(rhs.R_component_4());                    \
   786                 e += static_cast<type>(rhs.R_component_5());                    \
   787                 f += static_cast<type>(rhs.R_component_6());                    \
   788                 g += static_cast<type>(rhs.R_component_7());                    \
   789                 h += static_cast<type>(rhs.R_component_8());                    \
   790                                                                                 \
   791                 return(*this);                                                  \
   792             }
   793     
   794 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type)                  \
   795             octonion<type> &            operator -= (type const & rhs)  \
   796             {                                                           \
   797                 a -= rhs;                                               \
   798                                                                         \
   799                 return(*this);                                          \
   800             }
   801     
   802 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type)                                  \
   803             octonion<type> &            operator -= (::std::complex<type> const & rhs)  \
   804             {                                                                           \
   805                 a -= rhs.real();                                                        \
   806                 b -= rhs.imag();                                                        \
   807                                                                                         \
   808                 return(*this);                                                          \
   809             }
   810     
   811 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type)                                              \
   812             octonion<type> &            operator -= (::boost::math::quaternion<type> const & rhs)   \
   813             {                                                                                       \
   814                 a -= rhs.R_component_1();                                                           \
   815                 b -= rhs.R_component_2();                                                           \
   816                 c -= rhs.R_component_3();                                                           \
   817                 d -= rhs.R_component_4();                                                           \
   818                                                                                                     \
   819                 return(*this);                                                                      \
   820             }
   821     
   822 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type)                        \
   823             template<typename X>                                              \
   824             octonion<type> &            operator -= (octonion<X> const & rhs) \
   825             {                                                                 \
   826                 a -= static_cast<type>(rhs.R_component_1());                  \
   827                 b -= static_cast<type>(rhs.R_component_2());                  \
   828                 c -= static_cast<type>(rhs.R_component_3());                  \
   829                 d -= static_cast<type>(rhs.R_component_4());                  \
   830                 e -= static_cast<type>(rhs.R_component_5());                  \
   831                 f -= static_cast<type>(rhs.R_component_6());                  \
   832                 g -= static_cast<type>(rhs.R_component_7());                  \
   833                 h -= static_cast<type>(rhs.R_component_8());                  \
   834                                                                               \
   835                 return(*this);                                                \
   836             }
   837     
   838 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type)                   \
   839             octonion<type> &            operator *= (type const & rhs)   \
   840             {                                                            \
   841                 a *= rhs;                                                \
   842                 b *= rhs;                                                \
   843                 c *= rhs;                                                \
   844                 d *= rhs;                                                \
   845                 e *= rhs;                                                \
   846                 f *= rhs;                                                \
   847                 g *= rhs;                                                \
   848                 h *= rhs;                                                \
   849                                                                          \
   850                 return(*this);                                           \
   851             }
   852     
   853 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type)                                  \
   854             octonion<type> &            operator *= (::std::complex<type> const & rhs)  \
   855             {                                                                           \
   856                 type    ar = rhs.real();                                                \
   857                 type    br = rhs.imag();                                                \
   858                                                                                         \
   859                 type    at = +a*ar-b*br;                                                \
   860                 type    bt = +a*br+b*ar;                                                \
   861                 type    ct = +c*ar+d*br;                                                \
   862                 type    dt = -c*br+d*ar;                                                \
   863                 type    et = +e*ar+f*br;                                                \
   864                 type    ft = -e*br+f*ar;                                                \
   865                 type    gt = +g*ar-h*br;                                                \
   866                 type    ht = +g*br+h*ar;                                                \
   867                                                                                         \
   868                 a = at;                                                                 \
   869                 b = bt;                                                                 \
   870                 c = ct;                                                                 \
   871                 d = dt;                                                                 \
   872                 e = et;                                                                 \
   873                 f = ft;                                                                 \
   874                 g = gt;                                                                 \
   875                 h = ht;                                                                 \
   876                                                                                         \
   877                 return(*this);                                                          \
   878             }
   879     
   880 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type)                                                    \
   881             octonion<type> &            operator *= (::boost::math::quaternion<type> const & rhs)   \
   882             {                                                                                       \
   883                 type    ar = rhs.R_component_1();                                                   \
   884                 type    br = rhs.R_component_2();                                                   \
   885                 type    cr = rhs.R_component_2();                                                   \
   886                 type    dr = rhs.R_component_2();                                                   \
   887                                                                                                     \
   888                 type    at = +a*ar-b*br-c*cr-d*dr;                                                  \
   889                 type    bt = +a*br+b*ar+c*dr-d*cr;                                                  \
   890                 type    ct = +a*cr-b*dr+c*ar+d*br;                                                  \
   891                 type    dt = +a*dr+b*cr-c*br+d*ar;                                                  \
   892                 type    et = +e*ar+f*br+g*cr+h*dr;                                                  \
   893                 type    ft = -e*br+f*ar-g*dr+h*cr;                                                  \
   894                 type    gt = -e*cr+f*dr+g*ar-h*br;                                                  \
   895                 type    ht = -e*dr-f*cr+g*br+h*ar;                                                  \
   896                                                                                                     \
   897                 a = at;                                                                             \
   898                 b = bt;                                                                             \
   899                 c = ct;                                                                             \
   900                 d = dt;                                                                             \
   901                 e = et;                                                                             \
   902                 f = ft;                                                                             \
   903                 g = gt;                                                                             \
   904                 h = ht;                                                                             \
   905                                                                                                     \
   906                 return(*this);                                                                      \
   907             }
   908     
   909 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type)                          \
   910             template<typename X>                                                \
   911             octonion<type> &            operator *= (octonion<X> const & rhs)   \
   912             {                                                                   \
   913                 type    ar = static_cast<type>(rhs.R_component_1());            \
   914                 type    br = static_cast<type>(rhs.R_component_2());            \
   915                 type    cr = static_cast<type>(rhs.R_component_3());            \
   916                 type    dr = static_cast<type>(rhs.R_component_4());            \
   917                 type    er = static_cast<type>(rhs.R_component_5());            \
   918                 type    fr = static_cast<type>(rhs.R_component_6());            \
   919                 type    gr = static_cast<type>(rhs.R_component_7());            \
   920                 type    hr = static_cast<type>(rhs.R_component_8());            \
   921                                                                                 \
   922                 type    at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr;          \
   923                 type    bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr;          \
   924                 type    ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr;          \
   925                 type    dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er;          \
   926                 type    et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr;          \
   927                 type    ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr;          \
   928                 type    gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br;          \
   929                 type    ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar;          \
   930                                                                                 \
   931                 a = at;                                                         \
   932                 b = bt;                                                         \
   933                 c = ct;                                                         \
   934                 d = dt;                                                         \
   935                 e = et;                                                         \
   936                 f = ft;                                                         \
   937                 g = gt;                                                         \
   938                 h = ht;                                                         \
   939                                                                                 \
   940                 return(*this);                                                  \
   941             }
   942     
   943 // There is quite a lot of repetition in the code below. This is intentional.
   944 // The last conditional block is the normal form, and the others merely
   945 // consist of workarounds for various compiler deficiencies. Hopefuly, when
   946 // more compilers are conformant and we can retire support for those that are
   947 // not, we will be able to remove the clutter. This is makes the situation
   948 // (painfully) explicit.
   949     
   950 #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type)                  \
   951             octonion<type> &            operator /= (type const & rhs)  \
   952             {                                                           \
   953                 a /= rhs;                                               \
   954                 b /= rhs;                                               \
   955                 c /= rhs;                                               \
   956                 d /= rhs;                                               \
   957                                                                         \
   958                 return(*this);                                          \
   959             }
   960     
   961 #if defined(__GNUC__) && (__GNUC__ < 3)
   962     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)                                              \
   963             octonion<type> &            operator /= (::std::complex<type> const & rhs)                  \
   964             {                                                                                           \
   965                 using    ::std::valarray;                                                               \
   966                                                                                                         \
   967                 valarray<type>    tr(2);                                                                \
   968                                                                                                         \
   969                 tr[0] = rhs.real();                                                                     \
   970                 tr[1] = rhs.imag();                                                                     \
   971                                                                                                         \
   972                 type            mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();  \
   973                                                                                                         \
   974                 tr *= mixam;                                                                            \
   975                                                                                                         \
   976                 valarray<type>    tt(8);                                                                \
   977                                                                                                         \
   978                 tt[0] = +a*tr[0]-b*tr[1];                                                               \
   979                 tt[1] = -a*tr[1]+b*tr[0];                                                               \
   980                 tt[2] = +c*tr[0]-d*tr[1];                                                               \
   981                 tt[3] = +c*tr[1]+d*tr[0];                                                               \
   982                 tt[4] = +e*tr[0]-f*tr[1];                                                               \
   983                 tt[5] = +e*tr[1]+f*tr[0];                                                               \
   984                 tt[6] = +g*tr[0]+h*tr[1];                                                               \
   985                 tt[7] = +g*tr[1]+h*tr[0];                                                               \
   986                                                                                                         \
   987                 tr *= tr;                                                                               \
   988                                                                                                         \
   989                 tt *= (mixam/tr.sum());                                                                 \
   990                                                                                                         \
   991                 a = tt[0];                                                                              \
   992                 b = tt[1];                                                                              \
   993                 c = tt[2];                                                                              \
   994                 d = tt[3];                                                                              \
   995                 e = tt[4];                                                                              \
   996                 f = tt[5];                                                                              \
   997                 g = tt[6];                                                                              \
   998                 h = tt[7];                                                                              \
   999                                                                                                         \
  1000                 return(*this);                                                                          \
  1001             }
  1002 #elif    defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
  1003     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)                              \
  1004             octonion<type> &            operator /= (::std::complex<type> const & rhs)  \
  1005             {                                                                           \
  1006                 using    ::std::valarray;                                               \
  1007                 using    ::std::abs;                                                    \
  1008                                                                                         \
  1009                 valarray<type>    tr(2);                                                \
  1010                                                                                         \
  1011                 tr[0] = rhs.real();                                                     \
  1012                 tr[1] = rhs.imag();                                                     \
  1013                                                                                         \
  1014                 type            mixam = static_cast<type>(1)/(abs(tr).max)();           \
  1015                                                                                         \
  1016                 tr *= mixam;                                                            \
  1017                                                                                         \
  1018                 valarray<type>    tt(8);                                                \
  1019                                                                                         \
  1020                 tt[0] = +a*tr[0]-b*tr[1];                                               \
  1021                 tt[1] = -a*tr[1]+b*tr[0];                                               \
  1022                 tt[2] = +c*tr[0]-d*tr[1];                                               \
  1023                 tt[3] = +c*tr[1]+d*tr[0];                                               \
  1024                 tt[4] = +e*tr[0]-f*tr[1];                                               \
  1025                 tt[5] = +e*tr[1]+f*tr[0];                                               \
  1026                 tt[6] = +g*tr[0]+h*tr[1];                                               \
  1027                 tt[7] = +g*tr[1]+h*tr[0];                                               \
  1028                                                                                         \
  1029                 tr *= tr;                                                               \
  1030                                                                                         \
  1031                 tt *= (mixam/tr.sum());                                                 \
  1032                                                                                         \
  1033                 a = tt[0];                                                              \
  1034                 b = tt[1];                                                              \
  1035                 c = tt[2];                                                              \
  1036                 d = tt[3];                                                              \
  1037                 e = tt[4];                                                              \
  1038                 f = tt[5];                                                              \
  1039                 g = tt[6];                                                              \
  1040                 h = tt[7];                                                              \
  1041                                                                                         \
  1042                 return(*this);                                                          \
  1043             }
  1044 #else
  1045     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)                              \
  1046             octonion<type> &            operator /= (::std::complex<type> const & rhs)  \
  1047             {                                                                           \
  1048                 using    ::std::valarray;                                               \
  1049                                                                                         \
  1050                 valarray<type>    tr(2);                                                \
  1051                                                                                         \
  1052                 tr[0] = rhs.real();                                                     \
  1053                 tr[1] = rhs.imag();                                                     \
  1054                                                                                         \
  1055                 type            mixam = static_cast<type>(1)/(abs(tr).max)();           \
  1056                                                                                         \
  1057                 tr *= mixam;                                                            \
  1058                                                                                         \
  1059                 valarray<type>    tt(8);                                                \
  1060                                                                                         \
  1061                 tt[0] = +a*tr[0]-b*tr[1];                                               \
  1062                 tt[1] = -a*tr[1]+b*tr[0];                                               \
  1063                 tt[2] = +c*tr[0]-d*tr[1];                                               \
  1064                 tt[3] = +c*tr[1]+d*tr[0];                                               \
  1065                 tt[4] = +e*tr[0]-f*tr[1];                                               \
  1066                 tt[5] = +e*tr[1]+f*tr[0];                                               \
  1067                 tt[6] = +g*tr[0]+h*tr[1];                                               \
  1068                 tt[7] = +g*tr[1]+h*tr[0];                                               \
  1069                                                                                         \
  1070                 tr *= tr;                                                               \
  1071                                                                                         \
  1072                 tt *= (mixam/tr.sum());                                                 \
  1073                                                                                         \
  1074                 a = tt[0];                                                              \
  1075                 b = tt[1];                                                              \
  1076                 c = tt[2];                                                              \
  1077                 d = tt[3];                                                              \
  1078                 e = tt[4];                                                              \
  1079                 f = tt[5];                                                              \
  1080                 g = tt[6];                                                              \
  1081                 h = tt[7];                                                              \
  1082                                                                                         \
  1083                 return(*this);                                                          \
  1084             }
  1085 #endif    /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
  1086     
  1087 #if defined(__GNUC__) && (__GNUC__ < 3)
  1088     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)                                           \
  1089             octonion<type> &            operator /= (::boost::math::quaternion<type> const & rhs)    \
  1090             {                                                                                        \
  1091                 using    ::std::valarray;                                                            \
  1092                                                                                                      \
  1093                 valarray<type>    tr(4);                                                             \
  1094                                                                                                      \
  1095                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
  1096                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
  1097                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
  1098                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
  1099                                                                                                      \
  1100                 type           mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();\
  1101                                                                                                      \
  1102                 tr *= mixam;                                                                         \
  1103                                                                                                      \
  1104                 valarray<type>    tt(8);                                                             \
  1105                                                                                                      \
  1106                 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                                            \
  1107                 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                                            \
  1108                 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                                            \
  1109                 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                                            \
  1110                 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];                                            \
  1111                 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];                                            \
  1112                 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];                                            \
  1113                 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];                                            \
  1114                                                                                                      \
  1115                 tr *= tr;                                                                            \
  1116                                                                                                      \
  1117                 tt *= (mixam/tr.sum());                                                              \
  1118                                                                                                      \
  1119                 a = tt[0];                                                                           \
  1120                 b = tt[1];                                                                           \
  1121                 c = tt[2];                                                                           \
  1122                 d = tt[3];                                                                           \
  1123                 e = tt[4];                                                                           \
  1124                 f = tt[5];                                                                           \
  1125                 g = tt[6];                                                                           \
  1126                 h = tt[7];                                                                           \
  1127                                                                                                      \
  1128                 return(*this);                                                                       \
  1129             }
  1130 #elif    defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
  1131     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)                                           \
  1132             octonion<type> &            operator /= (::boost::math::quaternion<type> const & rhs)    \
  1133             {                                                                                        \
  1134                 using    ::std::valarray;                                                            \
  1135                 using    ::std::abs;                                                                 \
  1136                                                                                                      \
  1137                 valarray<type>    tr(4);                                                             \
  1138                                                                                                      \
  1139                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
  1140                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
  1141                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
  1142                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
  1143                                                                                                      \
  1144                 type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \
  1145                                                                                                      \
  1146                 tr *= mixam;                                                                         \
  1147                                                                                                      \
  1148                 valarray<type>    tt(8);                                                             \
  1149                                                                                                      \
  1150                 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                                            \
  1151                 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                                            \
  1152                 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                                            \
  1153                 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                                            \
  1154                 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];                                            \
  1155                 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];                                            \
  1156                 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];                                            \
  1157                 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];                                            \
  1158                                                                                                      \
  1159                 tr *= tr;                                                                            \
  1160                                                                                                      \
  1161                 tt *= (mixam/tr.sum());                                                              \
  1162                                                                                                      \
  1163                 a = tt[0];                                                                           \
  1164                 b = tt[1];                                                                           \
  1165                 c = tt[2];                                                                           \
  1166                 d = tt[3];                                                                           \
  1167                 e = tt[4];                                                                           \
  1168                 f = tt[5];                                                                           \
  1169                 g = tt[6];                                                                           \
  1170                 h = tt[7];                                                                           \
  1171                                                                                                      \
  1172                 return(*this);                                                                       \
  1173             }
  1174 #else
  1175     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)                                           \
  1176             octonion<type> &            operator /= (::boost::math::quaternion<type> const & rhs)    \
  1177             {                                                                                        \
  1178                 using    ::std::valarray;                                                            \
  1179                                                                                                      \
  1180                 valarray<type>    tr(4);                                                             \
  1181                                                                                                      \
  1182                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
  1183                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
  1184                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
  1185                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
  1186                                                                                                      \
  1187                 type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \
  1188                                                                                                      \
  1189                 tr *= mixam;                                                                         \
  1190                                                                                                      \
  1191                 valarray<type>    tt(8);                                                             \
  1192                                                                                                      \
  1193                 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                                            \
  1194                 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                                            \
  1195                 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                                            \
  1196                 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                                            \
  1197                 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];                                            \
  1198                 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];                                            \
  1199                 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];                                            \
  1200                 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];                                            \
  1201                                                                                                      \
  1202                 tr *= tr;                                                                            \
  1203                                                                                                      \
  1204                 tt *= (mixam/tr.sum());                                                              \
  1205                                                                                                      \
  1206                 a = tt[0];                                                                           \
  1207                 b = tt[1];                                                                           \
  1208                 c = tt[2];                                                                           \
  1209                 d = tt[3];                                                                           \
  1210                 e = tt[4];                                                                           \
  1211                 f = tt[5];                                                                           \
  1212                 g = tt[6];                                                                           \
  1213                 h = tt[7];                                                                           \
  1214                                                                                                      \
  1215                 return(*this);                                                                       \
  1216             }
  1217 #endif    /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
  1218     
  1219 #if defined(__GNUC__) && (__GNUC__ < 3)
  1220     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)                                           \
  1221             template<typename X>                                                                     \
  1222             octonion<type> &            operator /= (octonion<X> const & rhs)                        \
  1223             {                                                                                        \
  1224                 using    ::std::valarray;                                                            \
  1225                                                                                                      \
  1226                 valarray<type>    tr(8);                                                             \
  1227                                                                                                      \
  1228                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
  1229                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
  1230                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
  1231                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
  1232                 tr[4] = static_cast<type>(rhs.R_component_5());                                      \
  1233                 tr[5] = static_cast<type>(rhs.R_component_6());                                      \
  1234                 tr[6] = static_cast<type>(rhs.R_component_7());                                      \
  1235                 tr[7] = static_cast<type>(rhs.R_component_8());                                      \
  1236                                                                                                      \
  1237                 type           mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();\
  1238                                                                                                      \
  1239                 tr *= mixam;                                                                         \
  1240                                                                                                      \
  1241                 valarray<type>    tt(8);                                                             \
  1242                                                                                                      \
  1243                 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];            \
  1244                 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];            \
  1245                 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];            \
  1246                 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];            \
  1247                 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];            \
  1248                 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];            \
  1249                 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];            \
  1250                 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];            \
  1251                                                                                                      \
  1252                 tr *= tr;                                                                            \
  1253                                                                                                      \
  1254                 tt *= (mixam/tr.sum());                                                              \
  1255                                                                                                      \
  1256                 a = tt[0];                                                                           \
  1257                 b = tt[1];                                                                           \
  1258                 c = tt[2];                                                                           \
  1259                 d = tt[3];                                                                           \
  1260                 e = tt[4];                                                                           \
  1261                 f = tt[5];                                                                           \
  1262                 g = tt[6];                                                                           \
  1263                 h = tt[7];                                                                           \
  1264                                                                                                      \
  1265                 return(*this);                                                                       \
  1266             }
  1267 #elif    defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
  1268     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)                                           \
  1269             template<typename X>                                                                     \
  1270             octonion<type> &            operator /= (octonion<X> const & rhs)                        \
  1271             {                                                                                        \
  1272                 using    ::std::valarray;                                                            \
  1273                 using    ::std::abs;                                                                 \
  1274                                                                                                      \
  1275                 valarray<type>    tr(8);                                                             \
  1276                                                                                                      \
  1277                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
  1278                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
  1279                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
  1280                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
  1281                 tr[4] = static_cast<type>(rhs.R_component_5());                                      \
  1282                 tr[5] = static_cast<type>(rhs.R_component_6());                                      \
  1283                 tr[6] = static_cast<type>(rhs.R_component_7());                                      \
  1284                 tr[7] = static_cast<type>(rhs.R_component_8());                                      \
  1285                                                                                                      \
  1286                 type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \
  1287                                                                                                      \
  1288                 tr *= mixam;                                                                         \
  1289                                                                                                      \
  1290                 valarray<type>    tt(8);                                                             \
  1291                                                                                                      \
  1292                 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];            \
  1293                 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];            \
  1294                 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];            \
  1295                 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];            \
  1296                 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];            \
  1297                 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];            \
  1298                 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];            \
  1299                 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];            \
  1300                                                                                                      \
  1301                 tr *= tr;                                                                            \
  1302                                                                                                      \
  1303                 tt *= (mixam/tr.sum());                                                              \
  1304                                                                                                      \
  1305                 a = tt[0];                                                                           \
  1306                 b = tt[1];                                                                           \
  1307                 c = tt[2];                                                                           \
  1308                 d = tt[3];                                                                           \
  1309                 e = tt[4];                                                                           \
  1310                 f = tt[5];                                                                           \
  1311                 g = tt[6];                                                                           \
  1312                 h = tt[7];                                                                           \
  1313                                                                                                      \
  1314                 return(*this);                                                                       \
  1315             }
  1316 #else
  1317     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)                                           \
  1318             template<typename X>                                                                     \
  1319             octonion<type> &            operator /= (octonion<X> const & rhs)                        \
  1320             {                                                                                        \
  1321                 using    ::std::valarray;                                                            \
  1322                                                                                                      \
  1323                 valarray<type>    tr(8);                                                             \
  1324                                                                                                      \
  1325                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
  1326                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
  1327                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
  1328                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
  1329                 tr[4] = static_cast<type>(rhs.R_component_5());                                      \
  1330                 tr[5] = static_cast<type>(rhs.R_component_6());                                      \
  1331                 tr[6] = static_cast<type>(rhs.R_component_7());                                      \
  1332                 tr[7] = static_cast<type>(rhs.R_component_8());                                      \
  1333                                                                                                      \
  1334                 type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \
  1335                                                                                                      \
  1336                 tr *= mixam;                                                                         \
  1337                                                                                                      \
  1338                 valarray<type>    tt(8);                                                             \
  1339                                                                                                      \
  1340                 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];            \
  1341                 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];            \
  1342                 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];            \
  1343                 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];            \
  1344                 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];            \
  1345                 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];            \
  1346                 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];            \
  1347                 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];            \
  1348                                                                                                      \
  1349                 tr *= tr;                                                                            \
  1350                                                                                                      \
  1351                 tt *= (mixam/tr.sum());                                                              \
  1352                                                                                                      \
  1353                 a = tt[0];                                                                           \
  1354                 b = tt[1];                                                                           \
  1355                 c = tt[2];                                                                           \
  1356                 d = tt[3];                                                                           \
  1357                 e = tt[4];                                                                           \
  1358                 f = tt[5];                                                                           \
  1359                 g = tt[6];                                                                           \
  1360                 h = tt[7];                                                                           \
  1361                                                                                                      \
  1362                 return(*this);                                                                       \
  1363             }
  1364 #endif    /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
  1365     
  1366     
  1367 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR(type)       \
  1368         BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type)        \
  1369         BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type)        \
  1370         BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type)        \
  1371         BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type)
  1372         
  1373 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR(type)       \
  1374         BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type)        \
  1375         BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type)        \
  1376         BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type)        \
  1377         BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type)
  1378         
  1379 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR(type)       \
  1380         BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type)        \
  1381         BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type)        \
  1382         BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type)        \
  1383         BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type)
  1384         
  1385 #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR(type)       \
  1386         BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type)        \
  1387         BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)        \
  1388         BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)        \
  1389         BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)
  1390         
  1391 #define    BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(type) \
  1392         BOOST_OCTONION_MEMBER_ADD_GENERATOR(type)          \
  1393         BOOST_OCTONION_MEMBER_SUB_GENERATOR(type)          \
  1394         BOOST_OCTONION_MEMBER_MUL_GENERATOR(type)          \
  1395         BOOST_OCTONION_MEMBER_DIV_GENERATOR(type)
  1396         
  1397         
  1398         template<>
  1399         class octonion<float>
  1400         {
  1401         public:
  1402             
  1403             typedef float value_type;
  1404             
  1405             BOOST_OCTONION_CONSTRUCTOR_GENERATOR(float)
  1406             
  1407             // UNtemplated copy constructor
  1408             // (this is taken care of by the compiler itself)
  1409             
  1410             // explicit copy constructors (precision-loosing converters)
  1411             
  1412             explicit                    octonion(octonion<double> const & a_recopier)
  1413             {
  1414                 *this = detail::octonion_type_converter<float, double>(a_recopier);
  1415             }
  1416             
  1417             explicit                    octonion(octonion<long double> const & a_recopier)
  1418             {
  1419                 *this = detail::octonion_type_converter<float, long double>(a_recopier);
  1420             }
  1421             
  1422             // destructor
  1423             // (this is taken care of by the compiler itself)
  1424             
  1425             // accessors
  1426             //
  1427             // Note:    Like complex number, octonions do have a meaningful notion of "real part",
  1428             //            but unlike them there is no meaningful notion of "imaginary part".
  1429             //            Instead there is an "unreal part" which itself is an octonion, and usually
  1430             //            nothing simpler (as opposed to the complex number case).
  1431             //            However, for practicallity, there are accessors for the other components
  1432             //            (these are necessary for the templated copy constructor, for instance).
  1433             
  1434             BOOST_OCTONION_ACCESSOR_GENERATOR(float)
  1435             
  1436             // assignment operators
  1437             
  1438             BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(float)
  1439             
  1440             // other assignment-related operators
  1441             //
  1442             // NOTE:    Octonion multiplication is *NOT* commutative;
  1443             //            symbolically, "q *= rhs;" means "q = q * rhs;"
  1444             //            and "q /= rhs;" means "q = q * inverse_of(rhs);";
  1445             //            octonion multiplication is also *NOT* associative
  1446             
  1447             BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(float)
  1448             
  1449             
  1450         protected:
  1451             
  1452             BOOST_OCTONION_MEMBER_DATA_GENERATOR(float)
  1453             
  1454             
  1455         private:
  1456             
  1457         };
  1458         
  1459         
  1460         template<>
  1461         class octonion<double>
  1462         {
  1463         public:
  1464             
  1465             typedef double value_type;
  1466             
  1467             BOOST_OCTONION_CONSTRUCTOR_GENERATOR(double)
  1468             
  1469             // UNtemplated copy constructor
  1470             // (this is taken care of by the compiler itself)
  1471             
  1472             // converting copy constructor
  1473             
  1474             explicit                    octonion(octonion<float> const & a_recopier)
  1475             {
  1476                 *this = detail::octonion_type_converter<double, float>(a_recopier);
  1477             }
  1478             
  1479             // explicit copy constructors (precision-loosing converters)
  1480             
  1481             explicit                    octonion(octonion<long double> const & a_recopier)
  1482             {
  1483                 *this = detail::octonion_type_converter<double, long double>(a_recopier);
  1484             }
  1485             
  1486             // destructor
  1487             // (this is taken care of by the compiler itself)
  1488             
  1489             // accessors
  1490             //
  1491             // Note:    Like complex number, octonions do have a meaningful notion of "real part",
  1492             //            but unlike them there is no meaningful notion of "imaginary part".
  1493             //            Instead there is an "unreal part" which itself is an octonion, and usually
  1494             //            nothing simpler (as opposed to the complex number case).
  1495             //            However, for practicallity, there are accessors for the other components
  1496             //            (these are necessary for the templated copy constructor, for instance).
  1497             
  1498             BOOST_OCTONION_ACCESSOR_GENERATOR(double)
  1499             
  1500             // assignment operators
  1501             
  1502             BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(double)
  1503             
  1504             // other assignment-related operators
  1505             //
  1506             // NOTE:    Octonion multiplication is *NOT* commutative;
  1507             //            symbolically, "q *= rhs;" means "q = q * rhs;"
  1508             //            and "q /= rhs;" means "q = q * inverse_of(rhs);";
  1509             //            octonion multiplication is also *NOT* associative
  1510             
  1511             BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(double)
  1512             
  1513             
  1514         protected:
  1515             
  1516             BOOST_OCTONION_MEMBER_DATA_GENERATOR(double)
  1517             
  1518             
  1519         private:
  1520             
  1521         };
  1522         
  1523         
  1524         template<>
  1525         class octonion<long double>
  1526         {
  1527         public:
  1528             
  1529             typedef long double value_type;
  1530             
  1531             BOOST_OCTONION_CONSTRUCTOR_GENERATOR(long double)
  1532             
  1533             // UNtemplated copy constructor
  1534             // (this is taken care of by the compiler itself)
  1535             
  1536             // converting copy constructor
  1537             
  1538             explicit                            octonion(octonion<float> const & a_recopier)
  1539             {
  1540                 *this = detail::octonion_type_converter<long double, float>(a_recopier);
  1541             }
  1542             
  1543             
  1544             explicit                            octonion(octonion<double> const & a_recopier)
  1545             {
  1546                 *this = detail::octonion_type_converter<long double, double>(a_recopier);
  1547             }
  1548             
  1549             
  1550             // destructor
  1551             // (this is taken care of by the compiler itself)
  1552             
  1553             // accessors
  1554             //
  1555             // Note:    Like complex number, octonions do have a meaningful notion of "real part",
  1556             //            but unlike them there is no meaningful notion of "imaginary part".
  1557             //            Instead there is an "unreal part" which itself is an octonion, and usually
  1558             //            nothing simpler (as opposed to the complex number case).
  1559             //            However, for practicallity, there are accessors for the other components
  1560             //            (these are necessary for the templated copy constructor, for instance).
  1561             
  1562             BOOST_OCTONION_ACCESSOR_GENERATOR(long double)
  1563             
  1564             // assignment operators
  1565             
  1566             BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(long double)
  1567             
  1568             // other assignment-related operators
  1569             //
  1570             // NOTE:    Octonion multiplication is *NOT* commutative;
  1571             //            symbolically, "q *= rhs;" means "q = q * rhs;"
  1572             //            and "q /= rhs;" means "q = q * inverse_of(rhs);";
  1573             //            octonion multiplication is also *NOT* associative
  1574             
  1575             BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(long double)
  1576             
  1577             
  1578         protected:
  1579             
  1580             BOOST_OCTONION_MEMBER_DATA_GENERATOR(long double)
  1581             
  1582             
  1583         private:
  1584             
  1585         };
  1586         
  1587         
  1588 #undef    BOOST_OCTONION_CONSTRUCTOR_GENERATOR
  1589         
  1590 #undef    BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR
  1591     
  1592 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR
  1593 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR
  1594 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR
  1595 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR
  1596     
  1597 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_1
  1598 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_2
  1599 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_3
  1600 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_4
  1601 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_1
  1602 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_2
  1603 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_3
  1604 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_4
  1605 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_1
  1606 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_2
  1607 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_3
  1608 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_4
  1609 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_1
  1610 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2
  1611 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3
  1612 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4
  1613     
  1614     
  1615 #undef    BOOST_OCTONION_MEMBER_DATA_GENERATOR
  1616     
  1617 #undef    BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR
  1618     
  1619 #undef    BOOST_OCTONION_ACCESSOR_GENERATOR
  1620         
  1621         
  1622         // operators
  1623         
  1624 #define    BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) \
  1625         {                                             \
  1626             octonion<T>    res(lhs);                  \
  1627             res op##= rhs;                            \
  1628             return(res);                              \
  1629         }
  1630         
  1631 #define    BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op)                                                                              \
  1632         template<typename T>                                                                                                      \
  1633         inline octonion<T>                        operator op (T const & lhs, octonion<T> const & rhs)                            \
  1634         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
  1635         
  1636 #define    BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op)                                                                              \
  1637         template<typename T>                                                                                                      \
  1638         inline octonion<T>                        operator op (octonion<T> const & lhs, T const & rhs)                            \
  1639         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
  1640         
  1641 #define    BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op)                                                                              \
  1642         template<typename T>                                                                                                      \
  1643         inline octonion<T>                        operator op (::std::complex<T> const & lhs, octonion<T> const & rhs)            \
  1644         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
  1645         
  1646 #define    BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op)                                                                              \
  1647         template<typename T>                                                                                                      \
  1648         inline octonion<T>                        operator op (octonion<T> const & lhs, ::std::complex<T> const & rhs)            \
  1649         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
  1650         
  1651 #define    BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op)                                                                              \
  1652         template<typename T>                                                                                                      \
  1653         inline octonion<T>                        operator op (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs) \
  1654         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
  1655         
  1656 #define    BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op)                                                                              \
  1657         template<typename T>                                                                                                      \
  1658         inline octonion<T>                        operator op (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs) \
  1659         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
  1660         
  1661 #define    BOOST_OCTONION_OPERATOR_GENERATOR_4(op)                                                                                \
  1662         template<typename T>                                                                                                      \
  1663         inline octonion<T>                        operator op (octonion<T> const & lhs, octonion<T> const & rhs)                  \
  1664         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
  1665         
  1666 #define    BOOST_OCTONION_OPERATOR_GENERATOR(op)     \
  1667         BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op)    \
  1668         BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op)    \
  1669         BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op)    \
  1670         BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op)    \
  1671         BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op)    \
  1672         BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op)    \
  1673         BOOST_OCTONION_OPERATOR_GENERATOR_4(op)
  1674         
  1675         
  1676         BOOST_OCTONION_OPERATOR_GENERATOR(+)
  1677         BOOST_OCTONION_OPERATOR_GENERATOR(-)
  1678         BOOST_OCTONION_OPERATOR_GENERATOR(*)
  1679         BOOST_OCTONION_OPERATOR_GENERATOR(/)
  1680         
  1681         
  1682 #undef    BOOST_OCTONION_OPERATOR_GENERATOR
  1683         
  1684 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_1_L
  1685 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_1_R
  1686 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_2_L
  1687 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_2_R
  1688 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_3_L
  1689 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_3_R
  1690 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_4
  1691     
  1692 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_BODY
  1693         
  1694         
  1695         template<typename T>
  1696         inline octonion<T>                        operator + (octonion<T> const & o)
  1697         {
  1698             return(o);
  1699         }
  1700         
  1701         
  1702         template<typename T>
  1703         inline octonion<T>                        operator - (octonion<T> const & o)
  1704         {
  1705             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()));
  1706         }
  1707         
  1708         
  1709         template<typename T>
  1710         inline bool                                operator == (T const & lhs, octonion<T> const & rhs)
  1711         {
  1712             return(
  1713                         (rhs.R_component_1() == lhs)&&
  1714                         (rhs.R_component_2() == static_cast<T>(0))&&
  1715                         (rhs.R_component_3() == static_cast<T>(0))&&
  1716                         (rhs.R_component_4() == static_cast<T>(0))&&
  1717                         (rhs.R_component_5() == static_cast<T>(0))&&
  1718                         (rhs.R_component_6() == static_cast<T>(0))&&
  1719                         (rhs.R_component_7() == static_cast<T>(0))&&
  1720                         (rhs.R_component_8() == static_cast<T>(0))
  1721                     );
  1722         }
  1723         
  1724         
  1725         template<typename T>
  1726         inline bool                                operator == (octonion<T> const & lhs, T const & rhs)
  1727         {
  1728             return(
  1729                         (lhs.R_component_1() == rhs)&&
  1730                         (lhs.R_component_2() == static_cast<T>(0))&&
  1731                         (lhs.R_component_3() == static_cast<T>(0))&&
  1732                         (lhs.R_component_4() == static_cast<T>(0))&&
  1733                         (lhs.R_component_5() == static_cast<T>(0))&&
  1734                         (lhs.R_component_6() == static_cast<T>(0))&&
  1735                         (lhs.R_component_7() == static_cast<T>(0))&&
  1736                         (lhs.R_component_8() == static_cast<T>(0))
  1737                     );
  1738         }
  1739         
  1740         
  1741         template<typename T>
  1742         inline bool                                operator == (::std::complex<T> const & lhs, octonion<T> const & rhs)
  1743         {
  1744             return(
  1745                         (rhs.R_component_1() == lhs.real())&&
  1746                         (rhs.R_component_2() == lhs.imag())&&
  1747                         (rhs.R_component_3() == static_cast<T>(0))&&
  1748                         (rhs.R_component_4() == static_cast<T>(0))&&
  1749                         (rhs.R_component_5() == static_cast<T>(0))&&
  1750                         (rhs.R_component_6() == static_cast<T>(0))&&
  1751                         (rhs.R_component_7() == static_cast<T>(0))&&
  1752                         (rhs.R_component_8() == static_cast<T>(0))
  1753                     );
  1754         }
  1755         
  1756         
  1757         template<typename T>
  1758         inline bool                                operator == (octonion<T> const & lhs, ::std::complex<T> const & rhs)
  1759         {
  1760             return(
  1761                         (lhs.R_component_1() == rhs.real())&&
  1762                         (lhs.R_component_2() == rhs.imag())&&
  1763                         (lhs.R_component_3() == static_cast<T>(0))&&
  1764                         (lhs.R_component_4() == static_cast<T>(0))&&
  1765                         (lhs.R_component_5() == static_cast<T>(0))&&
  1766                         (lhs.R_component_6() == static_cast<T>(0))&&
  1767                         (lhs.R_component_7() == static_cast<T>(0))&&
  1768                         (lhs.R_component_8() == static_cast<T>(0))
  1769                     );
  1770         }
  1771         
  1772         
  1773         template<typename T>
  1774         inline bool                                operator == (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs)
  1775         {
  1776             return(
  1777                         (rhs.R_component_1() == lhs.R_component_1())&&
  1778                         (rhs.R_component_2() == lhs.R_component_2())&&
  1779                         (rhs.R_component_3() == lhs.R_component_3())&&
  1780                         (rhs.R_component_4() == lhs.R_component_4())&&
  1781                         (rhs.R_component_5() == static_cast<T>(0))&&
  1782                         (rhs.R_component_6() == static_cast<T>(0))&&
  1783                         (rhs.R_component_7() == static_cast<T>(0))&&
  1784                         (rhs.R_component_8() == static_cast<T>(0))
  1785                     );
  1786         }
  1787         
  1788         
  1789         template<typename T>
  1790         inline bool                                operator == (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs)
  1791         {
  1792             return(
  1793                         (lhs.R_component_1() == rhs.R_component_1())&&
  1794                         (lhs.R_component_2() == rhs.R_component_2())&&
  1795                         (lhs.R_component_3() == rhs.R_component_3())&&
  1796                         (lhs.R_component_4() == rhs.R_component_4())&&
  1797                         (lhs.R_component_5() == static_cast<T>(0))&&
  1798                         (lhs.R_component_6() == static_cast<T>(0))&&
  1799                         (lhs.R_component_7() == static_cast<T>(0))&&
  1800                         (lhs.R_component_8() == static_cast<T>(0))
  1801                     );
  1802         }
  1803         
  1804         
  1805         template<typename T>
  1806         inline bool                                operator == (octonion<T> const & lhs, octonion<T> const & rhs)
  1807         {
  1808             return(
  1809                         (rhs.R_component_1() == lhs.R_component_1())&&
  1810                         (rhs.R_component_2() == lhs.R_component_2())&&
  1811                         (rhs.R_component_3() == lhs.R_component_3())&&
  1812                         (rhs.R_component_4() == lhs.R_component_4())&&
  1813                         (rhs.R_component_5() == lhs.R_component_5())&&
  1814                         (rhs.R_component_6() == lhs.R_component_6())&&
  1815                         (rhs.R_component_7() == lhs.R_component_7())&&
  1816                         (rhs.R_component_8() == lhs.R_component_8())
  1817                     );
  1818         }
  1819         
  1820         
  1821 #define    BOOST_OCTONION_NOT_EQUAL_GENERATOR \
  1822         {                                     \
  1823             return(!(lhs == rhs));            \
  1824         }
  1825         
  1826         template<typename T>
  1827         inline bool                                operator != (T const & lhs, octonion<T> const & rhs)
  1828         BOOST_OCTONION_NOT_EQUAL_GENERATOR
  1829         
  1830         template<typename T>
  1831         inline bool                                operator != (octonion<T> const & lhs, T const & rhs)
  1832         BOOST_OCTONION_NOT_EQUAL_GENERATOR
  1833         
  1834         template<typename T>
  1835         inline bool                                operator != (::std::complex<T> const & lhs, octonion<T> const & rhs)
  1836         BOOST_OCTONION_NOT_EQUAL_GENERATOR
  1837         
  1838         template<typename T>
  1839         inline bool                                operator != (octonion<T> const & lhs, ::std::complex<T> const & rhs)
  1840         BOOST_OCTONION_NOT_EQUAL_GENERATOR
  1841         
  1842         template<typename T>
  1843         inline bool                                operator != (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs)
  1844         BOOST_OCTONION_NOT_EQUAL_GENERATOR
  1845         
  1846         template<typename T>
  1847         inline bool                                operator != (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs)
  1848         BOOST_OCTONION_NOT_EQUAL_GENERATOR
  1849         
  1850         template<typename T>
  1851         inline bool                                operator != (octonion<T> const & lhs, octonion<T> const & rhs)
  1852         BOOST_OCTONION_NOT_EQUAL_GENERATOR
  1853         
  1854     #undef    BOOST_OCTONION_NOT_EQUAL_GENERATOR
  1855         
  1856         
  1857         // Note:    the default values in the constructors of the complex and quaternions make for
  1858         //            a very complex and ambiguous situation; we have made choices to disambiguate.
  1859         
  1860 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  1861         template<typename T>
  1862         ::std::istream &                        operator >> (    ::std::istream & is,
  1863                                                                 octonion<T>& o)
  1864 #else
  1865         template<typename T, typename charT, class traits>
  1866         ::std::basic_istream<charT,traits> &    operator >> (    ::std::basic_istream<charT,traits> & is,
  1867                                                                 octonion<T> & o)
  1868 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  1869         {
  1870 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  1871             typedef    char    charT;
  1872 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  1873             
  1874 #ifdef     BOOST_NO_STD_LOCALE
  1875 #else
  1876             const ::std::ctype<charT> & ct = ::std::use_facet< ::std::ctype<charT> >(is.getloc());
  1877 #endif /* BOOST_NO_STD_LOCALE */
  1878             
  1879             T    a = T();
  1880             T    b = T();
  1881             T    c = T();
  1882             T    d = T();
  1883             T    e = T();
  1884             T    f = T();
  1885             T    g = T();
  1886             T    h = T();
  1887             
  1888             ::std::complex<T>    u = ::std::complex<T>();
  1889             ::std::complex<T>    v = ::std::complex<T>();
  1890             ::std::complex<T>    x = ::std::complex<T>();
  1891             ::std::complex<T>    y = ::std::complex<T>();
  1892             
  1893             ::boost::math::quaternion<T>    p = ::boost::math::quaternion<T>();
  1894             ::boost::math::quaternion<T>    q = ::boost::math::quaternion<T>();
  1895             
  1896             charT    ch = charT();
  1897             char    cc;
  1898             
  1899             is >> ch;                                        // get the first lexeme
  1900             
  1901             if    (!is.good())    goto finish;
  1902             
  1903 #ifdef    BOOST_NO_STD_LOCALE
  1904             cc = ch;
  1905 #else
  1906             cc = ct.narrow(ch, char());
  1907 #endif /* BOOST_NO_STD_LOCALE */
  1908             
  1909             if    (cc == '(')                            // read "("
  1910             {
  1911                 is >> ch;                                    // get the second lexeme
  1912                 
  1913                 if    (!is.good())    goto finish;
  1914                 
  1915 #ifdef    BOOST_NO_STD_LOCALE
  1916                 cc = ch;
  1917 #else
  1918                 cc = ct.narrow(ch, char());
  1919 #endif /* BOOST_NO_STD_LOCALE */
  1920                 
  1921                 if    (cc == '(')                                // read "(("
  1922                 {
  1923                     is >> ch;                                    // get the third lexeme
  1924                     
  1925                     if    (!is.good())    goto finish;
  1926                     
  1927 #ifdef    BOOST_NO_STD_LOCALE
  1928                     cc = ch;
  1929 #else
  1930                     cc = ct.narrow(ch, char());
  1931 #endif /* BOOST_NO_STD_LOCALE */
  1932                         
  1933                     if    (cc == '(')                                // read "((("
  1934                     {
  1935                         is.putback(ch);
  1936                         
  1937                         is >> u;                                // read "((u"
  1938                         
  1939                         if    (!is.good())    goto finish;
  1940                         
  1941                         is >> ch;                                // get the next lexeme
  1942                         
  1943                         if    (!is.good())    goto finish;
  1944                         
  1945 #ifdef    BOOST_NO_STD_LOCALE
  1946                         cc = ch;
  1947 #else
  1948                         cc = ct.narrow(ch, char());
  1949 #endif /* BOOST_NO_STD_LOCALE */
  1950                         
  1951                         if        (cc == ')')                        // read "((u)"
  1952                         {
  1953                             is >> ch;                                // get the next lexeme
  1954                             
  1955                             if    (!is.good())    goto finish;
  1956                             
  1957 #ifdef    BOOST_NO_STD_LOCALE
  1958                             cc = ch;
  1959 #else
  1960                             cc = ct.narrow(ch, char());
  1961 #endif /* BOOST_NO_STD_LOCALE */
  1962                             
  1963                             if        (cc == ')')                        // format: (((a))), (((a,b)))
  1964                             {
  1965                                 o = octonion<T>(u);
  1966                             }
  1967                             else if    (cc == ',')                        // read "((u),"
  1968                             {
  1969                                 p = ::boost::math::quaternion<T>(u);
  1970                                 
  1971                                 is >> q;                                // read "((u),q"
  1972                                 
  1973                                 if    (!is.good())    goto finish;
  1974                                 
  1975                                 is >> ch;                                // get the next lexeme
  1976                                 
  1977                                 if    (!is.good())    goto finish;
  1978                                 
  1979 #ifdef    BOOST_NO_STD_LOCALE
  1980                                 cc = ch;
  1981 #else
  1982                                 cc = ct.narrow(ch, char());
  1983 #endif /* BOOST_NO_STD_LOCALE */
  1984                                 
  1985                                 if        (cc == ')')                        // format: (((a)),q), (((a,b)),q)
  1986                                 {
  1987                                     o = octonion<T>(p,q);
  1988                                 }
  1989                                 else                                    // error
  1990                                 {
  1991 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  1992                                     is.setstate(::std::ios::failbit);
  1993 #else
  1994                                     is.setstate(::std::ios_base::failbit);
  1995 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  1996                                 }
  1997                             }
  1998                             else                                    // error
  1999                             {
  2000 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2001                                 is.setstate(::std::ios::failbit);
  2002 #else
  2003                                 is.setstate(::std::ios_base::failbit);
  2004 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2005                             }
  2006                         }
  2007                         else if    (cc ==',')                        // read "((u,"
  2008                         {
  2009                             is >> v;                                // read "((u,v"
  2010                             
  2011                             if    (!is.good())    goto finish;
  2012                             
  2013                             is >> ch;                                // get the next lexeme
  2014                             
  2015                             if    (!is.good())    goto finish;
  2016 
  2017 #ifdef    BOOST_NO_STD_LOCALE
  2018                             cc = ch;
  2019 #else
  2020                             cc = ct.narrow(ch, char());
  2021 #endif /* BOOST_NO_STD_LOCALE */
  2022                             
  2023                             if        (cc == ')')                        // read "((u,v)"
  2024                             {
  2025                                 p = ::boost::math::quaternion<T>(u,v);
  2026                                 
  2027                                 is >> ch;                                // get the next lexeme
  2028                                 
  2029                                 if    (!is.good())    goto finish;
  2030 
  2031 #ifdef    BOOST_NO_STD_LOCALE
  2032                                 cc = ch;
  2033 #else
  2034                                 cc = ct.narrow(ch, char());
  2035 #endif /* BOOST_NO_STD_LOCALE */
  2036                                 
  2037                                 if        (cc == ')')                        // format: (((a),v)), (((a,b),v))
  2038                                 {
  2039                                     o = octonion<T>(p);
  2040                                 }
  2041                                 else if    (cc == ',')                        // read "((u,v),"
  2042                                 {
  2043                                     is >> q;                                // read "(p,q"
  2044                                     
  2045                                     if    (!is.good())    goto finish;
  2046                                     
  2047                                     is >> ch;                                // get the next lexeme
  2048                                     
  2049                                     if    (!is.good())    goto finish;
  2050 
  2051 #ifdef    BOOST_NO_STD_LOCALE
  2052                                     cc = ch;
  2053 #else
  2054                                     cc = ct.narrow(ch, char());
  2055 #endif /* BOOST_NO_STD_LOCALE */
  2056                                     
  2057                                     if        (cc == ')')                        // format: (((a),v),q), (((a,b),v),q)
  2058                                     {
  2059                                         o = octonion<T>(p,q);
  2060                                     }
  2061                                     else                                    // error
  2062                                     {
  2063 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2064                                         is.setstate(::std::ios::failbit);
  2065 #else
  2066                                         is.setstate(::std::ios_base::failbit);
  2067 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2068                                     }
  2069                                 }
  2070                                 else                                    // error
  2071                                 {
  2072 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2073                                     is.setstate(::std::ios::failbit);
  2074 #else
  2075                                     is.setstate(::std::ios_base::failbit);
  2076 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2077                                 }
  2078                             }
  2079                             else                                    // error
  2080                             {
  2081 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2082                                 is.setstate(::std::ios::failbit);
  2083 #else
  2084                                 is.setstate(::std::ios_base::failbit);
  2085 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2086                             }
  2087                         }
  2088                         else                                    // error
  2089                         {
  2090 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2091                             is.setstate(::std::ios::failbit);
  2092 #else
  2093                             is.setstate(::std::ios_base::failbit);
  2094 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2095                         }
  2096                     }
  2097                     else                                        // read "((a"
  2098                     {
  2099                         is.putback(ch);
  2100                         
  2101                         is >> a;                                    // we extract the first component
  2102                         
  2103                         if    (!is.good())    goto finish;
  2104                         
  2105                         is >> ch;                                    // get the next lexeme
  2106                         
  2107                         if    (!is.good())    goto finish;
  2108 
  2109 #ifdef    BOOST_NO_STD_LOCALE
  2110                         cc = ch;
  2111 #else
  2112                         cc = ct.narrow(ch, char());
  2113 #endif /* BOOST_NO_STD_LOCALE */
  2114                         
  2115                         if        (cc == ')')                            // read "((a)"
  2116                         {
  2117                             is >> ch;                                    // get the next lexeme
  2118                             
  2119                             if    (!is.good())    goto finish;
  2120 
  2121 #ifdef    BOOST_NO_STD_LOCALE
  2122                             cc = ch;
  2123 #else
  2124                             cc = ct.narrow(ch, char());
  2125 #endif /* BOOST_NO_STD_LOCALE */
  2126                             
  2127                             if        (cc == ')')                            // read "((a))"
  2128                             {
  2129                                 o = octonion<T>(a);
  2130                             }
  2131                             else if    (cc == ',')                            // read "((a),"
  2132                             {
  2133                                 is >> ch;                                    // get the next lexeme
  2134                                 
  2135                                 if    (!is.good())    goto finish;
  2136                                 
  2137 #ifdef    BOOST_NO_STD_LOCALE
  2138                                 cc = ch;
  2139 #else
  2140                                 cc = ct.narrow(ch, char());
  2141 #endif /* BOOST_NO_STD_LOCALE */
  2142                                 
  2143                                 if        (cc == '(')                            // read "((a),("
  2144                                 {
  2145                                     is >> ch;                                    // get the next lexeme
  2146                                     
  2147                                     if    (!is.good())    goto finish;
  2148 
  2149 #ifdef    BOOST_NO_STD_LOCALE
  2150                                     cc = ch;
  2151 #else
  2152                                     cc = ct.narrow(ch, char());
  2153 #endif /* BOOST_NO_STD_LOCALE */
  2154                                     
  2155                                     if        (cc == '(')                            // read "((a),(("
  2156                                     {
  2157                                         is.putback(ch);
  2158                                         
  2159                                         is.putback(ch);                                // we backtrack twice, with the same value!
  2160                                         
  2161                                         is >> q;                                    // read "((a),q"
  2162                                         
  2163                                         if    (!is.good())    goto finish;
  2164                                         
  2165                                         is >> ch;                                    // get the next lexeme
  2166                                         
  2167                                         if    (!is.good())    goto finish;
  2168 
  2169 #ifdef    BOOST_NO_STD_LOCALE
  2170                                         cc = ch;
  2171 #else
  2172                                         cc = ct.narrow(ch, char());
  2173 #endif /* BOOST_NO_STD_LOCALE */
  2174                                         
  2175                                         if        (cc == ')')                            // read "((a),q)"
  2176                                         {
  2177                                             p = ::boost::math::quaternion<T>(a);
  2178                                             
  2179                                             o = octonion<T>(p,q);
  2180                                         }
  2181                                         else                                        // error
  2182                                         {
  2183 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2184                                             is.setstate(::std::ios::failbit);
  2185 #else
  2186                                             is.setstate(::std::ios_base::failbit);
  2187 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2188                                         }
  2189                                     }
  2190                                     else                                        // read "((a),(c" or "((a),(e"
  2191                                     {
  2192                                         is.putback(ch);
  2193                                         
  2194                                         is >> c;
  2195                                         
  2196                                         if    (!is.good())    goto finish;
  2197                                         
  2198                                         is >> ch;                                    // get the next lexeme
  2199                                         
  2200                                         if    (!is.good())    goto finish;
  2201                                         
  2202 #ifdef    BOOST_NO_STD_LOCALE
  2203                                         cc = ch;
  2204 #else
  2205                                         cc = ct.narrow(ch, char());
  2206 #endif /* BOOST_NO_STD_LOCALE */
  2207                                         
  2208                                         if        (cc == ')')                            // read "((a),(c)" (ambiguity resolution)
  2209                                         {
  2210                                             is >> ch;                                    // get the next lexeme
  2211                                             
  2212                                             if    (!is.good())    goto finish;
  2213                                             
  2214 #ifdef    BOOST_NO_STD_LOCALE
  2215                                             cc = ch;
  2216 #else
  2217                                             cc = ct.narrow(ch, char());
  2218 #endif /* BOOST_NO_STD_LOCALE */
  2219                                             
  2220                                             if        (cc == ')')                        // read "((a),(c))"
  2221                                             {
  2222                                                 o = octonion<T>(a,b,c);
  2223                                             }
  2224                                             else if    (cc == ',')                        // read "((a),(c),"
  2225                                             {
  2226                                                 u = ::std::complex<T>(a);
  2227                                                 
  2228                                                 v = ::std::complex<T>(c);
  2229                                                 
  2230                                                 is >> x;                            // read "((a),(c),x"
  2231                                                 
  2232                                                 if    (!is.good())    goto finish;
  2233                                                 
  2234                                                 is >> ch;                                // get the next lexeme
  2235                                                 
  2236                                                 if    (!is.good())    goto finish;
  2237                                                 
  2238 #ifdef    BOOST_NO_STD_LOCALE
  2239                                                 cc = ch;
  2240 #else
  2241                                                 cc = ct.narrow(ch, char());
  2242 #endif /* BOOST_NO_STD_LOCALE */
  2243                                                 
  2244                                                 if        (cc == ')')                        // read "((a),(c),x)"
  2245                                                 {
  2246                                                     o = octonion<T>(u,v,x);
  2247                                                 }
  2248                                                 else if    (cc == ',')                        // read "((a),(c),x,"
  2249                                                 {
  2250                                                     is >> y;                                // read "((a),(c),x,y"
  2251                                                     
  2252                                                     if    (!is.good())    goto finish;
  2253                                                     
  2254                                                     is >> ch;                                // get the next lexeme
  2255                                                     
  2256                                                     if    (!is.good())    goto finish;
  2257                                                     
  2258 #ifdef    BOOST_NO_STD_LOCALE
  2259                                                     cc = ch;
  2260 #else
  2261                                                     cc = ct.narrow(ch, char());
  2262 #endif /* BOOST_NO_STD_LOCALE */
  2263                                                     
  2264                                                     if        (cc == ')')                        // read "((a),(c),x,y)"
  2265                                                     {
  2266                                                         o = octonion<T>(u,v,x,y);
  2267                                                     }
  2268                                                     else                                    // error
  2269                                                     {
  2270 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2271                                                         is.setstate(::std::ios::failbit);
  2272 #else
  2273                                                         is.setstate(::std::ios_base::failbit);
  2274 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2275                                                     }
  2276                                                 }
  2277                                                 else                                    // error
  2278                                                 {
  2279 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2280                                                     is.setstate(::std::ios::failbit);
  2281 #else
  2282                                                     is.setstate(::std::ios_base::failbit);
  2283 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2284                                                 }
  2285                                             }
  2286                                             else                                    // error
  2287                                             {
  2288 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2289                                                 is.setstate(::std::ios::failbit);
  2290 #else
  2291                                                 is.setstate(::std::ios_base::failbit);
  2292 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2293                                             }
  2294                                         }
  2295                                         else if    (cc == ',')                            // read "((a),(c," or "((a),(e,"
  2296                                         {
  2297                                             is >> ch;                                // get the next lexeme
  2298                                             
  2299                                             if    (!is.good())    goto finish;
  2300 
  2301 #ifdef    BOOST_NO_STD_LOCALE
  2302                                             cc = ch;
  2303 #else
  2304                                             cc = ct.narrow(ch, char());
  2305 #endif /* BOOST_NO_STD_LOCALE */
  2306                                             
  2307                                             if        (cc == '(')                        // read "((a),(e,(" (ambiguity resolution)
  2308                                             {
  2309                                                 p = ::boost::math::quaternion<T>(a);
  2310                                                 
  2311                                                 x = ::std::complex<T>(c);                // "c" was actually "e"
  2312                                                 
  2313                                                 is.putback(ch);                            // we can only backtrace once
  2314                                                 
  2315                                                 is >> y;                                // read "((a),(e,y"
  2316                                                 
  2317                                                 if    (!is.good())    goto finish;
  2318                                                 
  2319                                                 is >> ch;                                // get the next lexeme
  2320                                                 
  2321 #ifdef    BOOST_NO_STD_LOCALE
  2322                                                 cc = ch;
  2323 #else
  2324                                                 cc = ct.narrow(ch, char());
  2325 #endif /* BOOST_NO_STD_LOCALE */
  2326                                                 
  2327                                                 if        (cc == ')')                        // read "((a),(e,y)"
  2328                                                 {
  2329                                                     q = ::boost::math::quaternion<T>(x,y);
  2330                                                     
  2331                                                     is >> ch;                                // get the next lexeme
  2332 
  2333 #ifdef    BOOST_NO_STD_LOCALE
  2334                                                     cc = ch;
  2335 #else
  2336                                                     cc = ct.narrow(ch, char());
  2337 #endif /* BOOST_NO_STD_LOCALE */
  2338                                                     
  2339                                                     if        (cc == ')')                        // read "((a),(e,y))"
  2340                                                     {
  2341                                                         o = octonion<T>(p,q);
  2342                                                     }
  2343                                                     else                                    // error
  2344                                                     {
  2345 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2346                                                         is.setstate(::std::ios::failbit);
  2347 #else
  2348                                                         is.setstate(::std::ios_base::failbit);
  2349 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2350                                                     }
  2351                                                 }
  2352                                                 else                                    // error
  2353                                                 {
  2354 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2355                                                     is.setstate(::std::ios::failbit);
  2356 #else
  2357                                                     is.setstate(::std::ios_base::failbit);
  2358 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2359                                                 }
  2360                                             }
  2361                                             else                                    // read "((a),(c,d" or "((a),(e,f"
  2362                                             {
  2363                                                 is.putback(ch);
  2364                                                 
  2365                                                 is >> d;
  2366                                                 
  2367                                                 if    (!is.good())    goto finish;
  2368                                                 
  2369                                                 is >> ch;                                // get the next lexeme
  2370                                                 
  2371                                                 if    (!is.good())    goto finish;
  2372                                                 
  2373 #ifdef    BOOST_NO_STD_LOCALE
  2374                                                 cc = ch;
  2375 #else
  2376                                                 cc = ct.narrow(ch, char());
  2377 #endif /* BOOST_NO_STD_LOCALE */
  2378                                                 
  2379                                                 if        (cc == ')')                        // read "((a),(c,d)" (ambiguity resolution)
  2380                                                 {
  2381                                                     is >> ch;                                // get the next lexeme
  2382                                                     
  2383                                                     if    (!is.good())    goto finish;
  2384 
  2385 #ifdef    BOOST_NO_STD_LOCALE
  2386                                                     cc = ch;
  2387 #else
  2388                                                     cc = ct.narrow(ch, char());
  2389 #endif /* BOOST_NO_STD_LOCALE */
  2390                                                     
  2391                                                     if        (cc == ')')                        // read "((a),(c,d))"
  2392                                                     {
  2393                                                         o = octonion<T>(a,b,c,d);
  2394                                                     }
  2395                                                     else if    (cc == ',')                        // read "((a),(c,d),"
  2396                                                     {
  2397                                                         u = ::std::complex<T>(a);
  2398                                                         
  2399                                                         v = ::std::complex<T>(c,d);
  2400                                                         
  2401                                                         is >> x;                                // read "((a),(c,d),x"
  2402                                                         
  2403                                                         if    (!is.good())    goto finish;
  2404                                                         
  2405                                                         is >> ch;                                // get the next lexeme
  2406                                                         
  2407                                                         if    (!is.good())    goto finish;
  2408                                                         
  2409 #ifdef    BOOST_NO_STD_LOCALE
  2410                                                         cc = ch;
  2411 #else
  2412                                                         cc = ct.narrow(ch, char());
  2413 #endif /* BOOST_NO_STD_LOCALE */
  2414                                                         
  2415                                                         if        (cc == ')')                        // read "((a),(c,d),x)"
  2416                                                         {
  2417                                                             o = octonion<T>(u,v,x);
  2418                                                         }
  2419                                                         else if    (cc == ',')                        // read "((a),(c,d),x,"
  2420                                                         {
  2421                                                             is >> y;                                // read "((a),(c,d),x,y"
  2422                                                             
  2423                                                             if    (!is.good())    goto finish;
  2424                                                             
  2425                                                             is >> ch;                                // get the next lexeme
  2426                                                             
  2427                                                             if    (!is.good())    goto finish;
  2428                                                             
  2429 #ifdef    BOOST_NO_STD_LOCALE
  2430                                                             cc = ch;
  2431 #else
  2432                                                             cc = ct.narrow(ch, char());
  2433 #endif /* BOOST_NO_STD_LOCALE */
  2434                                                             
  2435                                                             if        (cc == ')')                        // read "((a),(c,d),x,y)"
  2436                                                             {
  2437                                                                 o = octonion<T>(u,v,x,y);
  2438                                                             }
  2439                                                             else                                    // error
  2440                                                             {
  2441 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2442                                                                 is.setstate(::std::ios::failbit);
  2443 #else
  2444                                                                 is.setstate(::std::ios_base::failbit);
  2445 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2446                                                             }
  2447                                                         }
  2448                                                         else                                    // error
  2449                                                         {
  2450 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2451                                                             is.setstate(::std::ios::failbit);
  2452 #else
  2453                                                             is.setstate(::std::ios_base::failbit);
  2454 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2455                                                         }
  2456                                                     }
  2457                                                     else                                    // error
  2458                                                     {
  2459 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2460                                                         is.setstate(::std::ios::failbit);
  2461 #else
  2462                                                         is.setstate(::std::ios_base::failbit);
  2463 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2464                                                     }
  2465                                                 }
  2466                                                 else if    (cc == ',')                        // read "((a),(e,f," (ambiguity resolution)
  2467                                                 {
  2468                                                     p = ::boost::math::quaternion<T>(a);
  2469                                                     
  2470                                                     is >> g;                                // read "((a),(e,f,g" (too late to backtrack)
  2471                                                     
  2472                                                     if    (!is.good())    goto finish;
  2473                                                     
  2474                                                     is >> ch;                                // get the next lexeme
  2475                                                     
  2476                                                     if    (!is.good())    goto finish;
  2477                                                     
  2478 #ifdef    BOOST_NO_STD_LOCALE
  2479                                                     cc = ch;
  2480 #else
  2481                                                     cc = ct.narrow(ch, char());
  2482 #endif /* BOOST_NO_STD_LOCALE */
  2483                                                     
  2484                                                     if        (cc == ')')                        // read "((a),(e,f,g)"
  2485                                                     {
  2486                                                         q = ::boost::math::quaternion<T>(c,d,g);        // "c" was actually "e", and "d" was actually "f"
  2487                                                         
  2488                                                         is >> ch;                                // get the next lexeme
  2489                                                         
  2490                                                         if    (!is.good())    goto finish;
  2491                                                         
  2492 #ifdef    BOOST_NO_STD_LOCALE
  2493                                                         cc = ch;
  2494 #else
  2495                                                         cc = ct.narrow(ch, char());
  2496 #endif /* BOOST_NO_STD_LOCALE */
  2497                                                         
  2498                                                         if        (cc == ')')                        // read "((a),(e,f,g))"
  2499                                                         {
  2500                                                             o = octonion<T>(p,q);
  2501                                                         }
  2502                                                         else                                    // error
  2503                                                         {
  2504 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2505                                                             is.setstate(::std::ios::failbit);
  2506 #else
  2507                                                             is.setstate(::std::ios_base::failbit);
  2508 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2509                                                         }
  2510                                                     }
  2511                                                     else if    (cc == ',')                        // read "((a),(e,f,g,"
  2512                                                     {
  2513                                                         is >> h;                                // read "((a),(e,f,g,h"
  2514                                                         
  2515                                                         if    (!is.good())    goto finish;
  2516                                                         
  2517                                                         is >> ch;                                // get the next lexeme
  2518                                                         
  2519                                                         if    (!is.good())    goto finish;
  2520                                                         
  2521 #ifdef    BOOST_NO_STD_LOCALE
  2522                                                         cc = ch;
  2523 #else
  2524                                                         cc = ct.narrow(ch, char());
  2525 #endif /* BOOST_NO_STD_LOCALE */
  2526                                                         
  2527                                                         if        (cc == ')')                        // read "((a),(e,f,g,h)"
  2528                                                         {
  2529                                                             q = ::boost::math::quaternion<T>(c,d,g,h);    // "c" was actually "e", and "d" was actually "f"
  2530                                                             
  2531                                                             is >> ch;                                // get the next lexeme
  2532                                                             
  2533                                                             if    (!is.good())    goto finish;
  2534                                                             
  2535 #ifdef    BOOST_NO_STD_LOCALE
  2536                                                             cc = ch;
  2537 #else
  2538                                                             cc = ct.narrow(ch, char());
  2539 #endif /* BOOST_NO_STD_LOCALE */
  2540                                                             
  2541                                                             if        (cc == ')')                        // read "((a),(e,f,g,h))"
  2542                                                             {
  2543                                                                 o = octonion<T>(p,q);
  2544                                                             }
  2545                                                             else                                    // error
  2546                                                             {
  2547 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2548                                                                 is.setstate(::std::ios::failbit);
  2549 #else
  2550                                                                 is.setstate(::std::ios_base::failbit);
  2551 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2552                                                             }
  2553                                                         }
  2554                                                         else                                    // error
  2555                                                         {
  2556 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2557                                                             is.setstate(::std::ios::failbit);
  2558 #else
  2559                                                             is.setstate(::std::ios_base::failbit);
  2560 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2561                                                         }
  2562                                                     }
  2563                                                     else                                    // error
  2564                                                     {
  2565 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2566                                                         is.setstate(::std::ios::failbit);
  2567 #else
  2568                                                         is.setstate(::std::ios_base::failbit);
  2569 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2570                                                     }
  2571                                                 }
  2572                                                 else                                    // error
  2573                                                 {
  2574 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2575                                                     is.setstate(::std::ios::failbit);
  2576 #else
  2577                                                     is.setstate(::std::ios_base::failbit);
  2578 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2579                                                 }
  2580                                             }
  2581                                         }
  2582                                         else                                        // error
  2583                                         {
  2584 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2585                                             is.setstate(::std::ios::failbit);
  2586 #else
  2587                                             is.setstate(::std::ios_base::failbit);
  2588 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2589                                         }
  2590                                     }
  2591                                 }
  2592                                 else                                        // read "((a),c" (ambiguity resolution)
  2593                                 {
  2594                                     is.putback(ch);
  2595                                     
  2596                                     is >> c;                                    // we extract the third component
  2597                                     
  2598                                     if    (!is.good())    goto finish;
  2599                                     
  2600                                     is >> ch;                                    // get the next lexeme
  2601                                     
  2602                                     if    (!is.good())    goto finish;
  2603                                     
  2604 #ifdef    BOOST_NO_STD_LOCALE
  2605                                     cc = ch;
  2606 #else
  2607                                     cc = ct.narrow(ch, char());
  2608 #endif /* BOOST_NO_STD_LOCALE */
  2609                                     
  2610                                     if        (cc == ')')                            // read "((a),c)"
  2611                                     {
  2612                                         o = octonion<T>(a,b,c);
  2613                                     }
  2614                                     else if    (cc == ',')                            // read "((a),c,"
  2615                                     {
  2616                                         is >> x;                                    // read "((a),c,x"
  2617                                         
  2618                                         if    (!is.good())    goto finish;
  2619                                         
  2620                                         is >> ch;                                    // get the next lexeme
  2621                                         
  2622                                         if    (!is.good())    goto finish;
  2623                                         
  2624 #ifdef    BOOST_NO_STD_LOCALE
  2625                                         cc = ch;
  2626 #else
  2627                                         cc = ct.narrow(ch, char());
  2628 #endif /* BOOST_NO_STD_LOCALE */
  2629                                         
  2630                                         if        (cc == ')')                            // read "((a),c,x)"
  2631                                         {
  2632                                             o = octonion<T>(a,b,c,d,x.real(),x.imag());
  2633                                         }
  2634                                         else if    (cc == ',')                            // read "((a),c,x,"
  2635                                         {
  2636                                             is >> y;if    (!is.good())    goto finish;        // read "((a),c,x,y"
  2637                                             
  2638                                             is >> ch;                                    // get the next lexeme
  2639                                             
  2640                                             if    (!is.good())    goto finish;
  2641                                             
  2642 #ifdef    BOOST_NO_STD_LOCALE
  2643                                             cc = ch;
  2644 #else
  2645                                             cc = ct.narrow(ch, char());
  2646 #endif /* BOOST_NO_STD_LOCALE */
  2647                                             
  2648                                             if        (cc == ')')                            // read "((a),c,x,y)"
  2649                                             {
  2650                                                 o = octonion<T>(a,b,c,d,x.real(),x.imag(),y.real(),y.imag());
  2651                                             }
  2652                                             else                                        // error
  2653                                             {
  2654 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2655                                                 is.setstate(::std::ios::failbit);
  2656 #else
  2657                                                 is.setstate(::std::ios_base::failbit);
  2658 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2659                                             }
  2660                                         }
  2661                                         else                                        // error
  2662                                         {
  2663 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2664                                             is.setstate(::std::ios::failbit);
  2665 #else
  2666                                             is.setstate(::std::ios_base::failbit);
  2667 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2668                                         }
  2669                                     }
  2670                                     else                                        // error
  2671                                     {
  2672 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2673                                         is.setstate(::std::ios::failbit);
  2674 #else
  2675                                         is.setstate(::std::ios_base::failbit);
  2676 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2677                                     }
  2678                                 }
  2679                             }
  2680                             else                                        // error
  2681                             {
  2682 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2683                                 is.setstate(::std::ios::failbit);
  2684 #else
  2685                                 is.setstate(::std::ios_base::failbit);
  2686 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2687                             }
  2688                         }
  2689                         else if    (cc ==',')                            // read "((a,"
  2690                         {
  2691                             is >> ch;                                    // get the next lexeme
  2692                             
  2693                             if    (!is.good())    goto finish;
  2694                             
  2695 #ifdef    BOOST_NO_STD_LOCALE
  2696                             cc = ch;
  2697 #else
  2698                             cc = ct.narrow(ch, char());
  2699 #endif /* BOOST_NO_STD_LOCALE */
  2700                             
  2701                             if        (cc == '(')                            // read "((a,("
  2702                             {
  2703                                 u = ::std::complex<T>(a);
  2704                                 
  2705                                 is.putback(ch);                                // can only backtrack so much
  2706                                 
  2707                                 is >> v;                                    // read "((a,v"
  2708                                 
  2709                                 if    (!is.good())    goto finish;
  2710                                 
  2711                                 is >> ch;                                    // get the next lexeme
  2712                                 
  2713                                 if    (!is.good())    goto finish;
  2714                                 
  2715 #ifdef    BOOST_NO_STD_LOCALE
  2716                                 cc = ch;
  2717 #else
  2718                                 cc = ct.narrow(ch, char());
  2719 #endif /* BOOST_NO_STD_LOCALE */
  2720                                 
  2721                                 if        (cc == ')')                            // read "((a,v)"
  2722                                 {
  2723                                     is >> ch;                                    // get the next lexeme
  2724                                     
  2725                                     if    (!is.good())    goto finish;
  2726 
  2727 #ifdef    BOOST_NO_STD_LOCALE
  2728                                     cc = ch;
  2729 #else
  2730                                     cc = ct.narrow(ch, char());
  2731 #endif /* BOOST_NO_STD_LOCALE */
  2732                                     
  2733                                     if        (cc == ')')                            // read "((a,v))"
  2734                                     {
  2735                                         o = octonion<T>(u,v);
  2736                                     }
  2737                                     else if    (cc == ',')                            // read "((a,v),"
  2738                                     {
  2739                                         p = ::boost::math::quaternion<T>(u,v);
  2740                                         
  2741                                         is >> q;                                    // read "((a,v),q"
  2742                                         
  2743                                         if    (!is.good())    goto finish;
  2744                                         
  2745                                         is >> ch;                                    // get the next lexeme
  2746                                         
  2747                                         if    (!is.good())    goto finish;
  2748                                         
  2749 #ifdef    BOOST_NO_STD_LOCALE
  2750                                         cc = ch;
  2751 #else
  2752                                         cc = ct.narrow(ch, char());
  2753 #endif /* BOOST_NO_STD_LOCALE */
  2754                                         
  2755                                         if        (cc == ')')                            // read "((a,v),q)"
  2756                                         {
  2757                                             o = octonion<T>(p,q);
  2758                                         }
  2759                                         else                                        // error
  2760                                         {
  2761 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2762                                             is.setstate(::std::ios::failbit);
  2763 #else
  2764                                             is.setstate(::std::ios_base::failbit);
  2765 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2766                                         }
  2767                                     }
  2768                                     else                                        // error
  2769                                     {
  2770 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2771                                         is.setstate(::std::ios::failbit);
  2772 #else
  2773                                         is.setstate(::std::ios_base::failbit);
  2774 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2775                                     }
  2776                                 }
  2777                                 else                                        // error
  2778                                 {
  2779 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2780                                     is.setstate(::std::ios::failbit);
  2781 #else
  2782                                     is.setstate(::std::ios_base::failbit);
  2783 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2784                                 }
  2785                             }
  2786                             else
  2787                             {
  2788                                 is.putback(ch);
  2789                                 
  2790                                 is >> b;                                    // read "((a,b"
  2791                                 
  2792                                 if    (!is.good())    goto finish;
  2793                                 
  2794                                 is >> ch;                                    // get the next lexeme
  2795                                 
  2796                                 if    (!is.good())    goto finish;
  2797                                 
  2798 #ifdef    BOOST_NO_STD_LOCALE
  2799                                 cc = ch;
  2800 #else
  2801                                 cc = ct.narrow(ch, char());
  2802 #endif /* BOOST_NO_STD_LOCALE */
  2803                                 
  2804                                 if        (cc == ')')                            // read "((a,b)"
  2805                                 {
  2806                                     is >> ch;                                    // get the next lexeme
  2807                                     
  2808                                     if    (!is.good())    goto finish;
  2809                                     
  2810 #ifdef    BOOST_NO_STD_LOCALE
  2811                                     cc = ch;
  2812 #else
  2813                                     cc = ct.narrow(ch, char());
  2814 #endif /* BOOST_NO_STD_LOCALE */
  2815                                     
  2816                                     if        (cc == ')')                            // read "((a,b))"
  2817                                     {
  2818                                         o = octonion<T>(a,b);
  2819                                     }
  2820                                     else if    (cc == ',')                            // read "((a,b),"
  2821                                     {
  2822                                         is >> ch;                                    // get the next lexeme
  2823                                         
  2824                                         if    (!is.good())    goto finish;
  2825 
  2826 #ifdef    BOOST_NO_STD_LOCALE
  2827                                         cc = ch;
  2828 #else
  2829                                         cc = ct.narrow(ch, char());
  2830 #endif /* BOOST_NO_STD_LOCALE */
  2831                                         
  2832                                         if        (cc == '(')                            // read "((a,b),("
  2833                                         {
  2834                                             is >> ch;                                    // get the next lexeme
  2835                                             
  2836                                             if    (!is.good())    goto finish;
  2837                                             
  2838 #ifdef    BOOST_NO_STD_LOCALE
  2839                                             cc = ch;
  2840 #else
  2841                                             cc = ct.narrow(ch, char());
  2842 #endif /* BOOST_NO_STD_LOCALE */
  2843                                             
  2844                                             if        (cc == '(')                            // read "((a,b),(("
  2845                                             {
  2846                                                 p = ::boost::math::quaternion<T>(a,b);
  2847                                                 
  2848                                                 is.putback(ch);
  2849                                                 
  2850                                                 is.putback(ch);                            // we backtrack twice, with the same value
  2851                                                 
  2852                                                 is >> q;                                // read "((a,b),q"
  2853                                                 
  2854                                                 if    (!is.good())    goto finish;
  2855                                                 
  2856                                                 is >> ch;                                    // get the next lexeme
  2857                                                 
  2858                                                 if    (!is.good())    goto finish;
  2859                                                 
  2860 #ifdef    BOOST_NO_STD_LOCALE
  2861                                                 cc = ch;
  2862 #else
  2863                                                 cc = ct.narrow(ch, char());
  2864 #endif /* BOOST_NO_STD_LOCALE */
  2865                                                 
  2866                                                 if        (cc == ')')                            // read "((a,b),q)"
  2867                                                 {
  2868                                                     o = octonion<T>(p,q);
  2869                                                 }
  2870                                                 else                                        // error
  2871                                                 {
  2872 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2873                                                     is.setstate(::std::ios::failbit);
  2874 #else
  2875                                                     is.setstate(::std::ios_base::failbit);
  2876 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2877                                                 }
  2878                                             }
  2879                                             else                                        // read "((a,b),(c" or "((a,b),(e"
  2880                                             {
  2881                                                 is.putback(ch);
  2882                                                 
  2883                                                 is >> c;
  2884                                                 
  2885                                                 if    (!is.good())    goto finish;
  2886                                                 
  2887                                                 is >> ch;                                    // get the next lexeme
  2888                                                 
  2889                                                 if    (!is.good())    goto finish;
  2890                                                 
  2891 #ifdef    BOOST_NO_STD_LOCALE
  2892                                                 cc = ch;
  2893 #else
  2894                                                 cc = ct.narrow(ch, char());
  2895 #endif /* BOOST_NO_STD_LOCALE */
  2896                                                 
  2897                                                 if        (cc == ')')                            // read "((a,b),(c)" (ambiguity resolution)
  2898                                                 {
  2899                                                     is >> ch;                                    // get the next lexeme
  2900                                                     
  2901                                                     if    (!is.good())    goto finish;
  2902                                                     
  2903 #ifdef    BOOST_NO_STD_LOCALE
  2904                                                     cc = ch;
  2905 #else
  2906                                                     cc = ct.narrow(ch, char());
  2907 #endif /* BOOST_NO_STD_LOCALE */
  2908                                                     
  2909                                                     if        (cc == ')')                            // read "((a,b),(c))"
  2910                                                     {
  2911                                                         o = octonion<T>(a,b,c);
  2912                                                     }
  2913                                                     else if    (cc == ',')                            // read "((a,b),(c),"
  2914                                                     {
  2915                                                         u = ::std::complex<T>(a,b);
  2916                                                         
  2917                                                         v = ::std::complex<T>(c);
  2918                                                         
  2919                                                         is >> x;                                    // read "((a,b),(c),x"
  2920                                                         
  2921                                                         if    (!is.good())    goto finish;
  2922                                                         
  2923                                                         is >> ch;                                    // get the next lexeme
  2924                                                         
  2925                                                         if    (!is.good())    goto finish;
  2926                                                         
  2927 #ifdef    BOOST_NO_STD_LOCALE
  2928                                                         cc = ch;
  2929 #else
  2930                                                         cc = ct.narrow(ch, char());
  2931 #endif /* BOOST_NO_STD_LOCALE */
  2932                                                         
  2933                                                         if        (cc == ')')                            // read "((a,b),(c),x)"
  2934                                                         {
  2935                                                             o = octonion<T>(u,v,x);
  2936                                                         }
  2937                                                         else if    (cc == ',')                            // read "((a,b),(c),x,"
  2938                                                         {
  2939                                                             is >> y;                                    // read "((a,b),(c),x,y"
  2940                                                             
  2941                                                             if    (!is.good())    goto finish;
  2942                                                             
  2943                                                             is >> ch;                                    // get the next lexeme
  2944                                                             
  2945                                                             if    (!is.good())    goto finish;
  2946                                                             
  2947 #ifdef    BOOST_NO_STD_LOCALE
  2948                                                             cc = ch;
  2949 #else
  2950                                                             cc = ct.narrow(ch, char());
  2951 #endif /* BOOST_NO_STD_LOCALE */
  2952                                                             
  2953                                                             if        (cc == ')')                            // read "((a,b),(c),x,y)"
  2954                                                             {
  2955                                                                 o = octonion<T>(u,v,x,y);
  2956                                                             }
  2957                                                             else                                        // error
  2958                                                             {
  2959 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2960                                                                 is.setstate(::std::ios::failbit);
  2961 #else
  2962                                                                 is.setstate(::std::ios_base::failbit);
  2963 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2964                                                             }
  2965                                                         }
  2966                                                         else                                        // error
  2967                                                         {
  2968 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2969                                                             is.setstate(::std::ios::failbit);
  2970 #else
  2971                                                             is.setstate(::std::ios_base::failbit);
  2972 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2973                                                         }
  2974                                                     }
  2975                                                     else                                        // error
  2976                                                     {
  2977 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  2978                                                         is.setstate(::std::ios::failbit);
  2979 #else
  2980                                                         is.setstate(::std::ios_base::failbit);
  2981 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  2982                                                     }
  2983                                                 }
  2984                                                 else if    (cc == ',')                            // read "((a,b),(c," or "((a,b),(e,"
  2985                                                 {
  2986                                                     is >> ch;                                    // get the next lexeme
  2987                                                     
  2988                                                     if    (!is.good())    goto finish;
  2989                                                     
  2990 #ifdef    BOOST_NO_STD_LOCALE
  2991                                                     cc = ch;
  2992 #else
  2993                                                     cc = ct.narrow(ch, char());
  2994 #endif /* BOOST_NO_STD_LOCALE */
  2995                                                     
  2996                                                     if        (cc == '(')                            // read "((a,b),(e,(" (ambiguity resolution)
  2997                                                     {
  2998                                                         u = ::std::complex<T>(a,b);
  2999                                                         
  3000                                                         x = ::std::complex<T>(c);                    // "c" is actually "e"
  3001                                                         
  3002                                                         is.putback(ch);
  3003                                                         
  3004                                                         is >> y;                                    // read "((a,b),(e,y"
  3005                                                         
  3006                                                         if    (!is.good())    goto finish;
  3007                                                         
  3008                                                         is >> ch;                                    // get the next lexeme
  3009                                                         
  3010                                                         if    (!is.good())    goto finish;
  3011                                                         
  3012 #ifdef    BOOST_NO_STD_LOCALE
  3013                                                         cc = ch;
  3014 #else
  3015                                                         cc = ct.narrow(ch, char());
  3016 #endif /* BOOST_NO_STD_LOCALE */
  3017                                                         
  3018                                                         if        (cc == ')')                            // read "((a,b),(e,y)"
  3019                                                         {
  3020                                                             is >> ch;                                    // get the next lexeme
  3021                                                             
  3022                                                             if    (!is.good())    goto finish;
  3023 
  3024 #ifdef    BOOST_NO_STD_LOCALE
  3025                                                             cc = ch;
  3026 #else
  3027                                                             cc = ct.narrow(ch, char());
  3028 #endif /* BOOST_NO_STD_LOCALE */
  3029                                                             
  3030                                                             if        (cc == ')')                            // read "((a,b),(e,y))"
  3031                                                             {
  3032                                                                 o = octonion<T>(u,v,x,y);
  3033                                                             }
  3034                                                             else                                        // error
  3035                                                             {
  3036 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3037                                                                 is.setstate(::std::ios::failbit);
  3038 #else
  3039                                                                 is.setstate(::std::ios_base::failbit);
  3040 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3041                                                             }
  3042                                                         }
  3043                                                         else                                        // error
  3044                                                         {
  3045 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3046                                                             is.setstate(::std::ios::failbit);
  3047 #else
  3048                                                             is.setstate(::std::ios_base::failbit);
  3049 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3050                                                         }
  3051                                                     }
  3052                                                     else                                        // read "((a,b),(c,d" or "((a,b),(e,f"
  3053                                                     {
  3054                                                         is.putback(ch);
  3055                                                         
  3056                                                         is >> d;
  3057                                                         
  3058                                                         if    (!is.good())    goto finish;
  3059                                                         
  3060                                                         is >> ch;                                    // get the next lexeme
  3061                                                         
  3062                                                         if    (!is.good())    goto finish;
  3063                                                         
  3064 #ifdef    BOOST_NO_STD_LOCALE
  3065                                                         cc = ch;
  3066 #else
  3067                                                         cc = ct.narrow(ch, char());
  3068 #endif /* BOOST_NO_STD_LOCALE */
  3069                                                         
  3070                                                         if        (cc == ')')                            // read "((a,b),(c,d)" (ambiguity resolution)
  3071                                                         {
  3072                                                             u = ::std::complex<T>(a,b);
  3073                                                             
  3074                                                             v = ::std::complex<T>(c,d);
  3075                                                             
  3076                                                             is >> ch;                                    // get the next lexeme
  3077                                                             
  3078                                                             if    (!is.good())    goto finish;
  3079                                                             
  3080 #ifdef    BOOST_NO_STD_LOCALE
  3081                                                             cc = ch;
  3082 #else
  3083                                                             cc = ct.narrow(ch, char());
  3084 #endif /* BOOST_NO_STD_LOCALE */
  3085                                                             
  3086                                                             if        (cc == ')')                            // read "((a,b),(c,d))"
  3087                                                             {
  3088                                                                 o = octonion<T>(u,v);
  3089                                                             }
  3090                                                             else if    (cc == ',')                            // read "((a,b),(c,d),"
  3091                                                             {
  3092                                                                 is >> x;                                    // read "((a,b),(c,d),x
  3093                                                                 
  3094                                                                 if    (!is.good())    goto finish;
  3095                                                                 
  3096                                                                 is >> ch;                                    // get the next lexeme
  3097                                                                 
  3098                                                                 if    (!is.good())    goto finish;
  3099                                                                 
  3100 #ifdef    BOOST_NO_STD_LOCALE
  3101                                                                 cc = ch;
  3102 #else
  3103                                                                 cc = ct.narrow(ch, char());
  3104 #endif /* BOOST_NO_STD_LOCALE */
  3105                                                                 
  3106                                                                 if        (cc == ')')                            // read "((a,b),(c,d),x)"
  3107                                                                 {
  3108                                                                     o = octonion<T>(u,v,x);
  3109                                                                 }
  3110                                                                 else if    (cc == ',')                            // read "((a,b),(c,d),x,"
  3111                                                                 {
  3112                                                                     is >> y;                                    // read "((a,b),(c,d),x,y"
  3113                                                                     
  3114                                                                     if    (!is.good())    goto finish;
  3115                                                                     
  3116                                                                     is >> ch;                                    // get the next lexeme
  3117                                                                     
  3118                                                                     if    (!is.good())    goto finish;
  3119                                                                     
  3120 #ifdef    BOOST_NO_STD_LOCALE
  3121                                                                     cc = ch;
  3122 #else
  3123                                                                     cc = ct.narrow(ch, char());
  3124 #endif /* BOOST_NO_STD_LOCALE */
  3125                                                                     
  3126                                                                     if        (cc == ')')                            // read "((a,b),(c,d),x,y)"
  3127                                                                     {
  3128                                                                         o = octonion<T>(u,v,x,y);
  3129                                                                     }
  3130                                                                     else                                        // error
  3131                                                                     {
  3132 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3133                                                                         is.setstate(::std::ios::failbit);
  3134 #else
  3135                                                                         is.setstate(::std::ios_base::failbit);
  3136 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3137                                                                     }
  3138                                                                 }
  3139                                                                 else                                        // error
  3140                                                                 {
  3141 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3142                                                                     is.setstate(::std::ios::failbit);
  3143 #else
  3144                                                                     is.setstate(::std::ios_base::failbit);
  3145 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3146                                                                 }
  3147                                                             }
  3148                                                             else                                        // error
  3149                                                             {
  3150 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3151                                                                 is.setstate(::std::ios::failbit);
  3152 #else
  3153                                                                 is.setstate(::std::ios_base::failbit);
  3154 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3155                                                             }
  3156                                                         }
  3157                                                         else if    (cc == ',')                            // read "((a,b),(e,f," (ambiguity resolution)
  3158                                                         {
  3159                                                             p = ::boost::math::quaternion<T>(a,b);                // too late to backtrack
  3160                                                             
  3161                                                             is >> g;                                    // read "((a,b),(e,f,g"
  3162                                                             
  3163                                                             if    (!is.good())    goto finish;
  3164                                                             
  3165                                                             is >> ch;                                    // get the next lexeme
  3166                                                             
  3167                                                             if    (!is.good())    goto finish;
  3168                                                             
  3169 #ifdef    BOOST_NO_STD_LOCALE
  3170                                                             cc = ch;
  3171 #else
  3172                                                             cc = ct.narrow(ch, char());
  3173 #endif /* BOOST_NO_STD_LOCALE */
  3174                                                             
  3175                                                             if        (cc == ')')                            // read "((a,b),(e,f,g)"
  3176                                                             {
  3177                                                                 is >> ch;                                    // get the next lexeme
  3178                                                                 
  3179                                                                 if    (!is.good())    goto finish;
  3180                                                                 
  3181 #ifdef    BOOST_NO_STD_LOCALE
  3182                                                                 cc = ch;
  3183 #else
  3184                                                                 cc = ct.narrow(ch, char());
  3185 #endif /* BOOST_NO_STD_LOCALE */
  3186                                                                 
  3187                                                                 if        (cc == ')')                            // read "((a,b),(e,f,g))"
  3188                                                                 {
  3189                                                                     q = ::boost::math::quaternion<T>(c,d,g);            // "c" is actually "e" and "d" is actually "f"
  3190                                                                     
  3191                                                                     o = octonion<T>(p,q);
  3192                                                                 }
  3193                                                                 else                                        // error
  3194                                                                 {
  3195 #if BOOST_WORKAROUND(__GNUC__, < 3)
  3196                                                                     is.setstate(::std::ios::failbit);
  3197 #else
  3198                                                                     is.setstate(::std::ios_base::failbit);
  3199 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3200                                                                 }
  3201                                                             }
  3202                                                             else if    (cc == ',')                            // read "((a,b),(e,f,g,"
  3203                                                             {
  3204                                                                 is >> h;                                    // read "((a,b),(e,f,g,h"
  3205                                                                 
  3206                                                                 if    (!is.good())    goto finish;
  3207                                                                 
  3208                                                                 is >> ch;                                    // get the next lexeme
  3209                                                                 
  3210                                                                 if    (!is.good())    goto finish;
  3211                                                                 
  3212 #ifdef    BOOST_NO_STD_LOCALE
  3213                                                                 cc = ch;
  3214 #else
  3215                                                                 cc = ct.narrow(ch, char());
  3216 #endif /* BOOST_NO_STD_LOCALE */
  3217                                                                 
  3218                                                                 if        (cc == ')')                            // read "((a,b),(e,f,g,h)"
  3219                                                                 {
  3220                                                                     is >> ch;                                    // get the next lexeme
  3221                                                                     
  3222                                                                     if    (!is.good())    goto finish;
  3223                                                                     
  3224 #ifdef    BOOST_NO_STD_LOCALE
  3225                                                                     cc = ch;
  3226 #else
  3227                                                                     cc = ct.narrow(ch, char());
  3228 #endif /* BOOST_NO_STD_LOCALE */
  3229                                                                     
  3230                                                                     if        (cc == ')')                            // read ((a,b),(e,f,g,h))"
  3231                                                                     {
  3232                                                                         q = ::boost::math::quaternion<T>(c,d,g,h);            // "c" is actually "e" and "d" is actually "f"
  3233                                                                         
  3234                                                                         o = octonion<T>(p,q);
  3235                                                                     }
  3236                                                                     else                                        // error
  3237                                                                     {
  3238 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3239                                                                         is.setstate(::std::ios::failbit);
  3240 #else
  3241                                                                         is.setstate(::std::ios_base::failbit);
  3242 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3243                                                                     }
  3244                                                                 }
  3245                                                                 else                                        // error
  3246                                                                 {
  3247 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3248                                                                     is.setstate(::std::ios::failbit);
  3249 #else
  3250                                                                     is.setstate(::std::ios_base::failbit);
  3251 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3252                                                                 }
  3253                                                             }
  3254                                                             else                                        // error
  3255                                                             {
  3256 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3257                                                                 is.setstate(::std::ios::failbit);
  3258 #else
  3259                                                                 is.setstate(::std::ios_base::failbit);
  3260 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3261                                                             }
  3262                                                         }
  3263                                                         else                                        // error
  3264                                                         {
  3265 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3266                                                             is.setstate(::std::ios::failbit);
  3267 #else
  3268                                                             is.setstate(::std::ios_base::failbit);
  3269 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3270                                                         }
  3271                                                     }
  3272                                                 }
  3273                                                 else                                        // error
  3274                                                 {
  3275 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3276                                                     is.setstate(::std::ios::failbit);
  3277 #else
  3278                                                     is.setstate(::std::ios_base::failbit);
  3279 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3280                                                 }
  3281                                             }
  3282                                         }
  3283                                         else                                        // error
  3284                                         {
  3285 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3286                                             is.setstate(::std::ios::failbit);
  3287 #else
  3288                                             is.setstate(::std::ios_base::failbit);
  3289 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3290                                         }
  3291                                     }
  3292                                     else                                        // error
  3293                                     {
  3294 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3295                                         is.setstate(::std::ios::failbit);
  3296 #else
  3297                                         is.setstate(::std::ios_base::failbit);
  3298 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3299                                     }
  3300                                 }
  3301                                 else if    (cc == ',')                            // read "((a,b,"
  3302                                 {
  3303                                     is >> c;                                    // read "((a,b,c"
  3304                                     
  3305                                     if    (!is.good())    goto finish;
  3306                                     
  3307                                     is >> ch;                                    // get the next lexeme
  3308                                                                 
  3309                                     if    (!is.good())    goto finish;
  3310                                     
  3311 #ifdef    BOOST_NO_STD_LOCALE
  3312                                     cc = ch;
  3313 #else
  3314                                     cc = ct.narrow(ch, char());
  3315 #endif /* BOOST_NO_STD_LOCALE */
  3316                                     
  3317                                     if        (cc == ')')                            // read "((a,b,c)"
  3318                                     {
  3319                                         is >> ch;                                    // get the next lexeme
  3320                                                                     
  3321                                         if    (!is.good())    goto finish;
  3322                                         
  3323 #ifdef    BOOST_NO_STD_LOCALE
  3324                                         cc = ch;
  3325 #else
  3326                                         cc = ct.narrow(ch, char());
  3327 #endif /* BOOST_NO_STD_LOCALE */
  3328                                         
  3329                                         if        (cc == ')')                            // read "((a,b,c))"
  3330                                         {
  3331                                             o = octonion<T>(a,b,c);
  3332                                         }
  3333                                         else if    (cc == ',')                            // read "((a,b,c),"
  3334                                         {
  3335                                             p = ::boost::math::quaternion<T>(a,b,c);
  3336                                             
  3337                                             is >> q;                                    // read "((a,b,c),q"
  3338                                             
  3339                                             if    (!is.good())    goto finish;
  3340                                             
  3341                                             is >> ch;                                    // get the next lexeme
  3342                                                                         
  3343                                             if    (!is.good())    goto finish;
  3344                                             
  3345 #ifdef    BOOST_NO_STD_LOCALE
  3346                                             cc = ch;
  3347 #else
  3348                                             cc = ct.narrow(ch, char());
  3349 #endif /* BOOST_NO_STD_LOCALE */
  3350                                             
  3351                                             if        (cc == ')')                            // read "((a,b,c),q)"
  3352                                             {
  3353                                                 o = octonion<T>(p,q);
  3354                                             }
  3355                                             else                                        // error
  3356                                             {
  3357 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3358                                                 is.setstate(::std::ios::failbit);
  3359 #else
  3360                                                 is.setstate(::std::ios_base::failbit);
  3361 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3362                                             }
  3363                                         }
  3364                                         else                                        // error
  3365                                         {
  3366 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3367                                             is.setstate(::std::ios::failbit);
  3368 #else
  3369                                             is.setstate(::std::ios_base::failbit);
  3370 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3371                                         }
  3372                                     }
  3373                                     else if    (cc == ',')                            // read "((a,b,c,"
  3374                                     {
  3375                                         is >> d;                                    // read "((a,b,c,d"
  3376                                         
  3377                                         if    (!is.good())    goto finish;
  3378                                         
  3379                                         is >> ch;                                    // get the next lexeme
  3380                                                                     
  3381                                         if    (!is.good())    goto finish;
  3382                                         
  3383 #ifdef    BOOST_NO_STD_LOCALE
  3384                                         cc = ch;
  3385 #else
  3386                                         cc = ct.narrow(ch, char());
  3387 #endif /* BOOST_NO_STD_LOCALE */
  3388                                         
  3389                                         if        (cc == ')')                            // read "((a,b,c,d)"
  3390                                         {
  3391                                             is >> ch;                                    // get the next lexeme
  3392                                                                         
  3393                                             if    (!is.good())    goto finish;
  3394                                             
  3395 #ifdef    BOOST_NO_STD_LOCALE
  3396                                             cc = ch;
  3397 #else
  3398                                             cc = ct.narrow(ch, char());
  3399 #endif /* BOOST_NO_STD_LOCALE */
  3400                                             
  3401                                             if        (cc == ')')                            // read "((a,b,c,d))"
  3402                                             {
  3403                                                 o = octonion<T>(a,b,c,d);
  3404                                             }
  3405                                             else if    (cc == ',')                            // read "((a,b,c,d),"
  3406                                             {
  3407                                                 p = ::boost::math::quaternion<T>(a,b,c,d);
  3408                                                 
  3409                                                 is >> q;                                    // read "((a,b,c,d),q"
  3410                                                 
  3411                                                 if    (!is.good())    goto finish;
  3412                                                 
  3413                                                 is >> ch;                                    // get the next lexeme
  3414                                                                             
  3415                                                 if    (!is.good())    goto finish;
  3416                                                 
  3417 #ifdef    BOOST_NO_STD_LOCALE
  3418                                                 cc = ch;
  3419 #else
  3420                                                 cc = ct.narrow(ch, char());
  3421 #endif /* BOOST_NO_STD_LOCALE */
  3422                                                 
  3423                                                 if        (cc == ')')                            // read "((a,b,c,d),q)"
  3424                                                 {
  3425                                                     o = octonion<T>(p,q);
  3426                                                 }
  3427                                                 else                                        // error
  3428                                                 {
  3429 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3430                                                     is.setstate(::std::ios::failbit);
  3431 #else
  3432                                                     is.setstate(::std::ios_base::failbit);
  3433 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3434                                                 }
  3435                                             }
  3436                                             else                                        // error
  3437                                             {
  3438 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3439                                                 is.setstate(::std::ios::failbit);
  3440 #else
  3441                                                 is.setstate(::std::ios_base::failbit);
  3442 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3443                                             }
  3444                                         }
  3445                                         else                                        // error
  3446                                         {
  3447 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3448                                             is.setstate(::std::ios::failbit);
  3449 #else
  3450                                             is.setstate(::std::ios_base::failbit);
  3451 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3452                                         }
  3453                                     }
  3454                                     else                                        // error
  3455                                     {
  3456 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3457                                         is.setstate(::std::ios::failbit);
  3458 #else
  3459                                         is.setstate(::std::ios_base::failbit);
  3460 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3461                                     }
  3462                                 }
  3463                                 else                                        // error
  3464                                 {
  3465 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3466                                     is.setstate(::std::ios::failbit);
  3467 #else
  3468                                     is.setstate(::std::ios_base::failbit);
  3469 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3470                                 }
  3471                             }
  3472                         }
  3473                         else                                        // error
  3474                         {
  3475 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3476                             is.setstate(::std::ios::failbit);
  3477 #else
  3478                             is.setstate(::std::ios_base::failbit);
  3479 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3480                         }
  3481                     }
  3482                 }
  3483                 else                                        // read "(a"
  3484                 {
  3485                     is.putback(ch);
  3486                     
  3487                     is >> a;                                    // we extract the first component
  3488                     
  3489                     if    (!is.good())    goto finish;
  3490                     
  3491                     is >> ch;                                    // get the next lexeme
  3492                                                 
  3493                     if    (!is.good())    goto finish;
  3494                     
  3495 #ifdef    BOOST_NO_STD_LOCALE
  3496                     cc = ch;
  3497 #else
  3498                     cc = ct.narrow(ch, char());
  3499 #endif /* BOOST_NO_STD_LOCALE */
  3500                     
  3501                     if        (cc == ')')                            // read "(a)"
  3502                     {
  3503                         o = octonion<T>(a);
  3504                     }
  3505                     else if    (cc == ',')                            // read "(a,"
  3506                     {
  3507                         is >> ch;                                    // get the next lexeme
  3508                                                     
  3509                         if    (!is.good())    goto finish;
  3510                         
  3511 #ifdef    BOOST_NO_STD_LOCALE
  3512                         cc = ch;
  3513 #else
  3514                         cc = ct.narrow(ch, char());
  3515 #endif /* BOOST_NO_STD_LOCALE */
  3516                         
  3517                         if        (cc == '(')                            // read "(a,("
  3518                         {
  3519                             is >> ch;                                    // get the next lexeme
  3520                                                         
  3521                             if    (!is.good())    goto finish;
  3522 
  3523 #ifdef    BOOST_NO_STD_LOCALE
  3524                             cc = ch;
  3525 #else
  3526                             cc = ct.narrow(ch, char());
  3527 #endif /* BOOST_NO_STD_LOCALE */
  3528                             
  3529                             if        (cc == '(')                            // read "(a,(("
  3530                             {
  3531                                 p = ::boost::math::quaternion<T>(a);
  3532                                 
  3533                                 is.putback(ch);
  3534                                 
  3535                                 is.putback(ch);                                // we backtrack twice, with the same value
  3536                                 
  3537                                 is >> q;                                    // read "(a,q"
  3538                                 
  3539                                 if    (!is.good())    goto finish;
  3540                                 
  3541                                 is >> ch;                                    // get the next lexeme
  3542                                                             
  3543                                 if    (!is.good())    goto finish;
  3544                                 
  3545 #ifdef    BOOST_NO_STD_LOCALE
  3546                                 cc = ch;
  3547 #else
  3548                                 cc = ct.narrow(ch, char());
  3549 #endif /* BOOST_NO_STD_LOCALE */
  3550                                 
  3551                                 if        (cc == ')')                            // read "(a,q)"
  3552                                 {
  3553                                     o = octonion<T>(p,q);
  3554                                 }
  3555                                 else                                        // error
  3556                                 {
  3557 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3558                                     is.setstate(::std::ios::failbit);
  3559 #else
  3560                                     is.setstate(::std::ios_base::failbit);
  3561 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3562                                 }
  3563                             }
  3564                             else                                        // read "(a,(c" or "(a,(e"
  3565                             {
  3566                                 is.putback(ch);
  3567                                 
  3568                                 is >> c;
  3569                                 
  3570                                 if    (!is.good())    goto finish;
  3571                                 
  3572                                 is >> ch;                                    // get the next lexeme
  3573                                                             
  3574                                 if    (!is.good())    goto finish;
  3575                                 
  3576 #ifdef    BOOST_NO_STD_LOCALE
  3577                                 cc = ch;
  3578 #else
  3579                                 cc = ct.narrow(ch, char());
  3580 #endif /* BOOST_NO_STD_LOCALE */
  3581                                 
  3582                                 if        (cc == ')')                            // read "(a,(c)" (ambiguity resolution)
  3583                                 {
  3584                                     is >> ch;                                    // get the next lexeme
  3585                                                                 
  3586                                     if    (!is.good())    goto finish;
  3587                                     
  3588 #ifdef    BOOST_NO_STD_LOCALE
  3589                                     cc = ch;
  3590 #else
  3591                                     cc = ct.narrow(ch, char());
  3592 #endif /* BOOST_NO_STD_LOCALE */
  3593                                     
  3594                                     if        (cc == ')')                            // read "(a,(c))"
  3595                                     {
  3596                                         o = octonion<T>(a,b,c);
  3597                                     }
  3598                                     else if    (cc == ',')                            // read "(a,(c),"
  3599                                     {
  3600                                         u = ::std::complex<T>(a);
  3601                                         
  3602                                         v = ::std::complex<T>(c);
  3603                                         
  3604                                         is >> x;                                // read "(a,(c),x"
  3605                                         
  3606                                         if    (!is.good())    goto finish;
  3607                                         
  3608                                         is >> ch;                                    // get the next lexeme
  3609                                                                     
  3610                                         if    (!is.good())    goto finish;
  3611 
  3612 #ifdef    BOOST_NO_STD_LOCALE
  3613                                         cc = ch;
  3614 #else
  3615                                         cc = ct.narrow(ch, char());
  3616 #endif /* BOOST_NO_STD_LOCALE */
  3617                                         
  3618                                         if        (cc == ')')                            // read "(a,(c),x)"
  3619                                         {
  3620                                             o = octonion<T>(u,v,x);
  3621                                         }
  3622                                         else if    (cc == ',')                            // read "(a,(c),x,"
  3623                                         {
  3624                                             is >> y;                                    // read "(a,(c),x,y"
  3625                                             
  3626                                             if    (!is.good())    goto finish;
  3627                                             
  3628                                             is >> ch;                                    // get the next lexeme
  3629                                                                         
  3630                                             if    (!is.good())    goto finish;
  3631                                             
  3632 #ifdef    BOOST_NO_STD_LOCALE
  3633                                             cc = ch;
  3634 #else
  3635                                             cc = ct.narrow(ch, char());
  3636 #endif /* BOOST_NO_STD_LOCALE */
  3637                                             
  3638                                             if        (cc == ')')                            // read "(a,(c),x,y)"
  3639                                             {
  3640                                                 o = octonion<T>(u,v,x,y);
  3641                                             }
  3642                                             else                                        // error
  3643                                             {
  3644 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3645                                                 is.setstate(::std::ios::failbit);
  3646 #else
  3647                                                 is.setstate(::std::ios_base::failbit);
  3648 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3649                                             }
  3650                                         }
  3651                                         else                                        // error
  3652                                         {
  3653 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3654                                             is.setstate(::std::ios::failbit);
  3655 #else
  3656                                             is.setstate(::std::ios_base::failbit);
  3657 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3658                                         }
  3659                                     }
  3660                                     else                                        // error
  3661                                     {
  3662 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3663                                         is.setstate(::std::ios::failbit);
  3664 #else
  3665                                         is.setstate(::std::ios_base::failbit);
  3666 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3667                                     }
  3668                                 }
  3669                                 else if    (cc == ',')                            // read "(a,(c," or "(a,(e,"
  3670                                 {
  3671                                     is >> ch;                                    // get the next lexeme
  3672                                                                 
  3673                                     if    (!is.good())    goto finish;
  3674                                     
  3675 #ifdef    BOOST_NO_STD_LOCALE
  3676                                     cc = ch;
  3677 #else
  3678                                     cc = ct.narrow(ch, char());
  3679 #endif /* BOOST_NO_STD_LOCALE */
  3680                                     
  3681                                     if        (cc == '(')                            // read "(a,(e,(" (ambiguity resolution)
  3682                                     {
  3683                                         u = ::std::complex<T>(a);
  3684                                         
  3685                                         x = ::std::complex<T>(c);                // "c" is actually "e"
  3686                                         
  3687                                         is.putback(ch);                            // we backtrack
  3688                                         
  3689                                         is >> y;                                // read "(a,(e,y"
  3690                                         
  3691                                         if    (!is.good())    goto finish;
  3692                                         
  3693                                         is >> ch;                                    // get the next lexeme
  3694                                                                     
  3695                                         if    (!is.good())    goto finish;
  3696                                         
  3697 #ifdef    BOOST_NO_STD_LOCALE
  3698                                         cc = ch;
  3699 #else
  3700                                         cc = ct.narrow(ch, char());
  3701 #endif /* BOOST_NO_STD_LOCALE */
  3702                                         
  3703                                         if        (cc == ')')                            // read "(a,(e,y)"
  3704                                         {
  3705                                             is >> ch;                                    // get the next lexeme
  3706                                                                         
  3707                                             if    (!is.good())    goto finish;
  3708                                             
  3709 #ifdef    BOOST_NO_STD_LOCALE
  3710                                             cc = ch;
  3711 #else
  3712                                             cc = ct.narrow(ch, char());
  3713 #endif /* BOOST_NO_STD_LOCALE */
  3714                                             
  3715                                             if        (cc == ')')                            // read "(a,(e,y))"
  3716                                             {
  3717                                                 o = octonion<T>(u,v,x,y);
  3718                                             }
  3719                                             else                                        // error
  3720                                             {
  3721 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3722                                                 is.setstate(::std::ios::failbit);
  3723 #else
  3724                                                 is.setstate(::std::ios_base::failbit);
  3725 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3726                                             }
  3727                                         }
  3728                                         else                                        // error
  3729                                         {
  3730 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3731                                             is.setstate(::std::ios::failbit);
  3732 #else
  3733                                             is.setstate(::std::ios_base::failbit);
  3734 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3735                                         }
  3736                                     }
  3737                                     else                                        // read "(a,(c,d" or "(a,(e,f"
  3738                                     {
  3739                                         is.putback(ch);
  3740                                         
  3741                                         is >> d;
  3742                                         
  3743                                         if    (!is.good())    goto finish;
  3744                                         
  3745                                         is >> ch;                                    // get the next lexeme
  3746                                                                     
  3747                                         if    (!is.good())    goto finish;
  3748                                         
  3749 #ifdef    BOOST_NO_STD_LOCALE
  3750                                         cc = ch;
  3751 #else
  3752                                         cc = ct.narrow(ch, char());
  3753 #endif /* BOOST_NO_STD_LOCALE */
  3754                                         
  3755                                         if        (cc == ')')                            // read "(a,(c,d)" (ambiguity resolution)
  3756                                         {
  3757                                             is >> ch;                                    // get the next lexeme
  3758                                                                         
  3759                                             if    (!is.good())    goto finish;
  3760                                             
  3761 #ifdef    BOOST_NO_STD_LOCALE
  3762                                             cc = ch;
  3763 #else
  3764                                             cc = ct.narrow(ch, char());
  3765 #endif /* BOOST_NO_STD_LOCALE */
  3766                                             
  3767                                             if        (cc == ')')                            // read "(a,(c,d))"
  3768                                             {
  3769                                                 o = octonion<T>(a,b,c,d);
  3770                                             }
  3771                                             else if    (cc == ',')                            // read "(a,(c,d),"
  3772                                             {
  3773                                                 u = ::std::complex<T>(a);
  3774                                                 
  3775                                                 v = ::std::complex<T>(c,d);
  3776                                                 
  3777                                                 is >> x;                                // read "(a,(c,d),x"
  3778                                                 
  3779                                                 if    (!is.good())    goto finish;
  3780                                                 
  3781                                                 is >> ch;                                    // get the next lexeme
  3782                                                                             
  3783                                                 if    (!is.good())    goto finish;
  3784                                                 
  3785 #ifdef    BOOST_NO_STD_LOCALE
  3786                                                 cc = ch;
  3787 #else
  3788                                                 cc = ct.narrow(ch, char());
  3789 #endif /* BOOST_NO_STD_LOCALE */
  3790                                                 
  3791                                                 if        (cc == ')')                            // read "(a,(c,d),x)"
  3792                                                 {
  3793                                                     o = octonion<T>(u,v,x);
  3794                                                 }
  3795                                                 else if    (cc == ',')                            // read "(a,(c,d),x,"
  3796                                                 {
  3797                                                     is >> y;                                    // read "(a,(c,d),x,y"
  3798                                                     
  3799                                                     if    (!is.good())    goto finish;
  3800                                                     
  3801                                                     is >> ch;                                    // get the next lexeme
  3802                                                                                 
  3803                                                     if    (!is.good())    goto finish;
  3804                                                     
  3805 #ifdef    BOOST_NO_STD_LOCALE
  3806                                                     cc = ch;
  3807 #else
  3808                                                     cc = ct.narrow(ch, char());
  3809 #endif /* BOOST_NO_STD_LOCALE */
  3810                                                     
  3811                                                     if        (cc == ')')                            // read "(a,(c,d),x,y)"
  3812                                                     {
  3813                                                         o = octonion<T>(u,v,x,y);
  3814                                                     }
  3815                                                     else                                        // error
  3816                                                     {
  3817 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3818                                                         is.setstate(::std::ios::failbit);
  3819 #else
  3820                                                         is.setstate(::std::ios_base::failbit);
  3821 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3822                                                     }
  3823                                                 }
  3824                                                 else                                        // error
  3825                                                 {
  3826 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3827                                                     is.setstate(::std::ios::failbit);
  3828 #else
  3829                                                     is.setstate(::std::ios_base::failbit);
  3830 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3831                                                 }
  3832                                             }
  3833                                             else                                        // error
  3834                                             {
  3835 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3836                                                 is.setstate(::std::ios::failbit);
  3837 #else
  3838                                                 is.setstate(::std::ios_base::failbit);
  3839 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3840                                             }
  3841                                         }
  3842                                         else if    (cc == ',')                            // read "(a,(e,f," (ambiguity resolution)
  3843                                         {
  3844                                             p = ::boost::math::quaternion<T>(a);
  3845                                             
  3846                                             is >> g;                                    // read "(a,(e,f,g"
  3847                                             
  3848                                             if    (!is.good())    goto finish;
  3849                                             
  3850                                             is >> ch;                                    // get the next lexeme
  3851                                                                         
  3852                                             if    (!is.good())    goto finish;
  3853                                             
  3854 #ifdef    BOOST_NO_STD_LOCALE
  3855                                             cc = ch;
  3856 #else
  3857                                             cc = ct.narrow(ch, char());
  3858 #endif /* BOOST_NO_STD_LOCALE */
  3859                                             
  3860                                             if        (cc == ')')                            // read "(a,(e,f,g)"
  3861                                             {
  3862                                                 is >> ch;                                    // get the next lexeme
  3863                                                                             
  3864                                                 if    (!is.good())    goto finish;
  3865                                                 
  3866 #ifdef    BOOST_NO_STD_LOCALE
  3867                                                 cc = ch;
  3868 #else
  3869                                                 cc = ct.narrow(ch, char());
  3870 #endif /* BOOST_NO_STD_LOCALE */
  3871                                                 
  3872                                                 if        (cc == ')')                            // read "(a,(e,f,g))"
  3873                                                 {
  3874                                                     q = ::boost::math::quaternion<T>(c,d,g);            // "c" is actually "e" and "d" is actually "f"
  3875                                                     
  3876                                                     o = octonion<T>(p,q);
  3877                                                 }
  3878                                                 else                                        // error
  3879                                                 {
  3880 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3881                                                     is.setstate(::std::ios::failbit);
  3882 #else
  3883                                                     is.setstate(::std::ios_base::failbit);
  3884 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3885                                                 }
  3886                                             }
  3887                                             else if    (cc == ',')                            // read "(a,(e,f,g,"
  3888                                             {
  3889                                                 is >> h;                                    // read "(a,(e,f,g,h"
  3890                                                 
  3891                                                 if    (!is.good())    goto finish;
  3892                                                 
  3893                                                 is >> ch;                                    // get the next lexeme
  3894                                                                             
  3895                                                 if    (!is.good())    goto finish;
  3896                                                 
  3897 #ifdef    BOOST_NO_STD_LOCALE
  3898                                                 cc = ch;
  3899 #else
  3900                                                 cc = ct.narrow(ch, char());
  3901 #endif /* BOOST_NO_STD_LOCALE */
  3902                                                 
  3903                                                 if        (cc == ')')                            // read "(a,(e,f,g,h)"
  3904                                                 {
  3905                                                     is >> ch;                                    // get the next lexeme
  3906                                                                                 
  3907                                                     if    (!is.good())    goto finish;
  3908                                                     
  3909 #ifdef    BOOST_NO_STD_LOCALE
  3910                                                     cc = ch;
  3911 #else
  3912                                                     cc = ct.narrow(ch, char());
  3913 #endif /* BOOST_NO_STD_LOCALE */
  3914                                                     
  3915                                                     if        (cc == ')')                            // read "(a,(e,f,g,h))"
  3916                                                     {
  3917                                                         q = ::boost::math::quaternion<T>(c,d,g,h);            // "c" is actually "e" and "d" is actually "f"
  3918                                                         
  3919                                                         o = octonion<T>(p,q);
  3920                                                     }
  3921                                                     else                                        // error
  3922                                                     {
  3923 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3924                                                         is.setstate(::std::ios::failbit);
  3925 #else
  3926                                                         is.setstate(::std::ios_base::failbit);
  3927 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3928                                                     }
  3929                                                 }
  3930                                                 else                                        // error
  3931                                                 {
  3932 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3933                                                     is.setstate(::std::ios::failbit);
  3934 #else
  3935                                                     is.setstate(::std::ios_base::failbit);
  3936 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3937                                                 }
  3938                                             }
  3939                                             else                                        // error
  3940                                             {
  3941 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3942                                                 is.setstate(::std::ios::failbit);
  3943 #else
  3944                                                 is.setstate(::std::ios_base::failbit);
  3945 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3946                                             }
  3947                                         }
  3948                                         else                                        // error
  3949                                         {
  3950 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3951                                             is.setstate(::std::ios::failbit);
  3952 #else
  3953                                             is.setstate(::std::ios_base::failbit);
  3954 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3955                                         }
  3956                                     }
  3957                                 }
  3958                                 else                                        // error
  3959                                 {
  3960 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  3961                                     is.setstate(::std::ios::failbit);
  3962 #else
  3963                                     is.setstate(::std::ios_base::failbit);
  3964 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  3965                                 }
  3966                             }
  3967                         }
  3968                         else                                        // read "(a,b" or "(a,c" (ambiguity resolution)
  3969                         {
  3970                             is.putback(ch);
  3971                             
  3972                             is >> b;
  3973                             
  3974                             if    (!is.good())    goto finish;
  3975                             
  3976                             is >> ch;                                    // get the next lexeme
  3977                                                         
  3978                             if    (!is.good())    goto finish;
  3979                             
  3980 #ifdef    BOOST_NO_STD_LOCALE
  3981                             cc = ch;
  3982 #else
  3983                             cc = ct.narrow(ch, char());
  3984 #endif /* BOOST_NO_STD_LOCALE */
  3985                             
  3986                             if        (cc == ')')                            // read "(a,b)" (ambiguity resolution)
  3987                             {
  3988                                 o = octonion<T>(a,b);
  3989                             }
  3990                             else if    (cc == ',')                            // read "(a,b," or "(a,c,"
  3991                             {
  3992                                 is >> ch;                                    // get the next lexeme
  3993                                                             
  3994                                 if    (!is.good())    goto finish;
  3995                                 
  3996 #ifdef    BOOST_NO_STD_LOCALE
  3997                                 cc = ch;
  3998 #else
  3999                                 cc = ct.narrow(ch, char());
  4000 #endif /* BOOST_NO_STD_LOCALE */
  4001                                 
  4002                                 if        (cc == '(')                            // read "(a,c,(" (ambiguity resolution)
  4003                                 {
  4004                                     u = ::std::complex<T>(a);
  4005                                     
  4006                                     v = ::std::complex<T>(b);                    // "b" is actually "c"
  4007                                     
  4008                                     is.putback(ch);                                // we backtrack
  4009                                     
  4010                                     is >> x;                                    // read "(a,c,x"
  4011                                     
  4012                                     if    (!is.good())    goto finish;
  4013                                     
  4014                                     is >> ch;                                    // get the next lexeme
  4015                                                                 
  4016                                     if    (!is.good())    goto finish;
  4017                                     
  4018 #ifdef    BOOST_NO_STD_LOCALE
  4019                                     cc = ch;
  4020 #else
  4021                                     cc = ct.narrow(ch, char());
  4022 #endif /* BOOST_NO_STD_LOCALE */
  4023                                     
  4024                                     if        (cc == ')')                            // read "(a,c,x)"
  4025                                     {
  4026                                         o = octonion<T>(u,v,x);
  4027                                     }
  4028                                     else if    (cc == ',')                            // read "(a,c,x,"
  4029                                     {
  4030                                         is >> y;                                    // read "(a,c,x,y"                                    // read "(a,c,x"
  4031                                         
  4032                                         if    (!is.good())    goto finish;
  4033                                         
  4034                                         is >> ch;                                    // get the next lexeme
  4035                                                                     
  4036                                         if    (!is.good())    goto finish;
  4037                                         
  4038 #ifdef    BOOST_NO_STD_LOCALE
  4039                                         cc = ch;
  4040 #else
  4041                                         cc = ct.narrow(ch, char());
  4042 #endif /* BOOST_NO_STD_LOCALE */
  4043                                         
  4044                                         if        (cc == ')')                            // read "(a,c,x,y)"
  4045                                         {
  4046                                             o = octonion<T>(u,v,x,y);
  4047                                         }
  4048                                         else                                        // error
  4049                                         {
  4050 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4051                                             is.setstate(::std::ios::failbit);
  4052 #else
  4053                                             is.setstate(::std::ios_base::failbit);
  4054 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4055                                         }
  4056                                     }
  4057                                     else                                        // error
  4058                                     {
  4059 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4060                                         is.setstate(::std::ios::failbit);
  4061 #else
  4062                                         is.setstate(::std::ios_base::failbit);
  4063 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4064                                     }
  4065                                 }
  4066                                 else                                        // read "(a,b,c" or "(a,c,e"
  4067                                 {
  4068                                     is.putback(ch);
  4069                                     
  4070                                     is >> c;
  4071                                     
  4072                                     if    (!is.good())    goto finish;
  4073                                     
  4074                                     is >> ch;                                    // get the next lexeme
  4075                                                                 
  4076                                     if    (!is.good())    goto finish;
  4077                                     
  4078 #ifdef    BOOST_NO_STD_LOCALE
  4079                                     cc = ch;
  4080 #else
  4081                                     cc = ct.narrow(ch, char());
  4082 #endif /* BOOST_NO_STD_LOCALE */
  4083                                     
  4084                                     if        (cc == ')')                            // read "(a,b,c)" (ambiguity resolution)
  4085                                     {
  4086                                         o = octonion<T>(a,b,c);
  4087                                     }
  4088                                     else if    (cc == ',')                            // read "(a,b,c," or "(a,c,e,"
  4089                                     {
  4090                                         is >> ch;                                    // get the next lexeme
  4091                                                                     
  4092                                         if    (!is.good())    goto finish;
  4093                                         
  4094 #ifdef    BOOST_NO_STD_LOCALE
  4095                                         cc = ch;
  4096 #else
  4097                                         cc = ct.narrow(ch, char());
  4098 #endif /* BOOST_NO_STD_LOCALE */
  4099                                         
  4100                                         if        (cc == '(')                            // read "(a,c,e,(") (ambiguity resolution)
  4101                                         {
  4102                                             u = ::std::complex<T>(a);
  4103                                             
  4104                                             v = ::std::complex<T>(b);                    // "b" is actually "c"
  4105                                             
  4106                                             x = ::std::complex<T>(c);                    // "c" is actually "e"
  4107                                             
  4108                                             is.putback(ch);                                // we backtrack
  4109                                             
  4110                                             is >> y;                                    // read "(a,c,e,y"
  4111                                             
  4112                                             if    (!is.good())    goto finish;
  4113                                             
  4114                                             is >> ch;                                    // get the next lexeme
  4115                                                                         
  4116                                             if    (!is.good())    goto finish;
  4117                                             
  4118 #ifdef    BOOST_NO_STD_LOCALE
  4119                                             cc = ch;
  4120 #else
  4121                                             cc = ct.narrow(ch, char());
  4122 #endif /* BOOST_NO_STD_LOCALE */
  4123                                             
  4124                                             if        (cc == ')')                            // read "(a,c,e,y)"
  4125                                             {
  4126                                                 o = octonion<T>(u,v,x,y);
  4127                                             }
  4128                                             else                                        // error
  4129                                             {
  4130 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4131                                                 is.setstate(::std::ios::failbit);
  4132 #else
  4133                                                 is.setstate(::std::ios_base::failbit);
  4134 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4135                                             }
  4136                                         }
  4137                                         else                                        // read "(a,b,c,d" (ambiguity resolution)
  4138                                         {
  4139                                             is.putback(ch);                                // we backtrack
  4140                                             
  4141                                             is >> d;
  4142                                             
  4143                                             if    (!is.good())    goto finish;
  4144                                             
  4145                                             is >> ch;                                    // get the next lexeme
  4146                                                                         
  4147                                             if    (!is.good())    goto finish;
  4148                                             
  4149 #ifdef    BOOST_NO_STD_LOCALE
  4150                                             cc = ch;
  4151 #else
  4152                                             cc = ct.narrow(ch, char());
  4153 #endif /* BOOST_NO_STD_LOCALE */
  4154                                             
  4155                                             if        (cc == ')')                            // read "(a,b,c,d)"
  4156                                             {
  4157                                                 o = octonion<T>(a,b,c,d);
  4158                                             }
  4159                                             else if    (cc == ',')                            // read "(a,b,c,d,"
  4160                                             {
  4161                                                 is >> e;                                    // read "(a,b,c,d,e"
  4162                                                 
  4163                                                 if    (!is.good())    goto finish;
  4164                                                 
  4165                                                 is >> ch;                                    // get the next lexeme
  4166                                                                             
  4167                                                 if    (!is.good())    goto finish;
  4168                                                 
  4169 #ifdef    BOOST_NO_STD_LOCALE
  4170                                                 cc = ch;
  4171 #else
  4172                                                 cc = ct.narrow(ch, char());
  4173 #endif /* BOOST_NO_STD_LOCALE */
  4174                                                 
  4175                                                 if        (cc == ')')                            // read "(a,b,c,d,e)"
  4176                                                 {
  4177                                                     o = octonion<T>(a,b,c,d,e);
  4178                                                 }
  4179                                                 else if    (cc == ',')                            // read "(a,b,c,d,e,"
  4180                                                 {
  4181                                                     is >> f;                                    // read "(a,b,c,d,e,f"
  4182                                                     
  4183                                                     if    (!is.good())    goto finish;
  4184                                                     
  4185                                                     is >> ch;                                    // get the next lexeme
  4186                                                                                 
  4187                                                     if    (!is.good())    goto finish;
  4188                                                     
  4189 #ifdef    BOOST_NO_STD_LOCALE
  4190                                                     cc = ch;
  4191 #else
  4192                                                     cc = ct.narrow(ch, char());
  4193 #endif /* BOOST_NO_STD_LOCALE */
  4194                                                     
  4195                                                     if        (cc == ')')                            // read "(a,b,c,d,e,f)"
  4196                                                     {
  4197                                                         o = octonion<T>(a,b,c,d,e,f);
  4198                                                     }
  4199                                                     else if    (cc == ',')                            // read "(a,b,c,d,e,f,"
  4200                                                     {
  4201                                                         is >> g;                                    // read "(a,b,c,d,e,f,g"                                    // read "(a,b,c,d,e,f"
  4202                                                         
  4203                                                         if    (!is.good())    goto finish;
  4204                                                         
  4205                                                         is >> ch;                                    // get the next lexeme
  4206                                                                                     
  4207                                                         if    (!is.good())    goto finish;
  4208                                                         
  4209 #ifdef    BOOST_NO_STD_LOCALE
  4210                                                         cc = ch;
  4211 #else
  4212                                                         cc = ct.narrow(ch, char());
  4213 #endif /* BOOST_NO_STD_LOCALE */
  4214                                                         
  4215                                                         if        (cc == ')')                            // read "(a,b,c,d,e,f,g)"
  4216                                                         {
  4217                                                             o = octonion<T>(a,b,c,d,e,f,g);
  4218                                                         }
  4219                                                         else if    (cc == ',')                            // read "(a,b,c,d,e,f,g,"
  4220                                                         {
  4221                                                             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"
  4222                                                             
  4223                                                             if    (!is.good())    goto finish;
  4224                                                             
  4225                                                             is >> ch;                                    // get the next lexeme
  4226                                                                                         
  4227                                                             if    (!is.good())    goto finish;
  4228                                                             
  4229 #ifdef    BOOST_NO_STD_LOCALE
  4230                                                             cc = ch;
  4231 #else
  4232                                                             cc = ct.narrow(ch, char());
  4233 #endif /* BOOST_NO_STD_LOCALE */
  4234                                                             
  4235                                                             if        (cc == ')')                            // read "(a,b,c,d,e,f,g,h)"
  4236                                                             {
  4237                                                                 o = octonion<T>(a,b,c,d,e,f,g,h);
  4238                                                             }
  4239                                                             else                                        // error
  4240                                                             {
  4241 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4242                                                                 is.setstate(::std::ios::failbit);
  4243 #else
  4244                                                                 is.setstate(::std::ios_base::failbit);
  4245 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4246                                                             }
  4247                                                         }
  4248                                                         else                                        // error
  4249                                                         {
  4250 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4251                                                             is.setstate(::std::ios::failbit);
  4252 #else
  4253                                                             is.setstate(::std::ios_base::failbit);
  4254 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4255                                                         }
  4256                                                     }
  4257                                                     else                                        // error
  4258                                                     {
  4259 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4260                                                         is.setstate(::std::ios::failbit);
  4261 #else
  4262                                                         is.setstate(::std::ios_base::failbit);
  4263 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4264                                                     }
  4265                                                 }
  4266                                                 else                                        // error
  4267                                                 {
  4268 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4269                                                     is.setstate(::std::ios::failbit);
  4270 #else
  4271                                                     is.setstate(::std::ios_base::failbit);
  4272 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4273                                                 }
  4274                                             }
  4275                                             else                                        // error
  4276                                             {
  4277 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4278                                                 is.setstate(::std::ios::failbit);
  4279 #else
  4280                                                 is.setstate(::std::ios_base::failbit);
  4281 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4282                                             }
  4283                                         }
  4284                                     }
  4285                                     else                                        // error
  4286                                     {
  4287 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4288                                         is.setstate(::std::ios::failbit);
  4289 #else
  4290                                         is.setstate(::std::ios_base::failbit);
  4291 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4292                                     }
  4293                                 }
  4294                             }
  4295                             else                                        // error
  4296                             {
  4297 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4298                                 is.setstate(::std::ios::failbit);
  4299 #else
  4300                                 is.setstate(::std::ios_base::failbit);
  4301 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4302                             }
  4303                         }
  4304                     }
  4305                     else                                        // error
  4306                     {
  4307 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4308                         is.setstate(::std::ios::failbit);
  4309 #else
  4310                         is.setstate(::std::ios_base::failbit);
  4311 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4312                     }
  4313                 }
  4314             }
  4315             else                                        // format:    a
  4316             {
  4317                 is.putback(ch);
  4318                 
  4319                 is >> a;                                    // we extract the first component
  4320                 
  4321                 if    (!is.good())    goto finish;
  4322                 
  4323                 o = octonion<T>(a);
  4324             }
  4325             
  4326             finish:
  4327             return(is);
  4328         }
  4329         
  4330         
  4331 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4332         template<typename T>
  4333         ::std::ostream &                        operator << (    ::std::ostream & os,
  4334                                                                 octonion<T> const & o)
  4335 #else
  4336         template<typename T, typename charT, class traits>
  4337         ::std::basic_ostream<charT,traits> &    operator << (    ::std::basic_ostream<charT,traits> & os,
  4338                                                                 octonion<T> const & o)
  4339 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4340         {
  4341 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4342             ::std::ostringstream                        s;
  4343 #else
  4344             ::std::basic_ostringstream<charT,traits>    s;
  4345 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4346             
  4347             s.flags(os.flags());
  4348 #ifdef    BOOST_NO_STD_LOCALE
  4349 #else
  4350             s.imbue(os.getloc());
  4351 #endif /* BOOST_NO_STD_LOCALE */
  4352             s.precision(os.precision());
  4353             
  4354             s << '('    << o.R_component_1() << ','
  4355                         << o.R_component_2() << ','
  4356                         << o.R_component_3() << ','
  4357                         << o.R_component_4() << ','
  4358                         << o.R_component_5() << ','
  4359                         << o.R_component_6() << ','
  4360                         << o.R_component_7() << ','
  4361                         << o.R_component_8() << ')';
  4362             
  4363             return os << s.str();
  4364         }
  4365         
  4366         
  4367         // values
  4368         
  4369         template<typename T>
  4370         inline T                                real(octonion<T> const & o)
  4371         {
  4372             return(o.real());
  4373         }
  4374         
  4375         
  4376         template<typename T>
  4377         inline octonion<T>                        unreal(octonion<T> const & o)
  4378         {
  4379             return(o.unreal());
  4380         }
  4381         
  4382         
  4383 #define    BOOST_OCTONION_VALARRAY_LOADER   \
  4384             using    ::std::valarray;       \
  4385                                             \
  4386             valarray<T>    temp(8);         \
  4387                                             \
  4388             temp[0] = o.R_component_1();    \
  4389             temp[1] = o.R_component_2();    \
  4390             temp[2] = o.R_component_3();    \
  4391             temp[3] = o.R_component_4();    \
  4392             temp[4] = o.R_component_5();    \
  4393             temp[5] = o.R_component_6();    \
  4394             temp[6] = o.R_component_7();    \
  4395             temp[7] = o.R_component_8();
  4396         
  4397         
  4398         template<typename T>
  4399         inline T                                sup(octonion<T> const & o)
  4400         {
  4401 #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
  4402             using    ::std::abs;
  4403 #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
  4404             
  4405             BOOST_OCTONION_VALARRAY_LOADER
  4406             
  4407 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4408             return((BOOST_GET_VALARRAY(T, abs(temp)).max)());
  4409 #else
  4410             return((abs(temp).max)());
  4411 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4412         }
  4413         
  4414         
  4415         template<typename T>
  4416         inline T                                l1(octonion<T> const & o)
  4417         {
  4418 #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
  4419             using    ::std::abs;
  4420 #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
  4421             
  4422             BOOST_OCTONION_VALARRAY_LOADER
  4423             
  4424 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4425             return(BOOST_GET_VALARRAY(T, abs(temp)).sum());
  4426 #else
  4427             return(abs(temp).sum());
  4428 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4429         }
  4430         
  4431         
  4432         template<typename T>
  4433         inline T                                abs(const octonion<T> & o)
  4434         {
  4435 #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
  4436             using    ::std::abs;
  4437 #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
  4438             
  4439             using    ::std::sqrt;
  4440             
  4441             BOOST_OCTONION_VALARRAY_LOADER
  4442             
  4443 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4444             T            maxim = (BOOST_GET_VALARRAY(T,abs(temp)).max)();    // overflow protection
  4445 #else
  4446             T            maxim = (abs(temp).max)();    // overflow protection
  4447 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4448             
  4449             if    (maxim == static_cast<T>(0))
  4450             {
  4451                 return(maxim);
  4452             }
  4453             else
  4454             {
  4455                 T    mixam = static_cast<T>(1)/maxim;    // prefer multiplications over divisions
  4456                 
  4457                 temp *= mixam;
  4458                 
  4459                 temp *= temp;
  4460                 
  4461                 return(maxim*sqrt(temp.sum()));
  4462             }
  4463             
  4464             //return(::std::sqrt(norm(o)));
  4465         }
  4466         
  4467         
  4468 #undef    BOOST_OCTONION_VALARRAY_LOADER
  4469         
  4470         
  4471         // Note:    This is the Cayley norm, not the Euclidian norm...
  4472         
  4473         template<typename T>
  4474         inline T                                norm(octonion<T> const & o)
  4475         {
  4476             return(real(o*conj(o)));
  4477         }
  4478         
  4479         
  4480         template<typename T>
  4481         inline octonion<T>                        conj(octonion<T> const & o)
  4482         {
  4483             return(octonion<T>( +o.R_component_1(),
  4484                                 -o.R_component_2(),
  4485                                 -o.R_component_3(),
  4486                                 -o.R_component_4(),
  4487                                 -o.R_component_5(),
  4488                                 -o.R_component_6(),
  4489                                 -o.R_component_7(),
  4490                                 -o.R_component_8()));
  4491         }
  4492         
  4493         
  4494         // Note:    There is little point, for the octonions, to introduce the equivalents
  4495         //            to the complex "arg" and the quaternionic "cylindropolar".
  4496         
  4497         
  4498         template<typename T>
  4499         inline octonion<T>                        spherical(T const & rho,
  4500                                                             T const & theta,
  4501                                                             T const & phi1,
  4502                                                             T const & phi2,
  4503                                                             T const & phi3,
  4504                                                             T const & phi4,
  4505                                                             T const & phi5,
  4506                                                             T const & phi6)
  4507         {
  4508             using ::std::cos;
  4509             using ::std::sin;
  4510             
  4511             //T    a = cos(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
  4512             //T    b = sin(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
  4513             //T    c = sin(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
  4514             //T    d = sin(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
  4515             //T    e = sin(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
  4516             //T    f = sin(phi4)*cos(phi5)*cos(phi6);
  4517             //T    g = sin(phi5)*cos(phi6);
  4518             //T    h = sin(phi6);
  4519             
  4520             T    courrant = static_cast<T>(1);
  4521             
  4522             T    h = sin(phi6);
  4523             
  4524             courrant *= cos(phi6);
  4525             
  4526             T    g = sin(phi5)*courrant;
  4527             
  4528             courrant *= cos(phi5);
  4529             
  4530             T    f = sin(phi4)*courrant;
  4531             
  4532             courrant *= cos(phi4);
  4533             
  4534             T    e = sin(phi3)*courrant;
  4535             
  4536             courrant *= cos(phi3);
  4537             
  4538             T    d = sin(phi2)*courrant;
  4539             
  4540             courrant *= cos(phi2);
  4541             
  4542             T    c = sin(phi1)*courrant;
  4543             
  4544             courrant *= cos(phi1);
  4545             
  4546             T    b = sin(theta)*courrant;
  4547             T    a = cos(theta)*courrant;
  4548             
  4549             return(rho*octonion<T>(a,b,c,d,e,f,g,h));
  4550         }
  4551         
  4552         
  4553         template<typename T>
  4554         inline octonion<T>                        multipolar(T const & rho1,
  4555                                                              T const & theta1,
  4556                                                              T const & rho2,
  4557                                                              T const & theta2,
  4558                                                              T const & rho3,
  4559                                                              T const & theta3,
  4560                                                              T const & rho4,
  4561                                                              T const & theta4)
  4562         {
  4563             using ::std::cos;
  4564             using ::std::sin;
  4565             
  4566             T    a = rho1*cos(theta1);
  4567             T    b = rho1*sin(theta1);
  4568             T    c = rho2*cos(theta2);
  4569             T    d = rho2*sin(theta2);
  4570             T    e = rho3*cos(theta3);
  4571             T    f = rho3*sin(theta3);
  4572             T    g = rho4*cos(theta4);
  4573             T    h = rho4*sin(theta4);
  4574             
  4575             return(octonion<T>(a,b,c,d,e,f,g,h));
  4576         }
  4577         
  4578         
  4579         template<typename T>
  4580         inline octonion<T>                        cylindrical(T const & r,
  4581                                                               T const & angle,
  4582                                                               T const & h1,
  4583                                                               T const & h2,
  4584                                                               T const & h3,
  4585                                                               T const & h4,
  4586                                                               T const & h5,
  4587                                                               T const & h6)
  4588         {
  4589             using ::std::cos;
  4590             using ::std::sin;
  4591             
  4592             T    a = r*cos(angle);
  4593             T    b = r*sin(angle);
  4594             
  4595             return(octonion<T>(a,b,h1,h2,h3,h4,h5,h6));
  4596         }
  4597         
  4598         
  4599         template<typename T>
  4600         inline octonion<T>                        exp(octonion<T> const & o)
  4601         {
  4602             using    ::std::exp;
  4603             using    ::std::cos;
  4604             
  4605             using    ::boost::math::sinc_pi;
  4606             
  4607             T    u = exp(real(o));
  4608             
  4609             T    z = abs(unreal(o));
  4610             
  4611             T    w = sinc_pi(z);
  4612             
  4613             return(u*octonion<T>(cos(z),
  4614                 w*o.R_component_2(), w*o.R_component_3(),
  4615                 w*o.R_component_4(), w*o.R_component_5(),
  4616                 w*o.R_component_6(), w*o.R_component_7(),
  4617                 w*o.R_component_8()));
  4618         }
  4619         
  4620         
  4621         template<typename T>
  4622         inline octonion<T>                        cos(octonion<T> const & o)
  4623         {
  4624             using    ::std::sin;
  4625             using    ::std::cos;
  4626             using    ::std::cosh;
  4627             
  4628             using    ::boost::math::sinhc_pi;
  4629             
  4630             T    z = abs(unreal(o));
  4631             
  4632             T    w = -sin(o.real())*sinhc_pi(z);
  4633             
  4634             return(octonion<T>(cos(o.real())*cosh(z),
  4635                 w*o.R_component_2(), w*o.R_component_3(),
  4636                 w*o.R_component_4(), w*o.R_component_5(),
  4637                 w*o.R_component_6(), w*o.R_component_7(),
  4638                 w*o.R_component_8()));
  4639         }
  4640         
  4641         
  4642         template<typename T>
  4643         inline octonion<T>                        sin(octonion<T> const & o)
  4644         {
  4645             using    ::std::sin;
  4646             using    ::std::cos;
  4647             using    ::std::cosh;
  4648             
  4649             using    ::boost::math::sinhc_pi;
  4650             
  4651             T    z = abs(unreal(o));
  4652             
  4653             T    w = +cos(o.real())*sinhc_pi(z);
  4654             
  4655             return(octonion<T>(sin(o.real())*cosh(z),
  4656                 w*o.R_component_2(), w*o.R_component_3(),
  4657                 w*o.R_component_4(), w*o.R_component_5(),
  4658                 w*o.R_component_6(), w*o.R_component_7(),
  4659                 w*o.R_component_8()));
  4660         }
  4661         
  4662         
  4663         template<typename T>
  4664         inline octonion<T>                        tan(octonion<T> const & o)
  4665         {
  4666             return(sin(o)/cos(o));
  4667         }
  4668         
  4669         
  4670         template<typename T>
  4671         inline octonion<T>                        cosh(octonion<T> const & o)
  4672         {
  4673             return((exp(+o)+exp(-o))/static_cast<T>(2));
  4674         }
  4675         
  4676         
  4677         template<typename T>
  4678         inline octonion<T>                        sinh(octonion<T> const & o)
  4679         {
  4680             return((exp(+o)-exp(-o))/static_cast<T>(2));
  4681         }
  4682         
  4683         
  4684         template<typename T>
  4685         inline octonion<T>                        tanh(octonion<T> const & o)
  4686         {
  4687             return(sinh(o)/cosh(o));
  4688         }
  4689         
  4690         
  4691         template<typename T>
  4692         octonion<T>                                pow(octonion<T> const & o,
  4693                                                     int n)
  4694         {
  4695             if        (n > 1)
  4696             {
  4697                 int    m = n>>1;
  4698                 
  4699                 octonion<T>    result = pow(o, m);
  4700                 
  4701                 result *= result;
  4702                 
  4703                 if    (n != (m<<1))
  4704                 {
  4705                     result *= o; // n odd
  4706                 }
  4707                 
  4708                 return(result);
  4709             }
  4710             else if    (n == 1)
  4711             {
  4712                 return(o);
  4713             }
  4714             else if    (n == 0)
  4715             {
  4716                 return(octonion<T>(1));
  4717             }
  4718             else    /* n < 0 */
  4719             {
  4720                 return(pow(octonion<T>(1)/o,-n));
  4721             }
  4722         }
  4723         
  4724         
  4725         // helper templates for converting copy constructors (definition)
  4726         
  4727         namespace detail
  4728         {
  4729             
  4730             template<   typename T,
  4731                         typename U
  4732                     >
  4733             octonion<T>    octonion_type_converter(octonion<U> const & rhs)
  4734             {
  4735                 return(octonion<T>( static_cast<T>(rhs.R_component_1()),
  4736                                     static_cast<T>(rhs.R_component_2()),
  4737                                     static_cast<T>(rhs.R_component_3()),
  4738                                     static_cast<T>(rhs.R_component_4()),
  4739                                     static_cast<T>(rhs.R_component_5()),
  4740                                     static_cast<T>(rhs.R_component_6()),
  4741                                     static_cast<T>(rhs.R_component_7()),
  4742                                     static_cast<T>(rhs.R_component_8())));
  4743             }
  4744         }
  4745     }
  4746 }
  4747 
  4748 
  4749 #if    BOOST_WORKAROUND(__GNUC__, < 3)
  4750     #undef    BOOST_GET_VALARRAY
  4751 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
  4752 
  4753 
  4754 #endif /* BOOST_OCTONION_HPP */