Changeset 116 for trunk


Ignore:
Timestamp:
Oct 26, 2005 11:32:52 PM (17 years ago)
Author:
dkearney
Message:
  1. rewrote RpUnits::define(...) and RpUnits::convert(...) fxns.
  2. added functionality so you no longer need to call add_presets(...)
  3. RpUnits can now handle conversions as follows 1cm2/Vs -> 1e-7m2/kVus
  4. Cannot handle conversions dealing with Temperature very well because

Temperature conversions have offsets (+/- 32...). you can still do
F->C and Fs->Cs, but Fms->Cs provides unreliable results. (not to
mention that i'm still unsure how to do a conversion like this.

  1. still need to add Fo (delta fahrenheit) and Co (delta celcius)

units and conversions. These should not be effected by the notorious
temperature

  1. adjusted RpUnits_test.cc for testing. python.fortran and matlab

bindings have not been tested yet.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/core/RpUnits.h

    r115 r116  
    1515#include <iostream>
    1616#include <string>
     17#include <list>
    1718#include <sstream>
    1819#include <stdlib.h>
    1920#include <errno.h>
    20 
    21 #ifndef _RpDICT_H
    22     #include "RpDict.h"
    23 #endif
    24 
     21#include <math.h>
     22
     23#include "RpDict.h"
    2524#include "RpUnitsStd.h"
    2625
     
    2827#define _RpUNITS_H
    2928
     29#define LIST_TEMPLATE RpUnitsListEntry
     30
     31// should the define function:
     32// 1. compare portions of inStr to unit names that have previously
     33//    been defined (you must parse in order for this option to work)
     34#define COMPARE_MASK    1
     35// 2. create a unit if no unit by the name exists.
     36#define CREATE_MASK     2
     37// 3. parse the unit name to try to find previously defined units.
     38#define PARSE_MASK      4
     39
    3040class RpUnits;
    3141
    32 class unit
    33 {
    34 
     42class RpUnitsPreset {
    3543    public:
    36 
    37         const std::string getUnits(){ return units; };
    38         double getExponent() {return exponent;};
    39         const RpUnits * getBasis() {return basis;};
    40 
    41         friend class RpUnits;
    42 
    43     private:
    44         const std::string units;
    45         double exponent;
    46         const RpUnits* basis;
    47 
    48         unit* prev;
    49         unit* next;
    50 
    51         // private constructor
    52         unit (
    53                 const std::string& units,
    54                 double&            exponent,
    55                 const RpUnits*     basis,
    56                 unit*              prev,
    57                 unit*              next
    58              )
    59             :   units    (units),
    60                 exponent (exponent),
    61                 basis    (basis),
    62                 prev     (prev),
    63                 next     (next)
    64             {};
    65 
    66         /*
    67         // private copy constructor
    68         unit ( const unit& other )
    69             :   units        other.units,
    70                 exponent     other.exponent,
    71                 basis        other.basis,
    72                 prev         unit(other.prev),
    73                 next         unit(other.next)
    74             {};
    75 
    76         // copy assignment operator
    77         unit& operator= (unit& other)
    78             :   units        other.units,
    79                 exponent     other.exponent,
    80                 basis        RpUnits(other.basis),
    81                 prev         unit(other.prev),
    82                 next         unit(other.next)
    83         {}
    84         */
    85 
    86         /*
    87         // destructor (its not virtual yet, still testing)
    88         ~unit () {
    89 
    90         }
    91         */
    92 
    93         void newExponent(double newExponent) {exponent = newExponent;};
    94 
    95 
     44        RpUnitsPreset () {
     45            addPresetAll();
     46        };
     47
     48        static int addPresetAll();
     49        static int addPresetEnergy();
     50        static int addPresetLength();
     51        static int addPresetTemp();
     52        static int addPresetTime();
     53        static int addPresetVolume();
    9654};
    9755
     
    256214};
    257215
     216class RpUnitsListEntry
     217{
     218
     219    public:
     220
     221        // constructor
     222        RpUnitsListEntry (const RpUnits* unit, double exponent)
     223            : unit     (unit),
     224              exponent (exponent)
     225        {};
     226
     227        // copy constructor
     228        RpUnitsListEntry (const RpUnitsListEntry& other)
     229            : unit     (other.unit),
     230              exponent (other.exponent)
     231        {};
     232
     233        // copy assignment operator
     234        RpUnitsListEntry& operator= (const RpUnitsListEntry& other) {
     235            unit = other.unit;
     236            exponent = other.exponent;
     237            return *this;
     238        }
     239
     240        // negate the exponent
     241        void negateExponent() const;
     242
     243        // print the name of the object
     244        std::string name() const;
     245
     246        // report the basis of the RpUnits object being stored.
     247        const RpUnits* getBasis() const;
     248
     249        // return the RpUnits*
     250        const RpUnits* getUnitsObj() const;
     251
     252        // return the exponent
     253        double getExponent() const;
     254
     255        // destructor
     256        virtual ~RpUnitsListEntry ()
     257        {}
     258
     259    private:
     260
     261        const RpUnits* unit;
     262        mutable double exponent;
     263};
     264
    258265class RpUnits
    259266{
     
    261268     * helpful units site
    262269     * http://aurora.regenstrief.org/~gunther/units.html
     270     * http://www.nodc.noaa.gov/dsdt/ucg/
     271     * http://www.cellml.org/meeting_minutes/archive/
     272     *        20010110_meeting_minutes.html
    263273     */
    264274
     
    272282
    273283        // convert from one RpUnits to another if the conversion is defined
    274         double convert(         const RpUnits* toUnits, 
    275                                 double val, 
     284        double convert(         const RpUnits* toUnits,
     285                                double val,
    276286                                int* result=NULL    ) const;
    277287        // convert from one RpUnits to another if the conversion is defined
     
    292302                                     int* result = NULL );
    293303
     304        /*
     305        static std::string convert ( std::string val,
     306                                     std::string toUnits,
     307                                     int showUnits,
     308                                     int* result = NULL );
     309        */
     310
    294311        // dictionary to store the units.
    295312        // static RpDict<std::string,RpUnits> dict;
     
    312329        // add RpUnits Object
    313330        static RpUnits * define(const std::string units,
    314                                 const RpUnits* basis);
    315                                 // unsigned int create=0);
    316         static RpUnits * defineCmplx(   const std::string units,
    317                                         const RpUnits* basis);
     331                                const RpUnits* basis=NULL   );
     332        // static RpUnits * defineCmplx(   const std::string units,
     333        //                                 const RpUnits* basis);
    318334        //
    319335        // add relation rule
     
    357373        friend class RpDictEntry<std::string,RpUnits*>;
    358374
     375        friend int insert(std::string key,RpUnits* val);
     376
     377
    359378        // copy constructor
    360379        RpUnits (RpUnits &other)
    361             : head (NULL),
     380            : units    (other.units),
     381              exponent (other.exponent),
     382              basis    (other.basis),
    362383              convList (NULL)
    363384        {
    364             unit* p = NULL;
    365             unit* current = NULL;
    366385            convEntry* q = NULL;
    367             convEntry* curr2 = NULL;
     386            convEntry* curr = NULL;
    368387
    369388            dict = other.dict;
    370389
    371             if (other.head) {
    372                 p = other.head;
    373                 head = new unit(p->units, p->exponent, p->basis, NULL, NULL);
    374                 current = head;
    375 
    376                 while (p->next) {
    377                     p = p->next;
    378                     current->next = new unit( p->units,
    379                                               p->exponent,
    380                                               p->basis,
    381                                               current,
    382                                               NULL        );
    383                     current = current->next;
    384                 }
    385             }
    386390            if (other.convList) {
    387391                q = other.convList;
    388392                convList = new convEntry (q->conv,NULL,NULL);
    389                 curr2 = convList;
     393                curr = convList;
    390394                while (q->next) {
    391395                    q = q->next;
    392                     curr2->next = new convEntry (q->conv,curr2,NULL);
    393                     curr2 = curr2->next;
     396                    curr->next = new convEntry (q->conv,curr,NULL);
     397                    curr = curr->next;
    394398                }
    395399            }
     
    399403        RpUnits& operator= (const RpUnits& other) {
    400404
    401             unit* p = NULL;
    402             unit* current = NULL;
    403405            convEntry* q = NULL;
    404             convEntry* curr2 = NULL;
     406            convEntry* curr = NULL;
    405407
    406408            if ( this != &other ) {
    407                 delete head;
    408409                delete convList;
    409410            }
    410411
    411412            dict = other.dict;
    412 
    413             if (other.head) {
    414                 p = other.head;
    415                 head = new unit(p->units, p->exponent, p->basis, NULL, NULL);
    416                 current = head;
    417 
    418                 while (p->next) {
    419                     p = p->next;
    420                     current->next = new unit( p->units,
    421                                               p->exponent,
    422                                               p->basis,
    423                                               current,
    424                                               NULL        );
    425                     current = current->next;
    426                 }
    427             }
     413            units = other.units;
     414            exponent = other.exponent;
     415            basis = other.basis;
     416
    428417            if (other.convList) {
    429418                q = other.convList;
    430419                convList = new convEntry (q->conv,NULL,NULL);
    431                 curr2 = convList;
     420                curr = convList;
    432421                while (q->next) {
    433422                    q = q->next;
    434                     curr2->next = new convEntry (q->conv,curr2,NULL);
    435                     curr2 = curr2->next;
     423                    curr->next = new convEntry (q->conv,curr,NULL);
     424                    curr = curr->next;
    436425                }
    437426            }
     
    446435            // clean up dynamic memory
    447436
    448             unit* p = head;
    449             unit* tmp = p;
    450             convEntry* p2 = convList;
    451             convEntry* tmp2 = p2;
     437            convEntry* p = convList;
     438            convEntry* tmp = p;
    452439
    453440            while (p != NULL) {
     
    455442                p = p->next;
    456443                delete tmp;
    457             }
    458 
    459             while (p2 != NULL) {
    460                 tmp2 = p2;
    461                 p2 = p2->next;
    462                 delete tmp2;
    463444            }
    464445        }
     
    480461        //
    481462
    482         // used by the RpUnits when defining units elements
    483         unit* head;
     463        std::string units;
     464        double exponent;
     465        const RpUnits* basis;
    484466
    485467        // linked list of units this RpUnit can convert to
     
    501483        //
    502484
    503 
    504 
    505485        RpUnits (
    506486                    const std::string& units,
     
    508488                    const RpUnits* basis
    509489                )
    510             :   head        ( new unit( units, exponent, basis, NULL, NULL) ),
     490            :   units       (units),
     491                exponent    (exponent),
     492                basis       (basis),
    511493                convList    (NULL)
    512494        {};
    513 
    514         void RpUnits::connectConversion(conversion* conv) const;
    515495
    516496        // insert new RpUnits object into RpUnitsTable
    517497        // returns 0 on success (object inserted or already exists)
    518498        // returns !0 on failure (object cannot be inserted or dne)
    519         int RpUnits::insert(std::string key);
    520 
    521         // link two RpUnits objects that already exist in RpUnitsTable
    522         // returns 0 on success (linking within table was successful)
    523         // returns !0 on failure (linking was not successful)
    524         // int RpUnits::link(RpUnits * unitA);
    525 
    526 
    527         static int pre_compare( std::string& units,
    528                                 const RpUnits* basis = NULL);
    529 
    530         void addUnit( const std::string& units,
    531                       double &  exponent,
    532                       const RpUnits * basis
    533                      );
    534 
    535         static int addPresetAll();
    536         static int addPresetEnergy();
    537         static int addPresetLength();
    538         static int addPresetTemp();
    539         static int addPresetTime();
    540         static int addPresetVolume();
    541 
     499        // int RpUnits::insert(std::string key) const;
     500
     501        typedef std::list<LIST_TEMPLATE> RpUnitsList;
     502        typedef RpUnitsList::iterator RpUnitsListIter;
     503
     504        void newExponent(double newExponent) {exponent = newExponent;};
     505
     506        static int units2list( const std::string& inUnits,
     507                               RpUnitsList& outList         );
     508        static int grabExponent(const std::string& inStr, double* exp);
     509        static int grabUnitString( const std::string& inStr);
     510        static const RpUnits* grabUnits (std::string inStr, int* offset);
     511        static int negateListExponents(RpUnitsList& unitsList);
     512        static int RpUnits::printList(RpUnitsList& unitsList);
     513
     514        static int RpUnits::compareListEntryBasis( RpUnitsList& fromList,
     515                                                   RpUnitsListIter& fromIter,
     516                                                   RpUnitsListIter& toIter);
     517
     518        static int RpUnits::compareListEntrySearch( RpUnitsList& fromList,
     519                                                    RpUnitsListIter& fromIter,
     520                                                    RpUnitsListIter& toIter);
     521
     522        void RpUnits::connectConversion(conversion* conv) const;
    542523
    543524};
  • trunk/include/core/RpUnitsStd.h

    r115 r116  
    1212#endif
    1313
    14 double centi2base (double centi, double power);
    15 double milli2base (double milli, double power);
    16 double micro2base (double micro, double power);
    17 double nano2base (double nano, double power);
    18 double pico2base (double pico, double power);
    19 double femto2base (double femto, double power);
    20 double atto2base (double atto, double power);
    21 double kilo2base (double kilo, double power);
    22 double mega2base (double mega, double power);
    23 double giga2base (double giga, double power);
    24 double tera2base (double tera, double power);
    25 double peta2base (double peta, double power);
     14double centi2base (double centi);
     15double milli2base (double milli);
     16double micro2base (double micro);
     17double nano2base (double nano);
     18double pico2base (double pico);
     19double femto2base (double femto);
     20double atto2base (double atto);
     21double kilo2base (double kilo);
     22double mega2base (double mega);
     23double giga2base (double giga);
     24double tera2base (double tera);
     25double peta2base (double peta);
    2626
    2727
    2828
    29 double base2centi (double base, double power);
    30 double base2milli (double base, double power);
    31 double base2micro (double base, double power);
    32 double base2nano (double base, double power);
    33 double base2pico (double base, double power);
    34 double base2femto (double base, double power);
    35 double base2atto (double base, double power);
    36 double base2kilo (double base, double power);
    37 double base2mega (double base, double power);
    38 double base2giga (double base, double power);
    39 double base2tera (double base, double power);
    40 double base2peta (double base, double power);
     29double base2centi (double base);
     30double base2milli (double base);
     31double base2micro (double base);
     32double base2nano (double base);
     33double base2pico (double base);
     34double base2femto (double base);
     35double base2atto (double base);
     36double base2kilo (double base);
     37double base2mega (double base);
     38double base2giga (double base);
     39double base2tera (double base);
     40double base2peta (double base);
    4141
    4242
    4343
    44 double angstrom2meter (double angstrom, double power);
    45 double meter2angstrom (double meters, double power);
    46 double meter2inch (double m, double power);
    47 double inch2meter (double in, double power);
    48 double meter2feet (double m, double power);
    49 double feet2meter (double ft, double power);
    50 double meter2yard (double m, double power);
    51 double yard2meter (double yd, double power);
     44double angstrom2meter (double angstrom);
     45double meter2angstrom (double meter);
     46double meter2inch (double meter);
     47double inch2meter (double in);
     48double meter2feet (double meter);
     49double feet2meter (double ft);
     50double meter2yard (double meter);
     51double yard2meter (double yd);
    5252
    5353
     
    7171
    7272
    73 double cubicMeter2usGallon (double m3, double none);
    74 double usGallon2cubicMeter (double g, double none);
    75 double cubicFeet2usGallon (double ft3, double none);
    76 double usGallon2cubicFeet (double g, double none);
     73double cubicMeter2usGallon (double m3);
     74double usGallon2cubicMeter (double gal);
     75double cubicFeet2usGallon (double ft3);
     76double usGallon2cubicFeet (double gal);
    7777
    7878
  • trunk/src/core/RpUnits.cc

    r115 r116  
    1313 * ======================================================================
    1414 */
     15
    1516#include "RpUnits.h"
    1617
    1718// dict pointer
    1819RpDict<std::string,RpUnits*>* RpUnits::dict = new RpDict<std::string,RpUnits*>();
     20static RpUnitsPreset loader;
    1921
    2022/************************************************************************
     
    2527
    2628RpUnits *
    27 RpUnits::define(const std::string units, const RpUnits* basis) {
    28 
    29     RpUnits * newRpUnit = NULL;
     29RpUnits::define( const std::string units, const RpUnits* basis) {
     30
     31    RpUnits* newRpUnit = NULL;
     32
     33    std::string searchStr = units;
     34    std::string sendStr = "";
     35    int len = searchStr.length();
     36    int idx = len-1;
     37    double exponent = 1;
    3038
    3139    if (units == "") {
     
    4048    }
    4149
    42     double exp = 0.0;
    43     double oldExponent = 0;
    44     double newExponent = 0;
    45     int digiSearch = 0; // flag to show we are searching digits
    46     int alphaSearch = 0; // flag to show we are searching chars
    47 
    48     std::string cmpStr = "";
    49 
    50     std::string::size_type length = units.length();
    51     int srchIndex = length;
    52     std::string srchStr = units;
    53 
    54     while ((srchStr.length() > 0)) {
    55 
    56         srchIndex--;
    57 
    58         if (srchIndex < 0) {
    59             break;
    60         }
    61 
    62         if     ( isdigit(srchStr[srchIndex]) && !digiSearch && !alphaSearch) {
    63             digiSearch = 1;
    64         }
    65         else if(!isdigit(srchStr[srchIndex]) &&  digiSearch && !alphaSearch) {
    66 
    67             // convert our exponent to integer
    68 
    69             // check to see if there is a + or - sign
    70             if (  ( srchStr[srchIndex] == '+' )
    71                || ( srchStr[srchIndex] == '-' ) ) {
    72 
    73                 // evaluate a '+' or '-' sign with the value
    74                 srchIndex--;
    75             }
    76 
    77             srchIndex++;
    78 
    79             exp = atoi(&srchStr[srchIndex]);
    80 
    81             // we are no longer in a digit search
    82             digiSearch = 0;
    83 
    84             // place null character where the number starts
    85             // so we know what we've already parsed
    86 
    87             srchStr.erase(srchIndex);
    88             length = srchStr.length();
    89 
    90         }
    91         else if( isalpha(srchStr[srchIndex]) && !digiSearch && !alphaSearch) {
    92             alphaSearch = 1;
    93         }
    94         else if(!isalpha(srchStr[srchIndex]) && !digiSearch && alphaSearch) {
    95 
    96             // adjust the exponent if none was provided
    97             if (exp == 0) {
    98                 exp = 1;
    99             }
    100 
    101             // compare unit string to see if it is a recognized system
    102 
    103 
    104             std::string cmpStr = srchStr.substr(srchIndex+1,length-srchIndex-1);
    105             if (newRpUnit) {
    106                  newRpUnit->addUnit( cmpStr, exp, basis);
    107             }
    108             else {
    109                  newRpUnit= new RpUnits(cmpStr, exp, basis);
    110             }
    111 
    112             // place a null character at the end of the string
    113             // so we know what we've parsed so far.
    114 
    115             srchStr.erase(srchIndex);
    116             length = srchStr.length();
    117 
    118             // fix our searching flag
    119             alphaSearch = 0;
    120 
    121         }
    122         else if( srchStr[srchIndex] == '/' ) {
    123             // have to go back to all of the objects created and
    124             // multiply their exponents by -1.
    125 
    126             if (newRpUnit) {
    127                 unit* p = newRpUnit->head;
    128                 while (p) {
    129                     oldExponent = p->getExponent();
    130                     newExponent = oldExponent*-1;
    131                     p->newExponent(newExponent);
    132                     p = p->next;
    133                 }
    134             }
    135 
    136             // place a null character at the end of the string
    137             // so we know what we've parsed so far.
    138 
    139             srchStr.erase(srchIndex);
    140             length = srchStr.length();
    141 
    142         }
    143         else {
    144             continue;
    145         }
    146 
    147 
    148     } // end while loop
    149 
    150 
    151     // complete the last iteration
    152     if (srchIndex < 0) {
    153 
    154 
    155         if (digiSearch) {
    156             // convert whatever is left
    157             exp = atoi(&srchStr[srchIndex+1]);
    158 
    159             // if we get here, that means units name starts with a digit
    160             // normally we wont get here, but if we do, should we place
    161             // the unit into the dictionary? i think not since digits are
    162             // always considered exponents.
    163         }
    164         else if (alphaSearch) {
    165             // adjust the exponent if none was provided
    166             if (exp == 0) {
    167                 exp = 1;
    168             }
    169 
    170             // compare unit string to see if it is a recognized system
    171 
    172             std::string cmpStr = srchStr.substr(srchIndex+1,length-srchIndex-1);
    173             newRpUnit= new RpUnits(cmpStr, exp, basis);
    174             newRpUnit->insert(newRpUnit->getUnitsName());
    175         }
    176     }
    177 
    178     // place the new object into the dictionary
     50    // check to see if the said unit can already be found in the dictionary
     51    if (RpUnits::find(units)) {
     52        return NULL;
     53    }
     54
     55    //default exponent
     56    exponent = 1;
     57
     58    // check to see if there is an exponent at the end
     59    // of the search string
     60    idx = RpUnits::grabExponent(searchStr, &exponent);
     61    searchStr.erase(idx);
     62
     63    // move idx pointer back to where last character was found
     64    idx--;
     65
     66    if ( searchStr[0] == '/') {
     67        // need to negate all of the previous exponents
     68        exponent = -1*exponent;
     69        sendStr = searchStr.c_str()+1;
     70    }
     71    else {
     72        // sendStr = searchStr.substr(idx+1,);
     73        // we have a unit string to parse
     74        sendStr = searchStr;
     75    }
     76
     77    newRpUnit = new RpUnits(sendStr, exponent, basis);
     78    if (newRpUnit) {
     79        insert(newRpUnit->getUnitsName(),newRpUnit);
     80    }
    17981
    18082    // return a copy of the new object to user
     
    18284}
    18385
    184 
    185 /************************************************************************
    186  *
    187  * add a complex RpUnits Object
    188  *
    189  ************************************************************************/
    190 
    191 RpUnits *
    192 RpUnits::defineCmplx ( const std::string units, const RpUnits* basis ) {
    193 
    194     RpUnits * newRpUnit = NULL;
    195 
    196     if (units == "") {
    197         // raise error, user sent null units!
    198         return NULL;
    199     }
    200 
    201     // check to see if the user is trying to trick me!
    202     if ( (basis) && (units == basis->getUnits()) ) {
    203         // dont trick me!
    204         return NULL;
    205     }
    206 
    207     double exp = 0.0;
    208     double oldExponent = 0;
    209     double newExponent = 0;
    210     int digiSearch = 0; // flag to show we are searching digits
    211     int alphaSearch = 0; // flag to show we are searching chars
    212     std::string dbText = "";
    213 
    214     std::string cmpStr = "";
    215     int cmpIndex = 0;
    216 
    217     std::string::size_type length = units.length();
    218     int srchIndex = length;
    219     std::string srchStr = units;
    220 
    221 
    222     while ((srchStr.length() > 0)) {
    223 
    224         srchIndex--;
    225 
    226         if (srchIndex < 0) {
     86int
     87RpUnits::grabExponent(const std::string& inStr, double* exp) {
     88
     89    int len = inStr.length();
     90    int idx = len - 1;
     91
     92    *exp = 1;
     93
     94    while (isdigit(inStr[idx])) {
     95        idx--;
     96    }
     97
     98    if ( (inStr[idx] == '+') || (inStr[idx] == '-') ) {
     99        idx--;
     100    }
     101
     102    idx++;
     103
     104    if (idx != len) {
     105        // process the exponent.
     106        *exp = strtod(inStr.c_str()+idx,NULL);
     107    }
     108
     109    return idx;
     110}
     111
     112int
     113RpUnits::grabUnitString ( const std::string& inStr ) {
     114
     115    int idx = inStr.length() - 1;
     116
     117    while (isalpha(inStr[idx])) {
     118        idx--;
     119    }
     120
     121    // move the index forward one position to
     122    // represent the start of the unit string
     123    idx++;
     124
     125    return idx;
     126}
     127
     128const RpUnits*
     129RpUnits::grabUnits ( std::string inStr, int* offset) {
     130
     131    const RpUnits* unit = NULL;
     132    int len = inStr.length();
     133
     134    while ( ! inStr.empty() ) {
     135        unit = RpUnits::find(inStr);
     136        if (unit) {
     137            *offset = len - inStr.length();
    227138            break;
    228139        }
    229 
    230         if     ( isdigit(srchStr[srchIndex]) && !digiSearch && !alphaSearch) {
    231             digiSearch = 1;
    232         }
    233         else if(!isdigit(srchStr[srchIndex]) &&  digiSearch && !alphaSearch) {
    234 
    235             // convert our exponent to integer
    236 
    237             // check to see if there is a + or - sign
    238             if (  ( srchStr[srchIndex] == '+' )
    239                || ( srchStr[srchIndex] == '-' ) ) {
    240 
    241                 // evaluate a '+' or '-' sign with the value
    242                 srchIndex--;
    243             }
    244 
    245             srchIndex++;
    246 
    247             exp = atoi(&srchStr[srchIndex]);
    248 
    249             // we are no longer in a digit search
    250             digiSearch = 0;
    251 
    252             // place null character where the number starts
    253             // so we know what we've already parsed
    254 
    255             srchStr.erase(srchIndex);
    256             length = srchStr.length();
    257 
    258         }
    259         else if( isalpha(srchStr[srchIndex]) && !digiSearch && !alphaSearch) {
    260             alphaSearch = 1;
    261         }
    262         else if(!isalpha(srchStr[srchIndex]) && !digiSearch && alphaSearch) {
    263 
    264             // adjust the exponent if none was provided
    265             if (exp == 0) {
    266                 exp = 1;
    267             }
    268 
    269             // compare unit string to see if it is a recognized system
    270 
    271 
    272             std::string cmpStr = srchStr.substr(srchIndex+1,length-srchIndex-1);
    273             cmpIndex = 0;
    274 
    275             if ( (unsigned)(cmpIndex = pre_compare(cmpStr,basis)) ==
    276                     std::string::npos ) {
    277                 alphaSearch = 0;
    278 
    279                 // there are units we did not recognize,
    280                 // right now we ignore them,
    281                 // we may want to deal with them differntly in the future
    282 
    283                 // erase only the last character and reprocess the string
    284                 // because our precompare doesnt take care of this yet.
    285                 srchStr.erase(srchStr.length()-1);
    286                 length = srchStr.length();
    287                 srchIndex = length;
    288 
    289 
    290                 // continue parsing characters
    291                 continue;
    292             }
    293 
    294             // the compare function was successful
    295             // move the search pointer to one value infront of
    296             // where the units were found.
    297             //
    298             // cmpIndex tells us how far ahead of the srchIndex the matching
    299             // unit was found. so we add srchIndex to get the real index.
    300             cmpIndex += srchIndex+1;
    301             srchIndex = cmpIndex;
    302             std::string newUnitText = srchStr.substr(cmpIndex,length-cmpIndex);
    303 
    304             // call the function to create the unit object
    305 
    306             // we need pre-compare to return the basis of what it found.
    307             if (newRpUnit) {
    308                  newRpUnit->addUnit( newUnitText, exp, basis);
    309             }
    310             else {
    311                  newRpUnit= new RpUnits(newUnitText, exp, basis);
    312             }
    313 
    314 
    315             // place a null character at the end of the string
    316             // so we know what we've parsed so far.
    317 
    318             srchStr.erase(srchIndex);
    319             length = srchStr.length();
    320 
    321             // fix our searching flag
    322             alphaSearch = 0;
    323 
    324         }
    325         else if( srchStr[srchIndex] == '/' ) {
    326             // have to go back to all of the objects created and
    327             // multiply their exponents by -1.
    328 
    329             if (newRpUnit) {
    330                 unit* p = newRpUnit->head;
    331                 while (p) {
    332                     oldExponent = p->getExponent();
    333                     newExponent = oldExponent*-1;
    334                     p->newExponent(newExponent);
    335                     p = p->next;
    336                 }
    337             }
    338 
    339             // place a null character at the end of the string
    340             // so we know what we've parsed so far.
    341 
    342             srchStr.erase(srchIndex);
    343             length = srchStr.length();
    344 
    345         }
    346         else {
    347             continue;
    348         }
    349 
    350 
    351     } // end while loop
    352 
    353 
    354     // complete the last iteration
    355     if (srchIndex < 0) {
    356 
    357 
    358         if (digiSearch) {
    359             // convert whatever is left
    360             exp = atoi(&srchStr[srchIndex+1]);
    361 
    362             // if we get here, that means units name starts with a digit
    363             // normally we wont get here, but if we do, should we place
    364             // the unit into the dictionary? i think not since digits are
    365             // always considered exponents.
    366         }
    367         else if (alphaSearch) {
    368             // adjust the exponent if none was provided
    369             if (exp == 0) {
    370                 exp = 1;
    371             }
    372 
    373             // compare unit string to see if it is a recognized system
    374 
    375             std::string cmpStr = srchStr.substr(srchIndex+1,length-srchIndex-1);
    376             cmpIndex = 0;
    377 
    378             if ( (cmpIndex = pre_compare(cmpStr,basis)) < 0 ) {
    379                 // no matches in the compare function
    380 
    381                 // there are units we did not recognize,
    382 
    383                 // create a new unit with basis of null to show its a
    384                 // fundamental type
    385                 newRpUnit = new RpUnits(cmpStr, exp, basis);
    386 
    387                 // put the unit into the dictionary
    388                 //
    389                 newRpUnit->insert(newRpUnit->getUnitsName());
    390 
    391 
    392             }
    393             else {
    394 
    395                 // the compare function was successful
    396                 // move the search pointer to one value infront of
    397                 // where the units were found.
    398                 // adjusting the search pointer to point to the units
    399                 std::string newUnitText = srchStr.substr(cmpIndex,length-cmpIndex);
    400 
    401                 // call the function to create the unit object
    402 
    403                 // we need pre-compare to return the basis of what it found.
    404                 if (newRpUnit) {
    405                      newRpUnit->addUnit( newUnitText, exp, basis );
    406                 }
    407                 else {
    408                      newRpUnit = new RpUnits(newUnitText, exp, basis);
    409                 }
    410 
    411                 // creating unit
    412                 //
    413                 // putting unit into dictionary
    414                 newRpUnit->insert(newRpUnit->getUnitsName());
    415             }
    416 
    417         }
    418     }
    419 
    420     // place the new object into the dictionary
    421 
    422     // return a copy of the new object to user
    423     return newRpUnit;
    424 }
     140        inStr.erase(0,1);
     141    }
     142
     143    return unit;
     144}
     145
    425146
    426147
     
    445166    conversion* conv2 = NULL;
    446167
    447     conv1 = new conversion (from,to,convForwFxnPtr,convBackFxnPtr);
    448     conv2 = new conversion (from,to,convForwFxnPtr,convBackFxnPtr);
    449 
    450     from->connectConversion(conv1);
    451     to->connectConversion(conv2);
     168    if (from && to) {
     169
     170        conv1 = new conversion (from,to,convForwFxnPtr,convBackFxnPtr);
     171        conv2 = new conversion (from,to,convForwFxnPtr,convBackFxnPtr);
     172
     173        from->connectConversion(conv1);
     174        to->connectConversion(conv2);
     175    }
    452176
    453177    return NULL;
     
    461185
    462186    // this is kinda the wrong way to get the job done...
    463     // how do we only create 1 conversion object and share it between atleast two RpUnits
    464     // objs so that when the RpUnits objs are deleted, we are not trying to delete already
    465     // deleted memory.
     187    // how do we only create 1 conversion object and share it between
     188    // atleast two RpUnits objs so that when the RpUnits objs are
     189    // deleted, we are not trying to delete already deleted memory.
    466190    // so for the sake of safety we get the following few lines of code.
    467191
     
    469193    conversion* conv2 = NULL;
    470194
    471     conv1 = new conversion (from,to,convForwFxnPtr,convBackFxnPtr);
    472     conv2 = new conversion (from,to,convForwFxnPtr,convBackFxnPtr);
    473 
    474     from->connectConversion(conv1);
    475     to->connectConversion(conv2);
     195    if (from && to) {
     196        conv1 = new conversion (from,to,convForwFxnPtr,convBackFxnPtr);
     197        conv2 = new conversion (from,to,convForwFxnPtr,convBackFxnPtr);
     198
     199        from->connectConversion(conv1);
     200        to->connectConversion(conv2);
     201    }
    476202
    477203    return NULL;
     
    487213
    488214    // this is kinda the wrong way to get the job done...
    489     // how do we only create 1 conversion object and share it between atleast two RpUnits
    490     // objs so that when the RpUnits objs are deleted, we are not trying to delete already
    491     // deleted memory.
     215    // how do we only create 1 conversion object and share it between at
     216    // least two RpUnits objs so that when the RpUnits objs are deleted,
     217    // we are not trying to delete already deleted memory.
    492218    // so for the sake of safety we get the following few lines of code.
    493219
     
    495221    conversion* conv2 = NULL;
    496222
    497     conv1 = new conversion (from,to,convForwFxnPtr,convForwData,convBackFxnPtr,convBackData);
    498     conv2 = new conversion (from,to,convForwFxnPtr,convForwData,convBackFxnPtr,convBackData);
    499 
    500     from->connectConversion(conv1);
    501     to->connectConversion(conv2);
     223    if (from && to) {
     224        conv1 = new conversion ( from, to, convForwFxnPtr,convForwData,
     225                                 convBackFxnPtr,convBackData);
     226        conv2 = new conversion ( from,to,convForwFxnPtr,convForwData,
     227                                 convBackFxnPtr,convBackData);
     228
     229        from->connectConversion(conv1);
     230        to->connectConversion(conv2);
     231    }
    502232
    503233    return NULL;
     
    520250RpUnits::getUnits() const {
    521251
    522     std::stringstream unitText;
    523     unit* p = head;
    524 
    525     while (p) {
    526         unitText << p->getUnits() ;
    527         p = p->next;
    528     }
    529 
    530     return (unitText.str());
     252    return units;
    531253}
    532254
     
    550272
    551273    std::stringstream unitText;
    552     unit* p = head;
    553274    double exponent;
    554275
    555     while (p) {
    556 
    557         exponent = p->getExponent();
    558 
    559         if (exponent == 1) {
    560             unitText << p->getUnits();
    561         }
    562         else {
    563             unitText << p->getUnits() << p->getExponent();
    564         }
    565 
    566         p = p->next;
    567     }
    568 
    569     return (unitText.str());
     276    exponent = getExponent();
     277
     278    if (exponent == 1) {
     279        unitText << units;
     280    }
     281    else {
     282        unitText << units << exponent;
     283    }
     284
     285    return (std::string(unitText.str()));
    570286}
    571287
     
    587303RpUnits::getExponent() const {
    588304
    589     return head->getExponent();
     305    return exponent;
    590306}
    591307
     
    606322RpUnits::getBasis() const {
    607323
    608     // check if head exists?
    609     if (!head) {
    610         // raise error for badly formed Rappture Units object
    611     }
    612 
    613     return head->getBasis();
     324    return basis;
    614325}
    615326
     
    627338RpUnits::makeBasis(double value, int* result) const {
    628339
    629     const RpUnits* basis = getBasis();
    630340    double retVal = value;
    631341
     
    637347        // this unit is a basis
    638348        // do nothing
    639 
    640         // if (result) {
    641         //     *result = 1;
    642         // }
    643349    }
    644350    else {
     
    651357const RpUnits&
    652358RpUnits::makeBasis(double* value, int* result) const {
    653     const RpUnits* basis = getBasis();
    654359    double retVal = *value;
    655360    int convResult = 1;
     
    658363        // this unit is a basis
    659364        // do nothing
    660 
    661         // if (result) {
    662         //     *result = 1;
    663         // }
    664365    }
    665366    else {
     
    687388
    688389int
    689 RpUnits::makeMetric(const RpUnits * basis) {
     390RpUnits::makeMetric(const RpUnits* basis) {
    690391
    691392    if (!basis) {
     
    695396    std::string basisName = basis->getUnitsName();
    696397    std::string name;
    697     std::string forw, back;
    698398
    699399    name = "c" + basisName;
     
    752452RpUnits::find(std::string key) {
    753453
    754     // dict.find seems to return a (RpUnits* const) so i had to
    755     // cast it as a (RpUnits*)
    756 
    757454    // dict pointer
    758     const RpUnits* unitEntry = *(dict->find(key).getValue());
     455    const RpUnits* unitEntry = NULL;
     456    double exponent = 1;
     457    int idx = 0;
     458    std::stringstream tmpKey;
     459
     460    if (key[0] == '/') {
     461        // check to see if there is an exponent at the end
     462        // of the search string
     463        idx = RpUnits::grabExponent(key, &exponent);
     464        tmpKey << key.substr(1,idx-1) << (-1*exponent);
     465        key = tmpKey.str();
     466    }
     467
     468    unitEntry = *(dict->find(key).getValue());
    759469
    760470    // dict pointer
     
    766476}
    767477
     478int
     479RpUnits::negateListExponents(RpUnitsList& unitsList) {
     480    RpUnitsListIter iter = unitsList.begin();
     481    int nodeCnt = unitsList.size();
     482
     483    if (nodeCnt > 0) {
     484        for (; iter != unitsList.end(); iter++) {
     485            iter->negateExponent();
     486            nodeCnt--;
     487        }
     488    }
     489
     490    return nodeCnt;
     491}
     492
     493// negate the exponent
     494void
     495RpUnitsListEntry::negateExponent() const {
     496    exponent = exponent * -1;
     497    return;
     498}
     499
     500// provide the caller with the name of this object
     501std::string
     502RpUnitsListEntry::name() const {
     503    std::stringstream name;
     504    name << unit->getUnits() << exponent;
     505    return std::string(name.str());
     506}
     507
     508// provide the caller with the basis of the RpUnits object being stored
     509const RpUnits*
     510RpUnitsListEntry::getBasis() const {
     511    return unit->getBasis();
     512}
     513
     514// get the RpUnits*
     515const RpUnits*
     516RpUnitsListEntry::getUnitsObj() const {
     517    return unit;
     518}
     519
     520// get the RpUnits*
     521double
     522RpUnitsListEntry::getExponent() const {
     523    return exponent;
     524}
     525
     526int
     527RpUnits::printList(RpUnitsList& unitsList) {
     528    RpUnitsListIter iter = unitsList.begin();
     529    int nodeCnt = unitsList.size();
     530
     531    if (nodeCnt > 0) {
     532        for (; iter != unitsList.end(); iter++) {
     533            std::cout << iter->name() << " ";
     534            nodeCnt--;
     535        }
     536        std::cout << std::endl;
     537    }
     538
     539    return nodeCnt;
     540}
     541
     542int
     543RpUnits::units2list ( const std::string& inUnits,
     544                      RpUnitsList& outList ) {
     545
     546    std::string myInUnits   = inUnits;
     547    std::string sendUnitStr = "";
     548    double exponent         = 1;
     549    int offset              = 0;
     550    int idx                 = 0;
     551    int last                = 0;
     552    const RpUnits* unit     = NULL;
     553
     554
     555    while ( !myInUnits.empty() ) {
     556
     557        // check to see if we came across a '/' character
     558        last = myInUnits.length()-1;
     559        if (myInUnits[last] == '/') {
     560            myInUnits.erase(last);
     561            // multiply previous exponents by -1
     562            if ( ! outList.empty() ) {
     563                RpUnits::negateListExponents(outList);
     564            }
     565            continue;
     566        }
     567
     568        // get the exponent
     569        offset = RpUnits::grabExponent(myInUnits,&exponent);
     570        myInUnits.erase(offset);
     571        idx = offset - 1;
     572
     573        // grab the largest string we can find
     574        offset = RpUnits::grabUnitString(myInUnits);
     575        idx = offset;
     576
     577        // figure out if we have some defined units in that string
     578        sendUnitStr = myInUnits.substr(offset,std::string::npos);
     579        unit = grabUnits(sendUnitStr,&offset);
     580        if (unit) {
     581            // a unit was found
     582            // add this unit to the list
     583            // erase the found unit's name from our search string
     584            outList.push_front(RpUnitsListEntry(unit,exponent));
     585            myInUnits.erase(idx+offset);
     586        }
     587        else {
     588            // we came across a unit we did not recognize
     589            // raise error and delete character for now
     590            myInUnits.erase(last);
     591        }
     592
     593        // reset our vars
     594        idx = 0;
     595        offset = 0;
     596        exponent = 1;
     597    }
     598
     599    return 0;
     600}
     601
     602int RpUnits::compareListEntryBasis ( RpUnitsList& fromList,
     603                                     RpUnitsListIter& fromIter,
     604                                     RpUnitsListIter& toIter ) {
     605
     606    const RpUnits* toBasis = NULL;
     607    const RpUnits* fromBasis = NULL;
     608    int retVal = 1;
     609    double fromExp = 0;
     610    double toExp = 0;
     611
     612    fromIter = fromList.begin();
     613
     614    // get the basis of the object being stored
     615    // if the basis is NULL, then we'll compare the object
     616    // itself because the object is the basis.
     617    toBasis = toIter->getBasis();
     618    if (toBasis == NULL) {
     619        toBasis = toIter->getUnitsObj();
     620    }
     621
     622    toExp   = toIter->getExponent();
     623
     624    while ( fromIter != fromList.end() ) {
     625
     626        fromExp = fromIter->getExponent();
     627
     628        // in order to convert, exponents must be equal.
     629        if (fromExp == toExp) {
     630
     631            // get the basis of the object being stored
     632            // if the basis is NULL, then we'll compare the object
     633            // itself because the object is the basis.
     634            fromBasis = fromIter->getBasis();
     635            if (fromBasis == NULL) {
     636                fromBasis = fromIter->getUnitsObj();
     637            }
     638
     639            if (toBasis == fromBasis) {
     640                // conversion needed between 2 units of the same basis.
     641                // these two units could actually be the same unit (m->m)
     642                retVal = 0;
     643                break;
     644            }
     645        }
     646
     647        fromIter++;
     648    }
     649
     650    return retVal;
     651}
     652
     653int RpUnits::compareListEntrySearch ( RpUnitsList& fromList,
     654                                     RpUnitsListIter& fromIter,
     655                                     RpUnitsListIter& toIter ) {
     656
     657    const RpUnits* toBasis = NULL;
     658    const RpUnits* fromBasis = NULL;
     659    int retVal = 1;
     660
     661    fromIter = fromList.begin();
     662
     663    // get the basis of the object being stored
     664    // if the basis is NULL, then we'll compare the object
     665    // itself because the object is the basis.
     666    toBasis = toIter->getBasis();
     667    if (toBasis == NULL) {
     668        toBasis = toIter->getUnitsObj();
     669    }
     670
     671    while ( fromIter != fromList.end() ) {
     672
     673        // get the basis of the object being stored
     674        // if the basis is NULL, then we'll compare the object
     675        // itself because the object is the basis.
     676        fromBasis = fromIter->getBasis();
     677        if (fromBasis == NULL) {
     678            fromBasis = fromIter->getUnitsObj();
     679        }
     680
     681        if (toBasis == fromBasis) {
     682            // conversion needed between 2 units of the same basis.
     683            // these two units could actually be the same unit (m->m)
     684            retVal = 0;
     685            break;
     686        }
     687
     688        fromIter++;
     689    }
     690
     691    return retVal;
     692}
    768693
    769694// convert function so people can just send in two strings and
     
    776701                    int* result ) {
    777702
     703    RpUnitsList toUnitsList;
     704    RpUnitsList fromUnitsList;
     705
     706    RpUnitsListIter toIter;
     707    RpUnitsListIter fromIter;
     708    RpUnitsListIter tempIter;
     709
    778710    const RpUnits* toUnits = NULL;
    779711    const RpUnits* fromUnits = NULL;
     712
    780713    std::string tmpNumVal = "";
    781714    std::string fromUnitsName = "";
    782715    std::string convVal = "";
     716    double origNumVal = 0;
    783717    double numVal = 0;
    784     // int idx = 0;
     718    double toExp = 0;
     719    double fromExp = 0;
    785720    int convResult = 0;
    786721    char* endptr = NULL;
    787722    std::stringstream outVal;
    788723
     724    int rv = 0;
     725    double factor = 1;
     726
    789727
    790728    // set  default result flag/error code
    791729    if (result) {
    792730        *result = 0;
    793     }
    794 
    795     toUnits = find(toUnitsName);
    796 
    797     // did we find the unit in the dictionary?
    798     if (toUnits == NULL) {
    799         // toUnitsName was not found in the dictionary
    800         if (result) {
    801             *result = 1;
    802         }
    803         return val;
    804731    }
    805732
     
    813740
    814741    numVal = strtod(val.c_str(),&endptr);
     742    origNumVal = numVal;
    815743
    816744    if ( (numVal == 0) && (endptr == val.c_str()) ) {
     
    839767        }
    840768
    841         return outVal.str();
     769        return std::string(outVal.str());
     770    }
     771
     772    RpUnits::units2list(toUnitsName,toUnitsList);
     773    RpUnits::units2list(fromUnitsName,fromUnitsList);
     774
     775    // std::cout << "toUnitsList = ";
     776    // RpUnits::printList(toUnitsList);
     777    // std::cout << "fromUnitsList = ";
     778    // RpUnits::printList(fromUnitsList);
     779
     780    toIter = toUnitsList.begin();
     781
     782    // pass 1: compare basis' of objects to find intra-basis conversions
     783    while ( toIter != toUnitsList.end() ) {
     784        rv = RpUnits::compareListEntryBasis(fromUnitsList, fromIter, toIter);
     785        if (rv == 0) {
     786
     787            // check the names of the units provided by the user
     788            // if the names are the same, no need to do a conversion
     789            if (fromIter->name() != toIter->name()) {
     790
     791                // do an intra-basis conversion
     792                toUnits = toIter->getUnitsObj();
     793                fromUnits = fromIter->getUnitsObj();
     794
     795                // do conversions
     796                factor = 1;
     797                factor = fromUnits->convert(toUnits, factor, &convResult);
     798                numVal *= pow(factor,toIter->getExponent());
     799            }
     800
     801            // remove the elements from the lists
     802            tempIter = toIter;
     803            toUnitsList.erase(tempIter);
     804            toIter++;
     805
     806            tempIter = fromIter;
     807            fromUnitsList.erase(tempIter);
     808        }
     809        else {
     810            // this is not an intra-basis conversion.
     811            // move onto the next toIter
     812            toIter++;
     813        }
     814    }
     815
     816    toIter = toUnitsList.begin();
     817    fromIter = fromUnitsList.begin();
     818
     819    // pass 2: look for inter-basis conversions
     820    if (fromIter != fromUnitsList.end()) {
     821        // double while loop to compare each toIter with each fromIter.
     822        // the outter while checks the toIter and the inner while
     823        // which is conveniently hidden, adjusts the fromIter and toIter
     824        // (at the bottom in the else statement).
     825        while (toIter != toUnitsList.end()) {
     826
     827            toUnits = toIter->getUnitsObj();
     828            fromUnits = fromIter->getUnitsObj();
     829
     830            // do an inter-basis conversion...the slow way
     831            // there has to be a better way to do this...
     832            convResult = 1;
     833
     834            // in order to convert, exponents must be equal.
     835            fromExp = fromIter->getExponent();
     836            toExp   = toIter->getExponent();
     837
     838            if (fromExp == toExp) {
     839                if (toExp == 1) {
     840                    numVal = fromUnits->convert(toUnits, numVal, &convResult);
     841                }
     842                else {
     843                    factor = 1;
     844                    factor = fromUnits->convert(toUnits, factor, &convResult);
     845                    numVal *= pow(factor,toExp);
     846                }
     847            }
     848
     849            if (convResult == 0) {
     850                // successful conversion reported
     851                // remove the elements from the lists
     852                tempIter = toIter;
     853                toUnitsList.erase(tempIter);
     854                toIter++;
     855
     856                tempIter = fromIter;
     857                fromUnitsList.erase(tempIter);
     858
     859                // conversion complete, jump out of the
     860                // while loop
     861                break;
     862            }
     863            else {
     864                // conversion was unsuccessful
     865                // move onto the next fromIter
     866                fromIter++;
     867                if (fromIter == fromUnitsList.end()) {
     868                    // this is not an inter-basis conversion.
     869                    // move onto the next toIter
     870                    fromIter = fromUnitsList.begin();
     871                    toIter++;
     872                }
     873            } // end unsuccessful conversion
     874        } // end toIter while loop
     875    } // end
     876
     877
     878
     879    if ( (result) && (*result == 0) ) {
     880        *result = convResult;
     881    }
     882
     883    if (showUnits) {
     884        outVal << numVal << toUnitsName;
     885    }
     886    else {
     887        outVal << numVal;
     888    }
     889
     890    return std::string(outVal.str());
     891
     892}
     893
     894/*
     895 * this code will be removed after dsk does some more testing
     896 *
     897// convert function so people can just send in two strings and
     898// we'll see if the units exists and do a conversion
     899// strVal = RpUnits::convert("300K","C",1);
     900std::string
     901RpUnits::convert (  std::string val,
     902                    std::string toUnitsName,
     903                    int showUnits,
     904                    int* result ) {
     905
     906    RpUnitsList toUnitsList;
     907    RpUnitsList fromUnitsList;
     908
     909    const RpUnits* toUnits = NULL;
     910    const RpUnits* fromUnits = NULL;
     911
     912    std::string tmpNumVal = "";
     913    std::string fromUnitsName = "";
     914    std::string convVal = "";
     915    double numVal = 0;
     916    int convResult = 0;
     917    char* endptr = NULL;
     918    std::stringstream outVal;
     919
     920
     921    // set  default result flag/error code
     922    if (result) {
     923        *result = 0;
     924    }
     925
     926    toUnits = find(toUnitsName);
     927
     928    // did we find the unit in the dictionary?
     929    if (toUnits == NULL) {
     930        // toUnitsName was not found in the dictionary
     931        if (result) {
     932            *result = 1;
     933        }
     934        return val;
     935    }
     936
     937    // search our string to see where the numeric part stops
     938    // and the units part starts
     939    //
     940    //  convert("5J", "neV") => 3.12075e+28neV
     941    //  convert("3.12075e+28neV", "J") => 4.99999J
     942    // now we can actually get the scientific notation portion of the string.
     943    //
     944
     945    numVal = strtod(val.c_str(),&endptr);
     946
     947    if ( (numVal == 0) && (endptr == val.c_str()) ) {
     948        // no conversion was done.
     949        // number in incorrect format probably.
     950        if (result) {
     951            *result = 1;
     952        }
     953        return val;
     954    }
     955
     956    fromUnitsName = std::string(endptr);
     957    if ( fromUnitsName.empty() )  {
     958        // there were no units in the input string
     959        // assume fromUnitsName = toUnitsName
     960        // return the correct value
     961        if (result) {
     962            *result = 0;
     963        }
     964
     965        if (showUnits) {
     966            outVal << val << toUnitsName;
     967        }
     968        else {
     969            outVal << val;
     970        }
     971
     972        return std::string(outVal.str());
    842973    }
    843974
     
    862993
    863994}
     995*/
    864996
    865997std::string
     
    8801012    }
    8811013
    882     return (unitText.str());
     1014    return (std::string(unitText.str()));
    8831015
    8841016}
     
    8961028
    8971029    double value = val;
    898     const RpUnits* basis = this->getBasis();
    8991030    const RpUnits* toBasis = toUnit->getBasis();
    9001031    const RpUnits* fromUnit = this;
     
    9051036    // set *result to a default value
    9061037    if (result) {
    907         *result = 0;
     1038        *result = 1;
    9081039    }
    9091040
     
    10001131            }
    10011132
    1002             // we can probably remove this
    1003             if (result) {
    1004                 *result += 0;
     1133            // change the result code to zero, a conversion was performed
     1134            // (we think)... its ture that it is possible to get to this
     1135            // point and have skipped the conversion because the
     1136            // conversion object was not properly created...
     1137            // ie. both fxn ptrs were null or neither fxn ptr was null
     1138            //
     1139            if (result && (*result == 1)) {
     1140                *result = 0;
    10051141            }
    10061142            break;
     
    10431179            }
    10441180
    1045             // we can probably remove this
    1046             if (result) {
    1047                 *result += 0;
     1181            // change the result code to zero, a conversion was performed
     1182            // (we think)... its ture that it is possible to get to this
     1183            // point and have skipped the conversion because the
     1184            // conversion object was not properly created...
     1185            // ie. both fxn ptrs were null or neither fxn ptr was null
     1186            //
     1187            if (result && (*result == 1)) {
     1188                *result = 0;
    10481189            }
    10491190            break;
     
    10771218
    10781219    void* value = val;
    1079     const RpUnits* basis = this->getBasis();
    10801220    const RpUnits* toBasis = toUnit->getBasis();
    10811221    const RpUnits* fromUnit = this;
     
    10861226    // set *result to a default value
    10871227    if (result) {
    1088         *result = 0;
     1228        *result = 1;
    10891229    }
    10901230
     
    11661306            }
    11671307
    1168             // we can probably remove this
    1169             if (result) {
     1308            // change the result code to zero, a conversion was performed
     1309            // (we think)... its ture that it is possible to get to this
     1310            // point and have skipped the conversion because the
     1311            // conversion object was not properly created...
     1312            // ie. both fxn ptrs were null or neither fxn ptr was null
     1313            //
     1314            if (result && (*result == 1)) {
    11701315                *result = 0;
    11711316            }
     
    11941339            }
    11951340
    1196             // we can probably remove this
    1197             if (result) {
     1341            // change the result code to zero, a conversion was performed
     1342            // (we think)... its ture that it is possible to get to this
     1343            // point and have skipped the conversion because the
     1344            // conversion object was not properly created...
     1345            // ie. both fxn ptrs were null or neither fxn ptr was null
     1346            //
     1347            if (result && (*result == 1)) {
    11981348                *result = 0;
    11991349            }
     
    12201370}
    12211371
    1222 void
    1223 RpUnits::addUnit( const std::string& units,
    1224                   double&  exponent,
    1225                   const RpUnits* basis) {
    1226 
    1227     unit* p = NULL;
    1228 
    1229     // check if the list was created previously. if not, start the list
    1230     if (head == 0) {
    1231         head = new unit(units,exponent,basis,NULL,NULL);
    1232         return;
    1233     }
    1234 
    1235     // now add a new node at the beginning of the list:
    1236     p = new unit(units,exponent,basis,NULL,head);
    1237     head->prev = p;
    1238     head = p;
    1239 
    1240 }
    1241 
    12421372int
    1243 RpUnits::insert(std::string key) {
     1373// RpUnits::insert(std::string key,RpUnits* val) {
     1374insert(std::string key,RpUnits* val) {
    12441375
    12451376    int newRecord = 0;
    1246     RpUnits* val = this;
     1377    // RpUnits* val = this;
    12471378    // dict pointer
    12481379    RpUnits::dict->set(key,val,&newRecord);
    12491380    return newRecord;
    12501381}
    1251 
    1252 
    1253 int
    1254 RpUnits::pre_compare( std::string& units, const RpUnits* basis ) {
    1255 
    1256     // compare the incomming units with the previously defined units.
    1257     // compareStr will hold a copy of the incomming string.
    1258     // first look for the units as they are listed in the incomming variable
    1259     // next look move searchStr toward the end of the string,
    1260     // each time the pointer is moved, searchStr should be compared to all of
    1261     // the previously defined units.
    1262     // if searchStr is at the end of the string, then searchStr will be moved
    1263     // back to the beginning of the string.
    1264     // next it will traverse the string again, changing the case of the char
    1265     // it points to and the resultant string will be compared again to all
    1266     // of the previously defined units.
    1267 
    1268     int compareSuccess = 0;
    1269     // std::string::size_type units_len = units.length();
    1270     // char * retVal = NULL;
    1271     int retIndex = std::string::npos;
    1272     // std::string compareStr = units;
    1273     std::string searchStr = units;
    1274     std::string dbText = "";
    1275 
    1276     // pass 1: look for exact match of units as they came into the function
    1277     //          move searchStr pointer through string to find match.
    1278     while ( ! compareSuccess &&
    1279             (searchStr.length() > 0) ) {
    1280 
    1281         // dict pointer
    1282         if (dict->find(searchStr) == dict->getNullEntry()) {
    1283             // the string was not found,
    1284             // keep incrementing the pointer
    1285             // searchStr (pass1)  does not match";
    1286         }
    1287         else {
    1288             // compare was successful,
    1289             // searchStr (pass1)  found a match
    1290             compareSuccess++;
    1291             break;
    1292             // is it possible to create the unit here and
    1293             // keep looking for units fro mthe provided string?
    1294         }
    1295 
    1296         searchStr.erase(0,1);
    1297 
    1298         if (basis) {
    1299             if ( (searchStr == basis->getUnits()) &&
    1300                  (searchStr.length() == basis->getUnits().length()) )
    1301             {
    1302                 break;
    1303             }
    1304         }
    1305     }
    1306 
    1307 
    1308     if (compareSuccess == 0) {
    1309         // refresh our searchStr var.
    1310         searchStr = units;
    1311     }
    1312 
    1313     // pass 2: capitolize the first letter of the search string and compare
    1314     //          for each letter in the string
    1315     while ( ! compareSuccess &&
    1316             (searchStr.length() > 0) ) {
    1317 
    1318         if (islower((int)(searchStr[0]))) {
    1319             searchStr[0] = (char) toupper((int)(searchStr[0]));
    1320         }
    1321 
    1322         // dict pointer
    1323         if (dict->find(searchStr) == dict->getNullEntry()) {
    1324             // the string was not found,
    1325             // keep incrementing the pointer
    1326             // searchStr (pass2)  does not match
    1327         }
    1328         else {
    1329             // compare was successful,
    1330             // searchStr (pass2)  found a match
    1331             compareSuccess++;
    1332             break;
    1333         }
    1334         searchStr.erase(0,1);
    1335 
    1336         // check to see if we are at the basis.
    1337         if (basis) {
    1338             if ( (searchStr == basis->getUnits()) &&
    1339                  (searchStr.length() == basis->getUnits().length()) )
    1340             {
    1341                 break;
    1342             }
    1343 
    1344         }
    1345 
    1346     }
    1347 
    1348 
    1349 
    1350     // if we found a match, find the first occurance of the string which
    1351     // was used to get the match, in our original units string.
    1352     // this gets dicey for capitolizations.
    1353     if ( compareSuccess ) {
    1354         // need to think about if we want to search from the start
    1355         // or the end of the string (find or rfind)
    1356         // i think its the start because in this fxn (above)
    1357         // we start at the beginning of the string and work
    1358         // our way to the end. so if there is a second match at the
    1359         // end, we would have only seen the first match.
    1360         retIndex = units.find(searchStr);
    1361     }
    1362 
    1363     return retIndex;
    1364 
    1365 }
    1366 
    13671382
    13681383void
     
    13891404    int retVal = -1;
    13901405    if (group.compare("all") == 0) {
    1391         retVal = addPresetAll();
     1406        retVal = RpUnitsPreset::addPresetAll();
    13921407    }
    13931408    else if (group.compare("energy") == 0) {
    1394         retVal = addPresetEnergy();
     1409        retVal = RpUnitsPreset::addPresetEnergy();
    13951410    }
    13961411    else if (group.compare("length") == 0) {
    1397         retVal = addPresetLength();
     1412        retVal = RpUnitsPreset::addPresetLength();
    13981413    }
    13991414    else if (group.compare("temp") == 0) {
    1400         retVal = addPresetTemp();
     1415        retVal = RpUnitsPreset::addPresetTemp();
    14011416    }
    14021417    else if (group.compare("time") == 0) {
    1403         retVal = addPresetTime();
     1418        retVal = RpUnitsPreset::addPresetTime();
    14041419    }
    14051420    else if (group.compare("volume") == 0) {
    1406         retVal = addPresetTime();
     1421        retVal = RpUnitsPreset::addPresetTime();
    14071422    }
    14081423
     
    14121427// return codes: 0 success, anything else is error
    14131428int
    1414 RpUnits::addPresetAll () {
     1429RpUnitsPreset::addPresetAll () {
    14151430
    14161431    int result = 0;
     
    14271442// return codes: 0 success, anything else is error
    14281443int
    1429 RpUnits::addPresetTime () {
     1444RpUnitsPreset::addPresetTime () {
    14301445
    14311446    RpUnits* seconds    = RpUnits::define("s", NULL);
     
    14401455// return codes: 0 success, anything else is error
    14411456int
    1442 RpUnits::addPresetTemp () {
     1457RpUnitsPreset::addPresetTemp () {
    14431458
    14441459    RpUnits* fahrenheit = RpUnits::define("F", NULL);
     
    14581473// return codes: 0 success, anything else is error
    14591474int
    1460 RpUnits::addPresetLength () {
     1475RpUnitsPreset::addPresetLength () {
    14611476
    14621477    RpUnits* meters     = RpUnits::define("m", NULL);
     
    14791494// return codes: 0 success, anything else is error
    14801495int
    1481 RpUnits::addPresetEnergy () {
     1496RpUnitsPreset::addPresetEnergy () {
    14821497
    14831498    RpUnits* volt       = RpUnits::define("V", NULL);
     
    14971512// return codes: 0 success, anything else is error
    14981513int
    1499 RpUnits::addPresetVolume () {
     1514RpUnitsPreset::addPresetVolume () {
    15001515
    15011516    RpUnits* cubic_meter  = RpUnits::define("m3", NULL);
     1517    // RpUnits* pcubic_meter  = RpUnits::define("/m3", NULL);
    15021518    RpUnits* cubic_feet   = RpUnits::define("ft3", NULL);
    15031519    RpUnits* us_gallon    = RpUnits::define("gal", NULL);
  • trunk/src/core/RpUnitsStd.cc

    r115 r116  
    1919
    2020
    21 double centi2base (double centi, double power)
    22 {
    23    return centi*pow(1e-2,power);
    24 }
    25 
    26 double milli2base (double milli, double power)
    27 {
    28     return milli*pow(1e-3,power);
    29 }
    30 
    31 double micro2base (double micro, double power)
    32 {
    33     return micro*pow(1e-6,power);
    34 }
    35 
    36 double nano2base (double nano, double power)
    37 {
    38     return nano*pow(1e-9,power);
    39 }
    40 
    41 double pico2base (double pico, double power)
    42 {
    43     return pico*pow(1e-12,power);
    44 }
    45 
    46 double femto2base (double femto, double power)
    47 {
    48     return femto*pow(1e-15,power);
    49 }
    50 
    51 double atto2base (double atto, double power)
    52 {
    53     return atto*pow(1e-18,power);
    54 }
    55 
    56 double kilo2base (double kilo, double power)
    57 {
    58     return kilo*pow(1e3,power);
    59 }
    60 
    61 double mega2base (double mega, double power)
    62 {
    63     return mega*pow(1e6,power);
    64 }
    65 
    66 double giga2base (double giga, double power)
    67 {
    68     return giga*pow(1e9,power);
    69 }
    70 
    71 double tera2base (double tera, double power)
    72 {
    73     return tera*pow(1e12,power);
    74 }
    75 
    76 double peta2base (double peta, double power)
    77 {
    78     return peta*pow(1e15,power);
    79 }
    80 
    81 double base2centi (double base, double power)
    82 {
    83     return base*pow(1e2,power);
    84 }
    85 
    86 double base2milli (double base, double power)
    87 {
    88     return base*pow(1e3,power);
    89 }
    90 
    91 double base2micro (double base, double power)
    92 {
    93     return base*pow(1e6,power);
    94 }
    95 
    96 double base2nano (double base, double power)
    97 {
    98     return base*pow(1e9,power);
    99 }
    100 
    101 double base2pico (double base, double power)
    102 {
    103     return base*pow(1e12,power);
    104 }
    105 
    106 double base2femto (double base, double power)
    107 {
    108     return base*pow(1e15,power);
    109 }
    110 
    111 double base2atto (double base, double power)
    112 {
    113     return base*pow(1e18,power);
    114 }
    115 
    116 double base2kilo (double base, double power)
    117 {
    118     return base*pow(1e-3,power);
    119 }
    120 
    121 double base2mega (double base, double power)
    122 {
    123     return base*pow(1e-6,power);
    124 }
    125 
    126 double base2giga (double base, double power)
    127 {
    128     return base*pow(1e-9,power);
    129 }
    130 
    131 double base2tera (double base, double power)
    132 {
    133     return base*pow(1e-12,power);
    134 }
    135 
    136 double base2peta (double base, double power)
    137 {
    138     return base*pow(1e-15,power);
     21double centi2base (double centi)
     22{
     23   return centi*1e-2;
     24}
     25
     26double milli2base (double milli)
     27{
     28    return milli*1e-3;
     29}
     30
     31double micro2base (double micro)
     32{
     33    return micro*1e-6;
     34}
     35
     36double nano2base (double nano)
     37{
     38    return nano*1e-9;
     39}
     40
     41double pico2base (double pico)
     42{
     43    return pico*1e-12;
     44}
     45
     46double femto2base (double femto)
     47{
     48    return femto*1e-15;
     49}
     50
     51double atto2base (double atto)
     52{
     53    return atto*1e-18;
     54}
     55
     56double kilo2base (double kilo)
     57{
     58    return kilo*1e3;
     59}
     60
     61double mega2base (double mega)
     62{
     63    return mega*1e6;
     64}
     65
     66double giga2base (double giga)
     67{
     68    return giga*1e9;
     69}
     70
     71double tera2base (double tera)
     72{
     73    return tera*1e12;
     74}
     75
     76double peta2base (double peta)
     77{
     78    return peta*1e15;
     79}
     80
     81double base2centi (double base)
     82{
     83    return base*1e2;
     84}
     85
     86double base2milli (double base)
     87{
     88    return base*1e3;
     89}
     90
     91double base2micro (double base)
     92{
     93    return base*1e6;
     94}
     95
     96double base2nano (double base)
     97{
     98    return base*1e9;
     99}
     100
     101double base2pico (double base)
     102{
     103    return base*1e12;
     104}
     105
     106double base2femto (double base)
     107{
     108    return base*1e15;
     109}
     110
     111double base2atto (double base)
     112{
     113    return base*1e18;
     114}
     115
     116double base2kilo (double base)
     117{
     118    return base*1e-3;
     119}
     120
     121double base2mega (double base)
     122{
     123    return base*1e-6;
     124}
     125
     126double base2giga (double base)
     127{
     128    return base*1e-9;
     129}
     130
     131double base2tera (double base)
     132{
     133    return base*1e-12;
     134}
     135
     136double base2peta (double base)
     137{
     138    return base*1e-15;
    139139}
    140140
     
    145145 ****************************************/
    146146
    147 double angstrom2meter (double angstrom, double power)
    148 {
    149         return angstrom*(pow(1.0e-10,power));
    150 }
    151 
    152 double meter2angstrom (double meters, double power)
    153 {
    154         return meters*(pow(1.0e10,power));
    155 }
    156 
    157 double meter2inch (double m, double power)
    158 {
    159         return (m*(pow(39.37008,power)));
    160 }
    161 
    162 double inch2meter (double in, double power)
    163 {
    164         return (in/(pow(39.37008,power)));
    165 }
    166 
    167 double meter2feet (double m, double power)
    168 {
    169         return (m*(pow(3.280840,power)));
    170 }
    171 
    172 double feet2meter (double ft, double power)
    173 {
    174         return (ft/(pow(3.280840,power)));
    175 }
    176 
    177 double meter2yard (double m, double power)
    178 {
    179         return (m*(pow(1.093613,power)));
    180 }
    181 
    182 double yard2meter (double yd, double power)
    183 {
    184         return (yd/(pow(1.093613,power)));
     147double angstrom2meter (double angstrom)
     148{
     149        return angstrom*(1.0e-10);
     150}
     151
     152double meter2angstrom (double meter)
     153{
     154        return meter*(1.0e10);
     155}
     156
     157double meter2inch (double meter)
     158{
     159        return meter*(39.37008);
     160}
     161
     162double inch2meter (double in)
     163{
     164        return (in/(39.37008));
     165}
     166
     167double meter2feet (double meter)
     168{
     169        return (meter*(3.280840));
     170}
     171
     172double feet2meter (double ft)
     173{
     174        return (ft/(3.280840));
     175}
     176
     177double meter2yard (double meter)
     178{
     179        return (meter*(1.093613));
     180}
     181
     182double yard2meter (double yd)
     183{
     184        return (yd/(1.093613));
    185185}
    186186
     
    247247 ****************************************/
    248248
    249 double cubicMeter2usGallon (double m3, double none)
     249double cubicMeter2usGallon (double m3)
    250250{
    251251        return (m3*264.1721);
    252252}
    253253
    254 double usGallon2cubicMeter (double g, double none)
    255 {
    256         return (g/264.1721);
    257 }
    258 
    259 double cubicFeet2usGallon (double ft3, double none)
     254double usGallon2cubicMeter (double gal)
     255{
     256        return (gal/264.1721);
     257}
     258
     259double cubicFeet2usGallon (double ft3)
    260260{
    261261        return (ft3*7.48051);
    262262}
    263263
    264 double usGallon2cubicFeet (double g, double none)
    265 {
    266         return (g/7.48051);
     264double usGallon2cubicFeet (double gal)
     265{
     266        return (gal/7.48051);
    267267}
    268268
  • trunk/src/python/PyRpUnits.cc

    r115 r116  
    473473    retStr = RpUnits::convert(fromVal_S,to_S,unitsVal,&result);
    474474
     475    std::cout << result << std::endl;
    475476    if ( (!retStr.empty()) && (result == 0) ) {
    476477        if (unitsVal) {
     
    555556
    556557    // add some standard units definitions and conversions.
    557 
    558     RpUnits::addPresets("all");
    559 }
     558    // RpUnits::addPresets("all");
     559}
  • trunk/test/src/RpUnitsF_test.f

    r115 r116  
    3030        print *,"72F = ",dblVal, " (no units)"
    3131        print *,"retVal = ",retVal
    32        
     32
    3333      end program units_test
    3434
  • trunk/test/src/RpUnits_test.cc

    r115 r116  
    4141    //
    4242    printf ("=============== TEST 1 ===============\n");
    43     const RpUnits * meters = RpUnits::define("m", NULL);
    44     // (meters) ? success() : fail();
    45     // RpUnits * centimeter = RpUnits::define("cm", NULL);
    46 
    47     RpUnits::makeMetric(meters);
    48     RpUnits::define("V", NULL);
    49     RpUnits::define("s", NULL);
    50 
    5143/*
    5244    std::string srch_str = std::string("cm");
     
    6153
    6254*/
    63    
     55
     56/*
    6457    const RpUnits* mobility = RpUnits::defineCmplx("cm2/Vs", NULL);
    6558    std::cout << "mobility = :" << mobility->getUnitsName() <<":"<< std::endl;
     
    7467        std::cout << "mobility2 dn exists" << std::endl;
    7568    }
    76 
     69*/
     70
     71    const RpUnits* meters = RpUnits::find("m");
    7772    const RpUnits* cmeters = RpUnits::find("cm");
    78     const RpUnits* angstrom = RpUnits::define("A", NULL);
    79     RpUnits::define(angstrom, meters, angstrom2meter, meter2angstrom);
     73    const RpUnits* angstrom = RpUnits::find("A");
    8074
    8175    value = angstrom->convert(meters,1.0,&result);
    8276    std::cout << "1 angstrom = " << value << " meters" << std::endl;
     77    std::cout << "result = " << result << std::endl;
    8378
    8479    result = 0;
     
    8782
    8883
    89     const RpUnits* fahrenheit  = RpUnits::define("F", NULL);
    90     const RpUnits* celcius  = RpUnits::define("C", NULL);
    91     const RpUnits* kelvin  = RpUnits::define("K", NULL);
    92    
    93     RpUnits::define(fahrenheit, celcius, fahrenheit2centigrade, centigrade2fahrenheit);
    94     RpUnits::define(celcius, kelvin, centigrade2kelvin, kelvin2centigrade);
    95    
     84    const RpUnits* fahrenheit  = RpUnits::find("F");
     85    const RpUnits* celcius  = RpUnits::find("C");
     86    const RpUnits* kelvin  = RpUnits::find("K");
     87
    9688    value = fahrenheit->convert(celcius,72,&result);
    9789    std::cout << "72 degrees fahrenheit = " << value << " degrees celcius" << std::endl;
    98    
     90
    9991    value = celcius->convert(fahrenheit,value,&result);
    10092    std::cout << "22.222 degrees celcius = " << value << " degrees fahrenheit" << std::endl;
    101    
     93
    10294    value = celcius->convert(kelvin,20,&result);
    10395    std::cout << "20 degrees celcius = " << value << " kelvin" << std::endl;
     
    264256
    265257
    266     const RpUnits* eV  = RpUnits::define("eV", NULL);
    267     const RpUnits* joules  = RpUnits::define("J", NULL);
    268 
    269     RpUnits::define(eV, joules, electronVolt2joule, joule2electronVolt);
     258    const RpUnits* eV  = RpUnits::find("eV");
     259    const RpUnits* joules  = RpUnits::find("J");
    270260
    271261    value = joules->convert(eV,1,&result);
     
    323313    delete testRpUnits;
    324314    std::cout << "copyRpUnits = " << copyRpUnits.getUnitsName() << std::endl;
     315
     316
     317    // test deleting a const object
     318
     319    const RpUnits* myobj = RpUnits::define("myunit",NULL);
     320    delete myobj;
     321
     322    // test /cm2
     323    // std::cout << "convert (3m3 -> cm3)     = " << RpUnits::convert("3m3","cm3",0) << std::endl;
     324    // std::cout << "convert (3/m3 -> /cm3)   = " << RpUnits::convert("3/m3","/cm3",0) << std::endl;
     325    // std::cout << "convert (300cm3 -> m3)   = " << RpUnits::convert("300cm3","m3",0) << std::endl;
     326    // std::cout << "convert (300/cm3 -> /m3) = " << RpUnits::convert("300/cm3","/m3",0) << std::endl;
     327
     328    std::cout << "convert (3m3 -> cm3)     = " << RpUnits::convert("3m3","cm3",0) << std::endl;
     329    std::cout << "convert (3/m3 -> /cm3)   = " << RpUnits::convert("3/m3","/cm3",0) << std::endl;
     330    std::cout << "convert (300cm3 -> m3)   = " << RpUnits::convert("300cm3","m3",0) << std::endl;
     331    std::cout << "convert (300/cm3 -> /m3) = " << RpUnits::convert("300/cm3","/m3",0) << std::endl;
     332    std::cout << "convert (72F -> 22.22C) = " << RpUnits::convert("72F","C",0) << std::endl;
     333    std::cout << "convert (5J -> 3.12075e+28neV) = " << RpUnits::convert("5J","neV",0) << std::endl;
     334    std::cout << "convert (5J2 -> 1.9478e+56neV2) = " << RpUnits::convert("5J2","neV2",0) << std::endl;
     335
     336    // testing complex units
     337    std::cout << "convert (1cm2/Vs -> 0.0001m2/Vs) = " << RpUnits::convert("1cm2/Vs","m2/Vs",0) << std::endl;
     338    std::cout << "convert (1cm2/Vs -> 0.1m2/kVs) = " << RpUnits::convert("1cm2/Vs","m2/kVs",0) << std::endl;
     339    std::cout << "convert (1cm2/Vs -> 1e-7m2/kVus) = " << RpUnits::convert("1cm2/Vs","m2/kVus",0) << std::endl;
     340
    325341    return 0;
     342
    326343}
Note: See TracChangeset for help on using the changeset viewer.