mapimp.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 495 行

CPP
495
字号




/*
 *
 *          Copyright (C) 1994, M. A. Sridhar
 *  
 *
 *     This software is Copyright M. A. Sridhar, 1994. You are free
 *     to copy, modify or distribute this software  as you see fit,
 *     and to use  it  for  any  purpose, provided   this copyright
 *     notice and the following   disclaimer are included  with all
 *     copies.
 *
 *                        DISCLAIMER
 *
 *     The author makes no warranties, either expressed or implied,
 *     with respect  to  this  software, its  quality, performance,
 *     merchantability, or fitness for any particular purpose. This
 *     software is distributed  AS IS.  The  user of this  software
 *     assumes all risks  as to its quality  and performance. In no
 *     event shall the author be liable for any direct, indirect or
 *     consequential damages, even if the  author has been  advised
 *     as to the possibility of such damages.
 *
 */




#ifndef _mapimp_cxx_
#define _mapimp_cxx_  /* Prevent multiple includes */

#ifdef __GNUC__
#pragma implementation
#endif

#define _no_cl_map_typedefs_
#include "base/map.h"
#include "base/basicops.h"
#include "base/stream.h"

#include <iostream.h>


#ifdef __BORLANDC__
#pragma warn -lvc
#endif




// -------------------- MapAssoc methods -----------------------------


template <class Key, class Value>
short CL_MapAssoc<Key, Value>::_Compare (const CL_Object& o) const
{
    return CL_Basics<Key>::Compare
        (key, ((const CL_MapAssoc<Key,Value>&) o).key);
}


template <class KeyClass, class ValueClass>
CL_MapAssoc<KeyClass, ValueClass>::CL_MapAssoc ()
{
    key   = CL_Basics<KeyClass>  ::NullValue();
    value = CL_Basics<ValueClass>::NullValue();
}


template <class KeyClass, class ValueClass>
CL_MapAssoc<KeyClass, ValueClass>::CL_MapAssoc
(const KeyClass& k, const ValueClass& v)
{
    key = k; value = v;
}

template <class KeyClass, class ValueClass>
CL_MapAssoc<KeyClass, ValueClass>::CL_MapAssoc
(const CL_MapAssoc<KeyClass,ValueClass>& a)
{
    key = a.key; value = a.value;
}

template <class KeyClass, class ValueClass>
void CL_MapAssoc<KeyClass, ValueClass>::operator=
(const CL_MapAssoc<KeyClass,ValueClass>& o)
{
    if (this != &o) {
        if (PrepareToChange()) {
            key   = o.key;
            value = o.value;
            Notify();
        }
    }
};



template <class KeyClass, class ValueClass>
CL_String CL_MapAssoc<KeyClass, ValueClass>::AsString () const
{
    return CL_Basics<KeyClass>::PrintableForm(key) + " --> "
        + CL_Basics<ValueClass>::PrintableForm (value);
}








// ------------------------ Map methods ---------------------------





template <class KeyClass, class ValueClass>
CL_Map<KeyClass, ValueClass>::CL_Map
    (CL_ObjectIOFilter* key_builder,
     CL_ObjectIOFilter* value_builder)
{
    _null = CL_Basics<CL_MapAssoc<KeyClass,ValueClass> >::NullValue ();
    // Maybe when gcc supports static template instance vars, I'll make
    // _null a static inst var.
    _keyBuilder = key_builder;
    _valueBuilder = value_builder;
}





template <class KeyClass, class ValueClass>
CL_Map<KeyClass, ValueClass>::CL_Map
    (CL_MapAssoc <KeyClass, ValueClass> *assoc, long count,
     CL_ObjectIOFilter* key_builder,
     CL_ObjectIOFilter* value_builder)
{
    ValueClass p;
    _keyBuilder = key_builder;
    _valueBuilder = value_builder;
    if (!assoc)
        return;
    for (long i = 0; i < count; i++) {
        Add (assoc[i].key, assoc[i].value);
    }
}


template <class KeyClass, class ValueClass>
CL_Map<KeyClass, ValueClass>::CL_Map
(const CL_Map<KeyClass, ValueClass>& m)
: _data (m.Size())
{
    long n = m.Size();
    for (long i = 0; i < n; i++)
        _data[i] = new CL_MapAssoc<KeyClass, ValueClass>
            (* (CL_MapAssoc<KeyClass, ValueClass>*) m._data[i]);
    _keyBuilder   = m._keyBuilder;
    _valueBuilder = m._valueBuilder;
}

         



//
// ---------------------- Element access -----------------------------
//

