source: trunk/include/core/RpUnits.h @ 21

Last change on this file since 21 was 21, checked in by dkearney, 16 years ago

created Makefile for compiling rappture libraries.
created README which starts to outline how to compile a rappture library
adjusted #include lines in most .h,.c,.cc files and added Include path

searched to the makefile.

files changed listed below:
M include/core/RpUnits.h
M include/core/RpDict.h
M include/cee/rappture_interface.h
A src/python/PyRpUnits_setup.py
M src/core/RpUnits.cc
M src/fortran/RpUnits_fortran.c
M src/fortran/rappture_fortran.c
M src/cee/rappture_interface.c
M src/cee/RpUnitsCInterface.cc
A src/README
A src/Makefile

  • Property svn:executable set to *
File size: 13.7 KB
Line 
1#include <iostream>
2#include <string>
3#include <sstream>
4#include <stdlib.h>
5#include <errno.h>
6
7#include "RpDict.h"
8#include "RpUnitsStd.h"
9
10#ifndef _RpUNITS_H
11#define _RpUNITS_H
12
13class RpUnits;
14
15class unit
16{
17
18    public:
19
20        const std::string getUnits(){ return units; };
21        double getExponent() {return exponent;};
22        RpUnits * getBasis() {return basis;};
23
24        friend class RpUnits;
25
26    private:
27        const std::string units;
28        double exponent;
29        // RpUnits* basis[4];
30        RpUnits* basis;
31
32        unit* prev;
33        unit* next;
34
35        unit (
36                const std::string& units,
37                double&            exponent,
38                // RpUnits**           basis,
39                RpUnits*           basis,
40                unit*              next
41             )
42            :   units    (units),
43                exponent (exponent),
44                basis    (basis),
45                prev     (NULL),
46                next     (next)
47            { };
48
49
50        void newExponent(double newExponent) {exponent = newExponent;};
51
52
53};
54
55// simple class to hold info about a conversion.
56// holds where we are converting from
57// holds where we are converting to
58// hold the pointer to a function to do the forward conversion (from->to)
59// hold the pointer to a function to do the backward conversion (to->from)
60//
61class conversion
62{
63    public:
64
65        const RpUnits* getFrom()    { return (const RpUnits*) fromPtr; };
66        const RpUnits* getTo()      { return (const RpUnits*) toPtr; };
67       
68        friend class RpUnits;
69
70    private:
71
72        RpUnits* fromPtr;
73        RpUnits* toPtr;
74        double (*convForwFxnPtr)(double);
75        double (*convBackFxnPtr)(double);
76        void* (*convForwFxnPtrVoid)(void*, void*);
77        void* convForwData;
78        void* (*convBackFxnPtrVoid)(void*, void*);
79        void* convBackData;
80
81        conversion* prev;
82        conversion* next;
83
84        // constructor
85        // private because i only want RpUnits to be able to
86        // create a conversion
87        conversion (
88                RpUnits* fromPtr,
89                RpUnits* toPtr,
90                double (*convForwFxnPtr)(double),
91                double (*convBackFxnPtr)(double),
92                conversion* prev,
93                conversion* next
94             )
95            :   fromPtr             (fromPtr),
96                toPtr               (toPtr),
97                convForwFxnPtr      (convForwFxnPtr),
98                convBackFxnPtr      (convBackFxnPtr),
99                convForwFxnPtrVoid  (NULL),
100                convForwData        (NULL),
101                convBackFxnPtrVoid  (NULL),
102                convBackData        (NULL),
103                prev                (prev),
104                next                (next)
105            {
106            };
107
108        conversion (
109                RpUnits* fromPtr,
110                RpUnits* toPtr,
111                void* (*convForwFxnPtrVoid)(void*, void*),
112                void* convForwData,
113                void* (*convBackFxnPtrVoid)(void*, void*),
114                void* convBackData,
115                conversion* prev,
116                conversion* next
117             )
118            :   fromPtr             (fromPtr),
119                toPtr               (toPtr),
120                convForwFxnPtr      (NULL),
121                convBackFxnPtr      (NULL),
122                convForwFxnPtrVoid  (convForwFxnPtrVoid),
123                convForwData        (convForwData),
124                convBackFxnPtrVoid  (convBackFxnPtrVoid),
125                convBackData        (convBackData),
126                prev                (prev),
127                next                (next)
128            {
129            };
130
131        // copy constructor
132
133        // destructor
134};
135
136// used by the RpUnits class to create a linked list of the conversions
137// associated with the specific unit.
138//
139// we could templitize this and make a generic linked list
140// or could use generic linked list class from book programming with objects
141//
142class convEntry
143{
144
145    public:
146
147        friend class RpUnits;
148
149    private:
150
151        conversion* conv;
152        convEntry*  prev;
153        convEntry*  next;
154
155        convEntry (
156                conversion* conv,
157                convEntry*  prev,
158                convEntry*  next
159             )
160            :   conv    (conv),
161                prev    (prev),
162                next    (next)
163            { };
164
165        /*
166        ~convEntry()
167        {
168
169        }
170        */
171};
172
173class RpUnits
174{
175    /*
176     * helpful units site
177     * http://aurora.regenstrief.org/~gunther/units.html
178     */
179
180    public:
181       
182        // users member fxns
183        std::string getUnits();
184        std::string getUnitsName();
185        double getExponent();
186        RpUnits* getBasis();
187
188        // convert from one RpUnits to another if the conversion is defined
189        double convert(RpUnits* toUnits, double val, int* result = NULL);
190        // convert from one RpUnits to another if the conversion is defined
191        void* convert(RpUnits* toUnits, void* val, int* result = NULL);
192        // convert from one RpUnits to another if the conversion is defined
193        double convert(std::string, double val);
194        // convert from one RpUnits to another if the conversion is defined
195        std::string convert (   RpUnits* toUnits,
196                                double val,
197                                int showUnits = 0,
198                                int* result = NULL  );
199
200        // dictionary to store the units.
201        // static RpDict<std::string,RpUnits> dict;
202
203        // turn the current unit to the metric system
204        // this should only be used for units that are part of the
205        // metric system. doesnt deal with exponents, just prefixes
206        double makeBasis(double value, int* result = NULL);
207        RpUnits & makeBasis(double* value, int* result = NULL);
208       
209        static int makeMetric(RpUnits * basis);
210
211        // find an RpUnits object that should exist in RpUnitsTable
212        // returns 0 on success (object was found)
213        // returns !0 on failure (object not found)
214        static RpUnits* find(std::string key)
215        {
216            // dict.find seems to return a (RpUnits* const) so i had to
217            // cast it as a (RpUnits*)
218
219            // dict pointer
220             // RpUnits* unitEntry = (RpUnits*) *(dict.find(key).getValue());
221             RpUnits* unitEntry = (RpUnits*) *(dict->find(key).getValue());
222
223            // RpUnits* unitEntry = (RpUnits*) dEntr.getValue();
224
225            // dict pointer
226            // if (unitEntry == (RpUnits*)dict.getNullEntry().getValue()) {
227            if (unitEntry == (RpUnits*)dict->getNullEntry().getValue()) {
228                unitEntry = NULL;
229            }
230
231            return unitEntry;
232        };
233
234        // user calls define to add a RpUnits object or to add a relation rule
235        //
236        // add RpUnits Object
237        static RpUnits * define(const std::string units, RpUnits * basis);
238        //
239        // add relation rule
240
241        static RpUnits * define(RpUnits* from,
242                                RpUnits* to,
243                                double (*convForwFxnPtr)(double),
244                                double (*convBackFxnPtr)(double));
245
246        static RpUnits * define(RpUnits* from,
247                                RpUnits* to,
248                                void* (*convForwFxnPtr)(void*, void*),
249                                void* convForwData,
250                                void* (*convBackFxnPtr)(void*, void*),
251                                void* convBackData);
252
253        // undefining a relation rule is probably not needed
254        // int undefine(); // delete a relation
255
256        // convert fxn will be taken care of in the RpUnitsConversion class
257        // i think
258        // int convert(const char* from, const char* to);
259
260        // why are these functions friends...
261        // probably need to find a better way to let RpUnits
262        // use the RpDict and RpDictEntry fxns
263        friend class RpDict<std::string,RpUnits*>;
264        friend class RpDictEntry<std::string,RpUnits*>;
265
266        // copy constructor
267        RpUnits ( const RpUnits& myRpUnit )
268        {
269
270            /*
271            from = myRpUnit.from;
272            to = myRpUnit.to;
273            convertForw = myRpUnit.convertForw;
274            convertBack = myRpUnit.convertBack;
275            */
276
277            // copy constructor for unit
278            unit* tmp = NULL;
279            unit* newUnit = NULL;
280            unit* p = myRpUnit.head;
281
282            while (p != NULL) {
283                newUnit = new unit(p->units, p->exponent,p->basis,NULL);
284
285                newUnit->prev = tmp;
286                if (tmp) {
287                    tmp->next = newUnit;
288                }
289
290                tmp = newUnit;
291                p = p->next;
292            }
293
294            if (tmp) {
295                while (tmp->prev != NULL) {
296                   tmp = tmp->prev;
297                }
298            }
299
300            head = tmp;
301               
302        };
303
304    private:
305
306        // i hope to replace these vars with a small class representing a
307        // of a linked list of units. that way we can handle complex units.
308        // this will also require that we move the getUnits, getExponent,
309        // and getBasis, makeBasis functionality into the smaller class,
310        // that represents each part of the units. we should keep getUnits,
311        // getBasis, and makeBasis in this class, but modify them to go
312        // through the linked list of units and combine the units back into
313        // what the caller expects to see.
314        // ie. cm2/Vms (mobility), will be split into the objects cm2, V, ms
315        // when getUnits is called, the user should see cm2/Vms again.
316        // for basis, possibly let the user choose a basis, and for makeBasis
317        // move through the linked list, only converting the metric elements.
318        //
319       
320        // used by the RpUnits when defining units elements
321        unit* head;
322
323        // linked list of units this RpUnit can convert to
324        convEntry* convList;
325
326        // used by the RpUnits when defining conversion elements
327        conversion* conv;
328
329        // dictionary to store the units.
330        // dict pointer
331        // static RpDict<std::string,RpUnits*> dict;
332        static RpDict<std::string,RpUnits*>* dict;
333
334        // create a units element
335        // class takes in three pieces of info
336        // 1) string describing the units
337        // 2) double describing the exponent
338        // 3) pointer to RpUnits object describing the basis
339        //      of the units (the fundamental unit)
340        //
341        RpUnits (
342                    const std::string& units,
343                    double& exponent,
344                    // RpUnits* basis[]
345                    RpUnits* basis
346                )
347            :   head        ( new unit( units, exponent, basis, NULL) ),
348                convList    (NULL),
349                conv        (NULL)
350        {};
351
352        // create a conversion element
353
354        RpUnits (
355                    RpUnits* from,
356                    RpUnits* to,
357                    double (*convForwFxnPtr)(double),
358                    double (*convBackFxnPtr)(double),
359                    conversion* prev,
360                    conversion* next
361                )
362            :   head (NULL),
363                convList (NULL),
364                conv (new conversion
365                        (from,to,convForwFxnPtr,convBackFxnPtr,prev,next))
366        {
367            connectConversion(from);
368            connectConversion(to);
369        };
370
371        RpUnits (
372                    RpUnits* from,
373                    RpUnits* to,
374                    void* (*convForwFxnPtr)(void*, void*),
375                    void* convForwData,
376                    void* (*convBackFxnPtr)(void*, void*),
377                    void* convBackData,
378                    conversion* prev,
379                    conversion* next
380                )
381            :   head (NULL),
382                convList (NULL),
383                conv (new conversion (  from, to,
384                                        convForwFxnPtr, convForwData,
385                                        convBackFxnPtr, convBackData,
386                                        prev, next
387                                     )
388                     )
389        {
390            connectConversion(from);
391            connectConversion(to);
392        };
393
394        // default destructor
395        //
396        //~RpUnits ();
397        ~RpUnits ()
398        {
399            // clean up dynamic memory
400
401            unit* p = head;
402            while (p != NULL) {
403                unit* tmp = p;
404                p = p->next;
405                delete tmp;
406            }
407        }
408
409        void RpUnits::connectConversion(RpUnits* myRpUnit);
410
411        void RpUnits::fillMetricMap();
412
413        // create the container keeping track of defined units
414        // returns 0 on success (table created or already exists)
415        // returns !0 on failure (table not created or cannot exist)
416        int RpUnits::createUnitsTable();
417
418        // insert new RpUnits object into RpUnitsTable
419        // returns 0 on success (object inserted or already exists)
420        // returns !0 on failure (object cannot be inserted or dne)
421        int RpUnits::insert(std::string key);   
422
423        // link two RpUnits objects that already exist in RpUnitsTable
424        // returns 0 on success (linking within table was successful)
425        // returns !0 on failure (linking was not successful)
426        int RpUnits::link(RpUnits * unitA);
427
428
429        static int pre_compare( std::string& units, RpUnits* basis = NULL);
430        void addUnit( const std::string& units,
431                      double &  exponent,
432                      RpUnits * basis
433                     );
434
435
436};
437
438/*--------------------------------------------------------------------------*/
439/*--------------------------------------------------------------------------*/
440
441// #include "../src/RpUnits.cc"
442
443#endif
Note: See TracBrowser for help on using the repository browser.