1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef OOX_HELPER_REFMAP_HXX 25 #define OOX_HELPER_REFMAP_HXX 26 27 #include <map> 28 #include <boost/bind.hpp> 29 #include <boost/shared_ptr.hpp> 30 #include <sal/types.h> 31 32 namespace oox { 33 34 // ============================================================================ 35 36 /** Template for a map of ref-counted objects with additional accessor functions. 37 38 An instance of the class RefMap< Type > stores elements of the type 39 ::boost::shared_ptr< Type >. The new accessor functions has() and get() 40 work correctly for nonexisting keys, there is no need to check the passed 41 key before. 42 */ 43 template< typename KeyType, typename ObjType, typename CompType = ::std::less< KeyType > > 44 class RefMap : public ::std::map< KeyType, ::boost::shared_ptr< ObjType >, CompType > 45 { 46 public: 47 typedef ::std::map< KeyType, ::boost::shared_ptr< ObjType >, CompType > container_type; 48 typedef typename container_type::key_type key_type; 49 typedef typename container_type::mapped_type mapped_type; 50 typedef typename container_type::value_type value_type; 51 typedef typename container_type::key_compare key_compare; 52 53 public: 54 /** Returns true, if the object accossiated to the passed key exists. 55 Returns false, if the key exists but points to an empty reference. */ 56 inline bool has( key_type nKey ) const 57 { 58 const mapped_type* pxRef = getRef( nKey ); 59 return pxRef && pxRef->get(); 60 } 61 62 /** Returns a reference to the object accossiated to the passed key, or an 63 empty reference on error. */ 64 inline mapped_type get( key_type nKey ) const 65 { 66 if( const mapped_type* pxRef = getRef( nKey ) ) return *pxRef; 67 return mapped_type(); 68 } 69 70 /** Calls the passed functor for every contained object, automatically 71 skips all elements that are empty references. */ 72 template< typename FunctorType > 73 inline void forEach( const FunctorType& rFunctor ) const 74 { 75 ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( rFunctor ) ); 76 } 77 78 /** Calls the passed member function of ObjType on every contained object, 79 automatically skips all elements that are empty references. */ 80 template< typename FuncType > 81 inline void forEachMem( FuncType pFunc ) const 82 { 83 forEach( ::boost::bind( pFunc, _1 ) ); 84 } 85 86 /** Calls the passed member function of ObjType on every contained object, 87 automatically skips all elements that are empty references. */ 88 template< typename FuncType, typename ParamType > 89 inline void forEachMem( FuncType pFunc, ParamType aParam ) const 90 { 91 forEach( ::boost::bind( pFunc, _1, aParam ) ); 92 } 93 94 /** Calls the passed member function of ObjType on every contained object, 95 automatically skips all elements that are empty references. */ 96 template< typename FuncType, typename ParamType1, typename ParamType2 > 97 inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 98 { 99 forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) ); 100 } 101 102 /** Calls the passed member function of ObjType on every contained object, 103 automatically skips all elements that are empty references. */ 104 template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > 105 inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 106 { 107 forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) ); 108 } 109 /** Calls the passed functor for every contained object. Passes the key as 110 first argument and the object reference as second argument to rFunctor. */ 111 template< typename FunctorType > 112 inline void forEachWithKey( const FunctorType& rFunctor ) const 113 { 114 ::std::for_each( this->begin(), this->end(), ForEachFunctorWithKey< FunctorType >( rFunctor ) ); 115 } 116 117 /** Calls the passed member function of ObjType on every contained object. 118 Passes the object key as argument to the member function. */ 119 template< typename FuncType > 120 inline void forEachMemWithKey( FuncType pFunc ) const 121 { 122 forEachWithKey( ::boost::bind( pFunc, _2, _1 ) ); 123 } 124 125 /** Calls the passed member function of ObjType on every contained object. 126 Passes the object key as first argument to the member function. */ 127 template< typename FuncType, typename ParamType > 128 inline void forEachMemWithKey( FuncType pFunc, ParamType aParam ) const 129 { 130 forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam ) ); 131 } 132 133 /** Calls the passed member function of ObjType on every contained object. 134 Passes the object key as first argument to the member function. */ 135 template< typename FuncType, typename ParamType1, typename ParamType2 > 136 inline void forEachMemWithKey( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 137 { 138 forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam1, aParam2 ) ); 139 } 140 141 /** Calls the passed member function of ObjType on every contained object. 142 Passes the object key as first argument to the member function. */ 143 template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > 144 inline void forEachMemWithKey( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 145 { 146 forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam1, aParam2, aParam3 ) ); 147 } 148 149 private: 150 template< typename FunctorType > 151 struct ForEachFunctor 152 { 153 FunctorType maFunctor; 154 inline explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} 155 inline void operator()( const value_type& rValue ) { if( rValue.second.get() ) maFunctor( *rValue.second ); } 156 }; 157 158 template< typename FunctorType > 159 struct ForEachFunctorWithKey 160 { 161 FunctorType maFunctor; 162 inline explicit ForEachFunctorWithKey( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} 163 inline void operator()( const value_type& rValue ) { if( rValue.second.get() ) maFunctor( rValue.first, *rValue.second ); } 164 }; 165 166 inline const mapped_type* getRef( key_type nKey ) const 167 { 168 typename container_type::const_iterator aIt = find( nKey ); 169 return (aIt == this->end()) ? 0 : &aIt->second; 170 } 171 }; 172 173 // ============================================================================ 174 175 } // namespace oox 176 177 #endif 178