Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

/magnus/back_end/global/Trichotomy.h

Go to the documentation of this file.
00001 /*
00002  *   $Id: Trichotomy.h,v 1.4 1998/05/14 19:49:41 bormotov Exp $
00003  */
00004 /**<
00005 /file Trichotomy.h
00006 // Copyright (C) 1995 The New York Group Theory Cooperative
00007 // See magnus/doc/COPYRIGHT for the full notice.
00008 //
00009 /brief Contents: Definition of class Trichotomy
00010 //
00011 // Principal Author: Stephane Collart
00012 //
00013 // Status: Useable.
00014 //
00015 // Revision History:
00016 //
00017 // * 11/95 Roger made the conversion to bool, and all consequences,
00018 //         switch-outable, pending complete removal.
00019 //
00020 // * 01/96 Dmitry B. implemented IPC tools.
00021 //
00022 */
00023 #ifndef _TRICHOTOMY_H_
00024 #define _TRICHOTOMY_H_
00025 
00026 
00027 #include "global.h"
00028 
00029 #define ALLOW_BOGUS_CONVERSIONS
00030 
00031 
00032 //------------------------------------------------------------------------//
00033 //----------------------------- Trichotomy -------------------------------//
00034 //------------------------------------------------------------------------//
00035 //! class Trichotomy 
00036 /*!
00037 Class Trichotomy used to define objects that can have three states:
00038 DONTKNOW, NO, YES
00039 */
00040 class Trichotomy
00041 {
00042 
00043 public:
00044 
00045         ///////////////////////////////////////////////////////
00046         //                                                   //
00047         //  Helper Classes                                   //
00048         //                                                   //
00049         ///////////////////////////////////////////////////////
00050         /*! Enumerates logic constants. */
00051         enum TrichotomyValue { DONTKNOW = -1, NO, YES };
00052         
00053          //! used as marker in ctor of global Trich consts
00054         class dontknow { };
00055 
00056         // @stc it seems as though g++ 2.6.3 requires local classes declared before
00057         // first place of use in class definition
00058 
00059         ///////////////////////////////////////////////////////
00060         //                                                   //
00061         //  Constructors                                     //
00062         //                                                   //
00063         ///////////////////////////////////////////////////////
00064         //! From boolean
00065         /*! Creates a trichotmoy object from boolean variable*/
00066         Trichotomy( bool b ) : theValue(convert(b)) { }
00067 
00068         /*! /brief Constructor from integer
00069           Creates a trichotmoy object from integer variable*/
00070         Trichotomy( int i ) : theValue(convert(i)) { }
00071 
00072         //! Has to be completeed
00073         Trichotomy( void* p ) : theValue(convert(p)) { }
00074 
00075         // no default constructor
00076 
00077         // copy constructor provided by compiler
00078 
00079         ///////////////////////////////////////////////////////
00080         //                                                   //
00081         //!  Special Initialisation Constructors              //
00082         //                                                   //
00083         ///////////////////////////////////////////////////////
00084         /*! Creates a trichotomy object whose values is DONTKNOW
00085           This is the only way (execpt copying) to create DONTKNOW */
00086         Trichotomy( const dontknow& ) : theValue(DONTKNOW) { }
00087 
00088         ///////////////////////////////////////////////////////
00089         //                                                   //
00090         //  Conversion Operators                             //
00091         //                                                   //
00092         ///////////////////////////////////////////////////////
00093 
00094 #ifdef ALLOW_BOGUS_CONVERSIONS
00095         operator bool ( ) const
00096         {
00097                 if (theValue == -1) error("Non-bool value of Trichotomy in"
00098                         " Trichotomy::operator bool()");
00099                 return bool(theValue);
00100         }
00101 
00102         operator int ( ) const
00103         {
00104                 return bool(*this);
00105         }
00106 #endif
00107 
00108         ///////////////////////////////////////////////////////
00109         //                                                   //
00110         //  Conventional Operators                           //
00111         //                                                   //
00112         ///////////////////////////////////////////////////////
00113 
00114         // assignment operator provided by compiler
00115         //! equality operator
00116         inline friend bool operator == ( const Trichotomy& t, const Trichotomy& u )
00117         {
00118                 return t.theValue == u.theValue;
00119         }
00120         // global to permit dual promotion
00121 
00122         // op != global below
00123 
00124         ///////////////////////////////////////////////////////
00125         //                                                   //
00126         //  Logical Operations                               //
00127         //                                                   //
00128         ///////////////////////////////////////////////////////
00129 
00130 #ifdef ALLOW_BOGUS_CONVERSIONS
00131         /*! invert the value if defined (either yes or no) */
00132         Trichotomy operator ! ( ) const
00133         {
00134                 if (undefined()) return dontknow();
00135                 else return !bool(*this);
00136         }
00137   
00138         // the rest of these are implemented as global functions below
00139         // for dual type promotion
00140 
00141         ///////////////////////////////////////////////////////
00142         //                                                   //
00143         //  Accessors                                        //
00144         //                                                   //
00145         ///////////////////////////////////////////////////////
00146         //! true iff *this != dontknow
00147         /*! True if value is not DONTKNOW */
00148         bool defined( ) const { return theValue != -1; }
00149 
00150         //! true iff *this == dontknow
00151         bool undefined( ) const { return !defined(); }
00152 #endif
00153 
00154         ///////////////////////////////////////////////////////
00155         //                                                   //
00156         //!  I/O routines                                     //
00157         //                                                   //
00158         ///////////////////////////////////////////////////////
00159 
00160         /*! Print value into the stream */
00161         friend ostream& operator << ( ostream& ostr, const Trichotomy& t )
00162         {
00163           switch( t.theValue ) {
00164           case DONTKNOW : ostr << "DONTKNOW"; break;
00165           case NO       : ostr << "NO";  break;
00166           case YES      : ostr << "YES";
00167           }
00168           return ostr;
00169         }
00170         ///////////////////////////////////////////////////////
00171         //                                                   //
00172         //!  IPC operators                                    //
00173         //                                                   //
00174         ///////////////////////////////////////////////////////
00175 
00176         /*! Special opertor for interprocessing communication */
00177         friend ostream& operator < ( ostream& ostr, const Trichotomy& t )
00178         {
00179           int i; 
00180           switch( t.theValue ) {
00181           case DONTKNOW : i = -1; break;
00182           case NO       : i = 0;  break;
00183           case YES      : i = 1;
00184           }
00185           ostr < i;
00186 
00187           return ostr;
00188         }
00189   
00190         /*! Special opertor for interprocessing communication */
00191         friend istream& operator > ( istream& istr, Trichotomy& t )
00192         {
00193           int i;
00194           istr > i;
00195           switch( i ) {
00196           case -1 : t.theValue = DONTKNOW; break;
00197           case 0  : t.theValue = NO; break;
00198           case 1  : t.theValue = YES;
00199           }
00200 
00201           return istr;
00202         }
00203 
00204 
00205 private:
00206 
00207         ///////////////////////////////////////////////////////
00208         //                                                   //
00209         //  Conversion Helpers                               //
00210         //                                                   //
00211         ///////////////////////////////////////////////////////
00212 
00213         static TrichotomyValue convert( bool b )
00214         {
00215                 if (b) return YES; else return NO;
00216         }
00217         
00218         static TrichotomyValue convert( void* p )
00219         {
00220                 if (p) return YES; else return NO;
00221         }
00222         
00223         ///////////////////////////////////////////////////////
00224         //                                                   //
00225         //  Data Members                                     //
00226         //                                                   //
00227         ///////////////////////////////////////////////////////
00228 
00229         TrichotomyValue theValue;
00230 
00231 };
00232 
00233 
00234 //------------------ related global operators ---------------------//
00235 
00236 
00237 inline bool operator != ( const Trichotomy& t, const Trichotomy& u )
00238 {
00239         return !(t == u);
00240 }
00241 
00242 #ifdef ALLOW_BOGUS_CONVERSIONS
00243 inline Trichotomy operator && ( const Trichotomy& t, const Trichotomy& u )
00244 {
00245         if (t.undefined() || u.undefined()) return Trichotomy::dontknow();
00246         else return bool(t) && bool(u);
00247 }
00248 
00249 inline Trichotomy operator || ( const Trichotomy& t, const Trichotomy& u )
00250 {
00251         if (t.undefined() || u.undefined()) return Trichotomy::dontknow();
00252         else return bool(t) || bool(u);
00253 }
00254 #endif
00255 
00256 //------------------ global const declarations --------------------//
00257 
00258 
00259 /*! Constants representing Trichotomy values */
00260 extern const Trichotomy YES, NO, DONTKNOW, yes, no, dontknow;
00261 // @stc verify that it is necessary to explicitely give consts external linkage
00262 
00263 //@rn const bool forever = true; // useful synonym
00264 
00265 #endif

Generated at Tue Jun 19 09:49:36 2001 for Magnus Classes by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001