// map standard header
#ifndef _MAP_
#define _MAP_

/* This file is for use only in conjunction with a valid license for
Microsoft Visual C++ V5.0. Microsoft Corporation is in no way involved
with the production or release of this file. The file is offered on an
``as is'' basis.

DINKUMWARE, LTD. AND P.J. PLAUGER MAKE NO REPRESENTATIONS OR WARRANTIES
ABOUT THE SUITABILITY OF THIS FILES, EITHER EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. DINKUMWARE, LTD.
AND P.J. PLAUGER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
LICENSEE AS A RESULT OF USING THIS FILE.

For additional information, contact Dinkumware, Ltd. (+1-888-4DINKUM or
support@dinkumware.com).

Version date: 25 June 1998
 */

#include <functional>
#include "XTREE"

#ifdef  _MSC_VER
#pragma pack(push,8)
#endif  /* _MSC_VER */

_STD_BEGIN
        // TEMPLATE CLASS map
template<class _K, class _Ty, class _Pr = less<_K>,
    class _A = allocator<_Ty> >
    class map {
public:
    typedef map<_K, _Ty, _Pr, _A> _Myt;
    typedef pair<const _K, _Ty> value_type;
    struct _Kfn : public unary_function<value_type, _K> {
        const _K& operator()(const value_type& _X) const
        {return (_X.first); }
        };
    class value_compare
        : public binary_function<value_type, value_type, bool> {
        friend class map<_K, _Ty, _Pr, _A>;
    public:
        bool operator()(const value_type& _X,
            const value_type& _Y) const
            {return (comp(_X.first, _Y.first)); }
    _PROTECTED:
        value_compare(_Pr _Pred)
            : comp(_Pred) {}
        _Pr comp;
        };
    typedef _K key_type;
    typedef _Ty referent_type;
    typedef _Pr key_compare;
    typedef _A allocator_type;
    typedef _A::reference _Tref;
    typedef _Tree<_K, value_type, _Kfn, _Pr, _A> _Imp;
    typedef _Imp::size_type size_type;
    typedef _Imp::difference_type difference_type;
    typedef _Imp::reference reference;
    typedef _Imp::const_reference const_reference;
    typedef _Imp::iterator iterator;
    typedef _Imp::const_iterator const_iterator;
    typedef _Imp::reverse_iterator reverse_iterator;
    typedef _Imp::const_reverse_iterator const_reverse_iterator;
    typedef pair<iterator, bool> _Pairib;
    typedef pair<iterator, iterator> _Pairii;
    typedef pair<const_iterator, const_iterator> _Paircc;
    explicit map(const _Pr& _Pred = _Pr(), const _A& _Al = _A())
        : _Tr(_Pred, false, _Al) {}
    typedef const value_type *_It;
    map(_It _F, _It _L, const _Pr& _Pred = _Pr(),
        const _A& _Al = _A())
        : _Tr(_Pred, false, _Al)
        {for (; _F != _L; ++_F)
            _Tr.insert(*_F); }
    iterator begin()
        {return (_Tr.begin()); }
    const_iterator begin() const
        {return (_Tr.begin()); }
    iterator end()
        {return (_Tr.end()); }
    const_iterator end() const
        {return (_Tr.end()); }
    reverse_iterator rbegin()
        {return (_Tr.rbegin()); }
    const_reverse_iterator rbegin() const
        {return (_Tr.rbegin()); }
    reverse_iterator rend()
        {return (_Tr.rend()); }
    const_reverse_iterator rend() const
        {return (_Tr.rend()); }
    size_type size() const
        {return (_Tr.size()); }
    size_type max_size() const
        {return (_Tr.max_size()); }
    bool empty() const
        {return (_Tr.empty()); }
    _A get_allocator() const
        {return (_Tr.get_allocator()); }
    _Tref operator[](const key_type& _Kv)
        {iterator _P = insert(value_type(_Kv, _Ty())).first;
        return ((*_P).second); }
    _Pairib insert(const value_type& _X)
        {_Imp::_Pairib _Ans = _Tr.insert(_X);
        return (_Pairib(_Ans.first, _Ans.second)); }
    iterator insert(iterator _P, const value_type& _X)
        {return (_Tr.insert((_Imp::iterator&)_P, _X)); }
    void insert(_It _F, _It _L)
        {for (; _F != _L; ++_F)
            _Tr.insert(*_F); }
    iterator erase(iterator _P)
        {return (_Tr.erase((_Imp::iterator&)_P)); }
    iterator erase(iterator _F, iterator _L)
        {return (_Tr.erase((_Imp::iterator&)_F,
            (_Imp::iterator&)_L)); }
    size_type erase(const _K& _Kv)
        {return (_Tr.erase(_Kv)); }
    void clear()
        {_Tr.clear(); }
    void swap(_Myt& _X)
        {std::swap(_Tr, _X._Tr); }
    friend void swap(_Myt& _X, _Myt& _Y)
        {_X.swap(_Y); }
    key_compare key_comp() const
        {return (_Tr.key_comp()); }
    value_compare value_comp() const
        {return (value_compare(_Tr.key_comp())); }
    iterator find(const _K& _Kv)
        {return (_Tr.find(_Kv)); }
    const_iterator find(const _K& _Kv) const
        {return (_Tr.find(_Kv)); }
    size_type count(const _K& _Kv) const
        {return (_Tr.count(_Kv)); }
    iterator lower_bound(const _K& _Kv)
        {return (_Tr.lower_bound(_Kv)); }
    const_iterator lower_bound(const _K& _Kv) const
        {return (_Tr.lower_bound(_Kv)); }
    iterator upper_bound(const _K& _Kv)
        {return (_Tr.upper_bound(_Kv)); }
    const_iterator upper_bound(const _K& _Kv) const
        {return (_Tr.upper_bound(_Kv)); }
    _Pairii equal_range(const _K& _Kv)
        {return (_Tr.equal_range(_Kv)); }
    _Paircc equal_range(const _K& _Kv) const
        {return (_Tr.equal_range(_Kv)); }
protected:
    _Imp _Tr;
    };
        // map TEMPLATE OPERATORS
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator==(const map<_K, _Ty, _Pr, _A>& _X,
        const map<_K, _Ty, _Pr, _A>& _Y)
    {return (_X.size() == _Y.size()
        && equal(_X.begin(), _X.end(), _Y.begin())); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator!=(const map<_K, _Ty, _Pr, _A>& _X,
        const map<_K, _Ty, _Pr, _A>& _Y)
    {return (!(_X == _Y)); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator<(const map<_K, _Ty, _Pr, _A>& _X,
        const map<_K, _Ty, _Pr, _A>& _Y)
    {return (lexicographical_compare(_X.begin(), _X.end(),
        _Y.begin(), _Y.end())); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator>(const map<_K, _Ty, _Pr, _A>& _X,
        const map<_K, _Ty, _Pr, _A>& _Y)
    {return (_Y < _X); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator<=(const map<_K, _Ty, _Pr, _A>& _X,
        const map<_K, _Ty, _Pr, _A>& _Y)
    {return (!(_Y < _X)); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator>=(const map<_K, _Ty, _Pr, _A>& _X,
        const map<_K, _Ty, _Pr, _A>& _Y)
    {return (!(_X < _Y)); }
        // TEMPLATE CLASS multimap
template<class _K, class _Ty, class _Pr = less<_K>,
    class _A = allocator<_Ty> >
    class multimap {
public:
    typedef multimap<_K, _Ty, _Pr, _A> _Myt;
    typedef pair<const _K, _Ty> value_type;
    struct _Kfn : public unary_function<value_type, _K> {
        const _K& operator()(const value_type& _X) const
        {return (_X.first); }
        };
    class value_compare
        : public binary_function<value_type, value_type, bool> {
        friend class map<_K, _Ty, _Pr, _A>;
    public:
        bool operator()(const value_type& _X,
            const value_type& _Y) const
            {return (comp(_X.first, _Y.first)); }
    _PROTECTED:
        value_compare(_Pr _Pred)
            : comp(_Pred) {}
        _Pr comp;
        };
    typedef _K key_type;
    typedef _Ty referent_type;
    typedef _Pr key_compare;
    typedef _A allocator_type;
    typedef _Tree<_K, value_type, _Kfn, _Pr, _A> _Imp;
    typedef _Imp::size_type size_type;
    typedef _Imp::difference_type difference_type;
    typedef _Imp::reference reference;
    typedef _Imp::const_reference const_reference;
    typedef _Imp::iterator iterator;
    typedef _Imp::const_iterator const_iterator;
    typedef _Imp::reverse_iterator reverse_iterator;
    typedef _Imp::const_reverse_iterator const_reverse_iterator;
    typedef pair<iterator, iterator> _Pairii;
    typedef pair<const_iterator, const_iterator> _Paircc;
    explicit multimap(const _Pr& _Pred = _Pr(),
        const _A& _Al = _A())
        : _Tr(_Pred, true, _Al) {}
    typedef const value_type *_It;
    multimap(_It _F, _It _L, const _Pr& _Pred = _Pr(),
            const _A& _Al = _A())
        : _Tr(_Pred, true, _Al)
        {for (; _F != _L; ++_F)
            _Tr.insert(*_F); }
    iterator begin()
        {return (_Tr.begin()); }
    const_iterator begin() const
        {return (_Tr.begin()); }
    iterator end()
        {return (_Tr.end()); }
    const_iterator end() const
        {return (_Tr.end()); }
    reverse_iterator rbegin()
        {return (_Tr.rbegin()); }
    const_reverse_iterator rbegin() const
        {return (_Tr.rbegin()); }
    reverse_iterator rend()
        {return (_Tr.rend()); }
    const_reverse_iterator rend() const
        {return (_Tr.rend()); }
    size_type size() const
        {return (_Tr.size()); }
    size_type max_size() const
        {return (_Tr.max_size()); }
    bool empty() const
        {return (_Tr.empty()); }
    _A get_allocator() const
        {return (_Tr.get_allocator()); }
    iterator insert(const value_type& _X)
        {return (_Tr.insert(_X).first); }
    iterator insert(iterator _P, const value_type& _X)
        {return (_Tr.insert((_Imp::iterator&)_P, _X)); }
    void insert(_It _F, _It _L)
        {for (; _F != _L; ++_F)
            _Tr.insert(*_F); }
    iterator erase(iterator _P)
        {return (_Tr.erase((_Imp::iterator&)_P)); }
    iterator erase(iterator _F, iterator _L)
        {return (_Tr.erase((_Imp::iterator&)_F,
            (_Imp::iterator&)_L)); }
    size_type erase(const _K& _Kv = _K())
        {return (_Tr.erase(_Kv)); }
    void clear()
        {_Tr.clear(); }
    void swap(_Myt& _X)
        {std::swap(_Tr, _X._Tr); }
    friend void swap(_Myt& _X, _Myt& _Y)
        {_X.swap(_Y); }
    key_compare key_comp() const
        {return (_Tr.key_comp()); }
    value_compare value_comp() const
        {return (value_compare(_Tr.key_comp())); }
    iterator find(const _K& _Kv)
        {return (_Tr.find(_Kv)); }
    const_iterator find(const _K& _Kv) const
        {return (_Tr.find(_Kv)); }
    size_type count(const _K& _Kv) const
        {return (_Tr.count(_Kv)); }
    iterator lower_bound(const _K& _Kv)
        {return (_Tr.lower_bound(_Kv)); }
    const_iterator lower_bound(const _K& _Kv) const
        {return (_Tr.lower_bound(_Kv)); }
    iterator upper_bound(const _K& _Kv)
        {return (_Tr.upper_bound(_Kv)); }
    const_iterator upper_bound(const _K& _Kv) const
        {return (_Tr.upper_bound(_Kv)); }
    _Pairii equal_range(const _K& _Kv)
        {return (_Tr.equal_range(_Kv)); }
    _Paircc equal_range(const _K& _Kv) const
        {return (_Tr.equal_range(_Kv)); }
protected:
    _Imp _Tr;
    };
        // multimap TEMPLATE OPERATORS
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator==(const multimap<_K, _Ty, _Pr, _A>& _X,
        const multimap<_K, _Ty, _Pr, _A>& _Y)
    {return (_X.size() == _Y.size()
        && equal(_X.begin(), _X.end(), _Y.begin())); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator!=(const multimap<_K, _Ty, _Pr, _A>& _X,
        const multimap<_K, _Ty, _Pr, _A>& _Y)
    {return (!(_X == _Y)); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator<(const multimap<_K, _Ty, _Pr, _A>& _X,
        const multimap<_K, _Ty, _Pr, _A>& _Y)
    {return (lexicographical_compare(_X.begin(), _X.end(),
        _Y.begin(), _Y.end())); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator>(const multimap<_K, _Ty, _Pr, _A>& _X,
        const multimap<_K, _Ty, _Pr, _A>& _Y)
    {return (_Y < _X); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator<=(const multimap<_K, _Ty, _Pr, _A>& _X,
        const multimap<_K, _Ty, _Pr, _A>& _Y)
    {return (!(_Y < _X)); }
template<class _K, class _Ty, class _Pr, class _A> inline
    bool operator>=(const multimap<_K, _Ty, _Pr, _A>& _X,
        const multimap<_K, _Ty, _Pr, _A>& _Y)
    {return (!(_X < _Y)); }
_STD_END
#ifdef  _MSC_VER
#pragma pack(pop)
#endif  /* _MSC_VER */

#endif /* _MAP_ */

/*
 * Copyright (c) 1995 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 */

/*
 * This file is derived from software bearing the following
 * restrictions:
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this
 * software and its documentation for any purpose is hereby
 * granted without fee, provided that the above copyright notice
 * appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation.
 * Hewlett-Packard Company makes no representations about the
 * suitability of this software for any purpose. It is provided
 * "as is" without express or implied warranty.
 */

