source: tags/1.1-pre/src/core/RpUnits.h @ 4643

Last change on this file since 4643 was 709, checked in by dkearney, 17 years ago

added newton, amu as units.
clarified system names for hz, bq, mol

  • Property svn:executable set to *
File size: 27.3 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  RpUnits.h - Header file for Rappture Units
4 *
5 *   RpUnits Class Declaration / Definition
6 *
7 * ======================================================================
8 *  AUTHOR:  Derrick Kearney, Purdue University
9 *  Copyright (c) 2004-2007  Purdue Research Foundation
10 *
11 *  See the file "license.terms" for information on usage and
12 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * ======================================================================
14 */
15
16#ifndef _RpUNITS_H
17#define _RpUNITS_H
18
19enum RP_UNITS_CONSTS {
20    RPUNITS_UNITS_OFF           = 0,
21    RPUNITS_UNITS_ON            = 1,
22
23    // units naming flags
24    RPUNITS_POS_EXP             = 1,
25    RPUNITS_NEG_EXP             = 2,
26    RPUNITS_STRICT_NAME         = 4,
27    RPUNITS_ORIG_EXP            = 7
28};
29
30// RpUnits Case Insensitivity define
31#define RPUNITS_CASE_INSENSITIVE true
32
33#define RPUNITS_METRIC          true
34
35//define our different types of units
36#define RP_TYPE_ENERGY      "energy"
37#define RP_TYPE_EPOT        "electric_potential"
38#define RP_TYPE_LENGTH      "length"
39#define RP_TYPE_TEMP        "temperature"
40#define RP_TYPE_TIME        "time"
41#define RP_TYPE_VOLUME      "volume"
42#define RP_TYPE_ANGLE       "angle"
43#define RP_TYPE_MASS        "mass"
44#define RP_TYPE_PREFIX      "prefix"
45#define RP_TYPE_PRESSURE    "pressure"
46#define RP_TYPE_CONC        "concentration"
47#define RP_TYPE_FORCE       "force"
48#define RP_TYPE_MISC        "misc"
49
50
51#ifdef __cplusplus
52
53#include <iostream>
54#include <string>
55#include <list>
56#include <sstream>
57#include <stdlib.h>
58#include <errno.h>
59#include <math.h>
60
61#include "RpDict.h"
62#include "RpUnitsStd.h"
63
64#define LIST_TEMPLATE RpUnitsListEntry
65
66class RpUnits;
67
68class RpUnitsPreset {
69    public:
70        RpUnitsPreset () {
71            addPresetAll();
72        };
73
74        static int  addPresetAll();
75        static int  addPresetEnergy();
76        static int  addPresetLength();
77        static int  addPresetTemp();
78        static int  addPresetTime();
79        static int  addPresetVolume();
80        static int  addPresetAngle();
81        static int  addPresetMass();
82        static int  addPresetPrefix();
83        static int  addPresetPressure();
84        static int  addPresetConcentration();
85        static int  addPresetForce();
86        static int  addPresetMisc();
87};
88
89class RpUnitsTypes {
90    public:
91
92        typedef bool (*RpUnitsTypesHint)(RpUnits*);
93        static RpUnitsTypesHint getTypeHint (std::string type);
94
95        static bool hintTypePrefix    ( RpUnits* unitObj );
96        static bool hintTypeNonPrefix ( RpUnits* unitObj );
97        static bool hintTypeEnergy    ( RpUnits* unitObj );
98        static bool hintTypeEPot      ( RpUnits* unitObj );
99        static bool hintTypeLength    ( RpUnits* unitObj );
100        static bool hintTypeTemp      ( RpUnits* unitObj );
101        static bool hintTypeTime      ( RpUnits* unitObj );
102        static bool hintTypeVolume    ( RpUnits* unitObj );
103        static bool hintTypeAngle     ( RpUnits* unitObj );
104        static bool hintTypeMass      ( RpUnits* unitObj );
105        static bool hintTypePressure  ( RpUnits* unitObj );
106        static bool hintTypeConc      ( RpUnits* unitObj );
107        static bool hintTypeForce     ( RpUnits* unitObj );
108        static bool hintTypeMisc      ( RpUnits* unitObj );
109
110    private:
111
112        RpUnitsTypes () {};
113};
114
115// simple class to hold info about a conversion.
116// holds where we are converting from
117// holds where we are converting to
118// hold the pointer to a function to do the forward conversion (from->to)
119// hold the pointer to a function to do the backward conversion (to->from)
120//
121class conversion
122{
123    public:
124
125        const RpUnits* getFrom()    { return (const RpUnits*) fromPtr; };
126        const RpUnits* getTo()      { return (const RpUnits*) toPtr; };
127
128        friend class RpUnits;
129
130        // copy constructor
131        conversion ( conversion& other)
132            :   fromPtr             (other.fromPtr),
133                toPtr               (other.toPtr),
134                convForwFxnPtr      (other.convForwFxnPtr),
135                convBackFxnPtr      (other.convBackFxnPtr),
136                convForwFxnPtrDD    (other.convForwFxnPtrDD),
137                convBackFxnPtrDD    (other.convBackFxnPtrDD),
138                convForwFxnPtrVoid  (other.convForwFxnPtrVoid),
139                convForwData        (other.convForwData),
140                convBackFxnPtrVoid  (other.convBackFxnPtrVoid),
141                convBackData        (other.convBackData)
142            {};
143
144        // copy assignment operator
145        conversion& operator= ( conversion& other )
146            {
147                fromPtr             = other.fromPtr;
148                toPtr               = other.toPtr;
149                convForwFxnPtr      = other.convForwFxnPtr;
150                convBackFxnPtr      = other.convBackFxnPtr;
151                convForwFxnPtrDD    = other.convForwFxnPtrDD;
152                convBackFxnPtrDD    = other.convBackFxnPtrDD;
153                convForwFxnPtrVoid  = other.convForwFxnPtrVoid;
154                convForwData        = other.convForwData;
155                convBackFxnPtrVoid  = other.convBackFxnPtrVoid;
156                convBackData        = other.convBackData;
157                return *this;
158            }
159
160        // default destructor
161        virtual ~conversion ()
162        {}
163
164    private:
165
166        const RpUnits* fromPtr;
167        const RpUnits* toPtr;
168        double (*convForwFxnPtr)(double);
169        double (*convBackFxnPtr)(double);
170        double (*convForwFxnPtrDD)(double,double);
171        double (*convBackFxnPtrDD)(double,double);
172        void* (*convForwFxnPtrVoid)(void*, void*);
173        void* convForwData;
174        void* (*convBackFxnPtrVoid)(void*, void*);
175        void* convBackData;
176
177        // constructor
178        // private because i only want RpUnits to be able to
179        // create a conversion
180        conversion (
181                const RpUnits* fromPtr,
182                const RpUnits* toPtr,
183                double (*convForwFxnPtr)(double),
184                double (*convBackFxnPtr)(double)
185             )
186            :   fromPtr             (fromPtr),
187                toPtr               (toPtr),
188                convForwFxnPtr      (convForwFxnPtr),
189                convBackFxnPtr      (convBackFxnPtr),
190                convForwFxnPtrDD    (NULL),
191                convBackFxnPtrDD    (NULL),
192                convForwFxnPtrVoid  (NULL),
193                convForwData        (NULL),
194                convBackFxnPtrVoid  (NULL),
195                convBackData        (NULL)
196            {};
197
198        // constructor for 2 argument conversion functions
199        conversion (
200                const RpUnits* fromPtr,
201                const RpUnits* toPtr,
202                double (*convForwFxnPtr)(double,double),
203                double (*convBackFxnPtr)(double,double)
204             )
205            :   fromPtr             (fromPtr),
206                toPtr               (toPtr),
207                convForwFxnPtr      (NULL),
208                convBackFxnPtr      (NULL),
209                convForwFxnPtrDD    (convForwFxnPtr),
210                convBackFxnPtrDD    (convBackFxnPtr),
211                convForwFxnPtrVoid  (NULL),
212                convForwData        (NULL),
213                convBackFxnPtrVoid  (NULL),
214                convBackData        (NULL)
215            {};
216
217        // constructor for user defined void* returning 1 arg conversion fxns.
218        // the 1 arg is a user defined void* object
219        conversion (
220                const RpUnits* fromPtr,
221                const RpUnits* toPtr,
222                void* (*convForwFxnPtrVoid)(void*, void*),
223                void* convForwData,
224                void* (*convBackFxnPtrVoid)(void*, void*),
225                void* convBackData
226             )
227            :   fromPtr             (fromPtr),
228                toPtr               (toPtr),
229                convForwFxnPtr      (NULL),
230                convBackFxnPtr      (NULL),
231                convForwFxnPtrDD    (NULL),
232                convBackFxnPtrDD    (NULL),
233                convForwFxnPtrVoid  (convForwFxnPtrVoid),
234                convForwData        (convForwData),
235                convBackFxnPtrVoid  (convBackFxnPtrVoid),
236                convBackData        (convBackData)
237            {};
238
239};
240
241// used by the RpUnits class to create a linked list of the conversions
242// associated with the specific unit.
243//
244// we could templitize this and make a generic linked list
245// or could use generic linked list class from book programming with objects
246//
247class convEntry
248{
249
250    public:
251
252        friend class RpUnits;
253
254        virtual ~convEntry()
255        {}
256
257    private:
258
259        conversion* conv;
260        convEntry*  prev;
261        convEntry*  next;
262
263        convEntry (
264                conversion* conv,
265                convEntry*  prev,
266                convEntry*  next
267             )
268            :   conv    (conv),
269                prev    (prev),
270                next    (next)
271            {};
272
273};
274
275// used by the RpUnits class to create a linked list of the incarnated units
276// associated with the specific unit.
277//
278// we could templitize this and make a generic linked list
279// or could use generic linked list class from book programming with objects
280//
281class incarnationEntry
282{
283
284    public:
285
286        friend class RpUnits;
287
288        virtual ~incarnationEntry()
289        {}
290
291    private:
292
293        const RpUnits* unit;
294        incarnationEntry*  prev;
295        incarnationEntry*  next;
296
297        incarnationEntry (
298                const RpUnits* unit,
299                incarnationEntry*  prev,
300                incarnationEntry*  next
301             )
302            :   unit    (unit),
303                prev    (prev),
304                next    (next)
305            {};
306
307};
308
309class RpUnitsListEntry
310{
311
312    public:
313
314        // constructor
315        RpUnitsListEntry (const RpUnits* unit, double exponent, const RpUnits* prefix=NULL)
316            : unit     (unit),
317              exponent (exponent),
318              prefix   (prefix)
319        {};
320
321        // copy constructor
322        RpUnitsListEntry (const RpUnitsListEntry& other)
323            : unit     (other.unit),
324              exponent (other.exponent),
325              prefix   (other.prefix)
326        {};
327
328        // copy assignment operator
329        RpUnitsListEntry& operator= (const RpUnitsListEntry& other) {
330            unit = other.unit;
331            exponent = other.exponent;
332            prefix = other.prefix;
333            return *this;
334        }
335
336        // negate the exponent
337        void negateExponent() const;
338
339        // print the name of the object
340        std::string name(int flags=RPUNITS_ORIG_EXP) const;
341
342        // report the basis of the RpUnits object being stored.
343        const RpUnits* getBasis() const;
344
345        // return the RpUnits*
346        const RpUnits* getUnitsObj() const;
347
348        // return the exponent
349        double getExponent() const;
350
351        // return the metric prefix associated with this object
352        const RpUnits* getPrefix() const;
353
354        // destructor
355        virtual ~RpUnitsListEntry ()
356        {}
357
358    private:
359
360        const RpUnits* unit;
361        mutable double exponent;
362        const RpUnits* prefix;
363};
364
365class RpUnits
366{
367    /*
368     * helpful units site
369     * http://aurora.regenstrief.org/~gunther/units.html
370     * http://www.nodc.noaa.gov/dsdt/ucg/
371     * http://www.cellml.org/meeting_minutes/archive/
372     *        20010110_meeting_minutes.html
373     */
374
375    public:
376
377        static bool cmpFxn (char c1, char c2)
378        {
379            int lc1 = toupper(static_cast<unsigned char>(c1));
380            int lc2 = toupper(static_cast<unsigned char>(c2));
381
382            if ( (lc1 < lc2) || (lc1 > lc2) ) {
383                return false;
384            }
385
386            return true;
387
388        }
389        struct _key_compare:
390            public
391            std::binary_function<std::string,std::string,bool> {
392
393                bool operator() (   const std::string& lhs,
394                                    const std::string& rhs ) const
395                {
396                    return std::lexicographical_compare( lhs.begin(),lhs.end(),
397                                                         rhs.begin(),rhs.end(),
398                                                         RpUnits::cmpFxn  );
399                }
400            };
401
402        // why are these functions friends...
403        // probably need to find a better way to let RpUnits
404        // use the RpDict and RpDictEntry fxns
405        friend class RpDict<std::string,RpUnits*,_key_compare>;
406        friend class RpDictEntry<std::string,RpUnits*,_key_compare>;
407        // users member fxns
408        std::string getUnits() const;
409        std::string getUnitsName(int flags=RPUNITS_ORIG_EXP) const;
410        std::string getSearchName() const;
411        double getExponent() const;
412        const RpUnits* getBasis() const;
413        RpUnits& setMetric(bool newVal);
414
415        // retrieve a units type.
416        std::string getType() const;
417
418        // retrieve the case insensitivity of this unit object
419        bool getCI() const;
420
421        // retrieve a list of compatible units.
422        std::list<std::string> getCompatible(double expMultiplier=1.0) const;
423
424
425        // convert from one RpUnits to another if the conversion is defined
426        double convert(         const RpUnits* toUnits,
427                                double val,
428                                int* result=NULL    ) const;
429        // convert from one RpUnits to another if the conversion is defined
430        void* convert(          const RpUnits* toUnits,
431                                void* val,
432                                int* result=NULL) const;
433        // convert from one RpUnits to another if the conversion is defined
434        // double convert(std::string, double val);
435        // convert from one RpUnits to another if the conversion is defined
436        std::string convert (   const RpUnits* toUnits,
437                                double val,
438                                int showUnits = RPUNITS_UNITS_OFF,
439                                int* result = NULL  ) const;
440
441        static std::string convert ( std::string val,
442                                     std::string toUnits,
443                                     int showUnits = RPUNITS_UNITS_OFF,
444                                     int* result = NULL );
445
446        // turn the current unit to the metric system
447        // this should only be used for units that are part of the
448        // metric system. doesnt deal with exponents, just prefixes
449        double makeBasis(double value, int* result = NULL) const;
450        const RpUnits & makeBasis(double* value, int* result = NULL) const;
451
452        static int makeMetric(RpUnits * basis);
453
454        // find a RpUnits object that should exist in RpUnitsTable
455        // returns 0 on success (object was found)
456        // returns !0 on failure (object not found)
457        static const RpUnits* find( std::string key,
458        RpDict<std::string,RpUnits*,_key_compare>::RpDictHint hint = NULL);
459
460        // validate is very similar to find, but it works better
461        // for seeing complex units can be interpreted.
462        // it validates that if the a certain units string is
463        // provided as a unit type, then all of the base components
464        // of that unit are available for conversions.
465        // returns 0 on success (units are valid)
466        // returns !0 on failure (units not valid)
467        static int validate(std::string& inUnits,
468                            std::string& type,
469                            std::list<std::string>* compatList=NULL);
470
471        // user calls define to add a RpUnits object or to add a relation rule
472        //
473        // add RpUnits Object
474        static RpUnits * define(const std::string units,
475                                const RpUnits* basis=NULL,
476                                const std::string type="",
477                                bool metric=false,
478                                bool caseInsensitive=RPUNITS_CASE_INSENSITIVE);
479
480        // add relation rule
481
482        static RpUnits * define(const RpUnits* from,
483                                const RpUnits* to,
484                                double (*convForwFxnPtr)(double),
485                                double (*convBackFxnPtr)(double));
486
487        static RpUnits * define(const RpUnits* from,
488                                const RpUnits* to,
489                                double (*convForwFxnPtr)(double,double),
490                                double (*convBackFxnPtr)(double,double));
491
492        static RpUnits * define(const RpUnits* from,
493                                const RpUnits* to,
494                                void* (*convForwFxnPtr)(void*, void*),
495                                void* convForwData,
496                                void* (*convBackFxnPtr)(void*, void*),
497                                void* convBackData);
498
499        static int incarnate (  const RpUnits* abstraction,
500                                const RpUnits* entity);
501
502        // populate the dictionary with a set of units specified by group
503        // if group equals........................then load................
504        //                    "all"           load all available units
505        //  RP_TYPE_ENERGY    "energy"        load units related to energy
506        //  RP_TYPE_EPOT      "electric_potential" load units related to electric potential
507        //  RP_TYPE_LENGTH    "length"        load units related to length
508        //  RP_TYPE_TEMP      "temperature"   load units related to temperature
509        //  RP_TYPE_TIME      "time"          load units related to time
510        //  RP_TYPE_VOLUME    "volume"        load units related to volume
511        //  RP_TYPE_ANGLE     "angle"         load units related to angles
512        //  RP_TYPE_MASS      "mass"          load units related to mass
513        //  RP_TYPE_PREFIX    "prefix"        load unit prefixes
514        //  RP_TYPE_PRESSURE  "pressure"      load units related to pressure
515        //  RP_TYPE_CONC      "concentration" load units related to concentration
516        //  RP_TYPE_FORCE     "force"         load units related to force
517        //  RP_TYPE_MISC      "misc"          load units related to everything else
518        //  (no other groups have been created)
519
520        static int addPresets (const std::string group);
521
522        // undefining a relation rule is probably not needed
523        // int undefine(); // delete a relation
524
525
526        friend int insert(std::string key,RpUnits* val);
527
528
529        // copy constructor
530        RpUnits (RpUnits &other)
531            : units    (other.units),
532              exponent (other.exponent),
533              basis    (other.basis),
534              type     (other.type),
535              metric   (other.metric),
536              ci       (other.ci),
537              convList (NULL)
538        {
539            convEntry* q = NULL;
540            convEntry* curr = NULL;
541
542            incarnationEntry* r = NULL;
543            incarnationEntry* rcurr = NULL;
544
545            dict = other.dict;
546
547            if (other.convList) {
548                q = other.convList;
549                convList = new convEntry (q->conv,NULL,NULL);
550                curr = convList;
551                while (q->next) {
552                    q = q->next;
553                    curr->next = new convEntry (q->conv,curr,NULL);
554                    curr = curr->next;
555                }
556            }
557
558            if (other.incarnationList) {
559                r = other.incarnationList;
560                incarnationList = new incarnationEntry (r->unit,NULL,NULL);
561                rcurr = incarnationList;
562                while (r->next) {
563                    r = r->next;
564                    rcurr->next = new incarnationEntry (r->unit,rcurr,NULL);
565                    rcurr = rcurr->next;
566                }
567            }
568
569        }
570
571        // copy assignment operator
572        RpUnits& operator= (const RpUnits& other) {
573
574            convEntry* q = NULL;
575            convEntry* curr = NULL;
576
577            incarnationEntry* r = NULL;
578            incarnationEntry* rcurr = NULL;
579
580            if ( this != &other ) {
581                delete convList;
582            }
583
584            dict = other.dict;
585            units = other.units;
586            exponent = other.exponent;
587            basis = other.basis;
588            type = other.type;
589            metric = other.metric;
590            ci = other.ci;
591
592            if (other.convList) {
593                q = other.convList;
594                convList = new convEntry (q->conv,NULL,NULL);
595                curr = convList;
596                while (q->next) {
597                    q = q->next;
598                    curr->next = new convEntry (q->conv,curr,NULL);
599                    curr = curr->next;
600                }
601            }
602
603            if (other.incarnationList) {
604                r = other.incarnationList;
605                incarnationList = new incarnationEntry (r->unit,NULL,NULL);
606                rcurr = incarnationList;
607                while (r->next) {
608                    r = r->next;
609                    rcurr->next = new incarnationEntry (r->unit,rcurr,NULL);
610                    rcurr = rcurr->next;
611                }
612            }
613
614            return *this;
615        }
616
617        // default destructor
618        //
619        ~RpUnits ()
620        {
621            // go to the type list and remove a variable by this name
622
623
624            // clean up dynamic memory
625
626            convEntry* p = convList;
627            convEntry* tmp = p;
628
629            incarnationEntry* r = incarnationList;
630            incarnationEntry* rtmp = r;
631
632            while (p != NULL) {
633                tmp = p;
634                p = p->next;
635                delete tmp;
636            }
637
638            while (p != NULL) {
639                rtmp = r;
640                r = r->next;
641                delete rtmp;
642            }
643        }
644
645    private:
646
647        // i hope to replace these vars with a small class representing a
648        // of a linked list of units. that way we can handle complex units.
649        // this will also require that we move the getUnits, getExponent,
650        // and getBasis, makeBasis functionality into the smaller class,
651        // that represents each part of the units. we should keep getUnits,
652        // getBasis, and makeBasis in this class, but modify them to go
653        // through the linked list of units and combine the units back into
654        // what the caller expects to see.
655        // ie. cm2/Vms (mobility), will be split into the objects cm2, V, ms
656        // when getUnits is called, the user should see cm2/Vms again.
657        // for basis, possibly let the user choose a basis, and for makeBasis
658        // move through the linked list, only converting the metric elements.
659        //
660
661        std::string units;
662        double exponent;
663        const RpUnits* basis;
664        std::string type;
665
666        // tell if the unit can accept metric prefixes
667        bool metric;
668
669        // should this unit be inserted as a case insensitive unit?
670        bool ci;
671
672        // linked list of units this RpUnit can convert to
673        // its mutable because the connectConversion function takes in a
674        // const RpUnits* and attempts to change the convList variable
675        // within the RpUnits Object
676        mutable convEntry* convList;
677
678        // linked list of incarnation units for this RpUnit
679        // its mutable because the connectIncarnation function takes in a
680        // const RpUnits* and attempts to change the incarnationList variable
681        // within the RpUnits Object
682        mutable incarnationEntry* incarnationList;
683
684        // dictionary to store the units.
685        static RpDict<std::string,RpUnits*,_key_compare>* dict;
686
687        // create a units element
688        // class takes in three pieces of info
689        // 1) string describing the units
690        // 2) double describing the exponent
691        // 3) pointer to RpUnits object describing the basis
692        //      of the units (the fundamental unit)
693        //
694
695        RpUnits (
696                    const std::string& units,
697                    double& exponent,
698                    const RpUnits* basis,
699                    const std::string type,
700                    bool metric,
701                    bool caseInsensitive
702                )
703            :   units           (units),
704                exponent        (exponent),
705                basis           (basis),
706                type            (type),
707                metric          (metric),
708                ci              (caseInsensitive),
709                convList        (NULL),
710                incarnationList (NULL)
711        {};
712
713        // insert new RpUnits object into RpUnitsTable
714        // returns 0 on success (object inserted or already exists)
715        // returns !0 on failure (object cannot be inserted or dne)
716        // int RpUnits::insert(std::string key) const;
717
718        typedef std::list<LIST_TEMPLATE> RpUnitsList;
719        typedef double (*convFxnPtrD) (double);
720        typedef std::list<convFxnPtrD> convertList;
721        typedef RpUnitsList::iterator RpUnitsListIter;
722
723        // void newExponent                (double newExponent) {exponent = newExponent;};
724
725        static int      units2list          ( const std::string& inUnits,
726                                              RpUnitsList& outList,
727                                              std::string& type         );
728        static int      list2units          ( RpUnitsList& inList,
729                                              std::string& outUnitsStr  );
730        static int      grabExponent        ( const std::string& inStr,
731                                              double* exp               );
732        static int      grabUnitString      ( const std::string& inStr  );
733        static int      grabUnits           ( std::string inStr,
734                                              int* offset,
735                                              const RpUnits** unit,
736                                              const RpUnits** prefix    );
737        static int      checkMetricPrefix   ( std::string inStr,
738                                              int* offset,
739                                              const RpUnits** prefix    );
740        static int      negateListExponents ( RpUnitsList& unitsList    );
741        static int      printList           ( RpUnitsList& unitsList    );
742
743        static int compareListEntryBasis    ( RpUnitsList& fromList,
744                                              RpUnitsListIter& fromIter,
745                                              RpUnitsListIter& toIter   );
746
747        static int compareListEntrySearch   ( RpUnitsList& fromList,
748                                              RpUnitsListIter& fromIter,
749                                              RpUnitsListIter& toIter   );
750
751        void            connectConversion   ( conversion* conv      ) const;
752        void            connectIncarnation  ( const RpUnits* unit   ) const;
753
754        // return the conversion object that will convert
755        // from this RpUnits to the proovided toUnits object
756        // if the conversion is defined
757        int             getConvertFxnList   ( const RpUnits* toUnits,
758                                              convertList& cList    ) const;
759        static int      applyConversion     ( double* val,
760                                              convertList& cList    );
761        static int      combineLists        ( convertList& l1,
762                                              convertList& l2       );
763        static int      printList           ( convertList& l1       );
764
765};
766
767/*--------------------------------------------------------------------------*/
768/*--------------------------------------------------------------------------*/
769
770int list2str (std::list<std::string>& inList, std::string& outString);
771
772int unitSlice (std::string inStr, std::string& outUnits, double& outVal);
773
774#endif // ifdef __cplusplus
775
776#endif // ifndef _RpUNITS_H
Note: See TracBrowser for help on using the repository browser.