LCOV - code coverage report
Current view: top level - stdcasa/StdCasa - variant.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 1066 0.0 %
Date: 2024-10-10 11:40:37 Functions: 0 84 0.0 %

          Line data    Source code
       1             : #include <casacore/casa/Exceptions/Error.h>
       2             : 
       3             : #include <cstdlib>
       4             : #include <stdcasa/variant.h>
       5             : #include <stdcasa/record.h>
       6             : #include <cstring>
       7             : #include <iostream>
       8             : 
       9             : using namespace casacore;
      10             : namespace casac {
      11             : 
      12             : typedef std::string std_string;
      13             : 
      14             : unsigned int variant::record_id_count = 0;
      15             : 
      16           0 : variant::variant( ) : typev(BOOLVEC), shape_(1,0) {
      17           0 :     val.bv = new std::vector<bool>( );
      18           0 : }
      19             : 
      20           0 : const std::vector<ssize_t> &variant::shape() const {
      21           0 :     if ( typev == RECORD && (shape_.size() != 1 || (int) val.recordv->size() != shape_[0]) )
      22           0 :         ((variant*)this)->shape_ = std::vector<ssize_t>(1,val.recordv->size());
      23           0 :     return shape_;
      24             : }
      25           0 : std::vector<ssize_t> &variant::shape() {
      26           0 :   if ( typev == RECORD && (shape_.size() != 1 || (int) val.recordv->size() != shape_[0]) )
      27           0 :         shape_ = std::vector<ssize_t>(1,val.recordv->size());
      28           0 :     return shape_;
      29             : }
      30             : 
      31           0 : int variant::compare(const variant*) const { return -1; }
      32             : 
      33           0 : variant::TYPE variant::compatible_type( TYPE one_, TYPE two_ ) {
      34           0 :     TYPE one = one_;
      35           0 :     TYPE two = two_;
      36             : 
      37             :     // VEC has priority
      38           0 :     if ( one >= BOOLVEC || two >= BOOLVEC ) {
      39           0 :         if ( one < BOOLVEC ) {
      40           0 :             switch (one) {
      41           0 :                 case BOOL:      one = BOOLVEC; break;
      42           0 :                 case INT:       one = INTVEC; break;
      43           0 :                 case UINT:      one = UINTVEC; break;
      44           0 :                 case DOUBLE:    one = DOUBLEVEC; break;
      45           0 :                 case COMPLEX:   one = COMPLEXVEC; break;
      46           0 :                 case STRING:
      47           0 :                 default:        one = STRINGVEC; break;
      48             :             }
      49           0 :         } else if ( two < BOOLVEC ) {
      50           0 :             switch (two) {
      51           0 :                 case BOOL:      two = BOOLVEC; break;
      52           0 :                 case INT:       two = INTVEC; break;
      53           0 :                 case UINT:      two = UINTVEC; break;
      54           0 :                 case DOUBLE:    two = DOUBLEVEC; break;
      55           0 :                 case COMPLEX:   two = COMPLEXVEC; break;
      56           0 :                 default:        two = STRINGVEC; break;
      57             :             }
      58             :         }
      59             : 
      60           0 :         switch(one) {
      61           0 :             case BOOLVEC: return two;
      62           0 :             case INTVEC:  return two == BOOLVEC ? INTVEC : two;
      63           0 :             case UINTVEC:  return two == BOOLVEC ? UINTVEC : two;
      64           0 :             case DOUBLEVEC: return two == COMPLEXVEC || two == STRINGVEC ? two : DOUBLEVEC;
      65           0 :             case COMPLEXVEC: return two == STRINGVEC ? STRINGVEC : COMPLEXVEC;
      66           0 :             default: return STRINGVEC;
      67             :         }
      68             :     } else {
      69           0 :         switch(one) {
      70           0 :             case BOOL: return two;
      71           0 :             case INT:  return two == BOOL ? INT : two;
      72           0 :             case UINT:  return two == BOOL ? UINT : two;
      73           0 :             case DOUBLE: return two == COMPLEX || two == STRING ? two : DOUBLE;
      74           0 :             case COMPLEX: return two == STRING ? STRING : COMPLEX;
      75           0 :             default: return STRING;
      76             :         }
      77             :     }
      78             : }
      79             : 
      80             : #include "string_conversions.hpp"
      81             : 
      82           0 : variant::variant(const record &arg) : typev(RECORD), shape_(1,arg.size()) {
      83           0 :     val.recordv = new record(arg);
      84           0 : }
      85             : 
      86           0 : variant::variant(record *arg) : typev(RECORD), shape_(1,arg->size()) {
      87           0 :     val.recordv = arg;
      88           0 : }
      89             : 
      90           0 : variant::variant(const variant &other){
      91             : 
      92           0 :     typev = INT; // need to make it something easy for the assignment operator.
      93             : 
      94           0 :     * this = other;
      95           0 : }
      96             : 
      97             : variant &
      98           0 : variant::operator= (const variant &other){
      99             : 
     100           0 :     if (& other == this){
     101           0 :         return * this;
     102             :     }
     103             : 
     104           0 :     freeStorage (); // uses current typev for this
     105             : 
     106           0 :     typev = other.typev;
     107           0 :     shape_ = other.shape_;
     108             : 
     109           0 :     switch( typev ) {
     110             : 
     111           0 :         case BOOL:
     112           0 :             val.b = other.val.b;
     113           0 :             break;
     114           0 :         case INT:
     115           0 :             val.i = other.val.i;
     116           0 :             break;
     117             : 
     118           0 :     case UINT:
     119           0 :         val.ui = other.val.ui;
     120           0 :         break;
     121           0 :         case DOUBLE:
     122           0 :             val.d = other.val.d;
     123           0 :             break;
     124           0 :         case COMPLEX:
     125           0 :             val.c = new std::complex<double>(*other.val.c);
     126           0 :             break;
     127           0 :         case BOOLVEC:
     128           0 :             val.bv = new std::vector<bool>(*other.val.bv);
     129           0 :             break;
     130           0 :         case INTVEC:
     131           0 :             val.iv = new std::vector<long>(*other.val.iv);
     132           0 :             break;
     133           0 :         case UINTVEC:
     134           0 :             val.uiv = new std::vector<unsigned long>(*other.val.uiv);
     135           0 :             break;
     136           0 :         case DOUBLEVEC:
     137           0 :             val.dv = new std::vector<double>(*other.val.dv);
     138           0 :             break;
     139           0 :         case COMPLEXVEC:
     140           0 :             val.cv = new std::vector<std::complex<double> >(*other.val.cv);
     141           0 :             break;
     142           0 :         case STRING:
     143           0 :             val.s = new std::string(*other.val.s);
     144           0 :             break;
     145           0 :         case STRINGVEC:
     146           0 :             val.sv = new std::vector<std::string>(*other.val.sv);
     147           0 :             break;
     148           0 :         case RECORD:
     149           0 :             val.recordv = new record(*other.val.recordv);
     150           0 :             break;
     151           0 :         default:
     152           0 :             typev = BOOL;
     153           0 :             val.b = false;
     154           0 :             break;
     155             :     }
     156             : 
     157           0 :     return * this;
     158             : }
     159             : 
     160             : void
     161           0 : variant::freeStorage ()
     162             : {
     163           0 :     switch( typev ) {
     164           0 :         case BOOLVEC:
     165           0 :             delete val.bv;
     166           0 :             break;
     167           0 :         case INTVEC:
     168           0 :             delete val.iv;
     169           0 :             break;
     170           0 :         case UINTVEC:
     171           0 :             delete val.uiv;
     172           0 :             break;
     173           0 :         case DOUBLEVEC:
     174           0 :             delete val.dv;
     175           0 :             break;
     176           0 :         case COMPLEX:
     177           0 :             delete val.c;
     178           0 :             break;
     179           0 :         case COMPLEXVEC:
     180           0 :             delete val.cv;
     181           0 :             break;
     182           0 :         case STRING:
     183           0 :             delete val.s;
     184           0 :             break;
     185           0 :         case STRINGVEC:
     186           0 :             delete val.sv;
     187           0 :             break;
     188           0 :         case RECORD:
     189           0 :             delete val.recordv;
     190           0 :             break;
     191           0 :         default:
     192           0 :             break;
     193             :     }
     194           0 : }
     195             : 
     196           0 : variant::~variant( ) {
     197             : 
     198           0 :     freeStorage ();
     199           0 : }
     200             : 
     201           0 : const std::string &variant::typeString( ) const {
     202           0 :     static std::string bs("bool");
     203           0 :     static std::string bvs("boolvec");
     204           0 :     static std::string is("int");
     205           0 :     static std::string uis("uint");
     206           0 :     static std::string ivs("intvec");
     207           0 :     static std::string uivs("uintvec");
     208           0 :     static std::string ls("long");
     209           0 :     static std::string lvs("longvec");
     210           0 :     static std::string ds("double");
     211           0 :     static std::string dvs("doublevec");
     212           0 :     static std::string cs("complex");
     213           0 :     static std::string cvs("complexvec");
     214           0 :     static std::string ss("string");
     215           0 :     static std::string svs("stringvec");
     216           0 :     static std::string rec("record");
     217           0 :     static std::string unknown("unknown");
     218             : 
     219           0 :     switch( typev ) {
     220           0 :         case BOOL:              return bs;
     221           0 :         case BOOLVEC:           return bvs;
     222           0 :         case INT:               return is;
     223           0 :         case UINT:              return uis;
     224           0 :         case INTVEC:            return ivs;
     225           0 :         case UINTVEC:           return uivs;
     226           0 :         case DOUBLE:            return ds;
     227           0 :         case DOUBLEVEC:         return dvs;
     228           0 :         case COMPLEX:           return cs;
     229           0 :         case COMPLEXVEC:        return cvs;
     230           0 :         case STRING:            return ss;
     231           0 :         case STRINGVEC:         return svs;
     232           0 :         case RECORD:            return rec;
     233           0 :         default:                return unknown;
     234             :     }
     235             : }
     236             : 
     237           0 : bool variant::toBool( ) const {
     238           0 :     switch( typev ) {
     239           0 :         case BOOL:
     240           0 :             return val.b;
     241           0 :         case BOOLVEC:
     242           0 :             return (*val.bv).size() > 0 ? (*val.bv)[0] : false;
     243           0 :         case INT:
     244           0 :             return val.i ? true : false;
     245           0 :         case UINT:
     246           0 :             return val.ui ? true : false;
     247           0 :         case INTVEC:
     248           0 :             return (*val.iv).size() > 0 ? ((*val.iv)[0] ? true : false) : false;
     249           0 :         case UINTVEC:
     250           0 :             return (*val.uiv).size() > 0 ? ((*val.uiv)[0] ? true : false) : false;
     251           0 :         case DOUBLE:
     252           0 :             return val.d != 0.0 ? true : false;
     253           0 :         case DOUBLEVEC:
     254           0 :             return (*val.dv).size() > 0 ? ((*val.dv)[0] != 0.0 ? true : false) : false;
     255           0 :         case COMPLEX:
     256           0 :             return ((*val.c).real() != 0.0 || (*val.c).imag() != 0.0) ? true : false;
     257           0 :         case COMPLEXVEC:
     258           0 :             return (*val.cv).size() > 0 ? (((*val.cv)[0].real() != 0.0 || (*val.cv)[0].imag() != 0.0) ? true : false) : false;
     259           0 :         case STRING:
     260           0 :             return stringtobool( *val.s );
     261           0 :         case STRINGVEC:
     262           0 :             return (*val.sv).size() > 0 ? stringtobool((*val.sv)[0]) : false;
     263           0 :         case RECORD:
     264             :         default:
     265           0 :             return false;
     266             :     }
     267             : }
     268             : 
     269           0 : std::vector<bool> variant::toBoolVec( ) const {
     270           0 :     switch( typev ) {
     271           0 :         case BOOL:
     272           0 :             return std::vector<bool>(1,val.b);
     273           0 :         case INT:
     274           0 :             return std::vector<bool>(1, val.i != 0 ? true : false);
     275           0 :         case UINT:
     276           0 :             return std::vector<bool>(1, val.ui != 0 ? true : false);
     277           0 :         case DOUBLE:
     278           0 :             return std::vector<bool>(1, val.d != 0.0 ? true : false);
     279           0 :         case COMPLEX:
     280           0 :             return std::vector<bool>(1, ((*val.c).real() != 0.0 || (*val.c).imag() != 0.0)  ? true : false);
     281           0 :         case BOOLVEC:
     282           0 :             return std::vector<bool>(*val.bv);
     283           0 :         case INTVEC:
     284             :             {
     285           0 :             std::vector<bool> result((*val.iv).size());
     286           0 :             std::vector<long>::const_iterator from = (*val.iv).begin();
     287           0 :             for (unsigned int i=0; from != (*val.iv).end(); ++i, ++from)
     288           0 :                 result[i] = *from != 0 ? true : false;
     289           0 :             return result;
     290           0 :             }
     291           0 :         case UINTVEC:
     292             :             {
     293           0 :             std::vector<bool> result((*val.uiv).size());
     294           0 :             std::vector<unsigned long>::const_iterator from = (*val.uiv).begin();
     295           0 :             for (unsigned int i=0; from != (*val.uiv).end(); ++i, ++from)
     296           0 :                 result[i] = *from != 0 ? true : false;
     297           0 :             return result;
     298           0 :             }
     299           0 :         case DOUBLEVEC:
     300             :             {
     301           0 :             std::vector<bool> result((*val.dv).size());
     302           0 :             std::vector<double>::const_iterator from = (*val.dv).begin();
     303           0 :             for (unsigned int i=0; from != (*val.dv).end(); ++i, ++from)
     304           0 :                 result[i] = *from != 0.0 ? true : false;
     305           0 :             return result;
     306           0 :             }
     307           0 :         case COMPLEXVEC:
     308             :             {
     309           0 :             std::vector<bool> result((*val.dv).size());
     310           0 :             std::vector<std::complex<double> >::const_iterator from = (*val.cv).begin();
     311           0 :             for (unsigned int i=0; from != (*val.cv).end(); ++i, ++from) {
     312           0 :                 const std::complex<double> &cpx = *from;
     313           0 :                 result[i] = (cpx.real() != 0.0 || cpx.imag() != 0.0) ? true : false;
     314             :             }
     315           0 :             return result;
     316           0 :             }
     317           0 :         case STRING:
     318           0 :             return std::vector<bool>(1,stringtobool( *val.s ));
     319           0 :         case STRINGVEC:
     320             :             {
     321           0 :             std::vector<bool> result((*val.sv).size());
     322           0 :             std::vector<std::string>::const_iterator from = (*val.sv).begin();
     323           0 :             for (unsigned int i=0; from != (*val.sv).end(); ++i, ++from)
     324           0 :                 result[i] = stringtobool(*from);
     325           0 :             return result;
     326           0 :             }
     327           0 :         case RECORD:
     328             :         default:
     329           0 :             return std::vector<bool>(0);
     330             :     }
     331             : }
     332             : 
     333             : #define VECTOSTRING_CONVERSION(TYPE,IDTYPE,OPEN,CLOSE,DIVIDE,INVAR,OUTVAR,EMPTY) \
     334             :     if (INVAR.size() > 1) {                                                  \
     335             :         OUTVAR = OPEN;                                                          \
     336             :         std::vector<TYPE>::const_iterator from = INVAR.begin();                   \
     337             :         OUTVAR += IDTYPE ## tostring(*from++);                                  \
     338             :         while (from != INVAR.end())                                             \
     339             :             OUTVAR += DIVIDE + IDTYPE ## tostring(*from++);                     \
     340             :         OUTVAR += CLOSE;                                                        \
     341             :     } else if (INVAR.size() == 1) {                                             \
     342             :         OUTVAR = OPEN + IDTYPE ## tostring(INVAR[0]) + CLOSE;                   \
     343             :     } else {                                                                    \
     344             :         OUTVAR = EMPTY;                                                         \
     345             :     }                                                                           \
     346             : 
     347             : #define VECTOSTRING(TYPE,IDTYPE,MEM,SUBMEM,OPEN,CLOSE,DIVIDE,EMPTY)             \
     348             :     {                                                                           \
     349             :     std::string result;                                                         \
     350             :     VECTOSTRING_CONVERSION(TYPE,IDTYPE,OPEN,CLOSE,DIVIDE,(*val.MEM) SUBMEM,result,EMPTY) \
     351             :     return result;                                                              \
     352             :     }
     353             : #define VECASSTRING(TYPE,IDTYPE,MEM,SUBMEM,OPEN,CLOSE,DIVIDE,EMPTY)             \
     354             :     {                                                                           \
     355             :     std::string *tmp = new std::string();                                       \
     356             :     VECTOSTRING_CONVERSION(TYPE,IDTYPE,OPEN,CLOSE,DIVIDE,(*val.MEM) SUBMEM,(*tmp),EMPTY) \
     357             :     delete val.MEM;                                                             \
     358             :     val.s = tmp;                                                                \
     359             :     break;                                                                      \
     360             :     }
     361             : 
     362             : #define VECTOSTRINGVEC(TYPE,IDTYPE,MEM,SUBMEM)                                  \
     363             :     {                                                                           \
     364             :     std::vector<std::string> result;                                              \
     365             :     std::vector<TYPE>::const_iterator from = (*val.MEM) SUBMEM .begin();  \
     366             :     for (unsigned int i=0; from != (*val.MEM) SUBMEM .end(); ++i, ++from)       \
     367             :         result[i] = IDTYPE ## tostring(*from);                                  \
     368             :     return result;                                                              \
     369             :     }
     370             : 
     371             : #define VECASSTRINGVEC(TYPE,IDTYPE,MEM,SUBMEM,OPEN,CLOSE)                       \
     372             :     {                                                                           \
     373             :     ssize_t current_size = (*val.MEM) SUBMEM .size();                           \
     374             :     newsize = size > current_size ? size : current_size;                     \
     375             :     std::vector<std::string> *tmp = new std::vector<std::string>(newsize);  \
     376             :     std::vector<TYPE>::const_iterator from = (*val.MEM) SUBMEM .begin();  \
     377             :     for (unsigned int i=0; from != (*val.MEM) SUBMEM .end(); ++i, ++from)       \
     378             :         (*tmp)[i] = OPEN IDTYPE ## tostring(*from) CLOSE;                       \
     379             :     delete val.MEM;                                                             \
     380             :     val.sv = tmp;                                                               \
     381             :     break;                                                                      \
     382             :     }
     383             : 
     384           0 : std::string variant::toString( bool no_brackets ) const {
     385           0 :     switch( typev ) {
     386           0 :         case BOOL:
     387           0 :             return booltostring(val.b);
     388           0 :         case INT:
     389           0 :             return inttostring(val.i);
     390           0 :         case UINT:
     391           0 :             return inttostring(val.ui);
     392           0 :         case DOUBLE:
     393           0 :             return doubletostring(val.d);
     394           0 :         case COMPLEX:
     395           0 :             return complextostring(*val.c);
     396           0 :         case BOOLVEC:
     397           0 :             VECTOSTRING(bool,bool,bv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
     398           0 :         case INTVEC:
     399           0 :             VECTOSTRING(long,int,iv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
     400           0 :         case UINTVEC:
     401           0 :             VECTOSTRING(unsigned long,int,uiv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
     402           0 :         case DOUBLEVEC:
     403           0 :             VECTOSTRING(double,double,dv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
     404           0 :         case COMPLEXVEC:
     405           0 :             VECTOSTRING(std::complex<double>,complex,cv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
     406           0 :         case STRING:
     407           0 :             return std::string( *val.s );
     408           0 :         case STRINGVEC:
     409           0 :           VECTOSTRING(std_string,std_string,sv,,(no_brackets?"\"":"[\""),(no_brackets?"\"":"\"]"),"\",\"",(no_brackets?"":"[]"))
     410           0 :         case RECORD:
     411           0 :             return std::string("{...}");
     412           0 :         default:
     413           0 :             return std::string("");
     414             :     }
     415             : }
     416             : 
     417           0 : std::vector<std::string> variant::toStringVec( ) const {
     418           0 :     switch( typev ) {
     419           0 :         case BOOL:
     420           0 :             return std::vector<std::string>(1,booltostring(val.b));
     421           0 :         case INT:
     422           0 :             return std::vector<std::string>(1,inttostring(val.i));
     423           0 :         case UINT:
     424           0 :             return std::vector<std::string>(1,inttostring(val.ui));
     425           0 :         case DOUBLE:
     426           0 :             return std::vector<std::string>(1,doubletostring(val.d));
     427           0 :         case COMPLEX:
     428           0 :             return std::vector<std::string>(1,complextostring(*val.c));
     429           0 :         case BOOLVEC:
     430           0 :             VECTOSTRINGVEC(bool,bool,bv,)
     431           0 :         case INTVEC:
     432           0 :             VECTOSTRINGVEC(long,int,iv,)
     433           0 :         case UINTVEC:
     434           0 :             VECTOSTRINGVEC(unsigned long,int,uiv,)
     435           0 :         case DOUBLEVEC:
     436           0 :             VECTOSTRINGVEC(double,double,dv,)
     437           0 :         case COMPLEXVEC:
     438           0 :             VECTOSTRINGVEC(std::complex<double>,complex,cv,)
     439           0 :         case STRING:
     440           0 :             return std::vector<std::string>(1,*val.s);
     441           0 :         case STRINGVEC:
     442           0 :             return std::vector<std::string>(*val.sv);
     443           0 :         case RECORD:
     444           0 :             return std::vector<std::string>(1,"{...}");
     445           0 :         default:
     446           0 :             return std::vector<std::string>(0);
     447             :     }
     448             : }
     449             : 
     450             : 
     451             : #define TONUMERIC( NAME, TYPE, IDTYPE )                                         \
     452             : TYPE variant::NAME( ) const {                                                   \
     453             :     switch( typev ) {                                                           \
     454             :         case BOOL:                                                              \
     455             :             return (TYPE) (val.b ? 1 : 0);                                      \
     456             :         case INT:                                                               \
     457             :             return (TYPE) val.i;                                                \
     458             :         case UINT:                                                              \
     459             :             return (TYPE) val.ui;                                               \
     460             :         case DOUBLE:                                                            \
     461             :             return (TYPE) val.d;                                                \
     462             :         case COMPLEX:                                                           \
     463             :             return (TYPE) (*val.c).real();                                      \
     464             :         case BOOLVEC:                                                           \
     465             :             return (TYPE) ((*val.bv).size() > 0 ? ((*val.bv)[0] ? 1 : 0) : 0);       \
     466             :         case INTVEC:                                                            \
     467             :             return (TYPE) ((*val.iv).size() > 0 ? (*val.iv)[0] : 0);         \
     468             :         case UINTVEC:                                                           \
     469             :             return (TYPE) ((*val.uiv).size() > 0 ? (*val.uiv)[0] : 0);               \
     470             :         case DOUBLEVEC:                                                         \
     471             :             return (TYPE) ((*val.dv).size() > 0 ?  (*val.dv)[0] : 0);                \
     472             :         case COMPLEXVEC:                                                        \
     473             :             return (TYPE) ((*val.cv).size() > 0 ?  (*val.cv)[0].real() : 0); \
     474             :         case STRING:                                                            \
     475             :             return stringto ## IDTYPE( *val.s );                                \
     476             :         case STRINGVEC:                                                         \
     477             :             return (*val.sv).size() > 0 ? stringto ## IDTYPE((*val.sv)[0]) : 0;      \
     478             :         case RECORD:                                                            \
     479             :         default:                                                                \
     480             :           return (TYPE) 0;                                                      \
     481             :     }                                                                           \
     482             : }
     483             : 
     484           0 : TONUMERIC(toInt,long,int)
     485           0 : TONUMERIC(touInt,unsigned long,uInt)
     486           0 : TONUMERIC(toDouble,double,double)
     487             : 
     488           0 : std::complex<double> variant::toComplex( ) const {
     489           0 :     switch( typev ) {
     490           0 :         case BOOL:
     491           0 :             return std::complex<double>(val.b ? 1.0 : 0.0, 0.0);
     492           0 :         case INT:
     493           0 :             return std::complex<double>(val.i, 0.0);
     494           0 :         case UINT:
     495           0 :             return std::complex<double>(val.ui, 0.0);
     496           0 :         case DOUBLE:
     497           0 :             return std::complex<double>(val.d, 0.0);
     498           0 :         case COMPLEX:
     499           0 :             return std::complex<double>(*val.c);
     500           0 :         case BOOLVEC:
     501           0 :             return std::complex<double>(((*val.bv).size() > 0 ? ((*val.bv)[0] ? 1.0 : 0.0) : 0.0),0.0);;
     502           0 :         case INTVEC:
     503           0 :             return std::complex<double>(((*val.iv).size() > 0 ? (*val.iv)[0] : 0),0.0);
     504           0 :         case UINTVEC:
     505           0 :             return std::complex<double>(((*val.uiv).size() > 0 ? (*val.uiv)[0] : 0),0.0);
     506           0 :         case DOUBLEVEC:
     507           0 :             return std::complex<double>(((*val.dv).size() > 0 ?  (*val.dv)[0] : 0),0);
     508           0 :         case COMPLEXVEC:
     509           0 :             return (*val.cv).size() > 0 ?  std::complex<double>((*val.cv)[0]) : std::complex<double>(0.0,0.0);
     510           0 :         case STRING:
     511           0 :             return stringtocomplex( *val.s );
     512           0 :         case STRINGVEC:
     513           0 :             return (*val.sv).size() > 0 ? stringtocomplex((*val.sv)[0]) : 0;
     514           0 :         case RECORD:
     515             :         default:
     516           0 :           return std::complex<double>( 0.0, 0.0 );
     517             :     }
     518             : }
     519             : 
     520             : 
     521             : #define TONUMERICVEC( NAME, TYPE, IDTYPE, TYPET, TYPEM, ONE, ONET, ONEM )       \
     522             : std::vector<TYPE> variant::NAME( ) const {                                        \
     523             :     switch( typev ) {                                                           \
     524             :         case BOOL:                                                              \
     525             :             return std::vector<TYPE>(1,(TYPE)(val.b ? 1 : 0));                    \
     526             :         case INT:                                                               \
     527             :             return std::vector<TYPE>(1,(TYPE) val.i);                             \
     528             :         case UINT:                                                               \
     529             :             return std::vector<TYPE>(1,(TYPE) val.ui);                           \
     530             :         case DOUBLE:                                                            \
     531             :             return std::vector<TYPE>(1,(TYPE) val.d);                             \
     532             :         case COMPLEX:                                                           \
     533             :             return std::vector<TYPE>(1,(TYPE) (*val.c).real());                   \
     534             :         case BOOLVEC:                                                           \
     535             :             {                                                                   \
     536             :             std::vector<TYPE> result((*val.bv).size());                           \
     537             :             std::vector<bool>::const_iterator from = (*val.bv).begin();           \
     538             :             for (unsigned int i=0; from != (*val.bv).end(); ++i, ++from)        \
     539             :                 result[i] = (TYPE)(*from ? 1 : 0);                              \
     540             :             return result;                                                      \
     541             :             }                                                                   \
     542             :         case TYPET:                                                             \
     543             :             return std::vector<TYPE>(*val.TYPEM);                         \
     544             :         case ONET:                                                              \
     545             :             {                                                                   \
     546             :             std::vector<TYPE> result((*val.ONEM).size());                 \
     547             :             std::vector<ONE>::const_iterator from = (*val.ONEM).begin();  \
     548             :             for (unsigned int i=0; from != (*val.ONEM).end(); ++i, ++from)      \
     549             :                 result[i] = (TYPE)(*from);                                      \
     550             :             return result;                                                      \
     551             :             }                                                                   \
     552             :         case COMPLEXVEC:                                                        \
     553             :             {                                                                   \
     554             :             std::vector<TYPE> result((*val.cv).size());                           \
     555             :             std::vector<std::complex<double> >::const_iterator from = (*val.cv).begin();\
     556             :             for (unsigned int i=0; from != (*val.cv).end(); ++i, ++from)        \
     557             :                 result[i] = (TYPE)((*from).real());                             \
     558             :             return result;                                                      \
     559             :             }                                                                   \
     560             :         case STRING:                                                            \
     561             :             return std::vector<TYPE>(1,stringto ## IDTYPE( *val.s ));             \
     562             :         case STRINGVEC:                                                         \
     563             :             {                                                                   \
     564             :             std::vector<TYPE> result((*val.sv).size());                           \
     565             :             std::vector<std::string>::const_iterator from = (*val.sv).begin();    \
     566             :             for (unsigned int i=0; from != (*val.sv).end(); ++i, ++from)        \
     567             :                 result[i] = stringto ## IDTYPE(*from);                          \
     568             :             return result;                                                      \
     569             :             }                                                                   \
     570             :         case RECORD:                                                            \
     571             :         default:                                                                \
     572             :             return std::vector<TYPE>(0);                                  \
     573             :     }                                                                           \
     574             : }
     575             : 
     576             : 
     577             : 
     578           0 : TONUMERICVEC(toIntVec,   long,   int,   INTVEC,   iv,double,DOUBLEVEC,dv)
     579           0 : TONUMERICVEC(toDoubleVec,double,double,DOUBLEVEC,dv,long,   INTVEC,   iv)
     580             : 
     581           0 : std::vector<unsigned long> variant::touIntVec() const {
     582           0 :     return std::vector<unsigned long>(1,(unsigned long) val.ui);
     583             : }
     584             : 
     585           0 : std::vector<std::complex<double> > variant::toComplexVec( ) const {
     586           0 :     switch( typev ) {
     587           0 :         case BOOL:
     588           0 :             return std::vector<std::complex<double> >(1,std::complex<double>((val.b ? 1 : 0),0.0));
     589           0 :         case INT:
     590           0 :             return std::vector<std::complex<double> >(1,std::complex<double>(val.i,0.0));
     591           0 :         case UINT:
     592           0 :             return std::vector<std::complex<double> >(1,std::complex<double>(val.ui,0.0));
     593           0 :         case DOUBLE:
     594           0 :             return std::vector<std::complex<double> >(1,std::complex<double>(val.d,0.0));
     595           0 :         case COMPLEX:
     596           0 :             return std::vector<std::complex<double> >(1,*val.c);
     597           0 :         case BOOLVEC:
     598             :             {
     599           0 :             std::vector<std::complex<double> > result((*val.bv).size());
     600           0 :             std::vector<bool>::const_iterator from = (*val.bv).begin();
     601           0 :             for (unsigned int i=0; from != (*val.bv).end(); ++i, ++from)
     602           0 :                 result[i] = std::complex<double>((*from ? 1 : 0),0.0);
     603           0 :             return result;
     604           0 :             }
     605           0 :         case COMPLEXVEC:
     606           0 :             return std::vector<std::complex<double> >(*val.cv);
     607           0 :         case INTVEC:
     608             :             {
     609           0 :             std::vector<std::complex<double> > result((*val.iv).size());
     610           0 :             std::vector<long>::const_iterator from = (*val.iv).begin();
     611           0 :             for (unsigned int i=0; from != (*val.iv).end(); ++i, ++from)
     612           0 :                 result[i] = std::complex<double>(*from,0.0);
     613           0 :             return result;
     614           0 :             }
     615           0 :         case UINTVEC:
     616             :             {
     617           0 :             std::vector<std::complex<double> > result((*val.uiv).size());
     618           0 :             std::vector<unsigned long>::const_iterator from = (*val.uiv).begin();
     619           0 :             for (unsigned int i=0; from != (*val.uiv).end(); ++i, ++from)
     620           0 :                 result[i] = std::complex<double>(*from,0.0);
     621           0 :             return result;
     622           0 :             }
     623           0 :         case DOUBLEVEC:
     624             :             {
     625           0 :             std::vector<std::complex<double> > result((*val.dv).size());
     626           0 :             std::vector<double>::const_iterator from = (*val.dv).begin();
     627           0 :             for (unsigned int i=0; from != (*val.dv).end(); ++i, ++from)
     628           0 :                 result[i] = std::complex<double>(*from,0.0);
     629           0 :             return result;
     630           0 :             }
     631           0 :         case STRING:
     632           0 :             return std::vector<std::complex<double> >(1,stringtocomplex( *val.s ));
     633           0 :         case STRINGVEC:
     634             :             {
     635           0 :             std::vector<std::complex<double> > result((*val.sv).size());
     636           0 :             std::vector<std::string>::const_iterator from = (*val.sv).begin();
     637           0 :             for(unsigned int i=0; from != (*val.sv).end(); ++i, ++from)
     638           0 :                 result[i] = stringtocomplex(*from);
     639           0 :             return result;
     640           0 :             }
     641           0 :         case RECORD:
     642             :         default:
     643           0 :             return std::vector<std::complex<double> >(0);
     644             :     }
     645             : }
     646             : 
     647             : // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
     648             : #define ASNUMERIC( NAME, TYPE, IDTYPE, TYPETAG, VAL )                           \
     649             : TYPE &variant::NAME( ) {                                                    \
     650             :     if ( typev != TYPETAG ) {                                                   \
     651             :         switch( typev ) {                                                       \
     652             :             case BOOL:                                                          \
     653             :                 val.VAL = (TYPE) (val.b ? 1 : 0);                               \
     654             :                 break;                                                          \
     655             :             case INT:                                                           \
     656             :                 val.VAL = (TYPE) val.i;                                         \
     657             :                 break;                                                          \
     658             :             case UINT:                                                           \
     659             :                 val.VAL = (TYPE) val.ui;                                         \
     660             :                 break;                                                          \
     661             :             case DOUBLE:                                                        \
     662             :                 val.VAL = (TYPE) val.d;                                         \
     663             :                 break;                                                          \
     664             :             case COMPLEX:                                                       \
     665             :                 {                                                               \
     666             :                 std::complex<double> *tmp = val.c;                                \
     667             :                 val.VAL = (TYPE) (*tmp).real();                                 \
     668             :                 delete tmp;                                                     \
     669             :                 break;                                                          \
     670             :                 }                                                               \
     671             :             case BOOLVEC:                                                       \
     672             :                 {                                                               \
     673             :                 std::vector<bool> *tmp = val.bv;                          \
     674             :                 val.VAL = (TYPE) ((*tmp).size() > 0 ? ((*tmp)[0] ? 1 : 0) : 0);      \
     675             :                 delete tmp;                                                     \
     676             :                 break;                                                          \
     677             :                 }                                                               \
     678             :             case INTVEC:                                                        \
     679             :                 {                                                               \
     680             :                 std::vector<long> *tmp = val.iv;                                  \
     681             :                 val.VAL = (TYPE) ((*tmp).size() > 0 ? (*tmp)[0] : 0);                \
     682             :                 delete tmp;                                                     \
     683             :                 break;                                                          \
     684             :                 }                                                               \
     685             :             case UINTVEC:                                                        \
     686             :                 {                                                               \
     687             :                 std::vector<unsigned long> *tmp = val.uiv;                                 \
     688             :                 val.VAL = (TYPE) ((*tmp).size() > 0 ? (*tmp)[0] : 0);           \
     689             :                 delete tmp;                                                     \
     690             :                 break;                                                          \
     691             :                 }                                                               \
     692             :             case DOUBLEVEC:                                                     \
     693             :                 {                                                               \
     694             :                 std::vector<double> *tmp = val.dv;                                \
     695             :                 val.VAL = (TYPE) ((*tmp).size() > 0 ?  (*tmp)[0] : 0);               \
     696             :                 delete tmp;                                                     \
     697             :                 break;                                                          \
     698             :                 }                                                               \
     699             :             case COMPLEXVEC:                                                    \
     700             :                 {                                                               \
     701             :                 std::vector<std::complex<double> > *tmp = val.cv;           \
     702             :                 val.VAL = (TYPE) ((*tmp).size() > 0 ?  (*tmp)[0].real() : 0);        \
     703             :                 delete tmp;                                                     \
     704             :                 break;                                                          \
     705             :                 }                                                               \
     706             :             case STRING:                                                        \
     707             :                 {                                                               \
     708             :                 std::string *tmp = val.s;                                       \
     709             :                 val.VAL = stringto ## IDTYPE( *tmp );                           \
     710             :                 delete tmp;                                                     \
     711             :                 break;                                                          \
     712             :                 }                                                               \
     713             :             case STRINGVEC:                                                     \
     714             :                 {                                                               \
     715             :                 std::vector<std::string> *tmp = val.sv;                           \
     716             :                 val.VAL = (*tmp).size() > 0 ? stringto ## IDTYPE((*tmp)[0]) : 0;\
     717             :                 delete tmp;                                                     \
     718             :                 break;                                                          \
     719             :                 }                                                               \
     720             :             case RECORD:                                                        \
     721             :                 delete val.recordv;                                             \
     722             :             default:                                                            \
     723             :                 val.VAL = (TYPE) 0;                                             \
     724             :                 break;                                                          \
     725             :         }                                                                       \
     726             :                                                                                 \
     727             :         typev = TYPETAG;                                                        \
     728             :         shape_ = std::vector<ssize_t>(1,1);                                       \
     729             :                                                                                 \
     730             :     }                                                                           \
     731             :                                                                                 \
     732             :     return val.VAL;                                                             \
     733             : }
     734             : 
     735           0 : ASNUMERIC(asInt,long,int,INT,i)
     736           0 : ASNUMERIC(asuInt,unsigned long,uInt,UINT,ui)
     737           0 : ASNUMERIC(asDouble,double,double,DOUBLE,d)
     738             : 
     739             : 
     740           0 : std::complex<double> &variant::asComplex( ) {
     741           0 :     if ( typev != COMPLEX ) {
     742           0 :         switch( typev ) {
     743           0 :             case BOOL:
     744           0 :                 val.c = new std::complex<double>(val.b ? 1 : 0,0.0);
     745           0 :                 break;
     746           0 :             case INT:
     747           0 :                 val.c = new std::complex<double>(val.i,0.0);
     748           0 :                 break;
     749           0 :             case UINT:
     750           0 :                 val.c = new std::complex<double>(val.ui,0.0);
     751           0 :                 break;
     752           0 :             case DOUBLE:
     753           0 :                 val.c = new std::complex<double>(val.d,0.0);
     754           0 :                 break;
     755           0 :             case COMPLEX:
     756           0 :                 break;
     757           0 :             case BOOLVEC:
     758             :                 {
     759           0 :                 std::vector<bool> *tmp = val.bv;
     760           0 :                 val.c = new std::complex<double>((*tmp).size() > 0 ? ((*tmp)[0] ? 1 : 0) : 0,0.0);
     761           0 :                 delete tmp;
     762           0 :                 break;
     763             :                 }
     764           0 :             case INTVEC:
     765             :                 {
     766           0 :                 std::vector<long> *tmp = val.iv;
     767           0 :                 val.c = new std::complex<double>((*tmp).size() > 0 ? (*tmp)[0] : 0,0.0);
     768           0 :                 delete tmp;
     769           0 :                 break;
     770             :                 }
     771           0 :             case UINTVEC:
     772             :                 {
     773           0 :                 std::vector<unsigned long> *tmp = val.uiv;
     774           0 :                 val.c = new std::complex<double>((*tmp).size() > 0 ? (*tmp)[0] : 0,0.0);
     775           0 :                 delete tmp;
     776           0 :                 break;
     777             :                 }
     778           0 :             case DOUBLEVEC:
     779             :                 {
     780           0 :                 std::vector<double> *tmp = val.dv;
     781           0 :                 val.c = new std::complex<double>((*tmp).size() > 0 ?  (*tmp)[0] : 0,0.0);
     782           0 :                 delete tmp;
     783           0 :                 break;
     784             :                 }
     785           0 :             case COMPLEXVEC:
     786             :                 {
     787           0 :                 std::vector<std::complex<double> > *tmp = val.cv;
     788           0 :                 val.c = (*tmp).size() > 0 ?  new std::complex<double>((*tmp)[0]) : new std::complex<double>(0.0,0.0);
     789           0 :                 delete tmp;
     790           0 :                 break;
     791             :                 }
     792           0 :             case STRING:
     793             :                 {
     794           0 :                 std::string *tmp = val.s;
     795           0 :                 val.c = new std::complex<double>(stringtocomplex( *tmp ));
     796           0 :                 delete tmp;
     797           0 :                 break;
     798             :                 }
     799           0 :             case STRINGVEC:
     800             :                 {
     801           0 :                 std::vector<std::string> *tmp = val.sv;
     802           0 :                 val.c = (*tmp).size() > 0 ? new std::complex<double>(stringtocomplex((*tmp)[0])) : new std::complex<double>(0.0,0.0);
     803           0 :                 delete tmp;
     804           0 :                 break;
     805             :                 }
     806           0 :             case RECORD:
     807           0 :                 delete val.recordv;
     808             :             default:
     809           0 :                 val.c = new std::complex<double>(0.0,0.0);
     810           0 :                 break;
     811             :         }
     812             : 
     813           0 :         typev = COMPLEX;
     814           0 :         shape_ = std::vector<ssize_t>(1,1);
     815             : 
     816             :     }
     817             : 
     818           0 :     return *val.c;
     819             : }
     820             : 
     821             : #define ASNUMERICVEC( NAME, TYPE, IDTYPE, TYPETAG, VAL )                        \
     822             : std::vector<TYPE> &variant::NAME( ssize_t size ) {                                    \
     823             :     ssize_t newsize = -1;                                                               \
     824             :     if ( typev != TYPETAG ) {                                                   \
     825             :         switch( typev ) {                                                       \
     826             :             case BOOL:                                                          \
     827             :                 newsize = size > 1 ? size : 1;                                       \
     828             :                 val.VAL = new std::vector<TYPE>(newsize,(TYPE)(val.b ? 1 : 0));   \
     829             :                 break;                                                          \
     830             :             case INT:                                                           \
     831             :                 newsize = size > 1 ? size : 1;                                       \
     832             :                 val.VAL = new std::vector<TYPE>(newsize,(TYPE) val.i);            \
     833             :                 break;                                                          \
     834             :             case UINT:                                                           \
     835             :                 newsize = size > 1 ? size : 1;                                  \
     836             :                 val.VAL = new std::vector<TYPE>(newsize,(TYPE) val.ui);          \
     837             :                 break;                                                          \
     838             :             case DOUBLE:                                                        \
     839             :                 newsize = size > 1 ? size : 1;                                       \
     840             :                 val.VAL = new std::vector<TYPE>(newsize,(TYPE) val.d);            \
     841             :                 break;                                                          \
     842             :             case COMPLEX:                                                       \
     843             :                 {                                                               \
     844             :                 newsize = size > 1 ? size : 1;                                       \
     845             :                 std::complex<double> *tmp = val.c;                                \
     846             :                 val.VAL = new std::vector<TYPE>(newsize,(TYPE) (*tmp).real());    \
     847             :                 delete tmp;                                                     \
     848             :                 break;                                                          \
     849             :                 }                                                               \
     850             :             case BOOLVEC:                                                       \
     851             :                 {                                                               \
     852             :                 std::vector<bool> *tmp = val.bv;                          \
     853             :                 ssize_t current_size = (*tmp).size();                           \
     854             :                 newsize = size > current_size ? size : current_size;         \
     855             :                 val.VAL = new std::vector<TYPE>(newsize);                 \
     856             :                 std::vector<bool>::const_iterator from = (*tmp).begin();  \
     857             :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)       \
     858             :                     (*val.VAL)[i] = *from ? 1 : 0;                              \
     859             :                 delete tmp;                                                     \
     860             :                 break;                                                          \
     861             :                 }                                                               \
     862             :             case INTVEC:                                                        \
     863             :                 {                                                               \
     864             :                 std::vector<long> *tmp = val.iv;                                  \
     865             :                 int current_size = (*tmp).size();                               \
     866             :                 newsize = size > current_size ? size : current_size;         \
     867             :                 val.VAL = new std::vector<TYPE>(newsize);                 \
     868             :                 std::vector<long>::const_iterator from = (*tmp).begin();          \
     869             :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)       \
     870             :                     (*val.VAL)[i] = (TYPE)(*from);                              \
     871             :                 delete tmp;                                                     \
     872             :                 break;                                                          \
     873             :                 }                                                               \
     874             :             case UINTVEC:                                                        \
     875             :                 {                                                               \
     876             :                 std::vector<unsigned long> *tmp = val.uiv;                                 \
     877             :                 int current_size = (*tmp).size();                               \
     878             :                 newsize = size > current_size ? size : current_size;            \
     879             :                 val.VAL = new std::vector<TYPE>(newsize);                       \
     880             :                 std::vector<unsigned long>::const_iterator from = (*tmp).begin();         \
     881             :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)       \
     882             :                     (*val.VAL)[i] = (TYPE)(*from);                              \
     883             :                 delete tmp;                                                     \
     884             :                 break;                                                          \
     885             :                 }                                                               \
     886             :             case DOUBLEVEC:                                                     \
     887             :                 {                                                               \
     888             :                 std::vector<double> *tmp = val.dv;                                \
     889             :                 ssize_t current_size = (*tmp).size();                           \
     890             :                 newsize = size > current_size ? size : current_size;         \
     891             :                 val.VAL = new std::vector<TYPE>(newsize);                 \
     892             :                 std::vector<double>::const_iterator from = (*tmp).begin();        \
     893             :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)       \
     894             :                     (*val.VAL)[i] = (TYPE)(*from);                              \
     895             :                 delete tmp;                                                     \
     896             :                 break;                                                          \
     897             :                 }                                                               \
     898             :             case COMPLEXVEC:                                                    \
     899             :                 {                                                               \
     900             :                 std::vector<std::complex<double> > *tmp = val.cv;           \
     901             :                 ssize_t current_size = (*tmp).size();                           \
     902             :                 newsize = size > current_size ? size : current_size;         \
     903             :                 val.VAL = new std::vector<TYPE>(newsize);                 \
     904             :                 std::vector<std::complex<double> >::const_iterator from = (*tmp).begin();\
     905             :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)       \
     906             :                     (*val.VAL)[i] = (TYPE)((*from).real());                     \
     907             :                 delete tmp;                                                     \
     908             :                 break;                                                          \
     909             :                 }                                                               \
     910             :             case STRING:                                                        \
     911             :                 {                                                               \
     912             :                 std::string *tmp = val.s;                                       \
     913             :                 newsize = size > 1 ? size : 1;                                       \
     914             :                 val.VAL = new std::vector<TYPE>(newsize,stringto ## IDTYPE( *tmp ));\
     915             :                 delete tmp;                                                     \
     916             :                 break;                                                          \
     917             :                 }                                                               \
     918             :             case STRINGVEC:                                                     \
     919             :                 {                                                               \
     920             :                 std::vector<std::string> *tmp = val.sv;                           \
     921             :                 int current_size = (*tmp).size();                               \
     922             :                 newsize = size > current_size ? size : current_size;         \
     923             :                 val.VAL = new std::vector<TYPE>(newsize);                         \
     924             :                 std::vector<std::string>::const_iterator from = (*tmp).begin();   \
     925             :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)       \
     926             :                     (*val.VAL)[i] = stringto ## IDTYPE(*from);                  \
     927             :                 delete tmp;                                                     \
     928             :                 break;                                                          \
     929             :                 }                                                               \
     930             :             case RECORD:                                                        \
     931             :                 delete val.recordv;                                             \
     932             :             default:                                                            \
     933             :                 newsize = 0;                                                    \
     934             :                 val.VAL = new std::vector<TYPE>(0);                               \
     935             :                 break;                                                          \
     936             :         }                                                                       \
     937             :                                                                                 \
     938             :         typev = TYPETAG;                                                        \
     939             :         if ( shape_.size() == 1 )                                               \
     940             :             shape_[0] = newsize;                                                \
     941             :         else if ( shape_size() != newsize )                                     \
     942             :             shape_ = std::vector<ssize_t>(1,newsize);                             \
     943             :                                                                                 \
     944             :     } else if ( size > 0 && (unsigned int) size > (*val.VAL).size() ) {           \
     945             :         resize(size);                                                           \
     946             :         if ( shape_.size() == 1 )                                               \
     947             :             shape_[0] = size;                                                   \
     948             :         else if ( shape_size() != size )                                        \
     949             :             shape_ = std::vector<ssize_t>(1,size);                                        \
     950             :     }                                                                           \
     951             :     return *val.VAL;                                                            \
     952             : }
     953             : 
     954           0 : ASNUMERICVEC(asIntVec,long,int,INTVEC,iv)
     955           0 : ASNUMERICVEC(asuIntVec,unsigned long,int,UINTVEC,uiv)
     956           0 : ASNUMERICVEC(asDoubleVec,double,double,DOUBLEVEC,dv)
     957             : 
     958           0 : std::vector<std::complex<double> > &variant::asComplexVec( ssize_t size ) {
     959           0 :     ssize_t newsize = -1;
     960           0 :     if ( typev != COMPLEXVEC ) {
     961           0 :         switch( typev ) {
     962           0 :             case BOOL:
     963           0 :                 newsize = size > 1 ? size : 1;
     964           0 :                 val.cv = new std::vector<std::complex<double> >(newsize,std::complex<double>(val.b ? 1 : 0,0.0));
     965           0 :                 break;
     966           0 :             case INT:
     967           0 :                 newsize = size > 1 ? size : 1;
     968           0 :                 val.cv = new std::vector<std::complex<double> >(newsize,std::complex<double>(val.i,0.0));
     969           0 :                 break;
     970           0 :             case UINT:
     971           0 :                 newsize = size > 1 ? size : 1;
     972           0 :                 val.cv = new std::vector<std::complex<double> >(newsize,std::complex<double>(val.ui,0.0));
     973           0 :                 break;
     974           0 :             case DOUBLE:
     975           0 :                 newsize = size > 1 ? size : 1;
     976           0 :                 val.cv = new std::vector<std::complex<double> >(newsize,std::complex<double>(val.d,0.0));
     977           0 :                 break;
     978           0 :             case COMPLEX:
     979             :                 {
     980           0 :                 newsize = size > 1 ? size : 1;
     981           0 :                 std::complex<double> *tmp = val.c;
     982           0 :                 val.cv = new std::vector<std::complex<double> >(newsize,*tmp);
     983           0 :                 delete tmp;
     984           0 :                 break;
     985             :                 }
     986           0 :             case BOOLVEC:
     987             :                 {
     988           0 :                 std::vector<bool> *tmp = val.bv;
     989           0 :                 ssize_t current_size = (*tmp).size();
     990           0 :                 newsize = size > current_size ? size : current_size;
     991           0 :                 val.cv = new std::vector<std::complex<double> >(newsize);
     992           0 :                 std::vector<bool>::const_iterator from = (*tmp).begin();
     993           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) {
     994           0 :                     (*val.cv)[i] = std::complex<double>(*from ? 1 : 0,0.0);
     995             :                 }
     996           0 :                 delete tmp;
     997           0 :                 break;
     998             :                 }
     999           0 :             case INTVEC:
    1000             :                 {
    1001           0 :                 std::vector<long> *tmp = val.iv;
    1002           0 :                 int current_size = (*tmp).size();
    1003           0 :                 newsize = size > current_size ? size : current_size;
    1004           0 :                 val.cv = new std::vector<std::complex<double> >(newsize);
    1005           0 :                 std::vector<long>::const_iterator from = (*tmp).begin();
    1006           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
    1007           0 :                     (*val.cv)[i] = std::complex<double>(*from,0.0);
    1008           0 :                 delete tmp;
    1009           0 :                 break;
    1010             :                 }
    1011           0 :             case UINTVEC:
    1012             :                 {
    1013           0 :                 std::vector<unsigned long> *tmp = val.uiv;
    1014           0 :                 int current_size = (*tmp).size();
    1015           0 :                 newsize = size > current_size ? size : current_size;
    1016           0 :                 val.cv = new std::vector<std::complex<double> >(newsize);
    1017           0 :                 std::vector<unsigned long>::const_iterator from = (*tmp).begin();
    1018           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
    1019           0 :                     (*val.cv)[i] = std::complex<double>(*from,0.0);
    1020           0 :                 delete tmp;
    1021           0 :                 break;
    1022             :                 }
    1023           0 :             case DOUBLEVEC:
    1024             :                 {
    1025           0 :                 std::vector<double> *tmp = val.dv;
    1026           0 :                 ssize_t current_size = (*tmp).size();
    1027           0 :                 newsize = size > current_size ? size : current_size;
    1028           0 :                 val.cv = new std::vector<std::complex<double> >(newsize);
    1029           0 :                 std::vector<double>::const_iterator from = (*tmp).begin();
    1030           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
    1031           0 :                     (*val.cv)[i] = std::complex<double>(*from,0.0);
    1032           0 :                 delete tmp;
    1033           0 :                 break;
    1034             :                 }
    1035           0 :             case STRING:
    1036             :                 {
    1037           0 :                 std::string *tmp = val.s;
    1038           0 :                 newsize = 1;
    1039           0 :                 val.cv = new std::vector<std::complex<double> >(1,stringtocomplex( *tmp ));
    1040           0 :                 delete tmp;
    1041           0 :                 break;
    1042             :                 }
    1043           0 :             case STRINGVEC:
    1044             :                 {
    1045           0 :                 std::vector<std::string> *tmp = val.sv;
    1046           0 :                 ssize_t current_size = (*tmp).size();
    1047           0 :                 newsize = size > current_size ? size : current_size;
    1048           0 :                 val.cv = new std::vector<std::complex<double> >(newsize);
    1049           0 :                 std::vector<std::string>::const_iterator from = (*tmp).begin();
    1050           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
    1051           0 :                     (*val.cv)[i] = stringtocomplex(*from);
    1052           0 :                 delete tmp;
    1053           0 :                 break;
    1054             :                 }
    1055           0 :             case RECORD:
    1056           0 :                 delete val.recordv;
    1057             :             default:
    1058           0 :                 newsize = 0;
    1059           0 :                 val.cv = new std::vector<std::complex<double> >(0);
    1060           0 :                 break;
    1061             :         }
    1062             : 
    1063           0 :         typev = COMPLEXVEC;
    1064           0 :         if ( shape_.size() == 1 )
    1065           0 :             shape_[0] = newsize;
    1066           0 :         else if ( shape_size() != newsize )
    1067           0 :             shape_ = std::vector<ssize_t>(1,newsize);
    1068             : 
    1069           0 :     } else if ( size > 0 && (size_t) size > (*val.cv).size() ) {
    1070             : 
    1071           0 :         resize(size);
    1072           0 :         if ( shape_.size() == 1 )
    1073           0 :             shape_[0] = size;
    1074           0 :         else if ( shape_size() != size )
    1075           0 :             shape_ = std::vector<ssize_t>(1,size);
    1076             : 
    1077             :     }
    1078             : 
    1079           0 :     return *val.cv;
    1080             : }
    1081             : 
    1082           0 : std::vector<bool> &variant::asBoolVec( ssize_t size ) {
    1083           0 :     ssize_t newsize = -1;
    1084           0 :     if ( typev != BOOLVEC ) {
    1085           0 :         switch( typev ) {
    1086           0 :             case BOOL:
    1087           0 :                 newsize = size > 1 ? size : 1;
    1088           0 :                 val.bv = new std::vector<bool>(newsize);
    1089           0 :                 break;
    1090           0 :             case INT:
    1091           0 :                 newsize = size > 1 ? size : 1;
    1092           0 :                 val.bv = new std::vector<bool>(newsize, val.i != 0 ? true : false);
    1093           0 :                 break;
    1094           0 :             case UINT:
    1095           0 :                 newsize = size > 1 ? size : 1;
    1096           0 :                 val.bv = new std::vector<bool>(newsize, val.ui != 0 ? true : false);
    1097           0 :                 break;
    1098           0 :             case DOUBLE:
    1099           0 :                 newsize = size > 1 ? size : 1;
    1100           0 :                 val.bv = new std::vector<bool>(newsize, val.d != 0.0 ? true : false);
    1101           0 :                 break;
    1102           0 :             case COMPLEX:
    1103             :                 {
    1104           0 :                 std::complex<double> *tmp = val.c;
    1105           0 :                 newsize = size > 1 ? size : 1;
    1106           0 :                 val.bv = new std::vector<bool>(newsize, ((*tmp).real() != 0.0 || (*tmp).imag() != 0.0) ? true : false);
    1107           0 :                 delete tmp;
    1108           0 :                 break;
    1109             :                 }
    1110           0 :             case BOOLVEC:
    1111           0 :                 break;
    1112           0 :             case INTVEC:
    1113             :                 {
    1114           0 :                 std::vector<long> *tmp = val.iv;
    1115           0 :                 int current_size = (*tmp).size();
    1116           0 :                 newsize = size > current_size ? size : current_size;
    1117           0 :                 val.bv = new std::vector<bool>(newsize);
    1118           0 :                 std::vector<long>::const_iterator from = (*tmp).begin();
    1119           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
    1120           0 :                     (*val.bv)[i] = *from != 0 ? true : false;
    1121           0 :                 delete tmp;
    1122           0 :                 break;
    1123             :                 }
    1124           0 :             case UINTVEC:
    1125             :                 {
    1126           0 :                 std::vector<unsigned long> *tmp = val.uiv;
    1127           0 :                 int current_size = (*tmp).size();
    1128           0 :                 newsize = size > current_size ? size : current_size;
    1129           0 :                 val.bv = new std::vector<bool>(newsize);
    1130           0 :                 std::vector<unsigned long>::const_iterator from = (*tmp).begin();
    1131           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
    1132           0 :                     (*val.bv)[i] = *from != 0 ? true : false;
    1133           0 :                 delete tmp;
    1134           0 :                 break;
    1135             :                 }
    1136           0 :             case DOUBLEVEC:
    1137             :                 {
    1138           0 :                 std::vector<double> *tmp = val.dv;
    1139           0 :                 ssize_t current_size = (*tmp).size();
    1140           0 :                 newsize = size > current_size ? size : current_size;
    1141           0 :                 val.bv = new std::vector<bool>(newsize);
    1142           0 :                 std::vector<double>::const_iterator from = (*tmp).begin();
    1143           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
    1144           0 :                     (*val.bv)[i] = *from != 0.0 ? true : false;
    1145           0 :                 delete tmp;
    1146           0 :                 break;
    1147             :                 }
    1148           0 :             case COMPLEXVEC:
    1149             :                 {
    1150           0 :                 std::vector<std::complex<double> > *tmp = val.cv;
    1151           0 :                 ssize_t current_size = (*tmp).size();
    1152           0 :                 newsize = size > current_size ? size : current_size;
    1153           0 :                 val.bv = new std::vector<bool>(newsize);
    1154           0 :                 std::vector<std::complex<double> >::const_iterator from = (*tmp).begin();
    1155           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) {
    1156           0 :                     const std::complex<double> &cpx = *from;
    1157           0 :                     (*val.bv)[i] = (cpx.real() != 0.0 || cpx.imag() != 0.0) ? true : false;
    1158             :                 }
    1159           0 :                 delete tmp;
    1160           0 :                 break;
    1161             :                 }
    1162           0 :             case STRING:
    1163           0 :                 newsize = 1;
    1164           0 :                 val.bv = new std::vector<bool>(1,stringtobool( *val.s ));
    1165           0 :                 break;
    1166           0 :             case STRINGVEC:
    1167             :                 {
    1168           0 :                 std::vector<std::string> *tmp = val.sv;
    1169           0 :                 ssize_t current_size = (*tmp).size();
    1170           0 :                 newsize = size > current_size ? size : current_size;
    1171           0 :                 val.bv = new std::vector<bool>(newsize);
    1172           0 :                 std::vector<std::string>::const_iterator from = (*tmp).begin();
    1173           0 :                 for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
    1174           0 :                     (*val.bv)[i] = stringtobool(*from);
    1175           0 :                 delete tmp;
    1176           0 :                 break;
    1177             :                 }
    1178           0 :             case RECORD:
    1179           0 :                 delete val.recordv;
    1180             :             default:
    1181           0 :                 newsize = 0;
    1182           0 :                 val.bv = new std::vector<bool>(0);
    1183           0 :                 break;
    1184             :         }
    1185             : 
    1186           0 :         typev = BOOLVEC;
    1187           0 :         if ( shape_.size() == 1 )
    1188           0 :             shape_[0] = newsize;
    1189           0 :         else if ( shape_size() != newsize )
    1190           0 :             shape_ = std::vector<ssize_t>(1,newsize);
    1191             : 
    1192           0 :     } else if ( size > 0 && (size_t) size > (*val.bv).size() ) {
    1193           0 :         resize(size);
    1194           0 :         if ( shape_.size() == 1 )
    1195           0 :             shape_[0] = size;
    1196           0 :         else if ( shape_size() != size )
    1197           0 :             shape_ = std::vector<ssize_t>(1,size);
    1198             :     }
    1199             : 
    1200           0 :     return *val.bv;
    1201             : }
    1202             : 
    1203           0 : bool &variant::asBool( ) {
    1204           0 :     if (typev != BOOL) {
    1205           0 :         switch( typev ) {
    1206           0 :             case BOOL:
    1207           0 :                 break;
    1208           0 :             case BOOLVEC:
    1209             :                 {
    1210           0 :                 std::vector<bool> *tmp = val.bv;
    1211           0 :                 val.b = (*val.bv).size() > 0 ? (*val.bv)[0] : false;
    1212           0 :                 delete tmp;
    1213           0 :                 break;
    1214             :                 }
    1215           0 :             case INT:
    1216           0 :                 val.b = val.i ? true : false;
    1217           0 :                 break;
    1218           0 :             case UINT:
    1219           0 :                 val.b = val.ui ? true : false;
    1220           0 :                 break;
    1221           0 :             case INTVEC:
    1222             :                 {
    1223           0 :                 std::vector<long> *tmp = val.iv;
    1224           0 :                 val.b = (*tmp).size() > 0 ? ((*tmp)[0] ? true : false) : false;
    1225           0 :                 delete tmp;
    1226           0 :                 break;
    1227             :                 }
    1228           0 :             case UINTVEC:
    1229             :                 {
    1230           0 :                 std::vector<unsigned long> *tmp = val.uiv;
    1231           0 :                 val.b = (*tmp).size() > 0 ? ((*tmp)[0] ? true : false) : false;
    1232           0 :                 delete tmp;
    1233           0 :                 break;
    1234             :                 }
    1235           0 :             case DOUBLE:
    1236           0 :                 val.b = val.d != 0.0 ? true : false;
    1237           0 :                 break;
    1238           0 :             case DOUBLEVEC:
    1239             :                 {
    1240           0 :                 std::vector<double> *tmp = val.dv;
    1241           0 :                 val.b = (*tmp).size() > 0 ? ((*tmp)[0] != 0.0 ? true : false) : false;
    1242           0 :                 delete tmp;
    1243           0 :                 break;
    1244             :                 }
    1245           0 :             case COMPLEX:
    1246             :                 {
    1247           0 :                 std::complex<double> *tmp = val.c;
    1248           0 :                 val.b = ((*tmp).real() != 0.0 || (*tmp).imag() != 0.0) ? true : false;
    1249           0 :                 delete tmp;
    1250           0 :                 break;
    1251             :                 }
    1252           0 :             case COMPLEXVEC:
    1253             :                 {
    1254           0 :                 std::vector<std::complex<double> > *tmp = val.cv;
    1255           0 :                 val.b = (*tmp).size() > 0 ? (((*tmp)[0].real() != 0.0 || (*tmp)[0].imag() != 0.0) ? true : false) : false;
    1256           0 :                 delete tmp;
    1257           0 :                 break;
    1258             :                 }
    1259           0 :             case STRING:
    1260             :                 {
    1261           0 :                 std::string *tmp = val.s;
    1262           0 :                 val.b = stringtobool( *val.s );
    1263           0 :                 delete tmp;
    1264           0 :                 break;
    1265             :                 }
    1266           0 :             case STRINGVEC:
    1267             :                 {
    1268           0 :                 std::vector<std::string> *tmp = val.sv;
    1269           0 :                 val.b = (*tmp).size() > 0 ? stringtobool((*tmp)[0]) : false;
    1270           0 :                 delete tmp;
    1271           0 :                 break;
    1272             :                 }
    1273           0 :             case RECORD:
    1274           0 :                 delete val.recordv;
    1275             :             default:
    1276           0 :                 val.b = false;
    1277           0 :                 break;
    1278             :         }
    1279           0 :         typev = BOOL;
    1280             :     }
    1281             : 
    1282           0 :     if ( shape_.size() == 1 )
    1283           0 :         shape_[0] = 1;
    1284             :     else
    1285           0 :         shape_ = std::vector<ssize_t>(1,1);
    1286             : 
    1287           0 :     return val.b;
    1288             : }
    1289             : 
    1290           0 : std::string &variant::asString( ) {
    1291           0 :     if ( typev != STRING ) {
    1292           0 :         switch( typev ) {
    1293           0 :             case BOOL:
    1294           0 :                 val.s = booltostringptr(val.b);
    1295           0 :                 break;
    1296           0 :             case INT:
    1297           0 :                 val.s = inttostringptr(val.i);
    1298           0 :                 break;
    1299           0 :             case UINT:
    1300           0 :                 val.s =inttostringptr(val.ui);
    1301           0 :                 break;
    1302           0 :             case DOUBLE:
    1303           0 :                 val.s = doubletostringptr(val.d);
    1304           0 :                 break;
    1305           0 :             case COMPLEX:
    1306             :                 {
    1307           0 :                 std::complex<double> *tmp = val.c;
    1308           0 :                 val.s = complextostringptr(*tmp);
    1309           0 :                 delete tmp;
    1310           0 :                 break;
    1311             :                 }
    1312           0 :             case BOOLVEC:
    1313           0 :                 VECASSTRING(bool,bool,bv,,"[","]",",","[]")
    1314           0 :             case INTVEC:
    1315           0 :                 VECASSTRING(long,int,iv,,"[","]",",","[]")
    1316           0 :             case UINTVEC:
    1317           0 :                 VECASSTRING(unsigned long,int,uiv,,"[","]",",","[]")
    1318           0 :             case DOUBLEVEC:
    1319           0 :                 VECASSTRING(double,double,dv,,"[","]",",","[]")
    1320           0 :             case COMPLEXVEC:
    1321           0 :                 VECASSTRING(std::complex<double>,complex,cv,,"[","]",",","[]")
    1322           0 :             case STRING:
    1323           0 :                 break;
    1324           0 :             case STRINGVEC:
    1325           0 :                 VECASSTRING(std_string,std_string,sv,,"[\"","\"]","\",\"","[]")
    1326           0 :             case RECORD:
    1327           0 :                 delete val.recordv;
    1328           0 :                 val.s = new std::string("{...}");
    1329           0 :                 break;
    1330           0 :             default:
    1331           0 :                 val.s = new std::string("");
    1332           0 :                 break;
    1333             :         }
    1334           0 :         typev = STRING;
    1335             :     }
    1336             : 
    1337           0 :     if ( shape_.size() == 1 )
    1338           0 :         shape_[0] = 1;
    1339             :     else
    1340           0 :         shape_ = std::vector<ssize_t>(1,1);
    1341             : 
    1342           0 :     return *val.s;
    1343             : }
    1344             : 
    1345           0 : std::vector<std::string> &variant::asStringVec( ssize_t size ) {
    1346           0 :     ssize_t newsize = -1;
    1347           0 :     if ( typev != STRINGVEC ) {
    1348           0 :         switch( typev ) {
    1349           0 :             case BOOL:
    1350           0 :                 newsize = size > 1 ? size : 1;
    1351           0 :                 val.sv = new std::vector<std::string>(newsize,booltostring(val.b));
    1352           0 :                 break;
    1353           0 :             case INT:
    1354           0 :                 newsize = size > 1 ? size : 1;
    1355           0 :                 val.sv = new std::vector<std::string>(newsize,inttostring(val.i));
    1356           0 :                 break;
    1357           0 :             case UINT:
    1358           0 :                 newsize = size > 1 ? size : 1;
    1359           0 :                 val.sv = new std::vector<std::string>(newsize,inttostring(val.ui));
    1360           0 :                 break;
    1361           0 :             case DOUBLE:
    1362           0 :                 newsize = size > 1 ? size : 1;
    1363           0 :                 val.sv = new std::vector<std::string>(newsize,doubletostring(val.d));
    1364           0 :                 break;
    1365           0 :             case COMPLEX:
    1366             :                 {
    1367           0 :                 std::complex<double> *tmp = val.c;
    1368           0 :                 newsize = size > 1 ? size : 1;
    1369           0 :                 val.sv = new std::vector<std::string>(newsize,complextostring(*tmp));
    1370           0 :                 delete tmp;
    1371           0 :                 break;
    1372             :                 }
    1373           0 :             case BOOLVEC:
    1374           0 :                 VECASSTRINGVEC(bool,bool,bv,,,)
    1375           0 :             case INTVEC:
    1376           0 :                 VECASSTRINGVEC(long,int,iv,,,)
    1377           0 :             case UINTVEC:
    1378           0 :                 VECASSTRINGVEC(unsigned long,int,uiv,,,)
    1379           0 :             case DOUBLEVEC:
    1380           0 :                 VECASSTRINGVEC(double,double,dv,,,)
    1381           0 :             case COMPLEXVEC:
    1382           0 :                 VECASSTRINGVEC(std::complex<double>,complex,cv,,,)
    1383           0 :             case STRING:
    1384             :                 {
    1385           0 :                 newsize = 1;
    1386           0 :                 std::string *tmp = val.s;
    1387           0 :                 val.sv = new std::vector<std::string>(1,*tmp);
    1388           0 :                 delete tmp;
    1389           0 :                 break;
    1390             :                 }
    1391           0 :             case STRINGVEC:
    1392           0 :                 break;
    1393           0 :             case RECORD:
    1394           0 :                 newsize = 1;
    1395           0 :                 delete val.recordv;
    1396           0 :                 val.sv = new std::vector<std::string>(1,"{...}");
    1397           0 :                 break;
    1398           0 :             default:
    1399           0 :                 newsize = 0;
    1400           0 :                 val.sv = new std::vector<std::string>(0);
    1401           0 :                 break;
    1402             :         }
    1403             : 
    1404           0 :         typev = STRINGVEC;
    1405           0 :         if ( shape_.size() == 1 )
    1406           0 :             shape_[0] = newsize;
    1407           0 :         else if ( shape_size() != newsize )
    1408           0 :             shape_ = std::vector<ssize_t>(1,newsize);
    1409             : 
    1410           0 :     } else if ( size > 0 && (unsigned int) size > (*val.sv).size() ) {
    1411           0 :         resize(size);
    1412           0 :         if ( shape_.size() == 1 )
    1413           0 :             shape_[0] = size;
    1414           0 :         else if ( shape_size() != size )
    1415           0 :             shape_ = std::vector<ssize_t>(1,size);
    1416             :     }
    1417             : 
    1418           0 :     return *val.sv;
    1419             : }
    1420             : 
    1421           0 : record &variant::asRecord( ) {
    1422           0 :     switch( typev ) {
    1423           0 :         case RECORD:
    1424           0 :             return *val.recordv;
    1425           0 :         case INT:
    1426             :         case UINT:
    1427             :         case BOOL:
    1428             :         case DOUBLE:
    1429           0 :             break;
    1430           0 :         case BOOLVEC:
    1431           0 :             delete val.bv;
    1432           0 :             break;
    1433           0 :         case INTVEC:
    1434           0 :             delete val.iv;
    1435           0 :             break;
    1436           0 :         case UINTVEC:
    1437           0 :             delete val.uiv;
    1438           0 :             break;
    1439           0 :         case DOUBLEVEC:
    1440           0 :             delete val.dv;
    1441           0 :             break;
    1442           0 :         case COMPLEX:
    1443           0 :             delete val.c;
    1444           0 :             break;
    1445           0 :         case COMPLEXVEC:
    1446           0 :             delete val.cv;
    1447           0 :             break;
    1448           0 :         case STRING:
    1449           0 :             delete val.s;
    1450           0 :             break;
    1451           0 :         case STRINGVEC:
    1452           0 :             delete val.sv;
    1453           0 :             break;
    1454             :     }
    1455             : 
    1456           0 :     typev = RECORD;
    1457           0 :     val.recordv = new record();
    1458           0 :     if ( shape_.size() == 1 )
    1459           0 :         shape_[0] = 0;
    1460             :     else
    1461           0 :         shape_ = std::vector<ssize_t>(1,0);
    1462             : 
    1463           0 :     return *val.recordv;
    1464             : }
    1465             : 
    1466           0 : void variant::as( TYPE t, ssize_t size ) {
    1467             : 
    1468           0 :     if (typev == t) return;
    1469             : 
    1470           0 :     switch ( t ) {
    1471           0 :         case BOOL:
    1472           0 :             asBool();
    1473           0 :             break;
    1474           0 :         case INT:
    1475           0 :             asInt();
    1476           0 :             break;
    1477           0 :         case UINT:
    1478           0 :             asuInt();
    1479           0 :             break;
    1480           0 :         case DOUBLE:
    1481           0 :             asDouble();
    1482           0 :             break;
    1483           0 :         case COMPLEX:
    1484           0 :             asComplex();
    1485           0 :             break;
    1486           0 :         case STRING:
    1487           0 :             asString();
    1488           0 :             break;
    1489           0 :         case BOOLVEC:
    1490           0 :             asBoolVec(size);
    1491           0 :             break;
    1492           0 :         case INTVEC:
    1493           0 :             asIntVec(size);
    1494           0 :             break;
    1495           0 :         case UINTVEC:
    1496           0 :             asuIntVec(size);
    1497           0 :             break;
    1498           0 :         case DOUBLEVEC:
    1499           0 :             asDoubleVec(size);
    1500           0 :             break;
    1501           0 :         case STRINGVEC:
    1502           0 :             asStringVec(size);
    1503           0 :             break;
    1504           0 :         case COMPLEXVEC:
    1505           0 :             asComplexVec(size);
    1506           0 :             break;
    1507           0 :         case RECORD:
    1508           0 :             asRecord( );
    1509           0 :             break;
    1510             :     }
    1511             : }
    1512             : 
    1513             : #define GETIT(CONST,CONST2,RET_TYPE,NAME,TYPE,VAL,DEREF)        \
    1514             : CONST RET_TYPE variant::NAME( ) CONST2 {           \
    1515             :     if ( typev != TYPE )                                        \
    1516             :         ThrowCc( create_message( #NAME " called for type") );     \
    1517             :     return DEREF val.VAL;                                       \
    1518             : }
    1519             : 
    1520           0 : GETIT(, const, long,getInt,INT,i,)
    1521           0 : GETIT(, const, unsigned long,getuInt,UINT,ui,)
    1522           0 : GETIT(, const, bool,getBool,BOOL,b,)
    1523           0 : GETIT(, const, double,getDouble,DOUBLE,d,)
    1524           0 : GETIT(const, const, std::complex<double>&,getComplex,COMPLEX,c,*)
    1525           0 : GETIT(const, const, std::string&,getString,STRING,s,*)
    1526           0 : GETIT(const, const, std::vector<long>&,getIntVec,INTVEC,iv,*)
    1527           0 : GETIT(const, const, std::vector<unsigned long>&,getuIntVec,UINTVEC,uiv,*)
    1528           0 : GETIT(const, const, std::vector<bool>&,getBoolVec,BOOLVEC,bv,*)
    1529           0 : GETIT(const, const, std::vector<double>&,getDoubleVec,DOUBLEVEC,dv,*)
    1530           0 : GETIT(const, const, std::vector<std::complex<double> >&,getComplexVec,COMPLEXVEC,cv,*)
    1531           0 : GETIT(const, const, std::vector<std::string>&,getStringVec,STRINGVEC,sv,*)
    1532           0 : GETIT(const, const, record&,getRecord,RECORD,recordv,*)
    1533             : 
    1534           0 : GETIT(,,long&,getIntMod,INT,i,)
    1535           0 : GETIT(,,unsigned long&,getuIntMod,UINT,ui,)
    1536           0 : GETIT(,,bool&,getBoolMod,BOOL,b,)
    1537           0 : GETIT(,,double&,getDoubleMod,DOUBLE,d,)
    1538           0 : GETIT(,,std::complex<double>&,getComplexMod,COMPLEX,c,*)
    1539           0 : GETIT(,,std::string&,getStringMod,STRING,s,*)
    1540           0 : GETIT(,,std::vector<long>&,getIntVecMod,INTVEC,iv,*)
    1541           0 : GETIT(,,std::vector<unsigned long>&,getuIntVecMod,UINTVEC,uiv,*)
    1542           0 : GETIT(,,std::vector<bool>&,getBoolVecMod,BOOLVEC,bv,*)
    1543           0 : GETIT(,,std::vector<double>&,getDoubleVecMod,DOUBLEVEC,dv,*)
    1544           0 : GETIT(,,std::vector<std::complex<double> >&,getComplexVecMod,COMPLEXVEC,cv,*)
    1545           0 : GETIT(,,std::vector<std::string>&,getStringVecMod,STRINGVEC,sv,*)
    1546           0 : GETIT(,,record&,getRecordMod,RECORD,recordv,*)
    1547             : 
    1548             : #define PUSHIMPL(TYPEX,TYPETAG,TYPETOSTRING,NUMTWEAK,BOOLTWEAK,BOOLCPX,STRBOOL, STRINT,STRLONG,STRDBL,STRCPX) \
    1549             : void variant::push(TYPEX v, bool conform ) {                                    \
    1550             :                                                                                 \
    1551             :     if ( conform == true ) {                                                    \
    1552             :         TYPE new_type = variant::compatible_type(TYPETAG,typev);                \
    1553             :         if (new_type != typev) as(new_type);                                    \
    1554             :     }                                                                           \
    1555             :                                                                                 \
    1556             :     switch (typev) {                                                            \
    1557             :         case BOOL:                                                              \
    1558             :             asBoolVec().push_back((bool) STRBOOL(v NUMTWEAK));                  \
    1559             :             break;                                                              \
    1560             :         case INT:                                                               \
    1561             :             asIntVec().push_back((long) STRINT(v BOOLTWEAK));                   \
    1562             :             break;                                                              \
    1563             :         case UINT:                                                              \
    1564             :             asuIntVec().push_back((unsigned long) STRINT(v BOOLTWEAK));                 \
    1565             :             break;                                                              \
    1566             :         case DOUBLE:                                                            \
    1567             :             asDoubleVec().push_back((double) STRDBL(v BOOLTWEAK));              \
    1568             :             break;                                                              \
    1569             :         case COMPLEX:                                                           \
    1570             :             asComplexVec().push_back((std::complex<double>) STRCPX(v BOOLCPX));   \
    1571             :             break;                                                              \
    1572             :         case STRING:                                                            \
    1573             :             asStringVec().push_back( TYPETOSTRING(v));                          \
    1574             :             break;                                                              \
    1575             :         case BOOLVEC:                                                           \
    1576             :             (*val.bv).push_back((bool) STRBOOL(v NUMTWEAK));                    \
    1577             :             break;                                                              \
    1578             :         case INTVEC:                                                            \
    1579             :             (*val.iv).push_back((long) STRINT(v BOOLTWEAK));                    \
    1580             :             break;                                                              \
    1581             :         case UINTVEC:                                                           \
    1582             :             (*val.uiv).push_back((unsigned long) STRINT(v BOOLTWEAK));                  \
    1583             :             break;                                                              \
    1584             :         case DOUBLEVEC:                                                         \
    1585             :             (*val.dv).push_back((double) STRDBL(v BOOLTWEAK));                  \
    1586             :             break;                                                              \
    1587             :         case COMPLEXVEC:                                                        \
    1588             :             (*val.cv).push_back((std::complex<double>) STRCPX(v BOOLCPX));        \
    1589             :             break;                                                              \
    1590             :         case STRINGVEC:                                                         \
    1591             :             (*val.sv).push_back( TYPETOSTRING(v));                              \
    1592             :             break;                                                              \
    1593             :         case RECORD:                                                            \
    1594             :             {                                                                   \
    1595             :             char buf[512];                                                      \
    1596             :             sprintf(buf,"key*%010u",++record_id_count);                               \
    1597             :             while ( (*val.recordv).find(buf) != (*val.recordv).end() )          \
    1598             :                 sprintf(buf,"key*%010u",++record_id_count);                   \
    1599             :             (*val.recordv).insert(buf,variant(v));                              \
    1600             :             }                                                                   \
    1601             :             break;                                                              \
    1602             :     }                                                                           \
    1603             :                                                                                 \
    1604             :     if ( shape_.size() == 1 )                                                   \
    1605             :         shape_[0] += 1;                                                         \
    1606             :     else if ( shape_size() != size() )                                          \
    1607             :         shape_ = std::vector<ssize_t>(1,size());                                  \
    1608             : }
    1609             : 
    1610           0 : PUSHIMPL(bool                ,BOOL    ,tostring ,                                             ,== true ? 1 : 0      ,== true ? 1 : 0, , , , , )
    1611           0 : PUSHIMPL(std::complex<double>,COMPLEX ,tostring ,.real() == 0 && v.imag() == 0 ? false : true ,.real()              ,               , , , , , )
    1612           0 : PUSHIMPL(long                ,INT     ,tostring ,== 0 ? false : true                          ,                     ,               , , , , , )
    1613           0 : PUSHIMPL(unsigned long ,UINT     ,tostring ,== 0 ? false : true                          ,                     ,               , , , , , )
    1614           0 : PUSHIMPL(double              ,DOUBLE  ,tostring ,== 0 ? false : true                          ,                     ,               , , , , , )
    1615           0 : PUSHIMPL(const std::string&  ,STRING  ,         , , , ,stringtobool ,stringtoint,stringtolong, stringtodouble ,stringtocomplex )
    1616           0 : PUSHIMPL(const char*         ,STRING  ,         , , , ,stringtobool ,stringtoint,stringtolong, stringtodouble ,stringtocomplex )
    1617             : 
    1618             : #define PLACEIMPL(TYPEX,TYPETAG,TYPETOSTRING,NUMTWEAK,BOOLTWEAK,BOOLCPX,STRBOOL, STRINT, STRLONG ,STRDBL,STRCPX) \
    1619             : void variant::place(TYPEX v, unsigned int index, bool conform ) {                       \
    1620             :                                                                                 \
    1621             :     if ( conform == true ) {                                                    \
    1622             :         TYPE new_type = variant::compatible_type(TYPETAG,typev);                \
    1623             :         if (new_type != typev) as(new_type);                                    \
    1624             :     }                                                                           \
    1625             :                                                                                 \
    1626             :     switch (typev) {                                                            \
    1627             :         case BOOL:                                                              \
    1628             :             if ( index > 0 )                                                 \
    1629             :                 asBoolVec(index+1)[index] = (bool) (STRBOOL(v NUMTWEAK));       \
    1630             :             else                                                                \
    1631             :                 val.b = (bool) (STRBOOL(v NUMTWEAK));                           \
    1632             :             break;                                                              \
    1633             :         case INT:                                                               \
    1634             :             if ( index > 0 )                                                 \
    1635             :                 asIntVec(index+1)[index] = (long) (STRINT(v BOOLTWEAK));                \
    1636             :             else                                                                \
    1637             :                 val.i = (long) (STRINT(v BOOLTWEAK));                           \
    1638             :         case UINT:                                                              \
    1639             :             if ( index > 0 )                                                 \
    1640             :                 asuIntVec(index+1)[index] = (unsigned long) (STRINT(v BOOLTWEAK));      \
    1641             :             else                                                                \
    1642             :                 val.ui = (unsigned long) (STRINT(v BOOLTWEAK));                         \
    1643             :             break;                                                              \
    1644             :         case DOUBLE:                                                            \
    1645             :             if ( index > 0 )                                                 \
    1646             :                 asDoubleVec(index+1).push_back((double) STRDBL(v BOOLTWEAK));   \
    1647             :             break;                                                              \
    1648             :         case COMPLEX:                                                           \
    1649             :             asComplexVec(index+1).push_back((std::complex<double>) STRCPX(v BOOLCPX)); \
    1650             :             break;                                                              \
    1651             :         case STRING:                                                            \
    1652             :             asStringVec(index+1).push_back( TYPETOSTRING(v));                   \
    1653             :             break;                                                              \
    1654             :         case BOOLVEC:                                                           \
    1655             :             if ( index+1 > (*val.bv).size() )                                        \
    1656             :                 (*val.bv).resize(index+1);                                      \
    1657             :             (*val.bv)[index] = (bool) (STRBOOL(v NUMTWEAK));                    \
    1658             :             break;                                                              \
    1659             :         case INTVEC:                                                            \
    1660             :             if ( index+1 > (*val.iv).size() )                                        \
    1661             :                 (*val.iv).resize(index+1);                                      \
    1662             :             (*val.iv)[index] = (long) (STRINT(v BOOLTWEAK));                    \
    1663             :             break;                                                              \
    1664             :         case UINTVEC:                                                            \
    1665             :             if ( index+1 > (*val.uiv).size() )                                   \
    1666             :                 (*val.uiv).resize(index+1);                                      \
    1667             :             (*val.uiv)[index] = (unsigned long) (STRINT(v BOOLTWEAK));                     \
    1668             :             break;                                                              \
    1669             :         case DOUBLEVEC:                                                         \
    1670             :             if ( index+1 > (*val.dv).size() )                                        \
    1671             :                 (*val.dv).resize(index+1);                                      \
    1672             :             (*val.dv)[index] = (double) (STRDBL(v BOOLTWEAK));                  \
    1673             :             break;                                                              \
    1674             :         case COMPLEXVEC:                                                        \
    1675             :             if ( index+1 > (*val.cv).size() )                                        \
    1676             :                 (*val.cv).resize(index+1);                                      \
    1677             :             (*val.cv)[index] = (std::complex<double>) (STRCPX(v BOOLCPX));        \
    1678             :             break;                                                              \
    1679             :         case STRINGVEC:                                                         \
    1680             :             if ( index+1 > (*val.sv).size() )                                        \
    1681             :                 (*val.sv).resize(index+1);                                      \
    1682             :             (*val.sv)[index] = (TYPETOSTRING(v));                               \
    1683             :             break;                                                              \
    1684             :         case RECORD:                                                            \
    1685             :             {                                                                   \
    1686             :             char buf[512];                                                      \
    1687             :             sprintf(buf,"idx*%010u",index);                                   \
    1688             :             if ((*val.recordv).find(buf) == (*val.recordv).end())               \
    1689             :                 (*val.recordv).insert(buf,casac::variant(v));                   \
    1690             :             else {                                                              \
    1691             :                 sprintf(buf,"key*%010u",++record_id_count);                   \
    1692             :                 while ( (*val.recordv).find(buf) != (*val.recordv).end() )      \
    1693             :                     sprintf(buf,"key*%010u",++record_id_count);                       \
    1694             :                 (*val.recordv).insert(buf,casac::variant(v));                   \
    1695             :             }                                                                   \
    1696             :             }                                                                   \
    1697             :             break;                                                              \
    1698             :     }                                                                           \
    1699             : }
    1700             : 
    1701           0 : PLACEIMPL(bool                ,BOOL    ,tostring ,                                             ,== true ? 1 : 0      ,== true ? 1 : 0, , , , , )
    1702           0 : PLACEIMPL(std::complex<double>,COMPLEX ,tostring ,.real() == 0.0 && v.imag() == 0.0 ? false : true ,.real()              ,               , , , , , )
    1703           0 : PLACEIMPL(long                ,INT     ,tostring ,== 0 ? false : true                          ,                     ,               , , , , , )
    1704           0 : PLACEIMPL(unsigned long ,UINT    ,tostring ,== 0 ? false : true                          ,                     ,               , , , , , )
    1705           0 : PLACEIMPL(double              ,DOUBLE  ,tostring ,== 0 ? false : true                          ,                     ,               , , , , , )
    1706           0 : PLACEIMPL(const std::string&  ,STRING  ,         , , , ,stringtobool ,stringtoint, stringtolong, stringtodouble ,stringtocomplex )
    1707           0 : PLACEIMPL(const char*         ,STRING  ,         , , , ,stringtobool ,stringtoint, stringtolong, stringtodouble ,stringtocomplex )
    1708             : 
    1709           0 : std::string variant::create_message( const std::string s ) const {
    1710           0 :     std::string type = (typev == BOOL ? "bool" :
    1711           0 :                         typev == INT ? "int" :
    1712           0 :                         typev == UINT ? "uint" :
    1713           0 :                         typev == DOUBLE ? "double" :
    1714           0 :                         typev == STRING ? "string" :
    1715           0 :                         typev == BOOLVEC ? "boolvec" :
    1716           0 :                         typev == INTVEC ? "intvec" :
    1717           0 :                         typev == UINTVEC ? "uintvec" :
    1718           0 :                         typev == DOUBLEVEC ? "doublevec" :
    1719           0 :                         typev == STRINGVEC ? "stringvec" : "ErRoR");
    1720           0 :     return s + " " + type + " variant";
    1721           0 : }
    1722             : 
    1723           0 : ssize_t variant::shape_size( ) const {
    1724           0 :     ssize_t result = 1;
    1725           0 :     for ( std::vector<ssize_t>::const_iterator iter = shape_.begin( );
    1726           0 :           iter != shape_.end( ); ++iter ) result *= *iter;
    1727           0 :     return result;
    1728             : }
    1729             : 
    1730           0 : ssize_t variant::vec_size( ) const {
    1731           0 :     switch (typev) {
    1732           0 :         case BOOLVEC: return (*val.bv).size();
    1733           0 :         case INTVEC: return (*val.iv).size();
    1734           0 :         case UINTVEC: return (*val.uiv).size();
    1735           0 :         case DOUBLEVEC: return (*val.dv).size();
    1736           0 :         case COMPLEXVEC: return (*val.cv).size();
    1737           0 :         case STRINGVEC: return (*val.sv).size();
    1738           0 :         default: return 1;
    1739             :     }
    1740             : }
    1741             : 
    1742           0 : void variant::resize( ssize_t size ) {
    1743             : 
    1744           0 :     if ( size < 0 ) return;
    1745             : 
    1746           0 :     if ( size > 1 ) {
    1747           0 :         switch (typev) {
    1748           0 :             case BOOL:
    1749           0 :                 asBoolVec(size);
    1750           0 :                 break;
    1751           0 :             case INT:
    1752           0 :                 asIntVec(size);
    1753           0 :                 break;
    1754           0 :             case UINT:
    1755           0 :                 asuIntVec(size);
    1756           0 :                 break;
    1757           0 :             case DOUBLE:
    1758           0 :                 asDoubleVec(size);
    1759           0 :                 break;
    1760           0 :             case COMPLEX:
    1761           0 :                 asComplexVec(size);
    1762           0 :                 break;
    1763           0 :             case STRING:
    1764           0 :                 asStringVec(size);
    1765           0 :                 break;
    1766           0 :             case BOOLVEC:
    1767           0 :                 (*val.bv).resize(size);
    1768           0 :                 break;
    1769           0 :             case INTVEC:
    1770           0 :                 (*val.iv).resize(size);
    1771           0 :                 break;
    1772           0 :             case UINTVEC:
    1773           0 :                 (*val.uiv).resize(size);
    1774           0 :                 break;
    1775           0 :             case DOUBLEVEC:
    1776           0 :                 (*val.dv).resize(size);
    1777           0 :                 break;
    1778           0 :             case COMPLEXVEC:
    1779           0 :                 (*val.cv).resize(size);
    1780           0 :                 break;
    1781           0 :             case STRINGVEC:
    1782           0 :                 (*val.sv).resize(size);
    1783           0 :                 break;
    1784           0 :             case RECORD:
    1785           0 :                 break;
    1786             :         }
    1787             :     } else {
    1788           0 :         switch (typev) {
    1789           0 :             case BOOL:
    1790             :             case INT:
    1791             :             case UINT:
    1792             :             case DOUBLE:
    1793             :             case COMPLEX:
    1794             :             case STRING:
    1795           0 :                 break;
    1796           0 :             case BOOLVEC:
    1797           0 :                 (*val.bv).resize(size);
    1798           0 :                 break;
    1799           0 :             case INTVEC:
    1800           0 :                 (*val.iv).resize(size);
    1801           0 :                 break;
    1802           0 :             case UINTVEC:
    1803           0 :                 (*val.uiv).resize(size);
    1804           0 :                 break;
    1805           0 :             case DOUBLEVEC:
    1806           0 :                 (*val.dv).resize(size);
    1807           0 :                 break;
    1808           0 :             case COMPLEXVEC:
    1809           0 :                 (*val.cv).resize(size);
    1810           0 :                 break;
    1811           0 :             case STRINGVEC:
    1812           0 :                 (*val.sv).resize(size);
    1813           0 :                 break;
    1814           0 :             case RECORD:
    1815           0 :                 break;
    1816             :         }
    1817             :     }
    1818             : }
    1819             : 
    1820           0 : variant initialize_variant( const std::string & ) {
    1821           0 :             return variant();
    1822             : }
    1823             : 
    1824           0 : bool variant::empty() const {
    1825           0 :         switch (typev) {
    1826           0 :         case BOOL:
    1827             :         case INT:
    1828             :         case UINT:
    1829             :         case DOUBLE:
    1830             :         case COMPLEX:
    1831           0 :                 return false;
    1832           0 :         case STRING:
    1833           0 :                 return val.s->empty();
    1834           0 :         case BOOLVEC:
    1835             :         case INTVEC:
    1836             :         case UINTVEC:
    1837             :         case DOUBLEVEC:
    1838             :         case COMPLEXVEC:
    1839             :         case STRINGVEC:
    1840           0 :                 return size() == 0;
    1841           0 :         case RECORD:
    1842           0 :                 return val.recordv->empty();
    1843             :         }
    1844             : 
    1845           0 :         return false; // Looks right for unhandled case???
    1846             : }
    1847             : 
    1848             : }       // casac namespace
    1849             : 

Generated by: LCOV version 1.16