00001 // Additional Information Union implementation -*- C++ -*- 00002 00003 // Copyright (C) 2001-2003 Hermann Schichl 00004 // 00005 // This file is part of the COCONUT API. This library 00006 // is free software; you can redistribute it and/or modify it under the 00007 // terms of the Library GNU General Public License as published by the 00008 // Free Software Foundation; either version 2, or (at your option) 00009 // any later 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 // Library GNU General Public License for more details. 00015 00016 // As a special exception, you may use this file as part of a free software 00017 // library without restriction. Specifically, if other files instantiate 00018 // templates or use macros or inline functions from this file, or you compile 00019 // this file and link it with other files to produce an executable, this 00020 // file does not by itself cause the resulting executable to be covered by 00021 // the Library GNU General Public License. This exception does not however 00022 // invalidate any other reasons why the executable file might be covered by 00023 // the Library GNU General Public License. 00024 00027 #ifndef _ADDINFO_H_ 00028 #define _ADDINFO_H_ 00029 00030 #include <string> 00031 #include <vector> 00032 #include <coconut_config.h> 00033 #include <interval.h> 00034 #include <linalg.h> 00035 00036 // the simple types have to be < ADDINFO_EMPTY 00037 #define ADDINFO_INTERVAL -5 00038 #define ADDINFO_DOUBLE -4 00039 #define ADDINFO_UINT -3 00040 #define ADDINFO_INT -2 00041 #define ADDINFO_BOOL -1 00042 // 00043 #define ADDINFO_EMPTY 0 00044 // the complex types have to be > ADDINFO_EMPTY 00045 #define ADDINFO_ALLOCED_B 1 00046 #define ADDINFO_ALLOCED_N 2 00047 #define ADDINFO_ALLOCED_U 3 00048 #define ADDINFO_ALLOCED_D 4 00049 #define ADDINFO_ALLOCED_I 5 00050 #define ADDINFO_ALLOCED_S 6 00051 #define ADDINFO_ALLOCED_M 7 00052 #define ADDINFO_ALLOCED_NM 8 00053 #define ADDINFO_ALLOCED_IM 9 00054 00055 class additional_info_u 00056 { 00057 private: 00058 union 00059 { 00060 bool nb; // this union contains additional information 00061 int nn; // and standard types 00062 unsigned int nu; 00063 double nd; 00064 interval_st ni; 00065 std::string* s; 00066 std::vector<bool>* b; 00067 std::vector<int>* n; 00068 std::vector<unsigned int>* u; 00069 std::vector<double>* d; 00070 std::vector<interval>* i; 00071 matrix<double>* m; 00072 matrix<int>* nm; 00073 matrix<interval>* im; 00074 } __c; 00075 int __is_allocated; 00076 00077 private: 00078 void _destroy() 00079 { 00080 switch(__is_allocated) 00081 { 00082 case ADDINFO_INTERVAL: 00083 case ADDINFO_DOUBLE: 00084 case ADDINFO_UINT: 00085 case ADDINFO_INT: 00086 case ADDINFO_BOOL: 00087 case ADDINFO_EMPTY: 00088 break; 00089 case ADDINFO_ALLOCED_S: 00090 delete(__c.s); 00091 break; 00092 case ADDINFO_ALLOCED_B: 00093 delete(__c.b); 00094 break; 00095 case ADDINFO_ALLOCED_N: 00096 delete(__c.n); 00097 break; 00098 case ADDINFO_ALLOCED_U: 00099 delete(__c.u); 00100 break; 00101 case ADDINFO_ALLOCED_D: 00102 delete(__c.d); 00103 break; 00104 case ADDINFO_ALLOCED_I: 00105 delete(__c.i); 00106 break; 00107 case ADDINFO_ALLOCED_M: 00108 delete(__c.m); 00109 break; 00110 case ADDINFO_ALLOCED_NM: 00111 delete(__c.nm); 00112 break; 00113 case ADDINFO_ALLOCED_IM: 00114 delete(__c.im); 00115 break; 00116 } 00117 } 00118 00119 void _copy(const additional_info_u& __a) 00120 { 00121 __is_allocated = __a.__is_allocated; 00122 switch(__is_allocated) 00123 { 00124 case ADDINFO_EMPTY: 00125 break; 00126 case ADDINFO_INTERVAL: 00127 __c.ni = __a.__c.ni; 00128 break; 00129 case ADDINFO_DOUBLE: 00130 __c.nd = __a.__c.nd; 00131 break; 00132 case ADDINFO_UINT: 00133 __c.nu = __a.__c.nu; 00134 break; 00135 case ADDINFO_INT: 00136 __c.nn = __a.__c.nn; 00137 break; 00138 case ADDINFO_BOOL: 00139 __c.nb = __a.__c.nb; 00140 break; 00141 case ADDINFO_ALLOCED_S: 00142 __c.s = new std::string(*__a.__c.s); 00143 break; 00144 case ADDINFO_ALLOCED_B: 00145 __c.b = new std::vector<bool>(*__a.__c.b); 00146 break; 00147 case ADDINFO_ALLOCED_N: 00148 __c.n = new std::vector<int>(*__a.__c.n); 00149 break; 00150 case ADDINFO_ALLOCED_U: 00151 __c.u = new std::vector<unsigned int>(*__a.__c.u); 00152 break; 00153 case ADDINFO_ALLOCED_D: 00154 __c.d = new std::vector<double>(*__a.__c.d); 00155 break; 00156 case ADDINFO_ALLOCED_I: 00157 __c.i = new std::vector<interval>(*__a.__c.i); 00158 break; 00159 case ADDINFO_ALLOCED_M: 00160 __c.m = new matrix<double>(*__a.__c.m); 00161 break; 00162 case ADDINFO_ALLOCED_NM: 00163 __c.nm = new matrix<int>(*__a.__c.nm); 00164 break; 00165 case ADDINFO_ALLOCED_IM: 00166 __c.im = new matrix<interval>(*__a.__c.im); 00167 break; 00168 } 00169 } 00170 00171 public: 00172 additional_info_u() : __is_allocated(ADDINFO_EMPTY) {} 00173 additional_info_u(bool __x) : __is_allocated(ADDINFO_BOOL) 00174 { __c.nb = __x; } 00175 additional_info_u(int __x) : __is_allocated(ADDINFO_INT) 00176 { __c.nn = __x; } 00177 additional_info_u(unsigned int __x) : __is_allocated(ADDINFO_UINT) 00178 { __c.nu = __x; } 00179 additional_info_u(double __x) : __is_allocated(ADDINFO_DOUBLE) 00180 { __c.nd = __x;} 00181 additional_info_u(interval __x) : __is_allocated(ADDINFO_INTERVAL) 00182 { __c.ni = __x; } 00183 additional_info_u(const char* __cp) : __is_allocated(ADDINFO_ALLOCED_S) 00184 { __c.s = new std::string(__cp); } 00185 additional_info_u(const std::string& __x) : __is_allocated(ADDINFO_ALLOCED_S) 00186 { __c.s = new std::string(__x); } 00187 additional_info_u(const std::vector<bool>& __x) : __is_allocated(ADDINFO_ALLOCED_B) 00188 { __c.b = new std::vector<bool>(__x); } 00189 additional_info_u(const std::vector<int>& __x) : __is_allocated(ADDINFO_ALLOCED_N) 00190 { __c.n = new std::vector<int>(__x); } 00191 additional_info_u(const std::vector<unsigned int>& __x) : __is_allocated(ADDINFO_ALLOCED_U) 00192 { __c.u = new std::vector<unsigned int>(__x); } 00193 additional_info_u(const std::vector<double>& __x) : 00194 __is_allocated(ADDINFO_ALLOCED_D) 00195 { __c.d = new std::vector<double>(__x); } 00196 additional_info_u(const std::vector<interval>& __x) : 00197 __is_allocated(ADDINFO_ALLOCED_I) 00198 { __c.i = new std::vector<interval>(__x); } 00199 additional_info_u(const matrix<double>& __x) : 00200 __is_allocated(ADDINFO_ALLOCED_M) 00201 { __c.m = new matrix<double>(__x); } 00202 additional_info_u(const matrix<int>& __x) : 00203 __is_allocated(ADDINFO_ALLOCED_NM) 00204 { __c.nm = new matrix<int>(__x); } 00205 additional_info_u(const matrix<interval>& __x) : 00206 __is_allocated(ADDINFO_ALLOCED_IM) 00207 { __c.im = new matrix<interval>(__x); } 00208 00209 ~additional_info_u() 00210 { _destroy(); } 00211 00212 additional_info_u(const additional_info_u& __a) 00213 { _copy(__a); } 00214 00215 additional_info_u& operator=(bool __x) 00216 { _destroy(); __is_allocated = ADDINFO_BOOL; __c.nb = __x; 00217 return *this; 00218 } 00219 00220 additional_info_u& operator=(int __x) 00221 { _destroy(); __is_allocated = ADDINFO_INT; __c.nn = __x; 00222 return *this; 00223 } 00224 00225 additional_info_u& operator=(unsigned int __x) 00226 { _destroy(); __is_allocated = ADDINFO_UINT; __c.nu = __x; 00227 return *this; 00228 } 00229 00230 additional_info_u& operator=(double __x) 00231 { _destroy(); __is_allocated = ADDINFO_DOUBLE; __c.nd = __x; 00232 return *this; 00233 } 00234 00235 additional_info_u& operator=(interval __x) 00236 { _destroy(); __is_allocated = ADDINFO_INTERVAL; __c.ni = __x; 00237 return *this; 00238 } 00239 00240 additional_info_u& operator=(const std::string& __x) 00241 { _destroy(); __is_allocated = ADDINFO_ALLOCED_S; 00242 __c.s = new std::string(__x); 00243 return *this; 00244 } 00245 00246 additional_info_u& operator=(const char* __x) 00247 { _destroy(); __is_allocated = ADDINFO_ALLOCED_S; 00248 __c.s = new std::string(__x); 00249 return *this; 00250 } 00251 00252 additional_info_u& operator=(const std::vector<bool>& __x) 00253 { _destroy(); __is_allocated = ADDINFO_ALLOCED_B; 00254 __c.b = new std::vector<bool>(__x); 00255 return *this; 00256 } 00257 00258 additional_info_u& operator=(const std::vector<int>& __x) 00259 { _destroy(); __is_allocated = ADDINFO_ALLOCED_N; 00260 __c.n = new std::vector<int>(__x); 00261 return *this; 00262 } 00263 00264 additional_info_u& operator=(const std::vector<unsigned int>& __x) 00265 { _destroy(); __is_allocated = ADDINFO_ALLOCED_U; 00266 __c.u = new std::vector<unsigned int>(__x); 00267 return *this; 00268 } 00269 00270 additional_info_u& operator=(const std::vector<double>& __x) 00271 { _destroy(); __is_allocated = ADDINFO_ALLOCED_D; 00272 __c.d = new std::vector<double>(__x); 00273 return *this; 00274 } 00275 00276 additional_info_u& operator=(const std::vector<interval>& __x) 00277 { _destroy(); __is_allocated = ADDINFO_ALLOCED_I; 00278 __c.i = new std::vector<interval>(__x); 00279 return *this; 00280 } 00281 00282 additional_info_u& operator=(const matrix<double>& __x) 00283 { _destroy(); __is_allocated = ADDINFO_ALLOCED_M; 00284 __c.m = new matrix<double>(__x); 00285 return *this; 00286 } 00287 00288 additional_info_u& operator=(const matrix<int>& __x) 00289 { _destroy(); __is_allocated = ADDINFO_ALLOCED_NM; 00290 __c.nm = new matrix<int>(__x); 00291 return *this; 00292 } 00293 00294 additional_info_u& operator=(const matrix<interval>& __x) 00295 { _destroy(); __is_allocated = ADDINFO_ALLOCED_IM; 00296 __c.im = new matrix<interval>(__x); 00297 return *this; 00298 } 00299 00300 additional_info_u& operator=(const additional_info_u& __a) 00301 { 00302 _destroy(); 00303 _copy(__a); 00304 return *this; 00305 } 00306 00307 additional_info_u& clear() 00308 { 00309 _destroy(); 00310 __is_allocated = ADDINFO_EMPTY; 00311 return *this; 00312 } 00313 00314 public: 00315 // this constructor must not be used unless __m was allocated 00316 // by new matrix<double>. 00317 additional_info_u& set_m(matrix<double>* __m) 00318 { 00319 clear(); 00320 __is_allocated = ADDINFO_ALLOCED_M; 00321 __c.m = __m; 00322 return *this; 00323 } 00324 00325 // this constructor must not be used unless __m was allocated 00326 // by new matrix<interval>. 00327 additional_info_u& set_im(matrix<interval>* __m) 00328 { 00329 clear(); 00330 __is_allocated = ADDINFO_ALLOCED_IM; 00331 __c.im = __m; 00332 return *this; 00333 } 00334 00335 // this constructor must not be used unless __m was allocated 00336 // by new matrix<int>. 00337 additional_info_u& set_nm(matrix<int>* __m) 00338 { 00339 clear(); 00340 __is_allocated = ADDINFO_ALLOCED_NM; 00341 __c.nm = __m; 00342 return *this; 00343 } 00344 00345 public: 00346 bool nb() const { return __c.nb; } 00347 int nn() const { return __c.nn; } 00348 unsigned int nu() const { return __c.nu; } 00349 double nd() const { return __c.nd; } 00350 interval ni() const { return __c.ni; } 00351 std::string& s() const { return *__c.s; } 00352 std::vector<bool>& b() const { return *__c.b; } 00353 std::vector<int>& n() const { return *__c.n; } 00354 std::vector<unsigned int>& u() const { return *__c.u; } 00355 std::vector<double>& d() const { return *__c.d; } 00356 std::vector<interval>& i() const { return *__c.i; } 00357 matrix<double>& m() const { return *__c.m; } 00358 matrix<int>& nm() const { return *__c.nm; } 00359 matrix<interval>& im() const { return *__c.im; } 00360 00361 bool is_allocated() const { return __is_allocated > ADDINFO_EMPTY; } 00362 bool empty() const { return __is_allocated == ADDINFO_EMPTY; } 00363 int has_type() { return __is_allocated; } 00364 }; 00365 00366 #endif /* _ADDINFO_H_ */