assocvector.h
Upload User: zhongxx05
Upload Date: 2007-06-06
Package Size: 33641k
Code Size: 14k
Category:

Symbian

Development Platform:

C/C++

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