Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/math/qtypes.h

Go to the documentation of this file.
00001 
00002 //  Copyright (C) 1998--2001  Petter Urkedal (petter.urkedal@matfys.lth.se)
00003 
00004 //  This file is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version.
00008 
00009 //  This file is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 //  As a special exception, you may use this file as part of a free
00019 //  software library without restriction.  Specifically, if other files
00020 //  instantiate templates or use macros or inline functions from this
00021 //  file, or you compile this file and link it with other files to
00022 //  produce an executable, this file does not by itself cause the
00023 //  resulting executable to be covered by the GNU General Public
00024 //  License.  This exception does not however invalidate any other
00025 //  reasons why the executable file might be covered by the GNU General
00026 //  Public License.
00027 
00028 //  $Id: qtypes.h,v 1.1 2002/05/30 18:01:38 petter_urkedal Exp $
00029 
00030 
00031 #ifndef MORE_MATH_QTYPES_H
00032 #define MORE_MATH_QTYPES_H
00033 
00034 #include <stdexcept>
00035 #include <iosfwd>
00036 #include <more/bits/mathbits.h>
00037 #include <more/io/fwd.h>
00038 
00039 
00040 namespace more {
00041 namespace math {
00042 
00043   extern "C" {
00044     double sixj_2j(int, int, int, int, int, int);
00045     double ninej_2j(int, int, int, int, int, int, int, int, int);
00046     double clebsch_2j(int, int, int, int, int, int);
00047     double threejm_2j(int, int, int, int, int, int);
00048   }
00049 
00050   struct halfint;
00051   struct pm_half;
00052 
00053   struct half_tag {
00054       operator halfint();
00055       operator float() const { return .5f; }
00056       operator double() const { return .5; }
00057       operator long double() const { return .5l; }
00058   };
00059   extern half_tag half;
00060   struct minus_half_tag {
00061       operator halfint();
00062       operator float() const { return -.5f; }
00063       operator double() const { return -.5; }
00064       operator long double() const { return -.5l; }
00065   };
00066 
00067   inline minus_half_tag
00068     operator-(half_tag) { return minus_half_tag(); }
00069   inline half_tag
00070     operator+(half_tag)       { return half_tag(); }
00071   inline half_tag
00072     operator-(minus_half_tag) { return half_tag(); }
00073   inline minus_half_tag
00074     operator+(minus_half_tag) { return minus_half_tag(); }
00075 
00076 
00077   //--------------------------------------------------------------------
00078   //                           pm_half
00079   //--------------------------------------------------------------------
00080 
00081   //  NOTE: operator conversions take precedence over constructor
00082   //  conversions, so when we define operator conversions to floating
00083   //  point types, we have to do the same for conversion to halfint to
00084   //  avoid numerous additional overloads of binary operators.
00085 
00086   struct pm_half {
00087 //        typedef persistent_tag category;
00088     private:
00089       typedef unsigned char enumerator_type;
00090       static const enumerator_type plus_half = 1;
00091       static const enumerator_type minus_half = 0;
00092 
00093     public:
00094       pm_half() {}
00095       pm_half(half_tag const&) : e(plus_half) {}
00096       pm_half(minus_half_tag const&) : e(minus_half) {}
00097       operator float() const { return e==plus_half? .5f : -.5f; }
00098       operator double() const { return e==plus_half? .5 : -.5; }
00099       operator long double() const { return e==plus_half?.5l:-.5l; }
00100       int enumerator() const { return e; }
00101 
00102       pm_half& operator++() { e = plus_half; return *this; }
00103       pm_half operator++(int) { pm_half tmp = *this; ++*this; return tmp; }
00104       pm_half& operator--() { e = minus_half; return *this; }
00105       pm_half operator--(int) { pm_half tmp = *this; ++*this; return tmp; }
00106       pm_half operator-() const { return pm_half(enumerator_type(1-e)); }
00107       pm_half operator+() const { return *this; }
00108 
00109       bool operator==(pm_half rhs) const { return e==rhs.e; }
00110       bool operator==(half_tag const&) const { return e==plus_half; }
00111       bool operator==(minus_half_tag const&) const { return e==minus_half; }
00112 
00113       static minus_half_tag inf() { return minus_half_tag(); }
00114       static half_tag sup() { return half_tag(); }
00115 
00116       void sync(io::syncstream& sio);
00117 
00118     private:
00119       pm_half(enumerator_type e_) : e(e_) {}
00120       enumerator_type e;
00121   };
00122 
00123   inline bool
00124     operator==(half_tag x, pm_half y) { return y == x; }
00125   inline bool
00126     operator==(minus_half_tag x, pm_half y) { return y == x; }
00127 
00128   inline bool
00129     operator!=(pm_half x, pm_half y) { return !(x == y); }
00130   inline bool
00131     operator!=(pm_half x, half_tag y) { return !(x == y); }
00132   inline bool
00133     operator!=(pm_half x, minus_half_tag y) { return !(x == y); }
00134   inline bool
00135     operator!=(half_tag x, pm_half y) { return !(x == y); }
00136   inline bool
00137     operator!=(minus_half_tag x, pm_half y) { return !(x == y); }
00138 
00139   inline int
00140     operator+(half_tag, pm_half x) { return x.enumerator(); }
00141   inline int
00142     operator+(pm_half x, half_tag) { return x.enumerator(); }
00143   inline int
00144     operator+(minus_half_tag, pm_half x) { return x.enumerator()-1; }
00145   inline int
00146     operator+(pm_half x, minus_half_tag) { return x.enumerator()-1; }
00147   inline int
00148     operator+(pm_half x, pm_half y)
00149     { return x.enumerator()+y.enumerator()-1; }
00150   inline int
00151     operator-(half_tag, pm_half x) { return 1-x.enumerator(); }
00152   inline int
00153     operator-(pm_half x, half_tag) { return x.enumerator()-1; }
00154   inline int
00155     operator-(minus_half_tag, pm_half x) { return -x.enumerator(); }
00156   inline int
00157     operator-(pm_half x, minus_half_tag) { return x.enumerator(); }
00158   inline int
00159     operator-(pm_half x, pm_half y)
00160     { return x.enumerator()-y.enumerator(); }
00161 
00162   inline float
00163     operator*(pm_half x, float y)
00164     { if (x == half) return .5f*y; else return -.5f*y; }
00165   inline double
00166     operator*(pm_half x, double y)
00167     { if (x == half) return .5*y; else return -.5*y; }
00168   inline long double
00169     operator*(pm_half x, long double y)
00170     { if (x == half) return .5l*y; else return -.5l*y; }
00171 
00172   inline float
00173     operator*(float x, pm_half y)
00174     { if (y == half) return .5f*x; else return -.5f*x; }
00175   inline double
00176     operator*(double x, pm_half y)
00177     { if (y == half) return .5*x; else return -.5*x; }
00178   inline long double
00179     operator*(long double x, pm_half y)
00180     { if (y == half) return .5l*x; else return -.5l*x; }
00181 
00182   inline int enumerator(half_tag) { return 1; }
00183   inline int enumerator(minus_half_tag) { return 0; }
00184   inline int enumerator(pm_half x) { return x.enumerator(); }
00185 
00186   std::istream& operator>>(std::istream&, pm_half&);
00187   std::ostream& operator<<(std::ostream&, pm_half);
00188 
00189 
00190   //--------------------------------------------------------------------
00191   //                           halfint
00192   //--------------------------------------------------------------------
00193 
00194   struct halfint {
00195 //        typedef persistent_tag category;
00196       int twice;
00197       halfint() {}
00198       halfint(int x) : twice(x*2) {}
00199       halfint(const halfint& x) : twice(x.twice) {}
00200       halfint(const pm_half& x) : twice(x==half? 1 : -1) {}
00201       halfint(zero_tag) : twice(0) {}
00202       halfint(one_tag) : twice(2) {}
00203       operator float() const { return twice/2.0f; }
00204       operator double() const { return twice/2.0; }
00205       operator long double() const { return twice/2.0l; }
00206       halfint(int x, half_tag) : twice(x) {}
00207 
00208       halfint& operator--() { twice -= 2; return *this; }
00209       halfint& operator++() { twice += 2; return *this; }
00210       halfint operator--(int) { halfint tmp = *this; --*this; return tmp; }
00211       halfint operator++(int) { halfint tmp = *this; ++*this; return tmp; }
00212 
00213       void sync(io::syncstream& sio);
00214   };
00215 
00216   inline half_tag::operator halfint() { return halfint(1, half); }
00217   inline minus_half_tag::operator halfint() { return halfint(-1, half); }
00218 
00219   inline halfint operator*(int x, half_tag) { return halfint(x, half); }
00220   inline halfint operator*(half_tag, int y) { return halfint(y, half); }
00221   inline halfint operator*(int x, minus_half_tag)
00222           { return halfint(-x, half); }
00223   inline halfint operator*(minus_half_tag, int y)
00224           { return halfint(-y, half); }
00225 
00226   inline halfint operator+(halfint x, half_tag)
00227           { return halfint(x.twice+1, half); }
00228   inline halfint operator+(half_tag, halfint x)
00229           { return halfint(1+x.twice, half); }
00230   inline halfint operator-(halfint x, half_tag)
00231           { return halfint(x.twice-1, half); }
00232   inline halfint operator-(half_tag, halfint x)
00233           { return halfint(1-x.twice, half); }
00234 
00235   inline halfint operator+(halfint x, minus_half_tag)
00236           { return halfint(x.twice-1, half); }
00237   inline halfint operator+(minus_half_tag, halfint x)
00238           { return halfint(x.twice-1, half); }
00239   inline halfint operator-(halfint x, minus_half_tag)
00240           { return halfint(x.twice+1, half); }
00241   inline halfint operator-(minus_half_tag, halfint x)
00242           { return halfint(-1-x.twice, half); }
00243 
00244   inline halfint operator+(int x, half_tag) { return halfint(2*x+1, half); }
00245   inline halfint operator+(half_tag, int x) { return halfint(2*x+1, half); }
00246   inline halfint operator-(int x, half_tag) { return halfint(2*x-1, half); }
00247   inline halfint operator-(half_tag, int x) { return halfint(1-2*x, half); }
00248 
00249   inline halfint operator+(int x, minus_half_tag)
00250           { return halfint(2*x-1, half); }
00251   inline halfint operator+(minus_half_tag, int x)
00252           { return halfint(2*x-1, half); }
00253   inline halfint operator-(int x, minus_half_tag)
00254           { return halfint(2*x+1, half); }
00255   inline halfint operator-(minus_half_tag, int x)
00256           { return halfint(-1-2*x, half); }
00257 
00258   inline float operator*(float x, half_tag) { return .5*x; }
00259   inline float operator*(half_tag, float y) { return .5*y; }
00260   inline float operator*(float x, minus_half_tag) { return -.5*x; }
00261   inline float operator*(minus_half_tag, float y) { return -.5*y; }
00262   inline double operator*(double x, half_tag) { return .5*x; }
00263   inline double operator*(half_tag, double y) { return .5*y; }
00264   inline double operator*(double x, minus_half_tag) { return -.5*x; }
00265   inline double operator*(minus_half_tag, double y) { return -.5*y; }
00266   inline long double operator*(long double x, half_tag) { return .5*x; }
00267   inline long double operator*(half_tag, long double y) { return .5*y; }
00268   inline long double operator*(long double x, minus_half_tag)
00269     { return -.5*x; }
00270   inline long double operator*(minus_half_tag, long double y)
00271     { return -.5*y; }
00272 
00273   inline halfint operator+(halfint x, halfint y)
00274     { return (x.twice+y.twice)*half; }
00275   inline halfint operator-(halfint x, halfint y)
00276     { return (x.twice-y.twice)*half; }
00277 
00278   inline halfint operator+(halfint x) { return x; }
00279   inline halfint operator-(halfint x) { return (-x.twice)*half; }
00280   inline halfint operator+(halfint x, int y) { return (x.twice+2*y)*half; }
00281   inline halfint operator-(halfint x, int y) { return (x.twice-2*y)*half; }
00282   inline halfint operator*(halfint x, int y) { return (x.twice*y)*half; }
00283   inline float operator*(halfint x, float y) { return (x.twice*y)/2; }
00284   inline double operator*(halfint x, double y) { return (x.twice*y)/2; }
00285   inline long double operator*(halfint x, long double y)
00286     { return (x.twice*y)/2; }
00287 
00288   inline halfint operator+(int x, halfint y) { return (2*x+y.twice)*half; }
00289   inline halfint operator-(int x, halfint y) { return (2*x-y.twice)*half; }
00290   inline halfint operator*(int x, halfint y) { return (x*y.twice)*half; }
00291   inline float operator*(float x, halfint y) { return (x*y.twice)/2; }
00292   inline double operator*(double x, halfint y) { return (x*y.twice)/2; }
00293   inline long double operator*(long double x, halfint y)
00294     { return (x*y.twice)/2; }
00295 
00296   inline bool operator==(halfint x, halfint y) { return x.twice==y.twice; }
00297   inline bool operator!=(halfint x, halfint y) { return x.twice!=y.twice; }
00298   inline bool operator<(halfint x, halfint y) { return x.twice<y.twice; }
00299   inline bool operator>(halfint x, halfint y) { return x.twice>y.twice; }
00300   inline bool operator<=(halfint x, halfint y) { return x.twice<=y.twice; }
00301   inline bool operator>=(halfint x, halfint y) { return x.twice>=y.twice; }
00302 
00303   inline bool operator==(halfint x, int y) { return x.twice==y*2; }
00304   inline bool operator!=(halfint x, int y) { return x.twice!=y*2; }
00305   inline bool operator<(halfint x, int y) { return x.twice<y*2; }
00306   inline bool operator>(halfint x, int y) { return x.twice>y*2; }
00307   inline bool operator<=(halfint x, int y) { return x.twice<=y*2; }
00308   inline bool operator>=(halfint x, int y) { return x.twice>=y*2; }
00309 
00310   inline bool operator==(int x, halfint y) { return x*2==y.twice; }
00311   inline bool operator!=(int x, halfint y) { return x*2!=y.twice; }
00312   inline bool operator<(int x, halfint y) { return x*2<y.twice; }
00313   inline bool operator>(int x, halfint y) { return x*2>y.twice; }
00314   inline bool operator<=(int x, halfint y) { return x*2<=y.twice; }
00315   inline bool operator>=(int x, halfint y) { return x*2>=y.twice; }
00316 
00317   inline halfint
00318     operator+(int x, pm_half y) {
00319         return halfint(2*x + (y == half? 1 : -1), half);
00320     }
00321   inline halfint
00322     operator-(int x, pm_half y) {
00323         return halfint(2*x - (y == half? 1 : -1), half);
00324     }
00325   inline halfint
00326     operator+(pm_half x, int y) {
00327         return halfint((x == half? 1 : -1) + 2*y, half);
00328     }
00329   inline halfint
00330     operator-(pm_half x, int y) {
00331         return halfint((x == half? 1 : -1) - 2*y, half);
00332     }
00333 
00334   inline halfint ceil(halfint x) { return (x.twice+1)/2; }
00335   inline halfint floor(halfint x) { return (x.twice-1)/2; }
00336   inline halfint trunc(halfint x) { return x.twice/2; }
00337   inline int iceil(halfint x) { return (x.twice+1)/2; }
00338   inline int ifloor(halfint x) { return (x.twice-1)/2; }
00339   inline int itrunc(halfint x) { return x.twice/2; }
00340 
00341   inline halfint abs(halfint x) { return x.twice >= 0? x : -x; }
00342   inline halfint min(halfint x, halfint y) { return x<y? x : y; }
00343   inline halfint max(halfint x, halfint y) { return x<y? y : x; }
00344 
00345   template<typename T>
00346     inline T pow(T x, halfint y) {
00347         if(y.twice%2) return std::pow(x, ifloor(y))*sqrt(x);
00348         else return std::pow(x, itrunc(y));
00349     }
00350   template<typename T>
00351     inline T pow(T x, half_tag) { return sqrt(x); }
00352   template<typename T>
00353     inline T pow(T x, minus_half_tag) { return 1.0/sqrt(x); }
00354 
00355   inline double clebsch(halfint j1, halfint j2, halfint j3,
00356                         halfint m1, halfint m2, halfint m3) {
00357       return clebsch_2j(j1.twice, j2.twice, j3.twice,
00358                         m1.twice, m2.twice, m3.twice);
00359   }
00360 
00361   inline double threejm(halfint j1, halfint j2, halfint j3,
00362                         halfint m1, halfint m2, halfint m3) {
00363       return threejm_2j(j1.twice, j2.twice, j3.twice,
00364                         m1.twice, m2.twice, m3.twice);
00365   }
00366 
00367   inline double sixj(halfint j11, halfint j12, halfint j13,
00368                      halfint j21, halfint j22, halfint j23) {
00369       return sixj_2j(j11.twice, j12.twice, j13.twice,
00370                      j21.twice, j22.twice, j23.twice);
00371   }
00372 
00373   inline double ninej(halfint j11, halfint j12, halfint j13,
00374                       halfint j21, halfint j22, halfint j23,
00375                       halfint j31, halfint j32, halfint j33) {
00376       return ninej_2j(j11.twice, j12.twice, j13.twice,
00377                       j21.twice, j22.twice, j23.twice,
00378                       j31.twice, j32.twice, j33.twice);
00379   }
00380 
00381   inline bool threej(halfint j1, halfint j2, halfint j3) {
00382       return !(j1+j2 < j3) && !(j2+j3 < j1) && !(j3+j1 < j2)
00383           && (j1+j2+j3).twice % 2 == 0;
00384   }
00385   std::ostream& operator<<(std::ostream& out, halfint x);
00386   std::istream& operator>>(std::istream& in, halfint& x);
00387 
00388 
00389 
00390   //--------------------------------------------------------------------
00391   //                            pm_one
00392   //--------------------------------------------------------------------
00393 
00394   class pm_one {
00395 //        typedef persistent_tag category;
00396 
00397     private:
00398       typedef unsigned char enumerator_type;
00399       static const enumerator_type plus = 0;
00400       static const enumerator_type minus = 1;
00401       enumerator_type e;
00402 
00403     public:
00404       pm_one() {}
00405       explicit pm_one(int i) : e(i >= 0? plus : minus) {}
00406       pm_one(const pm_one& pi) : e(pi.e) {}
00407       pm_one(one_tag) : e(plus) {}
00408       pm_one(minus_one_tag) : e(minus) {}
00409       operator int() const { return e == plus? 1 : -1; }
00410 //    operator=(int i_) { i=i_; assert(i==-1 || i==+1); }
00411 
00412       friend bool operator==(pm_one x, pm_one y) { return x.e == y.e; }
00413       friend bool operator< (pm_one x, pm_one y) { return x.e < y.e; }
00414 
00415       friend bool operator==(one_tag, pm_one x) { return x.e == plus; }
00416       friend bool operator==(pm_one x, one_tag) { return x.e == plus; }
00417       friend bool operator==(minus_one_tag, pm_one x) { return x.e == minus; }
00418       friend bool operator==(pm_one x, minus_one_tag) { return x.e == minus; }
00419       friend bool operator< (one_tag, pm_one x) { return false; }
00420       friend bool operator< (pm_one x, one_tag) { return x.e == minus; }
00421       friend bool operator< (minus_one_tag, pm_one x) { return x.e == plus; }
00422       friend bool operator< (pm_one x, minus_one_tag) { return false; }
00423 
00424       friend pm_one operator*(pm_one x, pm_one y)
00425         { return x.e == y.e? pm_one(one) : pm_one(-one); }
00426 
00427       void sync(more::io::syncstream& sio);
00428   };
00429 
00430   //  Any better way to do this without providing rel_ops functionality?
00431   inline bool operator!=(pm_one x, pm_one y) { return !(x == y); }
00432   inline bool operator<=(pm_one x, pm_one y) { return !(y < x); }
00433   inline bool operator>(pm_one x, pm_one y) { return y < x; }
00434   inline bool operator>=(pm_one x, pm_one y) { return !(x < y); }
00435   inline bool operator!=(pm_one x, one_tag y) { return !(x == y); }
00436   inline bool operator<=(pm_one x, one_tag y) { return !(y < x); }
00437   inline bool operator>(pm_one x, one_tag y) { return y < x; }
00438   inline bool operator>=(pm_one x, one_tag y) { return !(x < y); }
00439   inline bool operator!=(pm_one x, minus_one_tag y) { return !(x == y); }
00440   inline bool operator<=(pm_one x, minus_one_tag y) { return !(y < x); }
00441   inline bool operator>(pm_one x, minus_one_tag y) { return y < x; }
00442   inline bool operator>=(pm_one x, minus_one_tag y) { return !(x < y); }
00443   inline bool operator!=(one_tag x, pm_one y) { return !(x == y); }
00444   inline bool operator<=(one_tag x, pm_one y) { return !(y < x); }
00445   inline bool operator>(one_tag x, pm_one y) { return y < x; }
00446   inline bool operator>=(one_tag x, pm_one y) { return !(x < y); }
00447   inline bool operator!=(minus_one_tag x, pm_one y) { return !(x == y); }
00448   inline bool operator<=(minus_one_tag x, pm_one y) { return !(y < x); }
00449   inline bool operator>(minus_one_tag x, pm_one y) { return y < x; }
00450   inline bool operator>=(minus_one_tag x, pm_one y) { return !(x < y); }
00451 
00452   template< typename T > inline
00453     T operator*(pm_one pi, const T& x) { return pi==one? x : -x; }
00454   template< typename T > inline
00455     T operator*(const T& x, pm_one pi) { return pi==one? x : -x; }
00456 
00457   inline pm_one where(bool c, one_tag x, minus_one_tag y)
00458     { if(c) return x; else return y; }
00459   inline pm_one where(bool c, minus_one_tag x, one_tag y)
00460     { if(c) return x; else return y; }
00461   inline one_tag where(bool, one_tag, one_tag) { return one; }
00462   inline minus_one_tag where(bool, minus_one_tag, minus_one_tag)
00463     { return -one; }
00464   inline pm_one where(bool c, pm_one x, pm_one y) { return c? x : y; }
00465 
00466   std::ostream& operator<<(std::ostream&, pm_one);
00467   std::istream& operator>>(std::istream&, pm_one&);
00468 
00469 
00470 
00471   //  ---   r a n g e   ---
00472 
00473 #if defined(MORE_BACKWARD) && MORE_BACKWARD < 20010330
00474   // !!! Backwards compatibility.  Don't use! !!!
00475   template<typename T>
00476     struct range {
00477         typedef T element_type;
00478         range() {}
00479         range(T inf__, T sup__) : sup_(sup__), inf_(inf__) {
00480             if(inf_ > sup_)
00481                 throw std::logic_error("inf > sup in range constructor");
00482         }
00483         T& sup() { return sup_; }
00484         T& inf() { return inf_; }
00485         T sup() const { return sup_; }
00486         T inf() const { return inf_; }
00487         void set_sup(T const& x) { sup_ = x; }
00488         void set_inf(T const& x) { inf_ = x; }
00489         T measure() const { return sup_-inf_; }
00490       private:
00491         T sup_, inf_;
00492     };
00493 
00494   template<typename T>
00495     inline T sup(const range<T>& x) { return x.sup(); }
00496   template<typename T>
00497     inline T inf(const range<T>& x) { return x.inf(); }
00498   template<typename T>
00499     inline T measure(const range<T>& x) { return x.measure(); }
00500   template<typename T>
00501     inline T center(const range<T>& x) { return .5*(x.sup() + x.inf()); }
00502 
00503   template<typename T>
00504     struct cc_range : range<T>
00505     { cc_range() {} cc_range(T x, T y) : range<T>(x, y) {} };
00506   template<typename T>
00507     struct co_range : range<T>
00508     { co_range() {} co_range(T x, T y) : range<T>(x, y) {} };
00509   template<typename T>
00510     struct oc_range : range<T>
00511     { oc_range() {} oc_range(T x, T y) : range<T>(x, y) {} };
00512   template<typename T>
00513     struct oo_range : range<T>
00514     { oo_range() {} oo_range(T x, T y) : range<T>(x, y) {} };
00515 
00516   template<typename T>
00517     std::ostream& operator<<(std::ostream& os, range<T> const& x);
00518 
00519   typedef pm_one sign;
00520   extern one_tag positive;
00521   extern minus_one_tag negative;
00522   typedef pm_half pmhalf;
00523   // !!! Backwards compatibility.  Don't use! !!!
00524 #endif
00525 
00526 } // math
00527   using namespace math;
00528 } // more
00529 
00530 
00531 #endif

Generated on Sat Sep 7 19:11:18 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.