Changeset 544 for trunk/src


Ignore:
Timestamp:
Nov 19, 2006 6:09:47 PM (17 years ago)
Author:
dkearney
Message:

added general case insensitivity capabilities to dictionary and units classes.
case insensitivity only cares about english alphabetic characters.
when units are created, there is now the opportunity for the user to
tell the dictionary that case does matter for that entry. this way we can
handle millimeters and megameters.

Location:
trunk/src/core
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/RpDict.h

    r536 r544  
    2020/**************************************************************************/
    2121
    22 template <typename KeyType, typename ValType> class RpDict;
    23 template <typename KeyType, typename ValType> class RpDictEntry;
     22template <  typename KeyType,
     23            typename ValType,
     24            class _Compare=std::equal_to<KeyType> >
     25    class RpDict;
     26
     27template <  typename KeyType,
     28            typename ValType,
     29            class _Compare=std::equal_to<KeyType> >
     30    class RpDictEntry;
     31
     32template <  typename KeyType,
     33            typename ValType,
     34            class _Compare=std::equal_to<KeyType> >
     35    class RpDictIterator;
     36/*
     37 * RpDictEntry should not depend on _Compare,
     38 * it was originally neede because RpDict is a friend class
     39 * then i needed to assign it a default value because RpUnits.cc
     40 * uses it in its find function. RpUnits::find should really not
     41 * have to use it.
     42 *
     43 * RpDictIterator has the same thing going on. It has a default value
     44 * because RpBindingsDict uses it.
     45 */
     46
    2447
    2548/**************************************************************************/
    2649
    27 template <typename KeyType, typename ValType> class RpDictIterator
     50template <typename KeyType, typename ValType, class _Compare>
     51class RpDictIterator
    2852{
    2953
     
    3559
    3660        // retrieve the table the iterator is iterating
    37         // virtual RpDict<KeyType,ValType>& getTable();
     61        // virtual RpDict<KeyType,ValType,_Compare>& getTable();
    3862
    3963        // send the search iterator to the beginning of the hash table
    40         /*virtual*/ RpDictEntry<KeyType,ValType>* first();
     64        /*virtual*/ RpDictEntry<KeyType,ValType,_Compare>* first();
    4165
    4266        // send the search iterator to the next element of the hash table
    43         /*virtual*/ RpDictEntry<KeyType,ValType>* next();
     67        /*virtual*/ RpDictEntry<KeyType,ValType,_Compare>* next();
    4468/*
    4569        RpDictIterator(RpDict* table_Ptr)
     
    5074        }
    5175*/
    52         RpDictIterator(RpDict<KeyType,ValType>& table_Ptr)
     76        RpDictIterator(RpDict<KeyType,ValType,_Compare>& table_Ptr)
    5377            : tablePtr(table_Ptr),
    5478              srchNextIndex(0),
     
    5882
    5983        // copy constructor
    60         RpDictIterator(RpDictIterator<KeyType,ValType>& iterRef)
     84        RpDictIterator(RpDictIterator<KeyType,ValType,_Compare>& iterRef)
    6185            : tablePtr(iterRef.tablePtr),
    6286              srchNextIndex(iterRef.srchNextIndex),
     
    6993    private:
    7094
    71         RpDict<KeyType,ValType>&
     95        RpDict<KeyType,ValType,_Compare>&
    7296            tablePtr;                   /* pointer to the table we want to
    7397                                         * iterate */
    7498        int srchNextIndex;              /* Index of next bucket to be
    7599                                         * enumerated after present one. */
    76         RpDictEntry<KeyType,ValType>*
     100        RpDictEntry<KeyType,ValType,_Compare>*
    77101            srchNextEntryPtr;           /* Next entry to be enumerated in the
    78102                                         * the current bucket. */
     
    81105
    82106
    83 template <typename KeyType, typename ValType> class RpDictEntry
     107template <typename KeyType, typename ValType, class _Compare>
     108class RpDictEntry
    84109{
    85110    public:
     
    106131        // template <KeyType,ValType> friend class RpDictIterator;
    107132
    108         friend class RpDict<KeyType,ValType>;
    109         friend class RpDictIterator<KeyType,ValType>;
     133        friend class RpDict<KeyType,ValType,_Compare>;
     134        friend class RpDictIterator<KeyType,ValType,_Compare>;
    110135
    111136        // one-arg constructor
     
    154179*/
    155180        // copy constructor
    156         RpDictEntry (const RpDictEntry<KeyType,ValType>& entry)
     181        RpDictEntry (const RpDictEntry<KeyType,ValType,_Compare>& entry)
    157182        {
    158183            nextPtr     = entry.nextPtr;
     
    174199
    175200        // private data members
    176         RpDictEntry<KeyType,ValType>*
     201        RpDictEntry<KeyType,ValType,_Compare>*
    177202            nextPtr;                /* Pointer to next entry in this
    178203                                     * hash bucket, or NULL for end of
    179204                                     * chain. */
    180205
    181         RpDict<KeyType,ValType>*
     206        RpDict<KeyType,ValType,_Compare>*
    182207            tablePtr;              /* Pointer to table containing entry. */
    183208
     
    207232
    208233
    209 template <typename KeyType, typename ValType> class RpDict
     234template <typename KeyType, typename ValType, class _Compare>
     235class RpDict
    210236{
    211237    public:
     
    221247        // returns !0 on failure (object cannot be inserted or dne)
    222248        //
    223         /*virtual*/ RpDict<KeyType,ValType>&
     249        /*virtual*/ RpDict<KeyType,ValType,_Compare>&
    224250                        set(    KeyType& key,
    225251                                ValType& value,
    226                                 int *newPtr=NULL );
     252                                int *newPtr=NULL,
     253                                bool ci=false);
    227254
    228255        // find an RpUnits object that should exist in RpUnitsTable
    229256        //
    230         /*virtual*/ RpDictEntry<KeyType,ValType>&
     257        /*virtual*/ RpDictEntry<KeyType,ValType,_Compare>&
    231258                        find( KeyType& key );
    232259
    233         /*virtual*/ RpDictEntry<KeyType,ValType>& operator[]( KeyType& key)
     260        /*virtual*/ RpDictEntry<KeyType,ValType,_Compare>& operator[]( KeyType& key)
    234261        {
    235262            return find(key);
    236263        }
    237264
     265        RpDict<KeyType,ValType,_Compare>& setCI( bool val );
     266        bool getCI();
     267        RpDict<KeyType,ValType,_Compare>& toggleCI();
     268
    238269        // clear the entire table
    239270        // iterate through the table and call erase on each element
    240         /*virtual*/ RpDict<KeyType,ValType>& clear();
     271        /*virtual*/ RpDict<KeyType,ValType,_Compare>& clear();
    241272
    242273        // get the nullEntry hash entry for initialization of references
    243         /*virtual*/ RpDictEntry<KeyType,ValType>& getNullEntry();
     274        /*virtual*/ RpDictEntry<KeyType,ValType,_Compare>& getNullEntry();
    244275
    245276        // template <KeyType, ValType> friend class RpDictEntry;
    246277        // template <KeyType, ValType> friend class RpDictIterator;
    247278
    248         friend class RpDictEntry<KeyType, ValType>;
    249         friend class RpDictIterator<KeyType, ValType>;
     279        friend class RpDictEntry<KeyType,ValType,_Compare>;
     280        friend class RpDictIterator<KeyType,ValType,_Compare>;
    250281
    251282        // default constructor
    252         RpDict ()
     283        RpDict (bool ci=false)
    253284            : SMALL_RP_DICT_SIZE(4),
    254285              REBUILD_MULTIPLIER(3),
     
    258289              rebuildSize(SMALL_RP_DICT_SIZE*REBUILD_MULTIPLIER),
    259290              downShift(28),
    260               mask(3)
     291              mask(3),
     292              caseInsensitive(ci)
    261293        {
    262294
     
    265297
    266298            // setup a dummy entry of NULL
    267             nullEntry = new RpDictEntry<KeyType,ValType>();
     299            nullEntry = new RpDictEntry<KeyType,ValType,_Compare>();
    268300
    269301            assert(nullEntry != NULL);
     
    293325        const int REBUILD_MULTIPLIER;
    294326
    295         RpDictEntry<KeyType,ValType>
     327        RpDictEntry<KeyType,ValType,_Compare>
    296328                    **buckets;        /* Pointer to bucket array.  Each
    297329                                       * element points to first entry in
    298330                                       * bucket's hash chain, or NULL. */
    299331        // RpDictEntry *staticBuckets[SMALL_RP_DICT_SIZE];
    300         RpDictEntry<KeyType,ValType>
     332        RpDictEntry<KeyType,ValType,_Compare>
    301333                    *staticBuckets[4];
    302334                                      /* Bucket array used for small tables
     
    313345        int mask;                     /* Mask value used in hashing
    314346                                       * function. */
    315         RpDictEntry<KeyType,ValType>
     347        bool caseInsensitive;         /* When set to true, dictionary uses
     348                                       * case insensitive functions,
     349                                       * translating chars to uppercase */
     350
     351        RpDictEntry<KeyType,ValType,_Compare>
    316352                    *nullEntry;   /* if not const, compiler complains*/
    317353
     
    352388 *************************************************************************/
    353389
    354 template <typename KeyType, typename ValType>
     390template <typename KeyType, typename ValType, class _Compare>
    355391const int
    356 RpDict<KeyType,ValType>::size() const
     392RpDict<KeyType,ValType,_Compare>::size() const
    357393{
    358394    return numEntries;
     
    373409 * Side Effects:
    374410 *  if successful, the hash table will have a new entry
    375  * 
     411 *
    376412 *
    377413 *************************************************************************/
    378 template <typename KeyType, typename ValType>
    379 RpDict<KeyType,ValType>&
    380 RpDict<KeyType,ValType>::set(   KeyType& key,
    381                                 ValType& value,
    382                                 int* newPtr)
    383 {
    384     RpDictEntry<KeyType,ValType> *hPtr = NULL;
     414template <typename KeyType, typename ValType, class _Compare>
     415RpDict<KeyType,ValType,_Compare>&
     416RpDict<KeyType,ValType,_Compare>::set(  KeyType& key,
     417                                        ValType& value,
     418                                        int* newPtr,
     419                                        bool ci )
     420{
     421    RpDictEntry<KeyType,ValType,_Compare> *hPtr = NULL;
    385422    unsigned int hash = 0;
    386423    int index = 0;
     424    bool oldCI = caseInsensitive;
    387425
    388426    assert(&key);
     
    391429    // take care of the case where we are creating a NULL key entry.
    392430    if (&key) {
     431        if (ci != oldCI) {
     432            setCI(ci);
     433        }
    393434        hash = (unsigned int) hashFxn(&key);
     435        if (ci != oldCI) {
     436            setCI(oldCI);
     437        }
    394438    }
    395439    else {
     
    407451        }
    408452        // if element already exists in hash, it should not be re-entered
    409         if (key == *(hPtr->getKey())){
     453        // if (key == *(hPtr->getKey())){
     454        if (_Compare()(key, *(hPtr->getKey()))){
    410455
    411456            // adjust the new flag if it was provided
     
    433478    }
    434479
    435     hPtr = new RpDictEntry<KeyType,ValType>(key,value);
     480    hPtr = new RpDictEntry<KeyType,ValType,_Compare>(key,value);
    436481    // hPtr->setValue(value);
    437482    //
     
    476521 */
    477522
    478 template <typename KeyType, typename ValType>
    479 RpDictEntry<KeyType,ValType>&
    480 RpDict<KeyType,ValType>::find(KeyType& key)
    481 {
    482     RpDictEntry<KeyType,ValType> *hPtr = NULL;
     523template <typename KeyType, typename ValType, class _Compare>
     524RpDictEntry<KeyType,ValType,_Compare>&
     525RpDict<KeyType,ValType,_Compare>::find(KeyType& key)
     526{
     527    RpDictEntry<KeyType,ValType,_Compare> *hPtr = NULL;
    483528    unsigned int hash = 0;
    484529    int index = 0;
     
    504549            continue;
    505550        }
    506         if (key == *(hPtr->getKey())) {
     551        // if (key == *(hPtr->getKey())) {
     552        if (_Compare()(key, *(hPtr->getKey()))){
    507553            // return a reference to the found object
    508554            return *hPtr;
     
    533579 *************************************************************************/
    534580/*
    535 template <typename KeyType,typename ValType>
    536 RpDict<KeyType,ValType>&
    537 RpDictIterator<KeyType,ValType>::getTable()
     581template <typename KeyType,typename ValType,class _Compare>
     582RpDict<KeyType,ValType,_Compare>&
     583RpDictIterator<KeyType,ValType,_Compare>::getTable()
    538584{
    539585    return tablePtr;
     
    554600 *
    555601 *************************************************************************/
    556 template <typename KeyType,typename ValType>
    557 RpDictEntry<KeyType,ValType>*
    558 RpDictIterator<KeyType,ValType>::first()
     602template <typename KeyType,typename ValType,class _Compare>
     603RpDictEntry<KeyType,ValType,_Compare>*
     604RpDictIterator<KeyType,ValType,_Compare>::first()
    559605{
    560606    srchNextIndex = 0;
     
    579625 *************************************************************************/
    580626
    581 template <typename KeyType,typename ValType>
    582 RpDictEntry<KeyType,ValType>*
    583 RpDictIterator<KeyType,ValType>::next()
    584 {
    585     RpDictEntry<KeyType,ValType>* hPtr = NULL;
     627template <typename KeyType,typename ValType,class _Compare>
     628RpDictEntry<KeyType,ValType,_Compare>*
     629RpDictIterator<KeyType,ValType,_Compare>::next()
     630{
     631    RpDictEntry<KeyType,ValType,_Compare>* hPtr = NULL;
    586632
    587633    while (srchNextEntryPtr == NULL) {
     
    600646/**************************************************************************
    601647 *
     648 * RpDict & setCI(bool val)
     649 *  Use case insensitive functions where applicable within the dictionary
     650 *
     651 * Results:
     652 *  sets the dictionary objects caseInsensitive variable to the boolean val
     653 *
     654 * Side Effects:
     655 *  mostly find and set functions will begin to execute their functions
     656 *  with case insensitivity in mind.
     657 *
     658 *
     659 *************************************************************************/
     660template <typename KeyType, typename ValType, class _Compare>
     661RpDict<KeyType,ValType,_Compare>&
     662RpDict<KeyType,ValType,_Compare>::setCI( bool val )
     663{
     664    caseInsensitive = val;
     665    return *this;
     666}
     667
     668/**************************************************************************
     669 *
     670 * bool getCI()
     671 *  Retrieve the case insensitivity of this dictionary object
     672 *
     673 * Results:
     674 *  returns the dictionary object's caseInsensitive variable to the user
     675 *
     676 * Side Effects:
     677 *  None
     678 *
     679 *************************************************************************/
     680template <typename KeyType, typename ValType, class _Compare>
     681bool
     682RpDict<KeyType,ValType,_Compare>::getCI()
     683{
     684    return caseInsensitive;
     685}
     686
     687/**************************************************************************
     688 *
     689 * RpDict & toggleCI()
     690 *  Toggle the case insensitivity of this dictionary object
     691 *
     692 * Results:
     693 *  returns the dictionary object's caseInsensitive variable to the user
     694 *
     695 * Side Effects:
     696 *  None
     697 *
     698 *************************************************************************/
     699template <typename KeyType, typename ValType, class _Compare>
     700RpDict<KeyType,ValType,_Compare>&
     701RpDict<KeyType,ValType,_Compare>::toggleCI()
     702{
     703    caseInsensitive = !caseInsensitive;
     704    return *this;
     705}
     706
     707/**************************************************************************
     708 *
    602709 * RpDict & clear()
    603710 *  iterate through the table and call erase on each element
     
    611718 *
    612719 *************************************************************************/
    613 template <typename KeyType, typename ValType>
    614 RpDict<KeyType,ValType>&
    615 RpDict<KeyType,ValType>::clear()
    616 {
    617     RpDictEntry<KeyType,ValType> *hPtr = NULL;
    618     RpDictIterator<KeyType,ValType> iter((RpDict&)*this);
     720template <typename KeyType, typename ValType, class _Compare>
     721RpDict<KeyType,ValType,_Compare>&
     722RpDict<KeyType,ValType,_Compare>::clear()
     723{
     724    RpDictEntry<KeyType,ValType,_Compare> *hPtr = NULL;
     725    RpDictIterator<KeyType,ValType,_Compare> iter((RpDict&)*this);
    619726
    620727    hPtr = iter.first();
     
    642749 *
    643750 *************************************************************************/
    644 template <typename KeyType, typename ValType>
    645 RpDictEntry<KeyType,ValType>&
    646 RpDict<KeyType,ValType>::getNullEntry()
     751template <typename KeyType, typename ValType, class _Compare>
     752RpDictEntry<KeyType,ValType,_Compare>&
     753RpDict<KeyType,ValType,_Compare>::getNullEntry()
    647754{
    648755    return *nullEntry;
     
    669776 */
    670777
    671 template <typename KeyType, typename ValType>
     778template <typename KeyType, typename ValType, class _Compare>
    672779void
    673 RpDictEntry<KeyType,ValType>::erase()
    674 {
    675     RpDictEntry<KeyType,ValType> *prevPtr = NULL;
    676     RpDictEntry<KeyType,ValType> **bucketPtr = NULL;
     780RpDictEntry<KeyType,ValType,_Compare>::erase()
     781{
     782    RpDictEntry<KeyType,ValType,_Compare> *prevPtr = NULL;
     783    RpDictEntry<KeyType,ValType,_Compare> **bucketPtr = NULL;
    677784    int index = 0;
    678785
     
    744851 */
    745852
    746 template <typename KeyType, typename ValType>
     853template <typename KeyType, typename ValType, class _Compare>
    747854const KeyType*
    748 RpDictEntry<KeyType,ValType>::getKey() const
     855RpDictEntry<KeyType,ValType,_Compare>::getKey() const
    749856{
    750857    return (const KeyType*) &key;
     
    769876 */
    770877
    771 template <typename KeyType, typename ValType>
     878template <typename KeyType, typename ValType, class _Compare>
    772879const ValType*
    773 RpDictEntry<KeyType,ValType>::getValue() const
     880RpDictEntry<KeyType,ValType,_Compare>::getValue() const
    774881{
    775882    return (const ValType*) &clientData;
     
    792899 */
    793900
    794 template <typename KeyType, typename ValType>
     901template <typename KeyType, typename ValType, class _Compare>
    795902const ValType*
    796 RpDictEntry<KeyType,ValType>::setValue(const ValType& value)
     903RpDictEntry<KeyType,ValType,_Compare>::setValue(const ValType& value)
    797904{
    798905    clientData = value;
     
    801908}
    802909
    803 template <typename KeyType, typename ValType>
    804 RpDictEntry<KeyType,ValType>::operator int() const
     910template <typename KeyType, typename ValType, class _Compare>
     911RpDictEntry<KeyType,ValType,_Compare>::operator int() const
    805912{
    806913
     
    829936 */
    830937
    831 template <typename KeyType, typename ValType>
     938template <typename KeyType, typename ValType, class _Compare>
    832939bool
    833 RpDictEntry<KeyType,ValType>::isValid() const
     940RpDictEntry<KeyType,ValType,_Compare>::isValid() const
    834941{
    835942    if (valid) {
     
    865972 */
    866973
    867 template <typename KeyType, typename ValType>
     974template <typename KeyType, typename ValType, class _Compare>
    868975void
    869 RpDict<KeyType,ValType>::RebuildTable()
     976RpDict<KeyType,ValType,_Compare>::RebuildTable()
    870977{
    871978    int oldSize=0, count=0, index=0;
    872     RpDictEntry<KeyType,ValType> **oldBuckets = NULL;
    873     RpDictEntry<KeyType,ValType> **oldChainPtr = NULL, **newChainPtr = NULL;
    874     RpDictEntry<KeyType,ValType> *hPtr = NULL;
     979    RpDictEntry<KeyType,ValType,_Compare> **oldBuckets = NULL;
     980    RpDictEntry<KeyType,ValType,_Compare> **oldChainPtr = NULL, **newChainPtr = NULL;
     981    RpDictEntry<KeyType,ValType,_Compare> *hPtr = NULL;
    875982
    876983    // void *key = NULL;
     
    887994    numBuckets *= 4;
    888995
    889     buckets = (RpDictEntry<KeyType,ValType> **) malloc((unsigned)
    890         (numBuckets * sizeof(RpDictEntry<KeyType,ValType> *)));
     996    buckets = (RpDictEntry<KeyType,ValType,_Compare> **) malloc((unsigned)
     997        (numBuckets * sizeof(RpDictEntry<KeyType,ValType,_Compare> *)));
    891998
    892999    for (count = numBuckets, newChainPtr = buckets;
     
    9451052 */
    9461053
    947 template <typename KeyType, typename ValType>
     1054template <typename KeyType, typename ValType, class _Compare>
    9481055unsigned int
    949 RpDict<KeyType,ValType>::hashFxn(const void *keyPtr) const
     1056RpDict<KeyType,ValType,_Compare>::hashFxn(const void *keyPtr) const
    9501057{
    9511058    const char *stopAddr = (const char *) keyPtr + sizeof(&keyPtr) - 1 ;
     
    9831090
    9841091
    985 template <typename KeyType, typename ValType>
     1092template <typename KeyType, typename ValType, class _Compare>
    9861093unsigned int
    987 RpDict<KeyType,ValType>::hashFxn(std::string* keyPtr) const
     1094RpDict<KeyType,ValType,_Compare>::hashFxn(std::string* keyPtr) const
    9881095{
    9891096    const char *str = (const char *) (keyPtr->c_str());
     
    9941101
    9951102    while (1) {
    996         c = *str;
     1103        // c = *str;
     1104
     1105        if (caseInsensitive == true) {
     1106            c = toupper(static_cast<unsigned char>(*str));
     1107        }
     1108        else {
     1109            c = *str;
     1110        }
     1111
    9971112        if (c == 0) {
    9981113            break;
     
    10051120}
    10061121
    1007 template <typename KeyType, typename ValType>
     1122template <typename KeyType, typename ValType, class _Compare>
    10081123unsigned int
    1009 RpDict<KeyType,ValType>::hashFxn(char* keyPtr) const
     1124RpDict<KeyType,ValType,_Compare>::hashFxn(char* keyPtr) const
    10101125{
    10111126    const char *str = (const char *) (keyPtr);
     
    10411156 */
    10421157
    1043 template <typename KeyType, typename ValType>
     1158template <typename KeyType, typename ValType, class _Compare>
    10441159int
    1045 RpDict<KeyType,ValType>::randomIndex(unsigned int hash)
     1160RpDict<KeyType,ValType,_Compare>::randomIndex(unsigned int hash)
    10461161{
    10471162    return (((((long) (hash))*1103515245) >> downShift) & mask);
  • trunk/src/core/RpUnits.cc

    r538 r544  
    1717
    1818// dict pointer
    19 RpDict<std::string,RpUnits*>* RpUnits::dict = new RpDict<std::string,RpUnits*>();
     19// set the dictionary to be case insensitive for seaches and storage
     20RpDict<std::string,RpUnits*,RpUnits::_key_compare>* RpUnits::dict =
     21    new RpDict<std::string,RpUnits*,RpUnits::_key_compare>(true);
    2022
    2123// install predefined units
     
    3335
    3436RpUnits *
    35 RpUnits::define(    const std::string units,
    36                     const RpUnits* basis,
    37                     const std::string type  ) {
     37RpUnits::define(    const std::string units,
     38                    const RpUnits* basis,
     39                    const std::string type,
     40                    bool caseInsensitive    ) {
    3841
    3942    RpUnits* newRpUnit = NULL;
     
    8386    }
    8487
    85     newRpUnit = new RpUnits(sendStr, exponent, basis, type);
     88    newRpUnit = new RpUnits(sendStr, exponent, basis, type, caseInsensitive);
    8689    if (newRpUnit) {
    8790        insert(newRpUnit->getUnitsName(),newRpUnit);
     
    146149/// Return units name from a units string containing a unit name and exponent
    147150/**
     151 * this function will be the cause of problems related to adding symbols like %
    148152 */
    149153
     
    197201RpUnits::getType() const {
    198202    return this->type;
     203}
     204
     205/**********************************************************************/
     206// METHOD: getCI()
     207/// Return the case insensitivity of an RpUnits object.
     208/**
     209 */
     210bool
     211RpUnits::getCI() const {
     212    return this->ci;
    199213}
    200214
     
    491505
    492506/**********************************************************************/
     507// METHOD: getSearchName()
     508/// Report the units name used when searching through the units dictionary.
     509/**
     510 * Reports the search name used to store and retrieve this object from
     511 * the units dictionary.
     512 */
     513
     514std::string
     515RpUnits::getSearchName() const {
     516
     517    std::string searchName = getUnitsName();
     518
     519    std::transform( searchName.begin(),
     520                    searchName.end(),
     521                    searchName.begin(),
     522                    tolower );
     523
     524    return (searchName);
     525}
     526
     527/**********************************************************************/
    493528// METHOD: getExponent()
    494529/// Report the exponent of the units of this object back to caller.
     
    611646
    612647    name = "m" + basisName;
    613     RpUnits * milli = RpUnits::define(name, basis, basis->type);
     648    RpUnits * milli = RpUnits::define(name, basis, basis->type,!RPUNITS_CI);
    614649    RpUnits::define(milli, basis, milli2base, base2milli);
    615650
     
    623658
    624659    name = "p" + basisName;
    625     RpUnits * pico  = RpUnits::define(name, basis, basis->type);
     660    RpUnits * pico  = RpUnits::define(name, basis, basis->type,!RPUNITS_CI);
    626661    RpUnits::define(pico, basis, pico2base, base2pico);
    627662
     
    647682
    648683    name = "M" + basisName;
    649     RpUnits * mega  = RpUnits::define(name, basis, basis->type);
     684    RpUnits * mega  = RpUnits::define(name, basis, basis->type,!RPUNITS_CI);
    650685    RpUnits::define(mega, basis, mega2base, base2mega);
    651686
     
    659694
    660695    name = "P" + basisName;
    661     RpUnits * peta  = RpUnits::define(name, basis, basis->type);
     696    RpUnits * peta  = RpUnits::define(name, basis, basis->type,!RPUNITS_CI);
    662697    RpUnits::define(peta, basis, peta2base, base2peta);
    663698
     
    672707/**********************************************************************/
    673708// METHOD: find()
    674 /// Find an RpUnits Object from the provided string.
     709/// Find a simple RpUnits Object from the provided string.
    675710/**
    676711 */
     
    679714RpUnits::find(std::string key) {
    680715
    681     // dict pointer
    682     /*
    683     const RpUnits* unitEntry = NULL;
    684     const RpUnits* nullEntry = NULL;
    685     */
    686     RpDictEntry<std::string,RpUnits*>* unitEntry = &(dict->getNullEntry());
    687     RpDictEntry<std::string,RpUnits*>* nullEntry = &(dict->getNullEntry());
     716    RpDictEntry<std::string,RpUnits*,_key_compare>* unitEntry = &(dict->getNullEntry());
     717    RpDictEntry<std::string,RpUnits*,_key_compare>* nullEntry = &(dict->getNullEntry());
    688718    double exponent = 1;
    689719    int idx = 0;
     
    698728    }
    699729
    700     /*
    701     unitEntry = *(dict->find(key).getValue());
    702     nullEntry = *(dict->getNullEntry().getValue());
    703     */
    704 
     730    // pass 1 - look for the unit name as it was stated by the user
    705731    unitEntry = &(dict->find(key));
    706732
    707     // dict pointer
     733    if (unitEntry == nullEntry) {
     734        // pass 2 - use case insensitivity to look for the unit
     735        dict->toggleCI();
     736        unitEntry = &(dict->find(key));
     737        dict->toggleCI();
     738    }
     739
    708740    if ( (!unitEntry->isValid()) || (unitEntry == nullEntry) ) {
    709741        // unitEntry = NULL;
     
    822854
    823855/**********************************************************************/
    824 // METHOD: define()
     856// METHOD: getBasis()
    825857/// Provide the caller with the basis of the RpUnits object being stored
    826858/**
     
    20412073    // RpUnits* val = this;
    20422074    // dict pointer
    2043     RpUnits::dict->set(key,val,&newRecord);
     2075    RpUnits::dict->set(key,val,&newRecord,val->getCI());
    20442076    return newRecord;
    20452077}
     
    24852517RpUnitsPreset::addPresetMisc () {
    24862518
    2487     RpUnits* volt      = RpUnits::define("V", NULL, RP_TYPE_ENERGY);
    2488     RpUnits* mole      = RpUnits::define("mol",  NULL, RP_TYPE_MISC);
    2489     RpUnits* hertz     = RpUnits::define("Hz",  NULL, RP_TYPE_MISC);
    2490     RpUnits* becquerel = RpUnits::define("Bq",  NULL, RP_TYPE_MISC);
     2519    RpUnits* volt      = RpUnits::define("V",  NULL, RP_TYPE_ENERGY);
     2520    RpUnits* mole      = RpUnits::define("mol",NULL, RP_TYPE_MISC);
     2521    RpUnits* hertz     = RpUnits::define("Hz", NULL, RP_TYPE_MISC);
     2522    RpUnits* becquerel = RpUnits::define("Bq", NULL, RP_TYPE_MISC);
     2523    // RpUnits* percent   = RpUnits::define("%",  NULL, RP_TYPE_MISC);
    24912524
    24922525    RpUnits::makeMetric(volt);
  • trunk/src/core/RpUnits.h

    r536 r544  
    2929#define LIST_TEMPLATE RpUnitsListEntry
    3030
     31// RpUnits Case Insensitivity define
     32#define RPUNITS_CI true
     33
    3134//define our different types of units
    3235#define RP_TYPE_ENERGY      "energy"
     
    334337        std::string getUnits() const;
    335338        std::string getUnitsName() const;
     339        std::string getSearchName() const;
    336340        double getExponent() const;
    337341        const RpUnits* getBasis() const;
     
    339343        // retrieve a units type.
    340344        std::string getType() const;
     345
     346        // retrieve the case insensitivity of this unit object
     347        bool getCI() const;
    341348
    342349        // retrieve a list of compatible units.
     
    406413        static RpUnits * define(const std::string units,
    407414                                const RpUnits* basis=NULL,
    408                                 const std::string type=""   );
     415                                const std::string type="",
     416                                bool caseInsensitive=RPUNITS_CI);
    409417
    410418        // add relation rule
     
    450458        // int undefine(); // delete a relation
    451459
     460        static bool cmpFxn (char c1, char c2)
     461        {
     462            int lc1 = toupper(static_cast<unsigned char>(c1));
     463            int lc2 = toupper(static_cast<unsigned char>(c2));
     464
     465            if ( (lc1 < lc2) || (lc1 > lc2) ) {
     466                return false;
     467            }
     468
     469            return true;
     470
     471        }
     472        struct _key_compare:
     473            public
     474            std::binary_function<std::string,std::string,bool> {
     475
     476                bool operator() (   const std::string& lhs,
     477                                    const std::string& rhs ) const
     478                {
     479                    return std::lexicographical_compare( lhs.begin(),lhs.end(),
     480                                                         rhs.begin(),rhs.end(),
     481                                                         RpUnits::cmpFxn  );
     482                }
     483            };
    452484        // why are these functions friends...
    453485        // probably need to find a better way to let RpUnits
    454486        // use the RpDict and RpDictEntry fxns
    455         friend class RpDict<std::string,RpUnits*>;
    456         friend class RpDictEntry<std::string,RpUnits*>;
     487        friend class RpDict<std::string,RpUnits*,_key_compare>;
     488        friend class RpDictEntry<std::string,RpUnits*,_key_compare>;
    457489
    458490        friend int insert(std::string key,RpUnits* val);
     
    465497              basis    (other.basis),
    466498              type     (other.type),
     499              ci       (other.ci),
    467500              convList (NULL)
    468501        {
     
    517550            basis = other.basis;
    518551            type = other.type;
     552            ci = other.ci;
    519553
    520554            if (other.convList) {
     
    592626        std::string type;
    593627
     628        // should this unit be inserted as a case insensitive unit?
     629        bool ci;
     630
    594631        // linked list of units this RpUnit can convert to
    595632        // its mutable because the connectConversion function takes in a
     
    604641        mutable incarnationEntry* incarnationList;
    605642
    606 
    607643        // dictionary to store the units.
    608         static RpDict<std::string,RpUnits*>* dict;
     644        static RpDict<std::string,RpUnits*,_key_compare>* dict;
    609645
    610646        // create a units element
     
    620656                    double& exponent,
    621657                    const RpUnits* basis,
    622                     const std::string type
     658                    const std::string type,
     659                    bool caseInsensitive
    623660                )
    624661            :   units       (units),
     
    626663                basis       (basis),
    627664                type        (type),
     665                ci          (caseInsensitive),
    628666                convList    (NULL),
    629667                incarnationList (NULL)
Note: See TracChangeset for help on using the changeset viewer.