assocvector.h
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:15k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: assocvector.h,v 1.1.1.1.50.3 2004/07/09 01:45:50 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer and/or licensor of the Original Code and owns the
  34.  * copyrights in the portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. ////////////////////////////////////////////////////////////////////////////////
  50. // The Loki Library
  51. // Copyright (c) 2001 by Andrei Alexandrescu
  52. // This code accompanies the book:
  53. // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
  54. //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
  55. // Permission to use, copy, modify, distribute and sell this software for any 
  56. //     purpose is hereby granted without fee, provided that the above copyright 
  57. //     notice appear in all copies and that both that copyright notice and this 
  58. //     permission notice appear in supporting documentation.
  59. // The author or Addison-Welsey Longman make no representations about the 
  60. //     suitability of this software for any purpose. It is provided "as is" 
  61. //     without express or implied warranty.
  62. ////////////////////////////////////////////////////////////////////////////////
  63. // Last update: February 19, 2001
  64. #ifndef ASSOCVECTOR_INC_
  65. #define ASSOCVECTOR_INC_
  66. #include <algorithm>
  67. #include <functional>
  68. #pragma warning (disable : 4530)
  69. #include <vector>
  70. #pragma warning (default : 4530)
  71. #include <utility>
  72. namespace Loki
  73. {
  74. ////////////////////////////////////////////////////////////////////////////////
  75. // class template Takeover
  76. // Used to convey move semantics to containers
  77. ////////////////////////////////////////////////////////////////////////////////
  78.     template <class T>
  79.     class Takeover
  80.     {
  81.     public:
  82.         Takeover(T& obj) : ref_(obj) {}
  83.         operator T&() const { return ref_; } 
  84.     private:
  85.         T& ref_;
  86.     };
  87. ////////////////////////////////////////////////////////////////////////////////
  88. // class template TakeoverIterator
  89. // Used to convey move semantics to containers
  90. ////////////////////////////////////////////////////////////////////////////////
  91.     template <class T, class Iter>
  92.     class TakeoverIterator
  93.     {
  94.     public:
  95.         TakeoverIterator(Iter i) : i_(i) {}
  96.         operator*() const { return Takeover<T>(*i_); } 
  97.         T* operator->() const { return &*i_; }
  98.         bool operator!=(const TakeoverIterator& rhs)
  99.         {
  100.             return i_ != rhs.i_;
  101.         }
  102.         TakeoverIterator& operator++()
  103.         {
  104.             ++i_;
  105.             return *this;
  106.         }
  107.     private:
  108.         Iter i_;
  109.     };
  110. ////////////////////////////////////////////////////////////////////////////////
  111. // class template AssocVectorCompare
  112. // Used by AssocVector
  113. ////////////////////////////////////////////////////////////////////////////////
  114.     namespace Private
  115.     {
  116.         template <class Value, class C>
  117.         class AssocVectorCompare : public C
  118.         {
  119.             typedef std::pair<typename C::first_argument_type, Value>
  120.                 Data;
  121.             typedef typename C::first_argument_type first_argument_type;
  122.         public:
  123.             AssocVectorCompare()
  124.             {}
  125.             
  126.             AssocVectorCompare(const C& src) : C(src)
  127.             {}
  128.             
  129.             bool operator()(const first_argument_type& lhs, 
  130.                 const first_argument_type& rhs) const
  131.             { return C::operator()(lhs, rhs); }
  132.             
  133.             bool operator()(const Data& lhs, const Data& rhs) const
  134.             { return operator()(lhs.first, rhs.first); }
  135.             
  136.             bool operator()(const Data& lhs, 
  137.                 const first_argument_type& rhs) const
  138.             { return operator()(lhs.first, rhs); }
  139.             
  140.             bool operator()(const first_argument_type& lhs,
  141.                 const Data& rhs) const
  142.             { return operator()(lhs, rhs.first); }
  143.         };
  144.     }
  145. ////////////////////////////////////////////////////////////////////////////////
  146. // class template AssocVector
  147. // An associative vector built as a syntactic drop-in replacement for std::map
  148. // BEWARE: AssocVector doesn't respect all map's guarantees, the most important
  149. //     being:
  150. // * iterators are invalidated by insert and erase operations
  151. // * the complexity of insert/erase is O(N) not O(log N)
  152. // * value_type is std::pair<K, V> not std::pair<const K, V>
  153. // * iterators are random
  154. ////////////////////////////////////////////////////////////////////////////////
  155.     template
  156.     <
  157.         class K,
  158.         class V,
  159.         class C = std::less<K>,
  160.         class A = std::allocator< std::pair<K, V> >
  161.     >
  162.     class AssocVector 
  163.         : private std::vector< std::pair<K, V>, A >
  164.         , private Private::AssocVectorCompare<V, C>
  165.     {
  166.         typedef std::vector<std::pair<K, V>, A> Base;
  167.         typedef Private::AssocVectorCompare<V, C> MyCompare;
  168.     public:
  169.         typedef K key_type;
  170.         typedef V mapped_type;
  171.         typedef typename Base::value_type value_type;
  172.         typedef C key_compare;
  173.         typedef A allocator_type;
  174.         typedef typename A::reference reference;
  175.         typedef typename A::const_reference const_reference;
  176.         typedef typename Base::iterator iterator;
  177.         typedef typename Base::const_iterator const_iterator;
  178.         typedef typename Base::size_type size_type;
  179.         typedef typename Base::difference_type difference_type;
  180.         typedef typename A::pointer pointer;
  181.         typedef typename A::const_pointer const_pointer;
  182.         typedef typename Base::reverse_iterator reverse_iterator;
  183.         typedef typename Base::const_reverse_iterator const_reverse_iterator;
  184.      class value_compare
  185.             : public std::binary_function<value_type, value_type, bool>
  186.             , private key_compare
  187.         {
  188.             friend class AssocVector;
  189.         
  190.         protected:
  191.             value_compare(key_compare pred) : key_compare(pred)
  192.             {}
  193.         public:
  194.             bool operator()(const value_type& lhs, const value_type& rhs) const
  195.             { return key_compare::operator()(lhs.first, rhs.first); }
  196.         };
  197.         
  198.         // 23.3.1.1 construct/copy/destroy
  199.         explicit AssocVector(const key_compare& comp = key_compare(), 
  200.             const A& alloc = A())
  201.         : Base(alloc), MyCompare(comp)
  202.         {}
  203.         
  204.         template <class InputIterator>
  205.         AssocVector(InputIterator first, InputIterator last, 
  206.             const key_compare& comp = key_compare(), 
  207.             const A& alloc = A())
  208.         : Base(first, last, alloc), MyCompare(comp)
  209.         {
  210.             MyCompare& me = *this;
  211.             std::sort(begin(), end(), me);
  212.         }
  213.         
  214.         AssocVector& operator=(const AssocVector& rhs)
  215.         { AssocVector(rhs).swap(*this);return *this;}
  216.         // iterators:
  217.         // The following are here because MWCW gets 'using' wrong
  218.         iterator begin() { return Base::begin(); }
  219.         const_iterator begin() const { return Base::begin(); }
  220.         iterator end() { return Base::end(); }
  221.         const_iterator end() const { return Base::end(); }
  222.         reverse_iterator rbegin() { return Base::rbegin(); }
  223.         const_reverse_iterator rbegin() const { return Base::rbegin(); }
  224.         reverse_iterator rend() { return Base::rend(); }
  225.         const_reverse_iterator rend() const { return Base::rend(); }
  226.         
  227.         // capacity:
  228.         bool empty() const { return Base::empty(); }
  229.         size_type size() const { return Base::size(); }
  230.         size_type max_size() { return Base::max_size(); }
  231.         // 23.3.1.2 element access:
  232.         mapped_type& operator[](const key_type& key)
  233.         { return insert(value_type(key, mapped_type())).first->second; }
  234.         // modifiers:
  235.         std::pair<iterator, bool> insert(const value_type& val)
  236.         {
  237.             bool notFound(false);
  238.             iterator i(lower_bound(val.first));
  239.             if (i == end() || operator()(val.first, i->first))
  240.             {
  241.                 i = Base::insert(i, val);
  242.                 notFound = true;
  243.             }
  244.             return std::make_pair(i, notFound);
  245.         }
  246.         iterator insert(iterator pos, const value_type& val)
  247.         {
  248.             if (pos != end() && operator()(*pos, val) && 
  249.                 (pos == end() - 1 ||
  250.                     !operator()(val, pos[1]) &&
  251.                         operator()(pos[1], val)))
  252.             {
  253.                 return Base::insert(pos, val);
  254.             }
  255.             return insert(val).first;
  256.         }
  257.        
  258.         template <class InputIterator>
  259.         iterator insert(InputIterator first, InputIterator last)
  260.         { for (; first != last; ++first) insert(*first); }
  261.         
  262.         void erase(iterator pos)
  263.         { Base::erase(pos); }
  264.         size_type erase(const key_type& k)
  265.         {
  266.             iterator i(find(k));
  267.             if (i == end()) return 0;
  268.             erase(i);
  269.             return 1;
  270.         }
  271.         void erase(iterator first, iterator last)
  272.         { Base::erase(first, last); }
  273.         void swap(AssocVector& other)
  274.         {
  275.             using namespace std;
  276.             Base::swap(other);
  277.             MyCompare& me = *this;
  278.             MyCompare& rhs = other;
  279.             std::swap(me, rhs);
  280.         }
  281.         
  282.         void clear()
  283.         { Base::clear(); }
  284.         // observers:
  285.         key_compare key_comp() const
  286.         { return *this; }
  287.         value_compare value_comp() const
  288.         {
  289.             const key_compare& comp = *this;
  290.             return value_compare(comp);
  291.         }
  292.         // 23.3.1.3 map operations:
  293.         iterator find(const key_type& k)
  294.         {
  295.             iterator i(lower_bound(k));
  296.             if (i != end() && operator()(k, i->first))
  297.             {
  298.                 i = end();
  299.             }
  300.             return i;
  301.         }
  302.         const_iterator find(const key_type& k) const
  303.         {       
  304.             const_iterator i(lower_bound(k));
  305.             if (i != end() && operator()(k, i->first))
  306.             {
  307.                 i = end();
  308.             }
  309.             return i;
  310.         }
  311.         size_type count(const key_type& k) const
  312.         { return find(k) != end(); }
  313.         iterator lower_bound(const key_type& k)
  314.         {
  315.             MyCompare& me = *this;
  316.             return std::lower_bound(begin(), end(), k, me);
  317.         }
  318.         const_iterator lower_bound(const key_type& k) const
  319.         {
  320.             const MyCompare& me = *this;
  321.             return std::lower_bound(begin(), end(), k, me);
  322.         }
  323.         iterator upper_bound(const key_type& k)
  324.         {
  325.             MyCompare& me = *this;
  326.             return std::upper_bound(begin(), end(), k, me);
  327.         }
  328.         const_iterator upper_bound(const key_type& k) const
  329.         {
  330.             const MyCompare& me = *this;
  331.             return std::upper_bound(begin(), end(), k, me);
  332.         }
  333.         std::pair<iterator, iterator> equal_range(const key_type& k)
  334.         {
  335.             MyCompare& me = *this;
  336.             return std::equal_range(begin(), end(), k, me);
  337.         }
  338.         std::pair<const_iterator, const_iterator> equal_range(
  339.             const key_type& k) const
  340.         {
  341.             const MyCompare& me = *this;
  342.             return std::equal_range(begin(), end(), k, me));
  343.         }
  344.         
  345.         friend bool operator==(const AssocVector& lhs, const AssocVector& rhs)
  346.         {
  347.             const Base& me = lhs;
  348.             return me == rhs;
  349.         } 
  350.         friend bool operator<(const AssocVector& lhs, const AssocVector& rhs)
  351.         {
  352.             const Base& me = lhs;
  353.             return me < rhs;
  354.         } 
  355.         friend bool operator!=(const AssocVector& lhs, const AssocVector& rhs)
  356.         { return !(lhs == rhs); } 
  357.         friend bool operator>(const AssocVector& lhs, const AssocVector& rhs)
  358.         { return rhs < lhs; }
  359.         friend bool operator>=(const AssocVector& lhs, const AssocVector& rhs)
  360.         { return !(lhs < rhs); } 
  361.         friend bool operator<=(const AssocVector& lhs, const AssocVector& rhs)
  362.         { return !(rhs < lhs); }
  363.     };
  364.     // specialized algorithms:
  365.     template <class K, class V, class C, class A>
  366.     void swap(AssocVector<K, V, C, A>& lhs, AssocVector<K, V, C, A>& rhs)
  367.     { lhs.swap(rhs); }
  368.     
  369. } // namespace Loki
  370. ////////////////////////////////////////////////////////////////////////////////
  371. // Change log:
  372. // May 20: change operator= - credit due to Cristoph Koegl
  373. ////////////////////////////////////////////////////////////////////////////////
  374. #endif // ASSOCVECTOR_INC_