home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 6.ddi / MWHC.006 / T2 < prev    next >
Encoding:
Text File  |  1992-06-07  |  8.9 KB  |  312 lines

  1. #ifndef __RWTVSLDICT_H__
  2. #define __RWTVSLDICT_H__
  3. pragma push_align_members(64);
  4.  
  5. /*
  6.  * A Singly-linked Key/Value dictionary.
  7.  *
  8.  * $Header:   E:/vcs/rw/tvsldict.h_v   1.1   04 Mar 1992 10:16:48   KEFFER  $
  9.  *
  10.  ****************************************************************************
  11.  *
  12.  * Rogue Wave Software, Inc.
  13.  * P.O. Box 2328
  14.  * Corvallis, OR 97339
  15.  *
  16.  * Copyright (C) 1992. This software is subject to copyright 
  17.  * protection under the laws of the United States and other countries.
  18.  *
  19.  ***************************************************************************
  20.  *
  21.  * Stores a *copy* of the inserted items into the collection.
  22.  *
  23.  * Assumes that K and V have:
  24.  *   - well-defined copy constructor (T::T(const T&) or equiv.);
  25.  *   - well-defined assignment operator (T::operator=(const T&) or equiv.);
  26.  *
  27.  * Assumes that K has:
  28.  *   - well-defined equality semantics (T::operator==(const T&)).
  29.  *
  30.  * Note that while these are automatically defined for builtin types
  31.  * (such as "int", "double", or any pointer), you may need to provide
  32.  * appropriate operators for your own classes, particularly those with
  33.  * constructors and/or pointers to other objects.
  34.  *
  35.  ***************************************************************************
  36.  *
  37.  * $Log:   E:/vcs/rw/tvsldict.h_v  $
  38.  * 
  39.  *    Rev 1.1   04 Mar 1992 10:16:48   KEFFER
  40.  *  
  41.  * 
  42.  *    Rev 1.0   02 Mar 1992 16:10:54   KEFFER
  43.  * Initial revision.
  44.  */
  45.  
  46. //$DECLARE_TEMPLATE
  47.  
  48. #include "rw/tislist.h"
  49. #include "rw/tvasslnk.h"
  50.  
  51.  
  52. /****************************************************************
  53.  *                                *
  54.  *    Declarations for RWTValSlistDictionary<K,V>        *
  55.  *                                *
  56.  ****************************************************************/
  57.  
  58.  
  59. template <class K, class V>
  60. class RWExport RWTValSlistDictionary : private RWTIsvSlist< RWTValAssocLink<K,V> > {
  61.  
  62.   friend class RWExport RWTValSlistDictionaryIterator<K,V>;
  63.   typedef RWTValSlistDictionary<K,V>        SELF;
  64.   typedef RWTValAssocLink<K,V>            LINK;
  65.   typedef RWTIsvSlist<LINK>            BASE;
  66.   typedef RWTValSlistDictionaryIterator<K,V>    ITERATOR;
  67.  
  68. protected:
  69.  
  70.   static RWBoolean    testKey(const LINK*, void*);    // Repackage tester function
  71.   static void        applyAssoc(LINK*, void*);    // Repackage apply function
  72.  
  73. public:
  74.  
  75.   // Constructors:
  76.   RWTValSlistDictionary()  { }
  77.   RWTValSlistDictionary(const RWTValSlistDictionary<K,V>&);
  78.   ~RWTValSlistDictionary() { clear(); }
  79.  
  80.   // Operators:
  81.   RWTValSlistDictionary<K,V>&    operator=(const RWTValSlistDictionary<K,V>&);
  82.   // Look up key, add if not there:
  83.   V&            operator[](K key);
  84.  
  85.   // Member functions:
  86.   void            applyToKeyAndValue(void (*applyFun)(K,V&,void*), void*);
  87.   void            clear()    {BASE::clearAndDestroy();}
  88.   RWBoolean        contains(K) const;    // Contain key?
  89.   BASE::entries;
  90.   BASE::isEmpty;
  91.   RWBoolean        find(K key, K& retKey) const;        // Returns key in "retKey" if found
  92.   RWBoolean        findValue(K key, V& retVal) const;    // Returns value in "retVal" if found
  93.   RWBoolean        findKeyAndValue(K key, K& retKey, V& retVal) const;
  94.   void            insertKeyAndValue(K key, V value)
  95.                   {(*this)[key] = value;}
  96.   RWBoolean        remove(K);
  97. };
  98.  
  99. // Helper class:
  100. template <class K, class V> struct RWTAssocApply {
  101.   typedef void (*KVFun)(K, V&, void*);
  102.   KVFun        _testFun;    // Pointer to K/V apply function
  103.   void*        _data;        // Client data
  104.   RWTAssocApply(KVFun f, void* p) : _testFun(f), _data(p) { }
  105. };
  106.   
  107.   
  108. /****************************************************************
  109.  *                                *
  110.  *    Declarations for RWTValSlistDictionaryIterator<K,V>    *
  111.  *                                *
  112.  ****************************************************************/
  113.  
  114. template <class K, class V>
  115. class RWExport RWTValSlistDictionaryIterator : private RWTIsvSlistIterator< RWTValAssocLink<K,V> > {
  116.  
  117.   // For convenience in what follows:
  118.   typedef RWTValSlistDictionary<K,V>    DICT;
  119.   typedef RWTValAssocLink<K,V>        LINK;
  120.   typedef RWTIsvSlistIterator<LINK>    BASE;
  121.  
  122.   // Disallow postfix increment.  Unless we hide it, some compilers will
  123.   // substitute the prefix increment operator in its place.
  124.   RWBoolean        operator++(int);
  125.  
  126. public:
  127.  
  128.   // Constructor: starts with iterator positioned at last link.
  129.   RWTValSlistDictionaryIterator(DICT& s) : RWTIsvSlistIterator< RWTValAssocLink<K,V> >(s) { }
  130.  
  131.  
  132.   // Operators:
  133.   RWBoolean    operator++()        {return BASE::operator++();}
  134.   BASE::operator+=;            // Advance iterator n links and test
  135.  
  136.   DICT*        container() const    {return (DICT*)BASE::container();}
  137.   RWBoolean    findNext(K);
  138.   K        key() const        {return BASE::key()->_key;}
  139.   RWBoolean     remove();        // Remove item at cursor
  140.   RWBoolean    removeNext(K);
  141.   void        reset()            {BASE::reset();}
  142.   void        reset(DICT& s)        {BASE::reset(s);}
  143.   V        value() const        {return BASE::key()->_value;}
  144. };
  145.  
  146.  
  147.  
  148. /****************************************************************
  149.  *                                *
  150.  *    Definitions for RWTValSlistDictionary<K,V>        *
  151.  *                                *
  152.  ****************************************************************/
  153.  
  154. //$IMPLEMENT_TEMPLATE
  155.  
  156. // Copy constructor (some of these names get pretty bloody long, eh?)
  157. template <class K, class V>
  158. RWTValSlistDictionary<K,V>::RWTValSlistDictionary(const RWTValSlistDictionary<K,V>& d)
  159. {
  160.   // Cast away "constness", which we will honor anyway...
  161.   ITERATOR next((SELF&)d);
  162.   while (++next)
  163.     insertKeyAndValue(next.key(), next.value());
  164. }
  165.  
  166. template <class K, class V> RWTValSlistDictionary<K,V>&
  167. RWTValSlistDictionary<K,V>::operator=(const RWTValSlistDictionary<K,V>& d)
  168. {
  169.   if (this!=&d){
  170.     clear();
  171.     // Cast away "constness", which we will honor anyway...
  172.     ITERATOR next((SELF&)d);
  173.     while (++next)
  174.       insertKeyAndValue(next.key(), next.value());
  175.   }
  176.   return *this;
  177. }
  178.  
  179. template <class K, class V> V&
  180. RWTValSlistDictionary<K,V>::operator[](K key)
  181. {
  182.   LINK* assoc = BASE::find(testKey, &key);
  183.   if (assoc==rwnil) BASE::insert(assoc = new LINK(key));
  184.   return assoc->_value;
  185. }
  186.  
  187. template <class K, class V> void
  188. RWTValSlistDictionary<K,V>::applyToKeyAndValue(void (*applyFun)(K,V&,void*), void* a)
  189. {
  190.   // Package together the user-supplied apply function and data:
  191.   RWTAssocApply<K,V> capsule(applyFun, a);
  192.   // Now use our own apply function:
  193.   BASE::apply(applyAssoc, &capsule);
  194. }
  195.  
  196. template <class K, class V> RWBoolean
  197. RWTValSlistDictionary<K,V>::contains(K key) const
  198. {
  199.   return BASE::contains(testKey, &key);
  200. }
  201.  
  202. template <class K, class V> RWBoolean
  203. RWTValSlistDictionary<K,V>::find(K key, K& retKey) const
  204. {
  205.   LINK* assoc = BASE::find(testKey, &key);
  206.   if (assoc) {
  207.     retKey   = assoc->_key;
  208.     return TRUE;
  209.   }
  210.   return FALSE;
  211. }
  212.  
  213. template <class K, class V> RWBoolean
  214. RWTValSlistDictionary<K,V>::findKeyAndValue(K key, K& retKey, V& retValue) const
  215. {
  216.   LINK* assoc = BASE::find(testKey, &key);
  217.   if (assoc) {
  218.     retKey   = assoc->_key;
  219.     retValue = assoc->_value;
  220.     return TRUE;
  221.   }
  222.   return FALSE;
  223. }
  224.  
  225. template <class K, class V> RWBoolean
  226. RWTValSlistDictionary<K,V>::findValue(K key, V& retValue) const
  227. {
  228.   LINK* assoc = BASE::find(testKey, &key);
  229.   if (assoc) {
  230.     retValue = assoc->_value;
  231.     return TRUE;
  232.   }
  233.   return FALSE;
  234. }
  235.  
  236. template <class K, class V> RWBoolean
  237. RWTValSlistDictionary<K,V>::remove(K key)
  238. {
  239.   LINK* assoc = (LINK*)BASE::remove(testKey, &key);
  240.   return assoc ? (delete assoc, TRUE) : FALSE;
  241. }
  242.  
  243.  
  244.  
  245. /********************************************************
  246.  *                            *
  247.  *    RWTValSlistDictionary<K,V> PROTECTED FUNCTIONS    *
  248.  *                            *
  249.  ********************************************************/
  250.  
  251. template <class K, class V> RWBoolean
  252. RWTValSlistDictionary<K,V>::testKey(const RWTValAssocLink<K,V>* a, void* p)
  253. {
  254.   return a->_key == *(K*)p;
  255. }
  256.  
  257. template <class K, class V> void
  258. RWTValSlistDictionary<K,V>::applyAssoc(RWTValAssocLink<K,V>* a, void* p)
  259. {
  260.   RWTAssocApply<K,V>* c = (RWTAssocApply<K,V>*)p;
  261.   (*c->_testFun)(a->_key, a->_value, c->_data);
  262. }
  263.   
  264.  
  265.  
  266. /****************************************************************
  267.  *                                *
  268.  *    Definitions for RWTValSlistDictionaryIterator<K,V>    *
  269.  *                                *
  270.  ****************************************************************/
  271.  
  272. template <class K, class V> RWBoolean
  273. RWTValSlistDictionaryIterator<K,V>::findNext(K ky)
  274. {
  275.   while (++(*this)) {
  276.     if (key()==ky) return TRUE;
  277.   }
  278.   return FALSE;
  279. }
  280.  
  281. // Remove item at cursor
  282. template <class K, class V> RWBoolean
  283. RWTValSlistDictionaryIterator<K,V>::remove()
  284. {
  285.   LINK* link = BASE::remove();
  286.   return link ? (delete link, TRUE) : FALSE;
  287. }
  288.  
  289. template <class K, class V> RWBoolean
  290. RWTValSlistDictionaryIterator<K,V>::removeNext(K key)
  291. {
  292.   LINK* cur;
  293.   LINK* prev = BASE::key();
  294.  
  295.   while (++(*this)) {
  296.     cur = BASE::key();
  297.     if (key == cur->_key){            // Is this the victim?
  298.       LINK* rem = (LINK*)BASE::removeRight(prev); // If so, remove it and...
  299. #ifdef RWDEBUG
  300.       assert (rem==cur);
  301. #endif
  302.       delete rem;                // ... delete it.
  303.       return TRUE;
  304.     }
  305.     prev = cur;
  306.   }
  307.   return FALSE;
  308. }
  309.  
  310. pragma pop_align_members();
  311. #endif    /* __RWTVSLDICT_H__ */
  312.