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