Oracle Coherence for C++ API
Release 3.7.1.0
E22845-01
00001 /* 00002 * adapter_map.hpp 00003 * 00004 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 00005 * 00006 * Oracle is a registered trademarks of Oracle Corporation and/or its 00007 * affiliates. 00008 * 00009 * This software is the confidential and proprietary information of Oracle 00010 * Corporation. You shall not disclose such confidential and proprietary 00011 * information and shall use it only in accordance with the terms of the 00012 * license agreement you entered into with Oracle. 00013 * 00014 * This notice may not be removed or altered. 00015 */ 00016 #ifndef COH_ADAPTER_MAP_HPP 00017 #define COH_ADAPTER_MAP_HPP 00018 00019 #include "coherence/lang.ns" 00020 00021 #include "coherence/util/Collection.hpp" 00022 #include "coherence/util/Collections.hpp" 00023 #include "coherence/util/HashMap.hpp" 00024 #include "coherence/util/InvocableMap.hpp" 00025 #include "coherence/util/Iterator.hpp" 00026 #include "coherence/util/Map.hpp" 00027 #include "coherence/util/filter/NotFilter.hpp" 00028 #include "coherence/util/filter/PresentFilter.hpp" 00029 #include "coherence/util/processor/ConditionalPut.hpp" 00030 #include "coherence/util/processor/ConditionalPutAll.hpp" 00031 00032 #include <functional> 00033 #include <iterator> 00034 #include <memory> 00035 #include <ostream> 00036 #include <utility> 00037 00038 COH_OPEN_NAMESPACE2(coherence,stl) 00039 00040 using coherence::util::Collection; 00041 using coherence::util::Collections; 00042 using coherence::util::HashMap; 00043 using coherence::util::InvocableMap; 00044 using coherence::util::Iterator; 00045 using coherence::util::Map; 00046 using coherence::util::filter::NotFilter; 00047 using coherence::util::filter::PresentFilter; 00048 using coherence::util::processor::ConditionalPut; 00049 using coherence::util::processor::ConditionalPutAll; 00050 00051 // ----- pre-definitions ---------------------------------------------------- 00052 00053 COH_OPEN_NAMESPACE(impl) 00054 00055 template<class K, class V> class _iterator; 00056 00057 template<class K, class V> class _const_iterator; 00058 00059 /** 00060 * @internal 00061 */ 00062 template<class K, class V> 00063 class _adapter_map_base 00064 { 00065 // ----- typedefs ------------------------------------------------------- 00066 00067 public: 00068 /** 00069 * @internal 00070 */ 00071 typedef K key_type; 00072 00073 /** 00074 * @internal 00075 */ 00076 typedef V data_type; 00077 00078 /** 00079 * @internal 00080 */ 00081 typedef V mapped_type; 00082 00083 /** 00084 * @internal 00085 */ 00086 typedef std::pair<const key_type, mapped_type> value_type; 00087 00088 /** 00089 * @internal 00090 */ 00091 typedef std::allocator<value_type> allocator_type; 00092 00093 /** 00094 * @internal 00095 */ 00096 typedef typename allocator_type::size_type size_type; 00097 00098 /** 00099 * @internal 00100 */ 00101 typedef typename allocator_type::difference_type difference_type; 00102 00103 /** 00104 * @internal 00105 */ 00106 typedef _iterator<K,V> iterator; 00107 00108 /** 00109 * @internal 00110 */ 00111 typedef _const_iterator<K,V> const_iterator; 00112 00113 00114 // ----- local class methods -------------------------------------------- 00115 00116 protected: 00117 /** 00118 * @internal 00119 */ 00120 iterator _make_iterator(Map::Handle hMap, Iterator::Handle hIter); 00121 00122 /** 00123 * @internal 00124 */ 00125 iterator _make_lazy_iterator(Map::Handle hMap, Object::View vKey); 00126 00127 /** 00128 * @internal 00129 */ 00130 const_iterator _make_const_iterator(Map::View vMap, 00131 Iterator::Handle hIter) const; 00132 00133 /** 00134 * @internal 00135 */ 00136 const_iterator _make_lazy_const_iterator(Map::View vMap, 00137 Object::View vKey) const; 00138 }; 00139 00140 /** 00141 * @internal 00142 * 00143 * Iterator which represents the end of an iteration. 00144 */ 00145 class EndIterator 00146 : public class_spec<EndIterator, 00147 extends<Object>, 00148 implements<Iterator> > 00149 { 00150 friend class factory<EndIterator>; 00151 00152 public: 00153 static Handle getInstance() 00154 { 00155 static FinalHandle<EndIterator> hIter 00156 (System::common(), create()); 00157 return hIter; 00158 } 00159 00160 protected: 00161 EndIterator() 00162 { 00163 } 00164 00165 public: 00166 virtual bool hasNext() const 00167 { 00168 return false; 00169 } 00170 virtual Object::Holder next() 00171 { 00172 COH_THROW (NoSuchElementException::create()); 00173 } 00174 }; 00175 COH_STATIC_INIT(EndIterator::getInstance()); 00176 00177 COH_CLOSE_NAMESPACE // impl 00178 00179 00180 // ----- class: adapter_map ------------------------------------------------- 00181 00182 /** 00183 * adapter_map provides an STL-like "pair associative container" wrapper 00184 * around coherence::util::Map implementations. 00185 * 00186 * An example usage examples may look as follows: 00187 * @code 00188 * typedef adapter_map<String::View, Integer32::View> month_cache; 00189 * 00190 * month_cache months(CacheFactory::getCache("dist-months")); 00191 * 00192 * months["january"] = Integer32::valueOf(31); 00193 * months["february"] = Integer32::valueOf(28); 00194 * months["march"] = Integer32::valueOf(31); 00195 * ... 00196 * 00197 * for (month_cache::iterator i = months.begin(), e = months.end(); i != e; ++i) 00198 * { 00199 * std::cout << i->first << " = " << i->second << std::endl; 00200 * } 00201 * @endcode 00202 * 00203 * adapter_map only supports keys and values which are handles, for instance 00204 * Integer32::View. See boxing_map for a variant which supports keys and values 00205 * of non-managed types, including primitives. 00206 * 00207 * @see boxing_map 00208 * @see Map 00209 * @see TypedCollections 00210 */ 00211 template<class K, class V> 00212 class adapter_map 00213 : private impl::_adapter_map_base<K,V> 00214 { 00215 // ----- typedefs ------------------------------------------------------- 00216 00217 private: 00218 /** 00219 * Super type 00220 */ 00221 typedef impl::_adapter_map_base<K,V> super; 00222 00223 public: 00224 /** 00225 * This type. 00226 */ 00227 typedef adapter_map<K, V> this_type; 00228 00229 /** 00230 * Key type of the map. Should be handle-to-const type. 00231 */ 00232 typedef typename super::key_type key_type; 00233 00234 /** 00235 * Value type of the map. Should be handle-to-const type. 00236 */ 00237 typedef typename super::data_type data_type; 00238 00239 /** 00240 * Value type of the map. Should be handle-to-const type. 00241 */ 00242 typedef typename super::mapped_type mapped_type; 00243 00244 /** 00245 * Entry type of the map. value_type is 00246 * @code std::pair<const key_type, mapped_type> @endcode. 00247 */ 00248 typedef typename super::value_type value_type; 00249 00250 /** 00251 * Allocator type for this map. allocator_type is 00252 * @code std::allocator<value_type> @endcode. 00253 */ 00254 typedef typename super::allocator_type allocator_type; 00255 00256 /** 00257 * Signed integral type. Identical to the difference type of iterator 00258 * and const_iterator. 00259 */ 00260 typedef typename super::difference_type difference_type; 00261 00262 /** 00263 * Unsigned integral type. size_type can represent any non-negative 00264 * value of difference_type. 00265 */ 00266 typedef typename super::size_type size_type; 00267 00268 /** 00269 * Iterator type of the <i>forward iterator category</i> which 00270 * iterates key-value std::pairs of this map. Convertible to 00271 * const_iterator. 00272 */ 00273 typedef typename super::iterator iterator; 00274 00275 /** 00276 * Const iterator type of the <i>forward iterator category</i> which 00277 * iterates key-value std::pairs of this map. 00278 */ 00279 typedef typename super::const_iterator const_iterator; 00280 00281 /** 00282 * Type of the values returned by @c iterator.operator-> 00283 */ 00284 typedef typename iterator::pointer pointer; 00285 00286 /** 00287 * Type of the values returned by @c const_iterator.operator-> 00288 */ 00289 typedef typename const_iterator::pointer const_pointer; 00290 00291 /** 00292 * Type of the values returned by @c iterator.operator* 00293 */ 00294 typedef typename iterator::reference reference; 00295 00296 /** 00297 * Type of the values returned by @c const_iterator.operator* 00298 */ 00299 typedef typename const_iterator::reference const_reference; 00300 00301 /** 00302 * Type of the values returned by adapter_map.operator[]() 00303 * operator[] 00304 */ 00305 typedef typename iterator::mapped_reference mapped_reference; 00306 00307 00308 // ---- hash map-specific ----------------------------------------------- 00309 00310 public: 00311 class hasher; 00312 class key_equal; 00313 00314 00315 // ----- constructors --------------------------------------------------- 00316 00317 public: 00318 /** 00319 * Create new adapter_map from the given Coherence Map. 00320 * 00321 * @param ohMap the Map to be delegated by the adapter_map. 00322 */ 00323 adapter_map(Map::Holder ohMap = NULL) 00324 : m_ohMap(System::common(), ohMap) 00325 { 00326 } 00327 00328 /** 00329 * Create a adapter_map copy. The new adapter_map will reference the 00330 * same Map, as the original adapter_map. 00331 */ 00332 adapter_map(const this_type& that) 00333 : m_ohMap(System::common(), that.m_ohMap) 00334 { 00335 } 00336 00337 /** 00338 * destructor 00339 */ 00340 virtual ~adapter_map() 00341 { 00342 } 00343 00344 /** 00345 * Reassign this adapter_map to reference the same Map as another 00346 * adapter_map. 00347 */ 00348 this_type& operator=(const this_type& that) 00349 { 00350 m_ohMap = that.m_ohMap; 00351 return *this; 00352 } 00353 00354 /** 00355 * Reassign this adapter_map to reference another Map. 00356 */ 00357 this_type& operator=(Map::Holder ohMap) 00358 { 00359 m_ohMap = ohMap; 00360 return *this; 00361 } 00362 00363 00364 // ---- delegate access ------------------------------------------------- 00365 00366 public: 00367 /** 00368 * Return the coherence::util::Map to which this adapter_map delegates. 00369 * 00370 * @return the associated coherence::util::Map::Handle 00371 * 00372 * @throws UnsupportedOperationException if the adapater_map is 00373 * delegating to a Map::View, rather then Map::Handle 00374 */ 00375 Map::Handle delegate() 00376 { 00377 Map::Holder ohMap = m_ohMap; 00378 Map::Handle hMap = cast<Map::Handle>(ohMap, false); 00379 if (NULL == hMap && NULL != ohMap) 00380 { 00381 COH_THROW (UnsupportedOperationException::create()); 00382 } 00383 return hMap; 00384 } 00385 00386 /** 00387 * Return the coherence::util::Map to which this adapter_map delegates. 00388 * 00389 * @return the associated coherence::util::Map::View 00390 */ 00391 Map::View delegate() const 00392 { 00393 return m_ohMap; 00394 } 00395 00396 00397 // ---- capacity -------------------------------------------------------- 00398 00399 public: 00400 /** 00401 * @return the number of the key-value std::pairs in the map 00402 */ 00403 size_type size() const 00404 { 00405 return delegate()->size(); 00406 } 00407 00408 /** 00409 * @return size() of the largest possible map 00410 */ 00411 size_type max_size() const 00412 { 00413 return static_cast<size_type>(-1); 00414 } 00415 00416 /** 00417 * @return true only iff this map is empty 00418 */ 00419 bool empty() const 00420 { 00421 return (size() == 0); 00422 } 00423 00424 00425 // ----- iterators ------------------------------------------------------ 00426 00427 public: 00428 /** 00429 * @return a const_iterator referring to the first element in the 00430 * container; if the map is empty, then 00431 * @code cbegin() == cend() @endcode 00432 */ 00433 const_iterator cbegin() const 00434 { 00435 Map::View vMap = delegate(); 00436 return super::_make_const_iterator 00437 (vMap, vMap->keySet()->iterator()); 00438 } 00439 00440 /** 00441 * @return a const_iterator referring to the first element in the 00442 * container; if the map is empty, then 00443 * @code begin() == end() @endcode 00444 */ 00445 const_iterator begin() const 00446 { 00447 return cbegin(); 00448 } 00449 00450 /** 00451 * @return an iterator referring to the first element in the 00452 * container; if the map is empty, then 00453 * @code begin() == end() @endcode 00454 */ 00455 iterator begin() 00456 { 00457 Map::Handle hMap = delegate(); 00458 return super::_make_iterator(hMap, hMap->keySet()->iterator()); 00459 } 00460 00461 /** 00462 * @return a const_iterator which is the past-the-end value for the 00463 * container; if the map is empty, then 00464 * @code cbegin() == cend() @endcode 00465 */ 00466 const_iterator cend() const 00467 { 00468 return super::_make_const_iterator(delegate(), 00469 impl::EndIterator::getInstance()); 00470 } 00471 00472 /** 00473 * @return a const_iterator which is the past-the-end value for the 00474 * container; if the map is empty, then 00475 * @code begin() == end() @endcode 00476 */ 00477 const_iterator end() const 00478 { 00479 return cend(); 00480 } 00481 00482 /** 00483 * @return an iterator which is the past-the-end value for the 00484 * container; if the map is empty, then 00485 * @code begin() == end() @endcode 00486 */ 00487 iterator end() 00488 { 00489 return super::_make_iterator(delegate(), 00490 impl::EndIterator::getInstance()); 00491 } 00492 00493 00494 // ----- element access ------------------------------------------------- 00495 00496 public: 00497 /** 00498 * Return a reference to the value mapped to the key. 00499 * 00500 * @param key a key to search in the map 00501 * 00502 * @return a reference to x.second, where x is the (unique) element 00503 * whose key is equal to @a key 00504 */ 00505 mapped_reference operator[](const key_type& key); 00506 00507 /** 00508 * Return a reference to the value mapped to the key. 00509 * 00510 * @param key a key to search in the map 00511 * 00512 * @return a reference to x.second, where x is the (unique) element 00513 * whose key is equal to @a key 00514 */ 00515 mapped_type operator[](const key_type& key) const; 00516 00517 00518 // ----- modifiers ------------------------------------------------------ 00519 00520 public: 00521 /** 00522 * Insert @a x if and only if there is no element in the map with key 00523 * equal to the key of @a x. The bool component of the returned 00524 * std::pair is true if and only if the insertion takes place, and the 00525 * iterator component of the std::pair points to the element with key 00526 * equal to the key of argument. 00527 * 00528 * All insert methods do not affect the validity of references to map 00529 * elements, but may invalidate all iterators to the map. 00530 * 00531 * @param x the key-value std::pair to insert into this map 00532 * 00533 * @return the std::pair which indicates the insertion status and points to 00534 * the corresponding map entry 00535 */ 00536 std::pair<iterator, bool> insert(const value_type& x); 00537 00538 /** 00539 * Insert @a x if and only if there is no element in the map with key 00540 * equal to the key of @a x. 00541 * 00542 * All insert methods do not affect the validity of references to map 00543 * elements, but may invalidate all iterators to the map. 00544 * 00545 * @param hint a hint pointing to where the insert should start to 00546 * search. Implementation is permitted to ignore the hint. 00547 * @param x the key-value std::pair to insert into this map. 00548 * 00549 * @return iterator pointing to the element with key equal to the key 00550 * of @a x. 00551 */ 00552 iterator insert(iterator hint, const value_type& x) 00553 { 00554 return insert(x).first; 00555 } 00556 00557 /** 00558 * Insert each element from the range [@a first, @a last) if and only 00559 * if there is no element with key equal to the key of that element in 00560 * this map. 00561 * 00562 * All insert methods do not affect the validity of references to map 00563 * elements, but may invalidate all iterators to the map. 00564 * 00565 * @note it is required that @a first and @a last are not iterators 00566 * into this map. Otherwise, behavior of 00567 * @code insert(first, last) @endcode is undefined. 00568 */ 00569 template<class InputIterator> 00570 void insert(InputIterator first, InputIterator last); 00571 00572 /** 00573 * Erase an element pointed to by @a position. 00574 * 00575 * All erase methods invalidate only iterators and references to the 00576 * erased elements. 00577 * 00578 * @param position an iterator specifying the element to erase 00579 */ 00580 void erase(iterator position); 00581 00582 /** 00583 * Erase all elements in the range <tt>[@a first, last)</tt>. 00584 * 00585 * All erase methods invalidate only iterators and references to the 00586 * erased elements. 00587 */ 00588 void erase(iterator first, iterator last); 00589 00590 /** 00591 * Erase an element in the map with key equal to the argument. 00592 * 00593 * All erase methods invalidate only iterators and references to the 00594 * erased elements. 00595 * 00596 * @param k key whose mapping is to be removed from the map. 00597 * 00598 * @return the number of erased elements (0 or 1). 00599 */ 00600 size_type erase(const key_type& k) 00601 { 00602 return delegate()->keySet()->remove(k) ? 1 : 0; 00603 } 00604 00605 /** 00606 * Remove all elements from this map. 00607 */ 00608 void clear() 00609 { 00610 delegate()->clear(); 00611 } 00612 00613 /** 00614 * Swap this map and argument map. 00615 */ 00616 void swap(this_type& x) 00617 { 00618 std::swap(m_ohMap, x.m_ohMap); 00619 } 00620 00621 00622 // ----- map operations ------------------------------------------------- 00623 00624 public: 00625 00626 /** 00627 * @return an iterator pointing to an element with the key equal to 00628 * @a k, or this->end() if such an element is not found. 00629 */ 00630 iterator find(const key_type& k) 00631 { 00632 Map::Handle hMap = delegate(); 00633 if (!hMap->containsKey(k)) 00634 { 00635 return end(); 00636 } 00637 00638 return this->_make_lazy_iterator(hMap, k); 00639 } 00640 00641 /** 00642 * @return an iterator pointing to an element with the key equal to 00643 * @a k, or this->end() if such an element is not found. 00644 */ 00645 const_iterator find(const key_type& k) const 00646 { 00647 Map::View vMap = delegate(); 00648 if (!vMap->containsKey(k)) 00649 { 00650 return end(); 00651 } 00652 00653 return this->_make_lazy_const_iterator(vMap, k); 00654 } 00655 00656 /** 00657 * @return the number of element with key equal to @a k (0 or 1). 00658 */ 00659 size_type count(const key_type& k) const 00660 { 00661 return delegate()->containsKey(k) ? 1 : 0; 00662 } 00663 00664 // sorted map-specific methods lower_bound() and upper_bound() are 00665 // not supported 00666 00667 /** 00668 * @return a std::pair of iterators which locate the element with key @a k. 00669 * If such element is found then the first component of the 00670 * returned std::pair points to the element and the second 00671 * component of the std::pair points to the element immediately 00672 * following the found one in the iterator's traverse order. 00673 * Otherwise returns a this->end(), this->;end() std::pair. 00674 * 00675 * In other words, equal_range always returns the range [x, y) which 00676 * contains the found element only. 00677 */ 00678 std::pair<iterator,iterator> equal_range(const key_type& k); 00679 00680 /** 00681 * @return a std::pair of iterators which locate the element with key @a k. 00682 * If such element is found then the first component of the 00683 * returned std::pair points to the element and the second 00684 * component of the std::pair points to the element immediately 00685 * following the found one in the iterator's traverse order. 00686 * Otherwise returns an this->end(), this->end() std::pair. 00687 * 00688 * In other words, equal_range always returns the range [x, y) which 00689 * contains the found element only. 00690 */ 00691 std::pair<const_iterator,const_iterator> equal_range(const key_type& k) 00692 const; 00693 00694 00695 // ----- other methods -------------------------------------------------- 00696 00697 public: 00698 /** 00699 * @return a copy of the Allocator object 00700 */ 00701 allocator_type get_allocator() const 00702 { 00703 return allocator_type(); 00704 } 00705 00706 00707 // ----- observers: unordered map --------------------------------------- 00708 00709 public: 00710 /** 00711 * @return hash function 00712 */ 00713 hasher hash_function() const 00714 { 00715 return hasher(); 00716 } 00717 00718 /** 00719 * @return key equality predicate 00720 */ 00721 key_equal key_eq() const 00722 { 00723 return key_equal(); 00724 } 00725 00726 00727 // ----- data members --------------------------------------------------- 00728 00729 protected: 00730 /** 00731 * The Coherence Map that is delegated by the adapter_map. 00732 */ 00733 MemberHolder<Map> m_ohMap; 00734 }; 00735 00736 //operators: 00737 00738 // operators ==,!=,<,>,<=,>= are NOT defined for adapter_map 00739 // as adapter_map can be sorted(ordered) or unordered map and 00740 // these operators are not required to be defined for unordered associative containers. 00741 // (see TR1:6.3.1.2 [tr.unord.req.2]) 00742 00743 //specialized algorithms: 00744 00745 /** @relates adapter_map 00746 * Swaps two argument maps. 00747 */ 00748 template <class K, class V> 00749 inline void swap(adapter_map<K,V>& x, adapter_map<K,V>& y) 00750 { 00751 x.swap(y); 00752 } 00753 00754 /** 00755 * Copy the contents of one map to another. 00756 * 00757 * @param mapSrc the source map 00758 * @param mapDes the destination map 00759 */ 00760 template <class MapSrc, class MapDes> void copy_map(const MapSrc& mapSrc, MapDes& mapDes) 00761 { 00762 for (typename MapSrc::const_iterator i = mapSrc.begin(), e = mapSrc.end(); i != e; ++i) 00763 { 00764 mapDes[i->first] = i->second; 00765 } 00766 } 00767 00768 // ----- implementation ----------------------------------------------------- 00769 00770 COH_OPEN_NAMESPACE(impl) 00771 00772 00773 // ----- class _array_proxy ------------------------------------------------- 00774 00775 /** 00776 * @internal 00777 */ 00778 template<class T> 00779 class _arrow_proxy 00780 { 00781 private: 00782 T value; 00783 00784 public: 00785 /** 00786 * @internal 00787 */ 00788 _arrow_proxy(const T& x) 00789 : value(x) 00790 { 00791 } 00792 00793 /** 00794 * @internal 00795 */ 00796 const T* operator->() const 00797 { 00798 return &value; 00799 } 00800 00801 // This function is needed for MWCW and BCC, which won't call 00802 // operator-> again automatically per 13.3.1.2 para 8 00803 /** 00804 * @internal 00805 */ 00806 operator const T*() const 00807 { 00808 return &value; 00809 } 00810 }; 00811 00812 /** 00813 * @internal 00814 */ 00815 template<class V> 00816 class _mapped_proxy : public V 00817 { 00818 private: 00819 const Map::Handle m_hMap; // on stack 00820 Object::View m_vKey; // on stack 00821 00822 public: //not for user! 00823 /** 00824 * @internal 00825 */ 00826 _mapped_proxy(Map::Handle hMap, Object::View vKey, V v) 00827 : V(v), m_hMap(hMap), m_vKey(vKey) 00828 { 00829 COH_ENSURE_PARAM(hMap); 00830 } 00831 00832 public: 00833 /** 00834 * @internal 00835 */ 00836 const _mapped_proxy& operator=(const V& v) const 00837 { 00838 m_hMap->putAll(Collections::singletonMap(m_vKey, v)); 00839 return *this; 00840 } 00841 00842 /** 00843 * @internal 00844 */ 00845 const _mapped_proxy& operator=(const _mapped_proxy& that) const 00846 { 00847 m_hMap->put(Collections::singletonMap(m_vKey, that.m_vValue)); 00848 return *this; 00849 } 00850 }; 00851 00852 /** 00853 * @internal 00854 */ 00855 template<class V> 00856 bool operator==(const _mapped_proxy<V>& x, const _mapped_proxy<V>& y) 00857 { 00858 return V(x) == V(y); 00859 } 00860 00861 /** 00862 * @internal 00863 */ 00864 template<class V> 00865 bool operator==(const _mapped_proxy<V>& x, const V& y) 00866 { 00867 return V(x) == y; 00868 } 00869 00870 /** 00871 * @internal 00872 */ 00873 template<class V> 00874 bool operator==(const V& x, const _mapped_proxy<V>& y) 00875 { 00876 return x == V(y); 00877 } 00878 00879 /** 00880 * @internal 00881 */ 00882 template<class V> 00883 bool operator!=(const _mapped_proxy<V>& x, const _mapped_proxy<V>& y) 00884 { 00885 return !(x == y); 00886 } 00887 00888 /** 00889 * @internal 00890 */ 00891 template<class V> 00892 bool operator!=(const _mapped_proxy<V>& x, const V& y) 00893 { 00894 return !(x == y); 00895 } 00896 00897 /** 00898 * @internal 00899 */ 00900 template<class V> 00901 bool operator!=(const V& x, const _mapped_proxy<V>& y) 00902 { 00903 return !(x == y); 00904 } 00905 00906 /** 00907 * @internal 00908 */ 00909 template<class V> 00910 std::ostream& operator<<(std::ostream& out, const _mapped_proxy<V>& proxy) 00911 { 00912 return out << V(proxy); 00913 } 00914 00915 /** 00916 * @internal 00917 */ 00918 template<class K, class V> 00919 struct _value_proxy 00920 : public std::pair< K, _mapped_proxy<V> > 00921 { 00922 /** 00923 * @internal 00924 */ 00925 typedef std::pair< K, _mapped_proxy<V> > super; 00926 00927 /** 00928 * @internal 00929 */ 00930 _value_proxy() 00931 : super() 00932 { 00933 } 00934 00935 /** 00936 * @internal 00937 */ 00938 _value_proxy(const K& key, const _mapped_proxy<V>& proxy) 00939 : super(key, proxy) 00940 { 00941 } 00942 }; 00943 00944 00945 // ----- iterators ---------------------------------------------------------- 00946 00947 /** 00948 * @internal 00949 */ 00950 template<typename difference_type> 00951 class _iterator_base 00952 { 00953 protected: 00954 /** 00955 * The associated Map. 00956 */ 00957 MemberView<Map> m_vMap; 00958 00959 /** 00960 * The delegate iterator. A value of NULL indicates that the iterator 00961 * has been created lazily, and the first call to _next() will advance 00962 * the iterator to m_vKey. 00963 */ 00964 MemberHandle<Iterator> m_hIter; 00965 00966 /** 00967 * The current key associated with the iterator. 00968 */ 00969 MemberView<Object> m_vKey; 00970 00971 /** 00972 * @internal 00973 */ 00974 _iterator_base(Map::View vMap, Object::View vKey) 00975 : m_vMap(System::common(), vMap), 00976 m_hIter(System::common(), NULL), 00977 m_vKey(System::common(), vKey) 00978 { 00979 } 00980 00981 /** 00982 * @internal 00983 */ 00984 _iterator_base(Map::View vMap, Iterator::Handle hIter) 00985 : m_vMap(System::common(), vMap), 00986 m_hIter(System::common(), hIter), 00987 m_vKey(System::common(), hIter->hasNext() ? hIter->next() : NULL) 00988 { 00989 } 00990 00991 /** 00992 * @internal 00993 */ 00994 _iterator_base(const _iterator_base& that) 00995 : m_vMap(System::common(), that.m_vMap), 00996 m_hIter(System::common(), NULL), 00997 m_vKey(System::common(), that.m_vKey) 00998 { 00999 Iterator::View vIterThat = that.m_hIter; 01000 if (NULL != vIterThat && !vIterThat->hasNext()) 01001 { 01002 m_hIter = EndIterator::getInstance(); 01003 } 01004 } 01005 01006 /** 01007 * @internal 01008 */ 01009 _iterator_base& operator=(const _iterator_base& that) 01010 { 01011 if (this != &that) 01012 { 01013 m_vMap = that.m_vMap; 01014 m_vKey = that.m_vKey; 01015 01016 Iterator::View vIterThat = that.m_hIter; 01017 m_hIter = vIterThat == NULL || vIterThat->hasNext() 01018 ? NULL /*lazy*/ 01019 : EndIterator::getInstance(); 01020 } 01021 return *this; 01022 } 01023 01024 /** 01025 * @internal 01026 */ 01027 void _next() 01028 { 01029 Iterator::Handle hIter = m_hIter; 01030 if (NULL == hIter) 01031 { 01032 // lazy create, and advance the iterator past the stored key 01033 // this is potentially expensive, but also quite rare 01034 hIter = m_vMap->keySet()->iterator(); 01035 Object::View vKey = m_vKey; 01036 01037 while (hIter->hasNext() && !Object::equals(vKey, hIter->next())); 01038 m_hIter = hIter; 01039 } 01040 else if (!hIter->hasNext()) 01041 { 01042 m_hIter = EndIterator::getInstance(); 01043 m_vKey = NULL; 01044 return; 01045 } 01046 01047 01048 if (hIter->hasNext()) 01049 { 01050 m_vKey = hIter->next(); 01051 } 01052 else 01053 { 01054 m_vKey = NULL; 01055 } 01056 } 01057 01058 /** 01059 * @internal 01060 */ 01061 void _incr(difference_type i) 01062 { 01063 COH_ENSURE(i >= 0); 01064 for ( ; i; --i) 01065 { 01066 _next(); 01067 } 01068 } 01069 01070 public: 01071 /** 01072 * @internal 01073 */ 01074 bool operator==(const _iterator_base& that) const 01075 { 01076 if (m_vMap == that.m_vMap) 01077 { 01078 if (m_hIter == EndIterator::getInstance()) 01079 { 01080 return that.m_hIter == EndIterator::getInstance(); 01081 } 01082 return Object::equals(m_vKey, that.m_vKey); 01083 } 01084 return false; 01085 } 01086 01087 /** 01088 * @internal 01089 */ 01090 bool operator!=(const _iterator_base& i) const 01091 { 01092 return !(*this == i); 01093 } 01094 }; 01095 01096 /** 01097 * @internal 01098 */ 01099 template<class K, class V> 01100 class _const_iterator 01101 : public _iterator_base<typename _adapter_map_base<K,V>::difference_type> 01102 { 01103 friend class _adapter_map_base<K,V>; 01104 friend class _iterator<K,V>; 01105 typedef _iterator_base<typename _adapter_map_base<K,V>::difference_type> 01106 super; 01107 01108 public: 01109 /** 01110 * @internal 01111 */ 01112 typedef std::forward_iterator_tag iterator_category; 01113 01114 /** 01115 * @internal 01116 */ 01117 typedef typename _adapter_map_base<K,V>::difference_type difference_type; 01118 01119 /** 01120 * @internal 01121 */ 01122 typedef typename _adapter_map_base<K,V>::value_type value_type; 01123 01124 /** 01125 * @internal 01126 */ 01127 typedef value_type reference; 01128 01129 /** 01130 * @internal 01131 */ 01132 typedef _arrow_proxy<const value_type> pointer; 01133 01134 /** 01135 * @internal 01136 */ 01137 _const_iterator(const _const_iterator& that) 01138 : super(that) 01139 { 01140 } 01141 01142 /** 01143 * @internal 01144 */ 01145 reference operator*() const 01146 { 01147 K key = cast<K>(super::m_vKey); 01148 return _make_pair(key, cast<V>(super::m_vMap->get(key))); 01149 } 01150 01151 /** 01152 * @internal 01153 */ 01154 pointer operator->() const 01155 { 01156 return pointer(operator*()); 01157 } 01158 01159 /** 01160 * @internal 01161 */ 01162 _const_iterator& operator++() 01163 { 01164 super::_next(); 01165 return *this; 01166 } 01167 01168 /** 01169 * @internal 01170 */ 01171 _const_iterator operator++(int) 01172 { 01173 _const_iterator r = *this; 01174 super::_next(); 01175 return r; 01176 } 01177 01178 /** 01179 * @internal 01180 */ 01181 _const_iterator& operator+=(difference_type i) 01182 { 01183 _incr(i); 01184 return *this; 01185 } 01186 01187 /** 01188 * @internal 01189 */ 01190 _const_iterator operator+(difference_type i) const 01191 { 01192 _const_iterator r = *this; 01193 return r += i; 01194 } 01195 01196 /** 01197 * @internal 01198 */ 01199 reference operator[](difference_type i) 01200 { 01201 return *(*this + i); 01202 } 01203 01204 private: 01205 /** 01206 * @internal 01207 */ 01208 _const_iterator(Map::View vMap, Iterator::Handle hIter) 01209 : super(vMap, hIter) 01210 { 01211 } 01212 01213 /** 01214 * @internal 01215 */ 01216 _const_iterator(Map::View vMap, Object::View vKey) 01217 : super(vMap, vKey) 01218 { 01219 } 01220 01221 /** 01222 * @internal 01223 */ 01224 reference _make_pair(K key, V value) const 01225 { 01226 return value_type(key, value); 01227 } 01228 }; 01229 01230 /** 01231 * @internal 01232 */ 01233 template<class K, class V> 01234 class _iterator 01235 : public _const_iterator<K,V> 01236 { 01237 friend class _adapter_map_base<K,V>; 01238 01239 private: 01240 typedef _const_iterator<K,V> super; 01241 01242 public: 01243 /** 01244 * @internal 01245 */ 01246 _iterator(const _iterator& that) 01247 : super(that), m_hMap(System::common(), that.m_hMap, true) 01248 { 01249 } 01250 01251 /** 01252 * @internal 01253 */ 01254 typedef typename super::difference_type difference_type; 01255 01256 /** 01257 * @internal 01258 */ 01259 typedef const _mapped_proxy<V> mapped_reference; 01260 01261 /** 01262 * @internal 01263 */ 01264 typedef const _value_proxy<const K, V> reference; 01265 01266 /** 01267 * @internal 01268 */ 01269 typedef const _arrow_proxy<reference> pointer; 01270 01271 /** 01272 * @internal 01273 */ 01274 reference operator*() const 01275 { 01276 K key = cast<K>(super::m_vKey); 01277 return _make_ref(key, cast<V>(m_hMap->get(key))); 01278 } 01279 01280 /** 01281 * @internal 01282 */ 01283 pointer operator->() const 01284 { 01285 return pointer(operator*()); 01286 } 01287 01288 /** 01289 * @internal 01290 */ 01291 _iterator& operator++() 01292 { 01293 super::_next(); 01294 return *this; 01295 } 01296 01297 /** 01298 * @internal 01299 */ 01300 _iterator operator++(int) 01301 { 01302 _iterator r = *this; 01303 super::_next(); 01304 return r; 01305 } 01306 01307 /** 01308 * @internal 01309 */ 01310 _iterator& operator+=(difference_type i) 01311 { 01312 _incr(i); 01313 return *this; 01314 } 01315 01316 /** 01317 * @internal 01318 */ 01319 _iterator operator+(difference_type i) const 01320 { 01321 _iterator r = *this; 01322 return r += i; 01323 } 01324 01325 /** 01326 * @internal 01327 */ 01328 reference operator[](difference_type i) 01329 { 01330 return *(*this + i); 01331 } 01332 01333 private: 01334 /** 01335 * @internal 01336 */ 01337 mutable MemberHandle<Map> m_hMap; 01338 01339 /** 01340 * @internal 01341 */ 01342 _iterator(Map::Handle hMap, Iterator::Handle hIter) 01343 : super(hMap, hIter), m_hMap(System::common(), hMap, true) 01344 { 01345 } 01346 01347 /** 01348 * @internal 01349 */ 01350 _iterator(Map::Handle hMap, Object::View vKey) 01351 : super(hMap, vKey), m_hMap(System::common(), hMap, true) 01352 { 01353 } 01354 01355 /** 01356 * @internal 01357 */ 01358 reference _make_ref(K key, V value) const 01359 { 01360 return reference(key, _mapped_proxy<V>(m_hMap, key, value)); 01361 } 01362 }; 01363 01364 /** 01365 * @internal 01366 */ 01367 template<class K, class V> 01368 inline _const_iterator<K,V> operator+ 01369 (typename _const_iterator<K,V>::difference_type n, 01370 const _const_iterator<K,V>& x) 01371 { 01372 return x + n; 01373 } 01374 01375 /** 01376 * @internal 01377 */ 01378 template<class K, class V> 01379 bool operator==(const _value_proxy<K,V>& x, const std::pair<K,V>& y) 01380 { 01381 return (x.first == y.first) && (x.second == y.second); 01382 } 01383 01384 /** 01385 * @internal 01386 */ 01387 template<class K, class V> 01388 bool operator==(const std::pair<K,V>& x, const _value_proxy<K,V>& y) 01389 { 01390 return (x.first == y.first) && (x.second == y.second); 01391 } 01392 01393 /** 01394 * @internal 01395 */ 01396 template<class K, class V> 01397 inline _iterator<K,V> 01398 operator+(typename _iterator<K,V>::difference_type n, const _iterator<K,V>& x) 01399 { 01400 return x + n; 01401 } 01402 01403 /** 01404 * @internal 01405 */ 01406 template<class K, class V> 01407 inline typename _adapter_map_base<K,V>::iterator 01408 _adapter_map_base<K,V>::_make_iterator(Map::Handle hMap, Iterator::Handle hIter) 01409 { 01410 return iterator(hMap, hIter); 01411 } 01412 01413 /** 01414 * @internal 01415 */ 01416 template<class K, class V> 01417 inline typename _adapter_map_base<K,V>::iterator 01418 _adapter_map_base<K,V>::_make_lazy_iterator(Map::Handle hMap, Object::View vKey) 01419 { 01420 return iterator(hMap, vKey); 01421 } 01422 01423 /** 01424 * @internal 01425 */ 01426 template<class K, class V> 01427 inline typename _adapter_map_base<K,V>::const_iterator 01428 _adapter_map_base<K,V>::_make_const_iterator(Map::View vMap, 01429 Iterator::Handle hIter) const 01430 { 01431 return const_iterator(vMap, hIter); 01432 } 01433 01434 /** 01435 * @internal 01436 */ 01437 template<class K, class V> 01438 inline typename _adapter_map_base<K,V>::const_iterator 01439 _adapter_map_base<K,V>::_make_lazy_const_iterator(Map::View vMap, 01440 Object::View vKey) const 01441 { 01442 return const_iterator(vMap, vKey); 01443 } 01444 01445 COH_CLOSE_NAMESPACE // impl 01446 01447 01448 // ----- Observers ----------------------------------------------------------- 01449 01450 /** @relates adapter_map 01451 * Hasher function. 01452 * 01453 * A function object that takes a single argument of type key_type and 01454 * returns a value of type size32_t. 01455 */ 01456 template<class K, class V> 01457 class adapter_map<K,V>::hasher 01458 : public std::unary_function<key_type, size32_t> 01459 { 01460 public: 01461 /** 01462 * Determine a hash code corresponding to a given key object. 01463 * 01464 * @param k the handle to the key Object, may be @c NULL. 01465 * 01466 * @return a hash code of the key object, or 0 if @c NULL handle 01467 * was provided 01468 */ 01469 size32_t operator()(const key_type& k) const 01470 { 01471 return Object::hashCode(k); 01472 } 01473 }; 01474 01475 /** @relates adapter_map 01476 * Key equality relation. 01477 * 01478 * Binary predicate that takes two arguments of type key_type. 01479 */ 01480 template<class K, class V> 01481 class adapter_map<K,V>::key_equal 01482 : public std::binary_function<key_type, key_type, bool> 01483 { 01484 public: 01485 /** 01486 * Compare two key objects for equality. 01487 * 01488 * @param x the handle to the first key Object 01489 * @param y the handle to the second key Object 01490 * 01491 * @return whether two keys are equal 01492 */ 01493 bool operator()(const key_type& x, const key_type& y) const 01494 { 01495 return Object::equals(x, y); 01496 } 01497 }; 01498 01499 01500 // ----- adapter_map methods ----------------------------------------------------- 01501 01502 //element access: 01503 template<class K, class V> 01504 inline typename adapter_map<K,V>::mapped_reference 01505 adapter_map<K,V>::operator[](const key_type& key) 01506 { 01507 // operator[] is not part of the associative container concept, but is 01508 // defined within map implementations. As it is not part of the concept 01509 // we have some leverage with respect to the implementation. Most notably 01510 // we are not required to delegate to the insert method, which can be 01511 // expensive as it requires an iteration scan. Additionally we are not 01512 // required to insert of test, i.e. v = m[k], does not have to set a value 01513 // for k if it did not already exist 01514 01515 Map::Handle hMap = delegate(); 01516 return mapped_reference(hMap, key, cast<V>(hMap->get(key))); 01517 } 01518 01519 template<class K, class V> 01520 inline typename adapter_map<K,V>::mapped_type 01521 adapter_map<K,V>::operator[](const key_type& key) const 01522 { 01523 // see note from non-const version 01524 return cast<V>(delegate()->get(key)); 01525 } 01526 01527 //modifiers: 01528 template<class K, class V> 01529 inline std::pair<typename adapter_map<K,V>::iterator, bool> 01530 adapter_map<K,V>::insert(const value_type& p) 01531 { 01532 Map::Handle hMap = delegate(); 01533 if (instanceof<InvocableMap::Handle>(hMap)) 01534 { 01535 // perform conditional put 01536 if (NULL == (cast<InvocableMap::Handle>(hMap)-> 01537 invoke(p.first, ConditionalPut::create(NotFilter::create( 01538 PresentFilter::getInstance()), p.second, true)))) 01539 { 01540 // insert occurred 01541 return std::pair<iterator, bool>(find(p.first), false); 01542 } 01543 } 01544 else if (!hMap->containsKey(p.first)) 01545 { 01546 // key not found, insert element 01547 hMap->put(p.first, p.second); 01548 return std::pair<iterator, bool>(find(p.first), false); 01549 } 01550 01551 // key already exists in the map 01552 return std::pair<iterator, bool>(find(p.first), true); 01553 } 01554 01555 template<class K, class V> 01556 template <class InputIterator> 01557 inline void adapter_map<K,V>::insert(InputIterator first, InputIterator last) 01558 { 01559 Map::Handle hMapDelegate = delegate(); 01560 if (instanceof<InvocableMap::Handle>(hMapDelegate)) 01561 { 01562 Map::Handle hMapTmp = HashMap::create(); 01563 for ( ;first != last; ++first) 01564 { 01565 hMapTmp->put(K(first->first), V(first->second)); 01566 } 01567 01568 cast<InvocableMap::Handle>(hMapDelegate)->invokeAll( 01569 (Collection::View) hMapTmp->keySet(), 01570 ConditionalPutAll::create(NotFilter::create( 01571 PresentFilter::getInstance()), 01572 hMapTmp)); 01573 } 01574 else 01575 { 01576 for ( ;first != last; ++first) 01577 { 01578 K key = K(first->first); 01579 if (!hMapDelegate->containsKey(key)) 01580 { 01581 hMapDelegate->put(key, V(first->second)); 01582 } 01583 } 01584 } 01585 } 01586 01587 template<class K, class V> 01588 inline void adapter_map<K,V>::erase(iterator position) 01589 { 01590 erase(position->first); 01591 } 01592 01593 template<class K, class V> 01594 inline void adapter_map<K,V>::erase(iterator first, iterator last) 01595 { 01596 if (first == begin() && last == end()) 01597 { 01598 clear(); 01599 } 01600 else 01601 { 01602 while (first != last) 01603 { 01604 erase(first++); 01605 } 01606 } 01607 } 01608 01609 //map operations: 01610 template<class K, class V> 01611 inline std::pair< typename adapter_map<K,V>::iterator, 01612 typename adapter_map<K,V>::iterator > 01613 adapter_map<K,V>::equal_range(const key_type& x) 01614 { 01615 iterator a = find(x); 01616 iterator b = a == end() ? end() : a + 1; 01617 return make_pair(a, b); 01618 } 01619 01620 template<class K, class V> 01621 inline std::pair< typename adapter_map<K,V>::const_iterator, 01622 typename adapter_map<K,V>::const_iterator > 01623 adapter_map<K,V>::equal_range(const key_type& x) const 01624 { 01625 const_iterator a = find(x); 01626 const_iterator b = a == end() ? end() : a + 1; 01627 return make_pair(a, b); 01628 } 01629 01630 COH_CLOSE_NAMESPACE2 01631 01632 #endif // COH_ADAPTER_MAP_HPP