/* ------------------------------------------------------------------------- */ /* * Copyright (c) 1999 * GMRS Software GmbH, Innsbrucker Ring 159, 81669 Munich, Germany. * http://www.gmrs.de * All rights reserved. * Author: Arno Unkrig (arno.unkrig@gmrs.de) * * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by GMRS Software GmbH. * 4. The name of GMRS Software GmbH may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY GMRS SOFTWARE GMBH ``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 GMRS SOFTWARE GMBH 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 __map_INCLUDED__ /* { */ #define __map_INCLUDED__ /* ------------------------------------------------------------------------- */ #ident "$Id: map,v 1.2 1999/11/09 19:54:44 arno Exp $" #include "../rb_tree.h" /* ------------------------------------------------------------------------- */ template class map__node; template class map__iterator; template class map__const_iterator; template class map; template class multimap; template struct map__node : public rb_tree::node_type { map__node(const pair &v) : value(v) { } //~map__node() { //} pair value; }; template class map__iterator { public: map__iterator() { } map__iterator(const map__iterator &x) : node(x.node) { } pair &operator*() const { return ((map__node *) node)->value; } pair *operator->() const { return &((map__node *) node)->value; } bool operator==(const map__iterator &x) const { return node == x.node; } bool operator!=(const map__iterator &x) const { return node != x.node; } const map__iterator &operator++() { // pre-increment node = rb_tree::successor(node); return *this; } private: map__iterator(rb_tree::node_type *n) : node(n) { } rb_tree::node_type *node; friend map; friend multimap; friend map__const_iterator; }; template class map__const_iterator { public: map__const_iterator() { } map__const_iterator(const map__const_iterator &x) : node(x.node) { } map__const_iterator(const map__iterator &x) : node(x.node) { } const pair &operator*() const { return ((const map__node *) node)->value; } const pair *operator->() const { return &((const map__node *) node)->value; } bool operator==(const map__const_iterator &x) const { return node == x.node; } bool operator!=(const map__const_iterator &x) const { return node != x.node; } const map__const_iterator &operator++() { // pre-incr node = rb_tree::successor(node); return *this; } private: map__const_iterator(const rb_tree::node_type *n) : node(n) { } const rb_tree::node_type *node; friend map; friend multimap; }; /* ------------------------------------------------------------------------- */ template class map : public rb_tree { // Public types public: typedef pair value_type; typedef map__iterator iterator; typedef map__const_iterator const_iterator; // Private types private: typedef map__node node_type; // Construct/Copy/Destroy public: explicit map() : rb_tree() { } map(const_iterator i1, const_iterator i2) : rb_tree(i1.node, i2.node, copy_node2) { } map(const map &x) : rb_tree(x) { } const map &operator=( const map &x ) { rb_tree::operator=(x); return *this; } ~map() { clear(delete_node2); } // Iterators iterator begin() { return iterator(rb_tree::begin()); } const_iterator begin() const { return const_iterator(rb_tree::begin()); } iterator end() { return iterator(rb_tree::end()); } const_iterator end() const { return const_iterator(rb_tree::end()); } //reverse_iterator rbegin(); //const_reverse_iterator rbegin() const; //reverse_iterator rend(); //const_reverse_iterator rend() const; // Capacity //bool empty() const; // Inherited from "rb_tree". //size_type size() const; // Inherited from "rb_tree". //size_type max_size() const; // Inherited from "rb_tree". // Element access mapped_type &operator[](const key_type &x) { rb_tree::node_type *n = rb_tree::find_any((value_pointer) &x); if (n == rb_tree::end()) { n = rb_tree::insert(new node_type(value_type(x, mapped_type()))); } return ((node_type *) n)->value.second; } // Modifiers // Must not use "iterator", else CFRONT fails. pair, bool> insert(const value_type &x) { if (rb_tree::find_any((value_pointer) &x.first) != rb_tree::end()) { return pair(end(), false); } return pair( iterator(rb_tree::insert(new node_type(x))), true ); } iterator insert(iterator, const value_type &); void insert(const_iterator from, const_iterator to) { rb_tree::insert(from.node, to.node); } size_type erase(const key_type &x) { return rb_tree::erase_one((value_pointer) &x); } iterator erase(iterator i) { return iterator(rb_tree::erase(i.node)); } iterator erase(iterator i1, iterator i2) { return iterator(rb_tree::erase(i1.node, i2.node)); } void swap(map &x) { rb_tree::swap((rb_tree &) x); } //void clear(); // Inherited from "rb_tree". // Map operations iterator find(const key_type &x) { return iterator(rb_tree::find_any((value_pointer) &x)); } const_iterator find(const key_type &x) const { return const_iterator(rb_tree::find_any((value_pointer) &x)); } size_type count(const key_type &x) const { return find_any((value_pointer) &x) != rb_tree::end(); } iterator lower_bound(const key_type &x) { return iterator(rb_tree::lower_bound((value_pointer) &x)); } const_iterator lower_bound(const key_type &x) const { return const_iterator(rb_tree::lower_bound((value_pointer) &x)); } iterator upper_bound(const key_type &x) { return iterator(rb_tree::upper_bound((value_pointer) &x)); } const_iterator upper_bound(const key_type &x) const { return const_iterator(rb_tree::upper_bound((value_pointer) &x)); } // Must not use "pair", else CFRONT fails pair< map__iterator, map__iterator > equal_range(const key_type &x) { return pair(lower_bound(x), upper_bound(x)); } // Must not use "pair", else CFRONT fails pair< map__const_iterator, map__const_iterator > equal_range(const key_type &x) const { return pair( lower_bound(x), upper_bound(x) ); } bool operator==(const map &x) const { return rb_tree::operator==((const rb_tree &) x); } bool operator<(const map &x) const { return rb_tree::operator<((const rb_tree &) x); } // Implementation of "rb_tree"'s virtual methods. private: /*virtual*/ bool node_less_than( const rb_tree::node_type *x, const rb_tree::node_type *y ) const { return ( ((const node_type *) x)->value.first < ((const node_type *) y)->value.first ); } /*virtual*/ bool node_less_than( value_pointer x, const rb_tree::node_type *y ) const { return *(const key_type *) x < ((const node_type *) y)->value.first; } /*virtual*/ bool node_less_than( const rb_tree::node_type *x, value_pointer y ) const { return ((const node_type *) x)->value.first < *(const key_type *) y; } /*virtual*/ rb_tree::node_type *copy_node(const rb_tree::node_type *n) const { return new node_type(((const node_type *) n)->value); } /*virtual*/ void delete_node(rb_tree::node_type *n) const { delete (node_type *) n; } typedef void (*key_mapped_printer)( ostream &, const key_type &, const mapped_type & ); /*virtual*/ void print_node_value( const rb_tree::node_type &n, ostream &os, void *closure ) const { (*(key_mapped_printer *) closure)( os, ((const node_type &) n).value.first, ((const node_type &) n).value.second ); } void print(ostream &os, key_mapped_printer np) const { rb_tree::print(os, (void *) &np); } friend ostream &operator<<( ostream &, const map & ); // Needed by "map(iter, iter)". static rb_tree::node_type *copy_node2(const rb_tree::node_type *n) { return new node_type(((const node_type *) n)->value); } // Needed by "~map()". static void delete_node2(rb_tree::node_type *n) { delete (node_type *) n; } friend map__iterator; friend map__const_iterator; }; /* ------------------------------------------------------------------------- */ template class multimap : public rb_tree { // Public types public: typedef pair value_type; typedef map__iterator iterator; typedef map__const_iterator const_iterator; // Private types private: typedef map__node node_type; // Construct/Copy/Destroy public: explicit multimap() : rb_tree() { } multimap(const_iterator i1, const_iterator i2) : rb_tree(i1.node, i2.node, copy_node2) { } multimap(const multimap &x) : rb_tree(x) { } const multimap &operator=( const multimap &x ) { rb_tree::operator=(x); return *this; } ~multimap() { clear(delete_node2); } // Iterators iterator begin() { return iterator((node_type *) rb_tree::begin()); } const_iterator begin() const { return const_iterator((const node_type *) rb_tree::begin()); } iterator end() { return iterator((node_type *) rb_tree::end()); } const_iterator end() const { return const_iterator((const node_type *) rb_tree::end()); } //reverse_iterator rbegin(); //const_reverse_iterator rbegin() const; //reverse_iterator rend(); //const_reverse_iterator rend() const; // Capacity //bool empty() const; // Inherited from "rb_tree". //size_type size() const; // Inherited from "rb_tree". //size_type max_size() const; // Inherited from "rb_tree". // Modifiers iterator insert(const value_type &x) { return iterator((node_type *) rb_tree::insert(new node_type(x))); } //iterator insert(iterator, const value_type &); void insert(const_iterator from, const_iterator to) { rb_tree::insert(from.node, to.node); } size_type erase(const key_type &x) { return rb_tree::erase_all((value_pointer) &x); } iterator erase(iterator i) { return iterator(rb_tree::erase(i.node)); } iterator erase(iterator i1, iterator i2) { return iterator(rb_tree::erase(i1.node, i2.node)); } void swap(multimap &x) { rb_tree::swap((rb_tree &) x); } //void clear(); // Inherited from "rb_tree". // Multimap operations iterator find(const key_type &x) { return iterator(rb_tree::find_first((value_pointer) &x)); } const_iterator find(const key_type &x) const { return const_iterator(rb_tree::find_first((value_pointer) &x)); } size_type count(const key_type &x) const { return rb_tree::count((value_pointer) &x); } iterator lower_bound(const key_type &x) { return iterator(rb_tree::lower_bound((value_pointer) &x)); } const_iterator lower_bound(const key_type &x) const { return const_iterator(rb_tree::lower_bound((value_pointer) &x)); } iterator upper_bound(const key_type &x) { return iterator(rb_tree::upper_bound((value_pointer) &x)); } const_iterator upper_bound(const key_type &x) const { return const_iterator(rb_tree::upper_bound((value_pointer) &x)); } // Must not use "pair", else CFRONT fails // G++ 2.7.2.1 cannot compile this ("field "first" has incomplete type")!? //pair< // map__iterator, // map__iterator //> equal_range(const key_type &x) { // return pair(lower_bound(x), upper_bound(x)); //} // Must not use "pair", else CFRONT fails pair< map__const_iterator, map__const_iterator > equal_range(const key_type &x) const { return pair(lower_bound(x), upper_bound(x)); } bool operator==(const multimap &x) const { return rb_tree::operator==((const rb_tree &) x); } bool operator<(const multimap &x) const { return rb_tree::operator<((const rb_tree &) x); } // Implementation of "rb_tree"'s virtual methods. private: /*virtual*/ bool node_less_than( const rb_tree::node_type *x, const rb_tree::node_type *y ) const { return ( ((const node_type *) x)->value.first < ((const node_type *) y)->value.first ); } /*virtual*/ bool node_less_than( value_pointer x, const rb_tree::node_type *y ) const { return *(const key_type *) x < ((const node_type *) y)->value.first; } /*virtual*/ bool node_less_than( const rb_tree::node_type *x, value_pointer y ) const { return ((const node_type *) x)->value.first < *(const key_type *) y; } /*virtual*/ rb_tree::node_type *copy_node(const rb_tree::node_type *n) const { return new node_type(((const node_type *) n)->value); } /*virtual*/ void delete_node(rb_tree::node_type *n) const { delete (node_type *) n; } typedef void (*key_mapped_printer)( ostream &, const key_type &, const mapped_type & ); /*virtual*/ void print_node_value( const rb_tree::node_type &n, ostream &os, void *closure ) const { (*(key_mapped_printer *) closure)( os, ((const node_type &) n).value.first, ((const node_type &) n).value.second ); } void print(ostream &os, key_mapped_printer np) const { rb_tree::print(os, (void *) &np); } friend ostream &operator<<( ostream &, const multimap & ); // Needed by "multimap(iter, iter)". static rb_tree::node_type *copy_node2(const rb_tree::node_type *n) { return new node_type(((const node_type *) n)->value); } // Needed by "~multimap()". static void delete_node2(rb_tree::node_type *n) { delete (node_type *) n; } friend map__iterator; friend map__const_iterator; }; /* ------------------------------------------------------------------------- */ /* * MUST DEFINE THESE HERE AT THE END OF THIS FILE; FOR ELSE STUPID CFRONT * INSTANTIATES IT OUT-OF-LINE!? */ template inline void map__print_key_mapped( ostream &os, const key_type &key, const mapped_type &mapped ) { os << "(" << key << " => " << mapped << ")"; } template inline ostream & operator<<(ostream &os, const map &x) { x.print(os, map__print_key_mapped); return os; } template inline ostream & operator<<(ostream &os, const multimap &x) { x.print(os, map__print_key_mapped); return os; } /* ------------------------------------------------------------------------- */ #endif /* } */ /* ------------------------------------------------------------------------- */