// IncludesKey: Tell whether the map includes the given key.
template <class KeyClass, class ValueClass>
bool CL_Map<KeyClass, ValueClass>::IncludesKey (const KeyClass& key) const
{
    long index = 0;
    CL_MapAssoc<KeyClass,ValueClass> a;
    a.key = key;
    return (_data.BinarySearch (&a, index));
}


// op[]: return the value associated with the given key. The
// return value is a reference, and may be modified, resulting in
// modification of the map.
template <class KeyClass, class ValueClass>
ValueClass& CL_Map<KeyClass, ValueClass>::operator []
    (const KeyClass& key)
{
    long index = 0;
    CL_MapAssoc<KeyClass,ValueClass> a;
    ValueClass p;

    a.key = key;
    if (_data.BinarySearch (&a, index)) {
        return ((CL_MapAssoc<KeyClass,ValueClass> *)_data[index])->value;
    }
    else {
        _null.value = CL_Basics<ValueClass>::NullValue ();
        return _null.value;
    }
}

template <class Key, class Value>
const CL_MapAssoc<Key, Value>& CL_Map<Key, Value>::ItemWithRank (long i) const
{
    i = maxl (0, minl (i, Size() - 1));
    return *(CL_MapAssoc<Key, Value>*) _data[i];
}



template <class Key, class Value>
long CL_Map<Key, Value>::RankOf (const Key& key) const
{
    long index = 0;
    Value p;
    CL_MapAssoc<Key,Value> a (key, p);
    bool b = _data.BinarySearch (&a, index);
    return b ? index : index+1;
}


//
// ------------------------- Modification ---------------------------
//


template <class KeyClass, class ValueClass>
bool CL_Map<KeyClass, ValueClass>::Add (const KeyClass& key,
                                        const ValueClass& value) 
{
    if (!PrepareToChange ())
        return FALSE;
    CL_MapAssoc<KeyClass,ValueClass>* p =
        new CL_MapAssoc<KeyClass,ValueClass> (key, value);

    if (!p)
        return FALSE;
    long index = 0;
    if (_data.BinarySearch (p, index)) {
        delete p;
        return FALSE;
    }
    if (_data.Insert (p, index)) {
        Notify ();
        return TRUE;
    }
    return FALSE;
}


    

template <class KeyClass, class ValueClass>
CL_MapAssoc<KeyClass, ValueClass> CL_Map<KeyClass, ValueClass>::Remove
     (const KeyClass& key)
{
    if (!PrepareToChange ())
        return CL_Basics<CL_MapAssoc<KeyClass, ValueClass> >::NullValue();
    CL_MapAssoc<KeyClass,ValueClass> a;
    a.key = key;

    long i;
    if (!_data.BinarySearch (&a, i))
        return CL_Basics<CL_MapAssoc<KeyClass, ValueClass> >::NullValue();
    CL_MapAssoc<KeyClass,ValueClass>* p =
        (CL_MapAssoc<KeyClass,ValueClass>*) _data[i];
    if (_data.Remove (i)) {
        CL_MapAssoc<KeyClass, ValueClass> a = *p;
        delete p;
        Notify ();
        return a;
    }
    return CL_Basics<CL_MapAssoc<KeyClass, ValueClass> >::NullValue();
}




template <class KeyClass, class ValueClass>
void CL_Map<KeyClass, ValueClass>::operator=
    (const CL_Map<KeyClass,ValueClass>& o)
{
    if (this == &o)
        return;
    if (!PrepareToChange())
        return;
    _data.DestroyContents ();
    if (!_data.ChangeSize (o._data.Size()))
        return;
    for (long i = 0; i < o._data.Size(); i++)
        _data[i] = new CL_MapAssoc<KeyClass, ValueClass>
            (*(CL_MapAssoc<KeyClass, ValueClass>*) o._data[i]);
    Notify();
}



template <class KeyClass, class ValueClass>
void CL_Map<KeyClass, ValueClass>::_Destructor ()
{
    _data.DestroyContents ();
}


template <class KeyClass, class ValueClass>
void CL_Map<KeyClass, ValueClass>::MakeEmpty ()
{
    _data.DestroyContents ();
}


template <class KeyClass, class ValueClass>
void CL_Map<KeyClass, ValueClass>::DestroyContents ()
{
    long size = _data.Size();
    for (long i = 0; i < size; i++) {
        CL_MapAssoc<KeyClass, ValueClass>* p =
            (CL_MapAssoc<KeyClass, ValueClass>*) _data[i];
        CL_Basics<KeyClass>::ReallyDestroy (p->key);
        CL_Basics<ValueClass>::ReallyDestroy (p->value);
    }
    _data.DestroyContents ();
}



