Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

MathUtils.h

Go to the documentation of this file.
00001 
00002 // MathCore = a WYSIWYG equation editor + a powerful math engine     //
00003 // Copyright (C) 2003 by Francesco Montorsi                          //
00004 //                                                                   //
00005 // This library is free software; you can redistribute it and/or     //
00006 // modify it under the terms of the GNU Lesser General Public        //
00007 // License as published by the Free Software Foundation; either      //
00008 // version 2.1 of the License, or (at your option) any later         //
00009 // version.                                                          //
00010 //                                                                   //
00011 // This library is distributed in the hope that it will be useful,   //
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of    //
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the      //
00014 // GNU Lesser General Public License for more details.               //
00015 //                                                                   //
00016 // You should have received a copy of the GNU Lesser General Public  //
00017 // License along with this program; if not, write to the Free        //
00018 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,   //
00019 // MA 02111-1307, USA.                                               //
00020 //                                                                   //
00021 // For any comment, suggestion or feature request, please contact    //
00022 // the administrator of the project at frm@users.sourceforge.net     //
00023 //                                                                   //
00032 
00033 
00034 
00035 #ifndef MATHUTILS_H
00036 #define MATHUTILS_H
00037 
00038 // optimization for GCC compiler
00039 #ifdef __GNUG__
00040 #pragma interface "MathUtils.h"
00041 #endif
00042 
00043 
00044 // -----------
00045 // INCLUDES
00046 // -----------
00047 
00048 #include "mc/Setup.h"  // contains all mcENABLE_XXX defines
00049 #include <wx/bitmap.h>
00050 #include <wx/log.h>   // for the mcLOG macro
00051 #include "wx/xml2.h"
00052 
00053 // these will be defined later... we just need them for mcStyle::gui_Select function
00054 class mcElement;
00055 class mcRealValue;
00056 
00057 
00058 
00059 
00060 // -----------
00061 // DEFINES
00062 // -----------
00063 
00064 #if defined(mcENABLE_LOG)
00065 
00066  // MathCore uses the wxWidgets' logging system:
00067  // it allows to exclude selectively some type of logs.
00068  // our logs are divided in some main types:
00069  enum {
00070   mcLOG_Generic = 1024,  // MathCore log level start here
00071   mcLOG_Math,
00072   mcLOG_GUI,
00073   mcLOG_IO
00074  };
00075 
00076 
00080  class mcLog : public wxLog
00081  {
00082   FILE *m_fp;
00083 
00084  public:
00085   mcLog(FILE *p = NULL) { m_fp = p; if (!m_fp) m_fp = stderr; }
00086   virtual ~mcLog() {}
00087 
00088   void DoLogString(const wxChar *msg, time_t timestamp);
00089  };
00090 
00091 #endif
00092 
00093 #if defined(mcENABLE_LOG) && \
00094  !(defined(__GNUG__) && defined(__WXMSW__)) // actually there is an inexplicable bug when using MinGW and mcENABLE_LOG is defined...
00095 
00096 
00097  #define mcDECLARE_MATHCORE_LOG_FUNCTION(level)        \
00098   extern void WXDLLEXPORT mcVLog##level(const wxChar *szFormat,     \
00099             va_list argptr);      \
00100   extern void WXDLLEXPORT mcLog##level(const wxChar *szFormat,      \
00101            ...) ATTRIBUTE_PRINTF_1
00102 
00103 
00104  mcDECLARE_MATHCORE_LOG_FUNCTION(Generic);
00105  mcDECLARE_MATHCORE_LOG_FUNCTION(Math);
00106  mcDECLARE_MATHCORE_LOG_FUNCTION(GUI);
00107  mcDECLARE_MATHCORE_LOG_FUNCTION(IO);
00108 
00109 
00111  #define mcLOG       mcLogGeneric
00112 
00114  #define mcGUILOG      mcLogGUI
00115 
00117  #define mcMATHLOG      mcLogMath
00118 
00120  #define mcIOLOG       mcLogIO
00121 
00123  #define mcSOLVERLOG      mcLogMath
00124 
00125 #else
00126 
00127  #ifdef __GNUG__
00128  
00129   // GCC accepts variadic macros and this avoids us a *lot* of
00130   // warnings about "statements with no effects" that it ouputs
00131   // if mcLOG is defined to nothing...
00132   #define mcLOG(...)        {;}
00133   #define mcMATHLOG(...)       {;}
00134   #define mcGUILOG(...)       {;}
00135   #define mcIOLOG(...)       {;}
00136   #define mcSOLVERLOG(...)      {;}
00137  #else
00138 
00139   // If all compilers supported the variadic macros (macros with a variable
00140   // number of arguments, declared using ... and __VA_ARGS__), then it would
00141   // be simpler to write these macros !!
00142   #define mcLOG        /* expand to nothing */
00143   #define mcMATHLOG       /* expand to nothing */
00144   #define mcGUILOG       /* expand to nothing */
00145   #define mcIOLOG        /* expand to nothing */
00146   #define mcSOLVERLOG       /* expand to nothing */
00147  #endif
00148 
00149 #endif
00150 
00152 #define mcTXT(x)    ((x).io_GetInlinedExpr().c_str())
00153 
00155 #define mcTXTP(x)    ((x)->io_GetInlinedExpr().c_str()) 
00156 
00158 #define mcTXTV(x)    ((x).GetSmartStr().c_str())
00159 
00163 #define mcTXTTHIS    (this->io_GetInlinedExpr().c_str()) 
00164 
00165 // define some useful UNICODE & ANSI support functions: if you want to
00166 // avoid #ifdefs in your source code, do not use strlen() or wcslen();
00167 // use wxStrlen(), wxStrcpy() or wxStrcat()
00168 #ifndef wxStrcpy
00169  #ifdef __UNICODE__
00170   #define wxStrcpy  wcscpy
00171  #else
00172   #define wxStrcpy  strcpy
00173  #endif
00174 #endif
00175 
00176 #ifndef wxStrcpy
00177  #ifdef __UNICODE__
00178   #define wxStrcat  wcscat
00179  #else
00180   #define wxStrcat  strcat
00181  #endif
00182 #endif
00183 
00184 
00185 
00186 // define the mcEXPORT & mcIMPORT macros which must be put everywhere
00187 // something must be exported in the DLL, when we are building a DLL
00188 // instead of a simple LIB
00189 #if defined(__MCMSW__)
00190     /*
00191        __declspec works in BC++ 5 and later, Watcom C++ 11.0 and later as well
00192        as VC++ and gcc
00193      */
00194 #    if defined(__VISUALC__) || defined(__BORLANDC__) || defined(__GNUC__) || defined(__WATCOMC__)
00195 #        define mcEXPORT __declspec(dllexport)
00196 #        define mcIMPORT __declspec(dllimport)
00197 #    else /* compiler doesn't support __declspec() */
00198 #        define mcEXPORT
00199 #        define mcIMPORT
00200 #    endif
00201 #elif defined(__MCPM__)
00202 #    if defined (__WATCOMC__)
00203 #        define mcEXPORT __declspec(dllexport)
00204         /*
00205            __declspec(dllimport) prepends __imp to imported symbols. We do NOT
00206            want that!
00207          */
00208 #        define mcIMPORT
00209 #    elif (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 )))
00210 #        define mcEXPORT _Export
00211 #        define mcIMPORT _Export
00212 #    endif
00213 #elif defined(__MCMAC__) || defined(__MCCOCOA__)
00214 #    ifdef __MWERKS__
00215 #        define mcEXPORT __declspec(export)
00216 #        define mcIMPORT __declspec(import)
00217 #    endif
00218 #endif
00219 
00220 /* for other platforms/compilers we don't anything */
00221 #ifndef mcEXPORT
00222 #    define mcEXPORT
00223 #    define mcIMPORT
00224 #endif
00225 
00226 
00227 
00228 
00229 
00230 // ------------------------
00231 // MISCELLANEOUS MACROS
00232 // ------------------------
00233 
00234 // function-like macros used to create new empty elements...
00235 #define mcNewAddOp()   mcElementHelpers::data_NewElem(mcET_ADDOP)
00236 #define mcNewSubOp()   mcElementHelpers::data_NewElem(mcET_SUBOP)
00237 #define mcNewMultOp()   mcElementHelpers::data_NewElem(mcET_MULTOP)
00238 #define mcNewDivOp()   mcElementHelpers::data_NewElem(mcET_DIVOP)
00239 #define mcNewSymbol()   mcElementHelpers::data_NewElem(mcET_SYMBOL)
00240 #define mcNewEmptyBox()   mcElementHelpers::data_NewElem(mcET_EMPTYBOX)
00241 #define mcNewNumber()   mcElementHelpers::data_NewElem(mcET_NUMBER)
00242 #define mcNewFunction()   mcElementHelpers::data_NewElem(mcET_FUNCTION)
00243 #define mcNewFraction()   mcElementHelpers::data_NewElem(mcET_FRACTION)
00244 #define mcNewBracket()   mcElementHelpers::data_NewElem(mcET_BRACKET)
00245 #define mcNewMonomial()   mcElementHelpers::data_NewElem(mcET_MONOMIAL)
00246 #define mcNewPolynomial()  mcElementHelpers::data_NewElem(mcET_POLYNOMIAL)
00247 
00248 
00249 // just to give a standard naming to macros...
00250 
00252 #define wxDEFINE_CLASS(x)   /*DECLARE_CLASS(x)*/
00253 
00256 #define wxIMPLEMENT_CLASS(x, y)  /*IMPLEMENT_CLASS(x, y)*/
00257 
00258 
00259 
00260 
00261 
00262 // ----------------------------------------------------
00263 // MACROS FOR FUNCTION DEFINITION & IMPLEMENTATION 
00264 // ----------------------------------------------------
00265 
00283 #define mcDEFINE_CUSTOM_CLONE_FNC(x)        \
00284  mc##x x##Clone() const;
00285 
00291 #define mcDEFINE_HELPER_GETMEMORYINFO_FNC(x)      \
00292  int data_GetMemoryInfo() const         \
00293   { return sizeof(x##Helpers); }
00294 
00297 #define mcDEFINE_DEBUGNAME_FNC(x)         \
00298  wxString data_GetDebugName() const        \
00299   { return wxT(#x); }
00300 
00303 #ifdef mcENABLE_COW_DEEPDEBUG
00304  #define mcDEFINE_HELPER_CLONE_FNC(x)        \
00305   virtual mcElementHelpers *data_Clone() const {     \
00306    mcLOG(#x wxT("Helpers::Clone"));       \
00307    x##Helpers *clone = new x##Helpers();      \
00308    clone->data_DeepCopy(this);         \
00309    return clone;            \
00310   }
00311 #else
00312  #define mcDEFINE_HELPER_CLONE_FNC(x)        \
00313   virtual mcElementHelpers *data_Clone() const {     \
00314    x##Helpers *clone = new x##Helpers();      \
00315    clone->data_DeepCopy(this);         \
00316    return clone;            \
00317   }
00318 #endif
00319 
00322 #define mcDEFINE_HELPER_GETTYPE_FNC(x)        \
00323  mcElementType data_GetType() const  { return x; }
00324 
00335 #define mcDEFINE_ASSIGNMENT_OPERATOR(x)         \
00336  x &operator=(const x &e)           \
00337   { if (this != &e) { data_UnRef(); data_Ref(e); } return *this; }
00338 
00344 #define mcDEFINE_COMPARISON_OPERATORS(x)             \
00345     bool operator==(const x &e) const               \
00346         { const mcElementHelpers *data = (const mcElementHelpers *)e.data_GetRefData();  \
00347         return data_GetRefData() ? (data && chlp()->data_isSameAs(data)) : !data; }  \
00348     bool operator!=(const x &e) const  { return !(*this == e); }
00349 
00352 #define mcDEFINE_ABSTRACT_CONSTRUCTORS(x, baseclass)      \
00353  x(const mcElementHelpers *p) : baseclass(p) { data_CheckContainer(); } \
00354  x(const mcElement &v) : baseclass(v.hlp()) { data_CheckContainer(); } \
00355  x(const x &toref) { data_Ref(toref); }         \
00356  x() { /* cannot create our helpers since we're abstract... */ }   \
00357  virtual ~x() {}
00358 
00359 #define mcDEFINE_MAIN_CONSTRUCTORS(x, baseclass)       \
00360  x(const mcElementHelpers *p) : baseclass(p) { data_CheckContainer(); } \
00361  x(const mcElement &v) : baseclass(v.hlp()) { data_CheckContainer(); } \
00362  x(const x &toref) { data_Ref(toref); }         \
00363  x() { data_SetRefData(new x##Helpers); }        \
00364  virtual ~x() {}
00365 
00370 #define mcDEFINE_REFERENCE_DATA(x, type)        \
00371  public:                \
00372   mcDEFINE_HELPER_GETMEMORYINFO_FNC(x)       \
00373   mcDEFINE_HELPER_CLONE_FNC(x)         \
00374   mcDEFINE_HELPER_GETTYPE_FNC(type)        \
00375   mcDEFINE_DEBUGNAME_FNC(x)
00376 
00378 
00379 
00380 
00381 
00382 
00383 
00391 
00392 #ifdef __MCDEBUG__
00393  #define mcGETTER   /* expand to nothing */
00394  #define mcWRAPPER   /* expand to nothing */
00395 #else
00396     // FIXME: by now, leave everything as if in debug mode: defining MCGETTER to
00397     // inline makes the release build fail due to a lot of unresolved externals...
00398     //#define mcGETTER   /* expand to nothing */
00399  #define mcGETTER   inline  // should be a very important optimization
00400  #define mcWRAPPER   inline  // should be a very important optimization
00401 #endif
00402 
00403 #define mcDEFINE_HLP_GETTER(x)           \
00404   \
00405  mcGETTER x##Helpers *hlp()   { return (x##Helpers *)mcElement::phlp(); }           \
00406  \
00407   mcGETTER const x##Helpers *hlp() const { return (const x##Helpers *)mcElement::chlp(); }
00408 
00409 #define mcDEFINE_HLP_CP_GETTER(x)          \
00410  mcGETTER x##Helpers *phlp()  { return (x##Helpers *)mcElement::phlp(); }  \
00411   mcGETTER const x##Helpers *chlp() const  { return (const x##Helpers *)mcElement::chlp(); }
00412 
00414 #define mcDEFINE_CLASS(x)      \
00415  mcDEFINE_HLP_GETTER(mc##x)     \
00416  mcDEFINE_HLP_CP_GETTER(mc##x)    \
00417  mcDEFINE_ASSIGNMENT_OPERATOR(mc##x)   \
00418  mcDEFINE_COMPARISON_OPERATORS(mc##x)  \
00419  mcDEFINE_DEBUGNAME_FNC(mc##x)
00420 
00428 #define mcDEFINE_HELPER_CLASSES(x)  \
00429  class x;       \
00430  class x##Helpers;
00431 
00436 #define mcDEFINE_ABSTRACT_CLASS(x, baseclass)   \
00437 public:             \
00438  mcDEFINE_CLASS(x)         \
00439  mcDEFINE_ABSTRACT_CONSTRUCTORS(mc##x, baseclass)
00440 
00450 #define mcDEFINE_MAIN_CLASS(x, baseclass)   \
00451 public:            \
00452  mcDEFINE_CLASS(x)        \
00453  mcDEFINE_MAIN_CONSTRUCTORS(mc##x, baseclass)
00454 
00456 
00457 
00458 
00459 
00464 
00465 #define mcIMPLEMENT_HLP_GETTER(x)                 \
00466  mcGETTER x##Helpers *x::hlp()    { return (x##Helpers *)mcElement::phlp(); }   \
00467  mcGETTER const x##Helpers *x::hlp() const { return (const x##Helpers *)mcElement::chlp(); } \
00468 
00469 #define mcIMPLEMENT_HLP_CP_GETTER(x)                \
00470  mcGETTER x##Helpers *x::phlp()    { return (x##Helpers *)mcElement::phlp(); }   \
00471  mcGETTER const x##Helpers *x::chlp() const { return (const x##Helpers *)mcElement::chlp(); }
00472 
00473 #define mcIMPLEMENT_MAIN_CLASS(x, baseclass)  \
00474  /*mcIMPLEMENT_HLP_GETTER(x)      \
00475  mcIMPLEMENT_HLP_CP_GETTER(x)*/
00476 
00477 #define mcIMPLEMENT_ABSTRACT_CLASS(x, baseclass) \
00478  /*mcIMPLEMENT_HLP_GETTER(x)      \
00479  mcIMPLEMENT_HLP_CP_GETTER(x)*/
00480 
00481 
00490 #define mcCREATE_HELPER_CLASSES(x)  data_SetRefData(new x##Helpers());
00491 
00493 
00494 
00495 
00496 
00497 
00501 
00506 #define mcSAFE_DELETE(x)     { if (x) delete x; x = NULL; }
00507 
00509 #define mcSAFE_DELETE_ARRAY(x)    { if (x) delete [] x; x = NULL; }
00510 
00512 #define mcRETURN_ELEMENT_CHILD(n, baseclass)  \
00513  if (n < baseclass::data_GetChildrenCount())  \
00514   return baseclass::data_GetConstChild(n); \
00515  n -= baseclass::data_GetChildrenCount();
00516 
00517 #define mcSET_ELEMENT_CHILD(n, baseclass, p)  \
00518  if (n < baseclass::data_GetChildrenCount()) { \
00519   baseclass::data_SetChild(n, p);    \
00520   return;          \
00521  }             \
00522   n -= baseclass::data_GetChildrenCount();
00523 
00524 
00527 #define mcSIGN(x)    (((x) < 0) ? -1 : 1)
00528 
00530 #define mcMAX(x, y)    (((x) < (y)) ? (y) : (x))
00531 
00533 #define mcMIN(x, y)    (((x) < (y)) ? (x) : (y))
00534 
00537 #define mcSWAP(type, x, y)  { type tmp = x; x = y; y = tmp; }
00538 
00540 #define mcDBL_MAX    1.7976931348623157e+308
00541 
00543 #define mcINT_MAX    2147483647
00544 
00546 #define mcGETRED(c)    (((wxInt32)(c)) & 255)
00547 
00549 #define mcGETGREEN(c)   ((((wxInt32)(c)) >> 8) & 255)
00550 
00552 #define mcGETBLUE(c)   ((((wxInt32)(c)) >> 16) & 255)
00553 
00555 #define mcINITWX(x)    (wxColour(mcGETRED(x), mcGETGREEN(x), mcGETBLUE(x)))
00556 
00559 #define mcRGB_ENCODE(r, g, b)  (wxUint32) ((wxUint8)(r) |  \
00560     ((wxUint16)(g) << 8)) | (((wxUint32)((b) << 16))
00561 
00563 #if wxCHECK_VERSION(2, 5, 1)
00564  #define mcUNUSED(x)   wxUnusedVar(x)
00565 #else
00566  #define mcUNUSED(x)   { x == x; }
00567 #endif
00568 
00582 #define mcEXTEND_ARRAY(type, parray, oldsize, newsize)   \
00583  {               \
00584   type *pnew = new type[newsize];       \
00585   for (int e=0; e < oldsize; e++)       \
00586    pnew[e] = parray[e];         \
00587   delete [] parray;          \
00588   parray = pnew;           \
00589  }
00590 
00591 
00601 #define mcASSERT(x, desc)   wxASSERT_MSG(x, wxT("\n\n") desc wxT("\n\n"));
00602 
00604 
00605 
00606 
00607 
00608 
00609 // ------------------
00610 // GLOBAL FUNCTIONS
00611 // ------------------
00612 
00615 int wxFindOneOf(const wxString &str, const wxString &tofind);
00616 
00619 wxString wxIndent(const wxString &str, int indent);
00620 
00623 wxBitmap *wxLoadMaskForXPM(char **xpm, const wxColour &mask);
00624 
00625 
00626 
00627 #endif // MATHUTILS_H
00628 


Documentation generated with Doxygen on Sun Feb 6 17:10:47 2005
Visit MathStudio home page for more info

[ Top ]