Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/boost/math/octonion.hpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

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