Oracle® Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.1.3.0.0)

E47891-01

coherence/stl/adapter_map.hpp

00001 /*
00002 * adapter_map.hpp
00003 *
00004 * Copyright (c) 2000, 2014, 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             : f_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             : f_ohMap(System::common(), that.f_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             initialize(f_ohMap, (Map::Holder) that.f_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             initialize(f_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 = f_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 f_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(f_ohMap, x.f_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         FinalHolder<Map> f_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         FinalView<Map> f_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                 : f_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                 : f_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                 : f_vMap(System::common(), that.f_vMap),
00996                   m_hIter(System::common(), NULL),
00997                   m_vKey(System::common(), that.m_vKey)
00998             {
00999             Iterator::Handle endIterator = EndIterator::getInstance();
01000             if (endIterator == that.m_hIter)
01001                 {
01002                 m_hIter = endIterator;
01003                 }
01004             }
01005 
01006         /**
01007         * @internal
01008         */
01009         _iterator_base& operator=(const _iterator_base& that)
01010             {
01011             if (this != &that)
01012                 {
01013                 f_vMap  = that.f_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 = f_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 (f_vMap == that.f_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::f_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), f_hMap(System::common(), that.f_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>(f_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 FinalHandle<Map> f_hMap;
01338 
01339         /**
01340         * @internal
01341         */
01342         _iterator(Map::Handle hMap, Iterator::Handle hIter)
01343             : super(hMap, hIter), f_hMap(System::common(), hMap, true)
01344             {
01345             }
01346 
01347         /**
01348         * @internal
01349         */
01350         _iterator(Map::Handle hMap, Object::View vKey)
01351                 : super(hMap, vKey), f_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>(f_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
Copyright © 2000, 2014, Oracle and/or its affiliates. All rights reserved.