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
[ Top ] |