epoc32/include/stdapis/boost/math/octonion.hpp
branchSymbian2
changeset 2 2fe1408b6811
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     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 */