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_REFVECTOR_HXX 25 #define OOX_HELPER_REFVECTOR_HXX 26 27 #include <vector> 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 vector of ref-counted objects with additional accessor functions. 37 38 An instance of the class RefVector< Type > stores elements of the type 39 ::boost::shared_ptr< Type >. The new accessor functions has() and get() 40 work correctly for indexes out of the current range, there is no need to 41 check the passed index before. 42 */ 43 template< typename ObjType > 44 class RefVector : public ::std::vector< ::boost::shared_ptr< ObjType > > 45 { 46 public: 47 typedef ::std::vector< ::boost::shared_ptr< ObjType > > container_type; 48 typedef typename container_type::value_type value_type; 49 typedef typename container_type::size_type size_type; 50 51 public: 52 /** Returns true, if the object with the passed index exists. Returns 53 false, if the vector element exists but is an empty reference. */ has(sal_Int32 nIndex) const54 inline bool has( sal_Int32 nIndex ) const 55 { 56 const value_type* pxRef = getRef( nIndex ); 57 return pxRef && pxRef->get(); 58 } 59 60 /** Returns a reference to the object with the passed index, or 0 on error. */ get(sal_Int32 nIndex) const61 inline value_type get( sal_Int32 nIndex ) const 62 { 63 if( const value_type* pxRef = getRef( nIndex ) ) return *pxRef; 64 return value_type(); 65 } 66 67 /** Returns the index of the last element, or -1, if the vector is empty. 68 Does *not* check whether the last element is an empty reference. */ getLastIndex() const69 inline sal_Int32 getLastIndex() const { return static_cast< sal_Int32 >( this->size() ) - 1; } 70 71 /** Calls the passed functor for every contained object, automatically 72 skips all elements that are empty references. */ 73 template< typename FunctorType > forEach(FunctorType aFunctor) const74 inline void forEach( FunctorType aFunctor ) const 75 { 76 ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( aFunctor ) ); 77 } 78 79 /** Calls the passed member function of ObjType on every contained object, 80 automatically skips all elements that are empty references. */ 81 template< typename FuncType > forEachMem(FuncType pFunc) const82 inline void forEachMem( FuncType pFunc ) const 83 { 84 forEach( ::boost::bind( pFunc, _1 ) ); 85 } 86 87 /** Calls the passed member function of ObjType on every contained object, 88 automatically skips all elements that are empty references. */ 89 template< typename FuncType, typename ParamType > forEachMem(FuncType pFunc,ParamType aParam) const90 inline void forEachMem( FuncType pFunc, ParamType aParam ) const 91 { 92 forEach( ::boost::bind( pFunc, _1, aParam ) ); 93 } 94 95 /** Calls the passed member function of ObjType on every contained object, 96 automatically skips all elements that are empty references. */ 97 template< typename FuncType, typename ParamType1, typename ParamType2 > forEachMem(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2) const98 inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 99 { 100 forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) ); 101 } 102 103 /** Calls the passed member function of ObjType on every contained object, 104 automatically skips all elements that are empty references. */ 105 template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > forEachMem(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2,ParamType3 aParam3) const106 inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 107 { 108 forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) ); 109 } 110 111 /** Calls the passed functor for every contained object. Passes the index as 112 first argument and the object reference as second argument to rFunctor. */ 113 template< typename FunctorType > forEachWithIndex(const FunctorType & rFunctor) const114 inline void forEachWithIndex( const FunctorType& rFunctor ) const 115 { 116 ::std::for_each( this->begin(), this->end(), ForEachFunctorWithIndex< FunctorType >( rFunctor ) ); 117 } 118 119 /** Calls the passed member function of ObjType on every contained object. 120 Passes the vector index to the member function. */ 121 template< typename FuncType > forEachMemWithIndex(FuncType pFunc) const122 inline void forEachMemWithIndex( FuncType pFunc ) const 123 { 124 forEachWithIndex( ::boost::bind( pFunc, _2, _1 ) ); 125 } 126 127 /** Calls the passed member function of ObjType on every contained object. 128 Passes the vector index as first argument to the member function. */ 129 template< typename FuncType, typename ParamType > forEachMemWithIndex(FuncType pFunc,ParamType aParam) const130 inline void forEachMemWithIndex( FuncType pFunc, ParamType aParam ) const 131 { 132 forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam ) ); 133 } 134 135 /** Calls the passed member function of ObjType on every contained object. 136 Passes the vector index as first argument to the member function. */ 137 template< typename FuncType, typename ParamType1, typename ParamType2 > forEachMemWithIndex(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2) const138 inline void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 139 { 140 forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam1, aParam2 ) ); 141 } 142 143 /** Calls the passed member function of ObjType on every contained object. 144 Passes the vector index as first argument to the member function. */ 145 template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > forEachMemWithIndex(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2,ParamType3 aParam3) const146 inline void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 147 { 148 forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam1, aParam2, aParam3 ) ); 149 } 150 151 /** Searches for an element by using the passed functor that takes a 152 constant reference of the object type (const ObjType&). */ 153 template< typename FunctorType > findIf(const FunctorType & rFunctor) const154 inline value_type findIf( const FunctorType& rFunctor ) const 155 { 156 typename container_type::const_iterator aIt = ::std::find_if( this->begin(), this->end(), FindFunctor< FunctorType >( rFunctor ) ); 157 return (aIt == this->end()) ? value_type() : *aIt; 158 } 159 160 private: 161 template< typename FunctorType > 162 struct ForEachFunctor 163 { 164 FunctorType maFunctor; ForEachFunctoroox::RefVector::ForEachFunctor165 inline explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} operator ()oox::RefVector::ForEachFunctor166 inline void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( *rxValue ); } 167 }; 168 169 template< typename FunctorType > 170 struct ForEachFunctorWithIndex 171 { 172 FunctorType maFunctor; 173 sal_Int32 mnIndex; ForEachFunctorWithIndexoox::RefVector::ForEachFunctorWithIndex174 inline explicit ForEachFunctorWithIndex( const FunctorType& rFunctor ) : maFunctor( rFunctor ), mnIndex( 0 ) {} operator ()oox::RefVector::ForEachFunctorWithIndex175 inline void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( mnIndex, *rxValue ); ++mnIndex; } 176 }; 177 178 template< typename FunctorType > 179 struct FindFunctor 180 { 181 FunctorType maFunctor; FindFunctoroox::RefVector::FindFunctor182 inline explicit FindFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} operator ()oox::RefVector::FindFunctor183 inline bool operator()( const value_type& rxValue ) { return rxValue.get() && maFunctor( *rxValue ); } 184 }; 185 getRef(sal_Int32 nIndex) const186 inline const value_type* getRef( sal_Int32 nIndex ) const 187 { 188 return ((0 <= nIndex) && (static_cast< size_type >( nIndex ) < this->size())) ? 189 &(*this)[ static_cast< size_type >( nIndex ) ] : 0; 190 } 191 }; 192 193 // ============================================================================ 194 195 } // namespace oox 196 197 #endif 198