C++ Client API Reference for Oracle Coherence
14c (14.1.2.0.0)

F79659-03

coherence/stl/adapter_map.hpp

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