00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00028 #ifndef _BASIC_ALLTYPE_H_
00029 #define _BASIC_ALLTYPE_H_
00030
00031 #include <string>
00032 #include <vector>
00033 #include <climits>
00034 #include <coconut_config.h>
00035 #include <interval.h>
00036 #include <linalg.h>
00037 #include <api_exception.h>
00038
00039 namespace coco {
00040
00047 #define BASIC_ALLTYPE_CHECK 1
00048
00049
00050
00051 #define ALLTYPE_INTERVAL -5
00052 #define ALLTYPE_DOUBLE -4
00053 #define ALLTYPE_UINT -3
00054 #define ALLTYPE_INT -2
00055 #define ALLTYPE_BOOL -1
00056 //
00057 #define ALLTYPE_EMPTY 0
00058 // the complex types have to be > ALLTYPE_EMPTY
00059 #define ALLTYPE_ALLOCED_B 1
00060 #define ALLTYPE_ALLOCED_N 2
00061 #define ALLTYPE_ALLOCED_U 3
00062 #define ALLTYPE_ALLOCED_D 4
00063 #define ALLTYPE_ALLOCED_I 5
00064 #define ALLTYPE_ALLOCED_C 6
00065 // the string type has to be bigger than all the vectors
00066 #define ALLTYPE_ALLOCED_S 7
00067 // the matrix types have to be > ALLTYPE_ALLOCED_S
00068 #define ALLTYPE_ALLOCED_M 8
00069 #define ALLTYPE_ALLOCED_NM 9
00070 #define ALLTYPE_ALLOCED_IM 10
00071 #define ALLTYPE_ALLOCED_SM 11
00073 #define ALLTYPE_ANY 99
00075 #define BASIC_ALLTYPE_NAMES { \
00076 "interval", "double", "unsigned int", "int", "bool", "empty", \
00077 "bool vector", "int vector", "unsigned int vector", "double vector", \
00078 "interval vector", "string vector", "string", "double matrix", \
00079 "int matrix", "interval matrix", "string matrix" }
00080
00081 #if BASIC_ALLTYPE_CHECK
00082
00087 #define BASIC_ALLTYPE_ASSERT(A) do { \
00088 if(__cont_type != (A)) \
00089 throw api_exception(apiee_internal,\
00090 std::string("api/basic_alltype.h/1: Basic alltype ")+type_cstr((A))+\
00091 " requested, type was "+type_name());\
00092 } while(0)
00093
00098 #define BASIC_ALLTYPE_ASSERT2(A,B) do { \
00099 if(__cont_type != (A) && __cont_type != (B)) \
00100 throw api_exception(apiee_internal,\
00101 std::string("api/basic_alltype.h/2: Basic alltype ")+type_cstr((A))+\
00102 " requested, type was "+type_name());\
00103 } while(0)
00104
00105 #define BASIC_ALLTYPE_THROW throw(api_exception)
00106 #else
00107 #define BASIC_ALLTYPE_ASSERT(A)
00108 #define BASIC_ALLTYPE_ASSERT2(A,B)
00109 #define BASIC_ALLTYPE_THROW
00110 #endif
00111
00117 #define BASIC_ALLTYPE_FIX_EMPTY_VECTOR(CT,T) do { \
00118 if (__cont_type != (CT) && is_empty_vector()) \
00119 \
00120 const_cast<basic_alltype *>(this)->operator=(std::vector<T>()); \
00121 } while(0)
00122
00124
00133 class basic_alltype
00134 {
00135 private:
00139 union
00140 {
00141 bool nb;
00142 int nn;
00143 unsigned int nu;
00144 double nd;
00145 interval_st ni;
00146 std::string* s;
00147 std::vector<bool>* b;
00148 std::vector<int>* n;
00149 std::vector<unsigned int>* u;
00150 std::vector<double>* d;
00151 std::vector<interval>* i;
00152 std::vector<std::string>* sv;
00153 linalg::matrix<double>* m;
00154 linalg::matrix<int>* nm;
00155 linalg::matrix<interval>* im;
00156 linalg::matrix<std::string>* sm;
00157 } __c;
00159 int __cont_type;
00160
00162 static const char *__basic_alltype_name[];
00163
00164 private:
00166 void _destroy()
00167 {
00168 switch(__cont_type)
00169 {
00170 case ALLTYPE_INTERVAL:
00171 case ALLTYPE_DOUBLE:
00172 case ALLTYPE_UINT:
00173 case ALLTYPE_INT:
00174 case ALLTYPE_BOOL:
00175 case ALLTYPE_EMPTY:
00176 break;
00177 case ALLTYPE_ALLOCED_S:
00178 delete(__c.s);
00179 break;
00180 case ALLTYPE_ALLOCED_B:
00181 delete(__c.b);
00182 break;
00183 case ALLTYPE_ALLOCED_N:
00184 delete(__c.n);
00185 break;
00186 case ALLTYPE_ALLOCED_U:
00187 delete(__c.u);
00188 break;
00189 case ALLTYPE_ALLOCED_D:
00190 delete(__c.d);
00191 break;
00192 case ALLTYPE_ALLOCED_I:
00193 delete(__c.i);
00194 break;
00195 case ALLTYPE_ALLOCED_C:
00196 delete(__c.sv);
00197 break;
00198 case ALLTYPE_ALLOCED_M:
00199 delete(__c.m);
00200 break;
00201 case ALLTYPE_ALLOCED_NM:
00202 delete(__c.nm);
00203 break;
00204 case ALLTYPE_ALLOCED_IM:
00205 delete(__c.im);
00206 break;
00207 case ALLTYPE_ALLOCED_SM:
00208 delete(__c.sm);
00209 break;
00210 }
00211 }
00212
00214 void _copy(const basic_alltype& __a)
00215 {
00216 __cont_type = __a.__cont_type;
00217 switch(__cont_type)
00218 {
00219 case ALLTYPE_EMPTY:
00220 break;
00221 case ALLTYPE_INTERVAL:
00222 __c.ni = __a.__c.ni;
00223 break;
00224 case ALLTYPE_DOUBLE:
00225 __c.nd = __a.__c.nd;
00226 break;
00227 case ALLTYPE_UINT:
00228 __c.nu = __a.__c.nu;
00229 break;
00230 case ALLTYPE_INT:
00231 __c.nn = __a.__c.nn;
00232 break;
00233 case ALLTYPE_BOOL:
00234 __c.nb = __a.__c.nb;
00235 break;
00236 case ALLTYPE_ALLOCED_S:
00237 __c.s = new std::string(*__a.__c.s);
00238 break;
00239 case ALLTYPE_ALLOCED_B:
00240 __c.b = new std::vector<bool>(*__a.__c.b);
00241 break;
00242 case ALLTYPE_ALLOCED_N:
00243 __c.n = new std::vector<int>(*__a.__c.n);
00244 break;
00245 case ALLTYPE_ALLOCED_U:
00246 __c.u = new std::vector<unsigned int>(*__a.__c.u);
00247 break;
00248 case ALLTYPE_ALLOCED_D:
00249 __c.d = new std::vector<double>(*__a.__c.d);
00250 break;
00251 case ALLTYPE_ALLOCED_I:
00252 __c.i = new std::vector<interval>(*__a.__c.i);
00253 break;
00254 case ALLTYPE_ALLOCED_C:
00255 __c.sv = new std::vector<std::string>(*__a.__c.sv);
00256 break;
00257 case ALLTYPE_ALLOCED_M:
00258 __c.m = new linalg::matrix<double>(*__a.__c.m);
00259 break;
00260 case ALLTYPE_ALLOCED_NM:
00261 __c.nm = new linalg::matrix<int>(*__a.__c.nm);
00262 break;
00263 case ALLTYPE_ALLOCED_IM:
00264 __c.im = new linalg::matrix<interval>(*__a.__c.im);
00265 break;
00266 case ALLTYPE_ALLOCED_SM:
00267 __c.sm = new linalg::matrix<std::string>(*__a.__c.sm);
00268 break;
00269 }
00270 }
00271
00272 public:
00274 basic_alltype() : __cont_type(ALLTYPE_EMPTY) {}
00276 basic_alltype(bool __x) : __cont_type(ALLTYPE_BOOL)
00277 { __c.nb = __x; }
00279 basic_alltype(int __x) : __cont_type(ALLTYPE_INT)
00280 { __c.nn = __x; }
00282 basic_alltype(unsigned int __x) : __cont_type(ALLTYPE_UINT)
00283 { __c.nu = __x; }
00285 basic_alltype(double __x) : __cont_type(ALLTYPE_DOUBLE)
00286 { __c.nd = __x;}
00288 basic_alltype(interval __x) : __cont_type(ALLTYPE_INTERVAL)
00289 { __c.ni = __x; }
00291 basic_alltype(const char* __cp) : __cont_type(ALLTYPE_ALLOCED_S)
00292 { __c.s = new std::string(__cp); }
00294 basic_alltype(const std::string& __x) : __cont_type(ALLTYPE_ALLOCED_S)
00295 { __c.s = new std::string(__x); }
00297 basic_alltype(const std::vector<bool>& __x) : __cont_type(ALLTYPE_ALLOCED_B)
00298 { __c.b = new std::vector<bool>(__x); }
00300 basic_alltype(const std::vector<int>& __x) : __cont_type(ALLTYPE_ALLOCED_N)
00301 { __c.n = new std::vector<int>(__x); }
00303 basic_alltype(const std::vector<unsigned int>& __x) : __cont_type(ALLTYPE_ALLOCED_U)
00304 { __c.u = new std::vector<unsigned int>(__x); }
00306 basic_alltype(const std::vector<double>& __x) :
00307 __cont_type(ALLTYPE_ALLOCED_D)
00308 { __c.d = new std::vector<double>(__x); }
00310 basic_alltype(const std::vector<interval>& __x) :
00311 __cont_type(ALLTYPE_ALLOCED_I)
00312 { __c.i = new std::vector<interval>(__x); }
00314 basic_alltype(const std::vector<std::string>& __x) :
00315 __cont_type(ALLTYPE_ALLOCED_C)
00316 { __c.sv = new std::vector<std::string>(__x); }
00318 basic_alltype(const linalg::matrix<double>& __x) :
00319 __cont_type(ALLTYPE_ALLOCED_M)
00320 { __c.m = new linalg::matrix<double>(__x); }
00322 basic_alltype(const linalg::matrix<int>& __x) :
00323 __cont_type(ALLTYPE_ALLOCED_NM)
00324 { __c.nm = new linalg::matrix<int>(__x); }
00326 basic_alltype(const linalg::matrix<interval>& __x) :
00327 __cont_type(ALLTYPE_ALLOCED_IM)
00328 { __c.im = new linalg::matrix<interval>(__x); }
00330 basic_alltype(const linalg::matrix<std::string>& __x) :
00331 __cont_type(ALLTYPE_ALLOCED_SM)
00332 { __c.sm = new linalg::matrix<std::string>(__x); }
00333
00335 ~basic_alltype()
00336 { _destroy(); }
00337
00339 basic_alltype(const basic_alltype& __a)
00340 { _copy(__a); }
00341
00343 basic_alltype& operator=(bool __x)
00344 { _destroy(); __cont_type = ALLTYPE_BOOL; __c.nb = __x;
00345 return *this;
00346 }
00347
00349 basic_alltype& operator=(int __x)
00350 { _destroy(); __cont_type = ALLTYPE_INT; __c.nn = __x;
00351 return *this;
00352 }
00353
00355 basic_alltype& operator=(unsigned int __x)
00356 { _destroy(); __cont_type = ALLTYPE_UINT; __c.nu = __x;
00357 return *this;
00358 }
00359
00361 basic_alltype& operator=(double __x)
00362 { _destroy(); __cont_type = ALLTYPE_DOUBLE; __c.nd = __x;
00363 return *this;
00364 }
00365
00367 basic_alltype& operator=(interval __x)
00368 { _destroy(); __cont_type = ALLTYPE_INTERVAL; __c.ni = __x;
00369 return *this;
00370 }
00371
00373 basic_alltype& operator=(const std::string& __x)
00374 { _destroy(); __cont_type = ALLTYPE_ALLOCED_S;
00375 __c.s = new std::string(__x);
00376 return *this;
00377 }
00378
00380 basic_alltype& operator=(const char* __x)
00381 { _destroy(); __cont_type = ALLTYPE_ALLOCED_S;
00382 __c.s = new std::string(__x);
00383 return *this;
00384 }
00385
00387 basic_alltype& operator=(const std::vector<bool>& __x)
00388 { _destroy(); __cont_type = ALLTYPE_ALLOCED_B;
00389 __c.b = new std::vector<bool>(__x);
00390 return *this;
00391 }
00392
00394 basic_alltype& operator=(const std::vector<int>& __x)
00395 { _destroy(); __cont_type = ALLTYPE_ALLOCED_N;
00396 __c.n = new std::vector<int>(__x);
00397 return *this;
00398 }
00399
00401 basic_alltype& operator=(const std::vector<unsigned int>& __x)
00402 { _destroy(); __cont_type = ALLTYPE_ALLOCED_U;
00403 __c.u = new std::vector<unsigned int>(__x);
00404 return *this;
00405 }
00406
00408 basic_alltype& operator=(const std::vector<double>& __x)
00409 { _destroy(); __cont_type = ALLTYPE_ALLOCED_D;
00410 __c.d = new std::vector<double>(__x);
00411 return *this;
00412 }
00413
00415 basic_alltype& operator=(const std::vector<interval>& __x)
00416 { _destroy(); __cont_type = ALLTYPE_ALLOCED_I;
00417 __c.i = new std::vector<interval>(__x);
00418 return *this;
00419 }
00420
00422 basic_alltype& operator=(const std::vector<std::string>& __x)
00423 { _destroy(); __cont_type = ALLTYPE_ALLOCED_C;
00424 __c.sv = new std::vector<std::string>(__x);
00425 return *this;
00426 }
00427
00429 basic_alltype& operator=(const linalg::matrix<double>& __x)
00430 { _destroy(); __cont_type = ALLTYPE_ALLOCED_M;
00431 __c.m = new linalg::matrix<double>(__x);
00432 return *this;
00433 }
00434
00436 basic_alltype& operator=(const linalg::matrix<int>& __x)
00437 { _destroy(); __cont_type = ALLTYPE_ALLOCED_NM;
00438 __c.nm = new linalg::matrix<int>(__x);
00439 return *this;
00440 }
00441
00443 basic_alltype& operator=(const linalg::matrix<interval>& __x)
00444 { _destroy(); __cont_type = ALLTYPE_ALLOCED_IM;
00445 __c.im = new linalg::matrix<interval>(__x);
00446 return *this;
00447 }
00448
00450 basic_alltype& operator=(const linalg::matrix<std::string>& __x)
00451 { _destroy(); __cont_type = ALLTYPE_ALLOCED_SM;
00452 __c.sm = new linalg::matrix<std::string>(__x);
00453 return *this;
00454 }
00455
00457 basic_alltype& operator=(const basic_alltype& __a)
00458 {
00459 _destroy();
00460 _copy(__a);
00461 return *this;
00462 }
00463
00465 basic_alltype& clear()
00466 {
00467 _destroy();
00468 __cont_type = ALLTYPE_EMPTY;
00469 return *this;
00470 }
00471
00472 public:
00476 basic_alltype& set_m(linalg::matrix<double>* __m)
00477 {
00478 clear();
00479 __cont_type = ALLTYPE_ALLOCED_M;
00480 __c.m = __m;
00481 return *this;
00482 }
00483
00487 basic_alltype& set_nm(linalg::matrix<int>* __m)
00488 {
00489 clear();
00490 __cont_type = ALLTYPE_ALLOCED_NM;
00491 __c.nm = __m;
00492 return *this;
00493 }
00494
00498 basic_alltype& set_im(linalg::matrix<interval>* __m)
00499 {
00500 clear();
00501 __cont_type = ALLTYPE_ALLOCED_IM;
00502 __c.im = __m;
00503 return *this;
00504 }
00505
00509 basic_alltype& set_sm(linalg::matrix<std::string>* __m)
00510 {
00511 clear();
00512 __cont_type = ALLTYPE_ALLOCED_SM;
00513 __c.sm = __m;
00514 return *this;
00515 }
00516
00517 public:
00519 bool nb() const BASIC_ALLTYPE_THROW
00520 { BASIC_ALLTYPE_ASSERT(ALLTYPE_BOOL); return __c.nb; }
00522 int nn() const BASIC_ALLTYPE_THROW
00523 { BASIC_ALLTYPE_ASSERT2(ALLTYPE_INT,ALLTYPE_UINT);
00524 #if BASIC_ALLTYPE_CHECK
00525 if(__cont_type == ALLTYPE_UINT && __c.nu > (unsigned)INT_MAX)
00526 throw api_exception(apiee_internal,
00527 std::string("api/basic_alltype.h/nn() Unsigned integer out of range for signed integer"));
00528 #endif
00529 return __c.nn; }
00531 unsigned int nu() const BASIC_ALLTYPE_THROW
00532 { BASIC_ALLTYPE_ASSERT2(ALLTYPE_UINT,ALLTYPE_INT);
00533 #if BASIC_ALLTYPE_CHECK
00534 if(__cont_type == ALLTYPE_INT && __c.nn < 0)
00535 throw api_exception(apiee_internal,
00536 std::string("api/basic_alltype.h/nu(): Signed integer out of range for unsigned integer"));
00537 #endif
00538 return __c.nu; }
00540 double nd() const BASIC_ALLTYPE_THROW
00541 { BASIC_ALLTYPE_ASSERT(ALLTYPE_DOUBLE); return __c.nd; }
00543 interval ni() const BASIC_ALLTYPE_THROW
00544 { BASIC_ALLTYPE_ASSERT(ALLTYPE_INTERVAL); return __c.ni; }
00546 std::string& s() const BASIC_ALLTYPE_THROW
00547 { BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_S); return *__c.s; }
00549 std::vector<bool>& b() const BASIC_ALLTYPE_THROW
00550 { BASIC_ALLTYPE_FIX_EMPTY_VECTOR(ALLTYPE_ALLOCED_B,bool);
00551 BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_B); return *__c.b; }
00553 std::vector<int>& n() const BASIC_ALLTYPE_THROW
00554 { BASIC_ALLTYPE_FIX_EMPTY_VECTOR(ALLTYPE_ALLOCED_N,int);
00555 BASIC_ALLTYPE_ASSERT2(ALLTYPE_ALLOCED_N,ALLTYPE_ALLOCED_U);
00556 if (__cont_type == ALLTYPE_ALLOCED_U) {
00557 std::vector<unsigned int> *u = __c.u;
00558 std::vector<int> *n = new std::vector<int>;
00559 for (std::vector<unsigned int>::const_iterator i = u->begin(); i != u->end(); ++i) {
00560 unsigned int ui = *i;
00561 #if BASIC_ALLTYPE_CHECK
00562 if (ui > (unsigned int) INT_MAX)
00563 throw api_exception(apiee_internal,
00564 std::string("api/basic_alltype.h/n() Unsigned integer out of range for signed integer"));
00565 #endif
00566 n->push_back((int) ui);
00567 }
00568
00569 const_cast<basic_alltype *>(this)->__cont_type = ALLTYPE_ALLOCED_N;
00570 const_cast<basic_alltype *>(this)->__c.n = n;
00571 delete u;
00572 }
00573 return *__c.n; }
00575 std::vector<unsigned int>& u() const BASIC_ALLTYPE_THROW
00576 { BASIC_ALLTYPE_FIX_EMPTY_VECTOR(ALLTYPE_ALLOCED_U,unsigned int);
00577 BASIC_ALLTYPE_ASSERT2(ALLTYPE_ALLOCED_U,ALLTYPE_ALLOCED_N);
00578 if (__cont_type == ALLTYPE_ALLOCED_N) {
00579 std::vector<int> *n = __c.n;
00580 std::vector<unsigned int> *u = new std::vector<unsigned int>;
00581 for (std::vector<int>::const_iterator i = n->begin(); i != n->end(); ++i) {
00582 int ni = *i;
00583 #if BASIC_ALLTYPE_CHECK
00584 if (ni < 0)
00585 throw api_exception(apiee_internal,
00586 std::string("api/basic_alltype.h/u(): Signed integer out of range for unsigned integer"));
00587 #endif
00588 u->push_back((unsigned int) ni);
00589 }
00590
00591 const_cast<basic_alltype *>(this)->__cont_type = ALLTYPE_ALLOCED_U;
00592 const_cast<basic_alltype *>(this)->__c.u = u;
00593 delete n;
00594 }
00595 return *__c.u; }
00597 std::vector<double>& d() const BASIC_ALLTYPE_THROW
00598 { BASIC_ALLTYPE_FIX_EMPTY_VECTOR(ALLTYPE_ALLOCED_D,double);
00599 BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_D); return *__c.d; }
00601 std::vector<interval>& i() const BASIC_ALLTYPE_THROW
00602 { BASIC_ALLTYPE_FIX_EMPTY_VECTOR(ALLTYPE_ALLOCED_I,interval);
00603 BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_I); return *__c.i; }
00605 std::vector<std::string>& sv() const BASIC_ALLTYPE_THROW
00606 { BASIC_ALLTYPE_FIX_EMPTY_VECTOR(ALLTYPE_ALLOCED_C,std::string);
00607 BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_C); return *__c.sv; }
00609 linalg::matrix<double>& m() const BASIC_ALLTYPE_THROW
00610 { BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_M); return *__c.m; }
00612 linalg::matrix<int>& nm() const BASIC_ALLTYPE_THROW
00613 { BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_NM); return *__c.nm; }
00615 linalg::matrix<interval>& im() const BASIC_ALLTYPE_THROW
00616 { BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_IM); return *__c.im; }
00618 linalg::matrix<std::string>& sm() const BASIC_ALLTYPE_THROW
00619 { BASIC_ALLTYPE_ASSERT(ALLTYPE_ALLOCED_SM); return *__c.sm; }
00620
00624 bool is_allocated() const { return __cont_type > ALLTYPE_EMPTY; }
00627 bool is_scalar() const
00628 { return __cont_type < ALLTYPE_EMPTY || __cont_type == ALLTYPE_ALLOCED_S; }
00630 bool is_vector() const
00631 { return __cont_type > ALLTYPE_EMPTY && __cont_type < ALLTYPE_ALLOCED_S; }
00633 bool is_empty_vector() const
00634 { switch (__cont_type) {
00635 case ALLTYPE_ALLOCED_B: return __c.b->empty();
00636 case ALLTYPE_ALLOCED_N: return __c.n->empty();
00637 case ALLTYPE_ALLOCED_U: return __c.u->empty();
00638 case ALLTYPE_ALLOCED_D: return __c.d->empty();
00639 case ALLTYPE_ALLOCED_I: return __c.i->empty();
00640 case ALLTYPE_ALLOCED_C: return __c.sv->empty();
00641 default: return false;
00642 }; }
00644 bool is_matrix() const { return __cont_type > ALLTYPE_ALLOCED_S; }
00646 bool empty() const { return __cont_type == ALLTYPE_EMPTY; }
00649 int contents_type() const { return __cont_type; }
00651 std::string type_name() const
00652 { return std::string(type_cstr()); }
00654 const char* type_cstr() const
00655 { return type_cstr(__cont_type); }
00656
00658 bool operator==(const basic_alltype& b) const;
00660 bool operator!=(const basic_alltype& b) const;
00661
00662 private:
00664 const char* type_cstr(int tp) const
00665 { return __basic_alltype_name[tp-ALLTYPE_INTERVAL]; }
00666 };
00667
00668 const basic_alltype& basic_alltype_empty();
00669
00670 std::ostream& operator<<(std::ostream& os, const basic_alltype& b);
00671
00672 }
00673
00674 #endif