template <class KeyClass, class ValueClass>
void CL_Map<KeyClass, ValueClass>::IntoStream (ostream& strm) const
{
    register long size = _data.Size();
    for (register long i = 0; i < size; i++) {
        CL_MapAssoc<KeyClass, ValueClass>* p =
            (CL_MapAssoc<KeyClass, ValueClass>*) _data[i];
        strm << p->AsString() << endl;
    }
}



template <class KeyClass, class ValueClass>
CL_MapAssoc<KeyClass, ValueClass>*
CL_Map<KeyClass, ValueClass>::_ReadAssoc (const CL_Stream& s) const
{
    CL_MapAssoc<KeyClass, ValueClass>* m = new CL_MapAssoc
        <KeyClass, ValueClass>;
    if (!m)
        return NULL;
    if (!CL_RestoreFrom (m->key,   s, _keyBuilder) ||
        !CL_RestoreFrom (m->value, s, _valueBuilder))
        return NULL;
    return m;
}

template <class KeyClass, class ValueClass>
bool CL_Map<KeyClass, ValueClass>::_ReadFrom (const CL_Stream& s)
{
    _data.DestroyContents ();
    long sz;
    if (!s.Read (sz) || !_data.ChangeSize (sz))
        return FALSE;
    KeyClass k;
    ValueClass v;
    for (long i = 0; i < sz; i++) {
        CL_MapAssoc<KeyClass, ValueClass>* m = _ReadAssoc (s);
        if (!m)
            return FALSE;
        _data[i] = m;
    }
    return TRUE;
}




template <class KeyClass, class ValueClass>
bool CL_Map<KeyClass, ValueClass>::_WriteAssoc
    (CL_Stream& s, const CL_MapAssoc<KeyClass,ValueClass>& assoc) const
{
    return CL_SaveTo (assoc.key, s, _keyBuilder) &&
        CL_SaveTo (assoc.value, s, _valueBuilder);
}

template <class KeyClass, class ValueClass>
bool CL_Map<KeyClass, ValueClass>::_WriteTo (CL_Stream& s) const
{
    long size = _data.Size();
    if (!s.Write (size))
        return FALSE;
    for (long i = 0; i < size; i++) {
        CL_MapAssoc<KeyClass, ValueClass>* m = (CL_MapAssoc<KeyClass,
                                                ValueClass>*) _data[i];
        if (!m || !_WriteAssoc (s, *m))
            return FALSE;
    }
    return TRUE;
}








// -------------------------- MapIterator methods ---------------------

template <class KeyClass, class ValueClass>
CL_MapIterator<KeyClass, ValueClass>::CL_MapIterator
    (const CL_Map<KeyClass,ValueClass>& map)
: _map (map)
{
    _index = 0;
}


template <class KeyClass, class ValueClass>
CL_MapIterator<KeyClass, ValueClass>::CL_MapIterator
    (const CL_MapIterator<KeyClass, ValueClass>& itr)
: _map (itr._map)
{
    _index = itr._index;
}


template <class KeyClass, class ValueClass>
void CL_MapIterator<KeyClass, ValueClass>::Reset()
{
    _index = 0;
}


template <class KeyClass, class ValueClass>
void CL_MapIterator<KeyClass, ValueClass>::BeginFromRank (long l)
{
    _index = maxl (l, 0);
}


template <class KeyClass, class ValueClass>
bool CL_MapIterator<KeyClass, ValueClass>::More() const
{
    return _index < _map.Size();
}




template <class KeyClass, class ValueClass>
CL_MapAssoc<KeyClass, ValueClass>& CL_MapIterator<KeyClass, ValueClass>::Next()
{
    if (_index < _map.Size()) {
        CL_MapAssoc<KeyClass, ValueClass>* p =
            (CL_MapAssoc<KeyClass, ValueClass>*) _map._data[_index];
        _index++;
        return *p;
    }
    return (CL_MapAssoc<KeyClass, ValueClass>&) _map._null;
    //-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast away const
//     static CL_MapAssoc<KeyClass,ValueClass> nullValue =
//         CL_Basics<CL_MapAssoc<KeyClass,ValueClass> >::NullValue();
//     return nullValue;
}


    
    
// template <class KeyClass, class ValueClass>
// CL_MapAssoc<KeyClass, ValueClass>&
// CL_MapIterator<KeyClass, ValueClass>::Previous ()
// {
//     if (_index >= 0) {
//         CL_MapAssoc<KeyClass, ValueClass>* p =
//             (CL_MapAssoc<KeyClass, ValueClass>*) _map._data[_index];
//         _index--;
//         return *p;
//     }
//     static CL_MapAssoc<KeyClass,ValueClass> nullValue =
//         CL_Basics<CL_MapAssoc<KeyClass,ValueClass> >::NullValue();
//     return nullValue;
// }


    
    

#endif /* _mapimp_cxx_ */


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?