/* * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef QMAP_H_ #define QMAP_H_ #include "KWQDef.h" #include "KWQMapImpl.h" #ifdef _KWQ_IOSTREAM_ #include #endif template class QMap; template class QMapIterator; template class QMapConstIterator; template class QMapNode : private KWQMapNodeImpl { private: QMapNode(K k, V v) : key(k), value(v) { } // intentionally not defined QMapNode(const QMapNode&node); QMapNode& operator=(const QMapNode&); ~QMapNode() { delete (QMapNode *)left(); delete (QMapNode *)right(); } K key; V value; friend class QMap; friend class QMapIterator; friend class QMapConstIterator; }; template class QMapIterator : private KWQMapIteratorImpl { public: QMapIterator() { } const K& key() const { return ((QMapNode *)node)->key; } const V& data() const { return ((QMapNode *)node)->value; } bool operator==(const QMapIterator &iter) const { return node == iter.node; } bool operator!=(const QMapIterator &iter) const { return node != iter.node; } V& operator*() { return ((QMapNode *)node)->value; } const V& operator*() const { return ((QMapNode *)node)->value; } QMapIterator& operator++() { incrementInternal(); return *this; } private: QMapIterator(QMapNode *n) { node = n; } friend class QMap; friend class QMapConstIterator; }; template class QMapConstIterator : private KWQMapIteratorImpl { public: QMapConstIterator() { } QMapConstIterator(const QMapIterator &iter) : KWQMapIteratorImpl(iter) { } const K& key() const { return ((QMapNode *)node)->key; } const V& data() const { return ((QMapNode *)node)->value; } bool operator==(const QMapConstIterator &citer) const { return node == citer.node; } bool operator!=(const QMapConstIterator &citer) const { return node != citer.node; } const V &operator*() const { return ((QMapNode *)node)->value; } QMapConstIterator& operator++() { incrementInternal(); return *this; } private: QMapConstIterator(const QMapNode *n) { node = (KWQMapNodeImpl *)n; } friend class QMap; }; template class QMap : public KWQMapImpl { public: typedef QMapIterator Iterator; typedef QMapConstIterator ConstIterator; QMap() : KWQMapImpl(new QMapNode(K(),V()), deleteNode) { } QMap(const QMap& m) : KWQMapImpl(m) { } void clear() { clearInternal(); } uint count() const { return countInternal(); } Iterator begin() { return (QMapNode *)beginInternal(); } Iterator end() { return (QMapNode *)endInternal(); } ConstIterator begin() const { return (QMapNode *)beginInternal(); } ConstIterator end() const { return ConstIterator((QMapNode *)endInternal()); } Iterator insert(const K& key, const V& value) { QMapNode tmp(key,value); return Iterator((QMapNode *)insertInternal(&tmp, true)); } void remove(const K& key) { QMapNode tmp(key, V()); removeEqualInternal(&tmp); } void remove(const QMapIterator &iterator) { removeEqualInternal(iterator.node, true); } Iterator find (const K &key) { QMapNode tmp(key, V()); QMapNode *result = (QMapNode *)findInternal(&tmp); if (result != NULL) { return Iterator(result); } else { return Iterator(end()); } } ConstIterator find (const K &key) const { QMapNode tmp(key, V()); QMapNode *result = (QMapNode *)findInternal(&tmp); if (result != NULL) { return ConstIterator(result); } else { return ConstIterator(end()); } } bool contains(const K &key) const { QMapNode tmp(key, V()); return findInternal(&tmp); } QMap& operator=(const QMap&map) { QMap tmp(map); swap(tmp); return *this; } V& operator[](const K& key) { QMapNode tmp(key, V()); return ((QMapNode *)insertInternal(&tmp, false))->value; } V operator[](const K& key) const { QMapNode tmp(key, V()); QMapNode *result = (QMapNode *)findInternal(&tmp); return result ? result->value : V(); } protected: virtual void copyNode(const KWQMapNodeImpl *isrc, KWQMapNodeImpl *idst) const { QMapNode *src = (QMapNode *)isrc; QMapNode *dst = (QMapNode *)idst; dst->key = src->key; dst->value = src->value; } virtual KWQMapNodeImpl *duplicateNode(const KWQMapNodeImpl *isrc) const { QMapNode *src = (QMapNode *)isrc; return new QMapNode(src->key, src->value); } virtual CompareResult compareNodes(const KWQMapNodeImpl *ia, const KWQMapNodeImpl *ib) const { QMapNode *a = (QMapNode *)ia; QMapNode *b = (QMapNode *)ib; if (a->key == b->key) { return Equal; } else if (a->key < b->key) { return Less; } else { return Greater; } } virtual void swapNodes(KWQMapNodeImpl *ia, KWQMapNodeImpl *ib) const { QMapNode *a = (QMapNode *)ia; QMapNode *b = (QMapNode *)ib; K tmpKey = a->key; V tmpValue = a->value; a->key = b->key; a->value = b->value; b->key = tmpKey; b->value = tmpValue; } static void deleteNode(KWQMapNodeImpl *inode) { delete (QMapNode *)inode; } }; #ifdef _KWQ_IOSTREAM_ template inline std::ostream &operator<<(std::ostream &stream, const QMap &m) { uint count = m.count(); stream << "QMap: [size: " << count << "; items: "; QMapConstIterator iter = m.begin(); for (unsigned int i = 0; i < count; i++) { stream << "(" << iter.key() << "," << iter.data() << ")"; if (i + 1 < count) { stream << ", "; } ++iter; } return stream << "]"; } #endif #endif