1*e3508121SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*e3508121SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*e3508121SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*e3508121SAndrew Rist * distributed with this work for additional information 6*e3508121SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*e3508121SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*e3508121SAndrew Rist * "License"); you may not use this file except in compliance 9*e3508121SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*e3508121SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*e3508121SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*e3508121SAndrew Rist * software distributed under the License is distributed on an 15*e3508121SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*e3508121SAndrew Rist * KIND, either express or implied. See the License for the 17*e3508121SAndrew Rist * specific language governing permissions and limitations 18*e3508121SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*e3508121SAndrew Rist *************************************************************/ 21*e3508121SAndrew Rist 22*e3508121SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #ifndef OOX_HELPER_REFVECTOR_HXX 25cdf0e10cSrcweir #define OOX_HELPER_REFVECTOR_HXX 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <vector> 28cdf0e10cSrcweir #include <boost/bind.hpp> 29cdf0e10cSrcweir #include <boost/shared_ptr.hpp> 30cdf0e10cSrcweir #include <sal/types.h> 31cdf0e10cSrcweir 32cdf0e10cSrcweir namespace oox { 33cdf0e10cSrcweir 34cdf0e10cSrcweir // ============================================================================ 35cdf0e10cSrcweir 36cdf0e10cSrcweir /** Template for a vector of ref-counted objects with additional accessor functions. 37cdf0e10cSrcweir 38cdf0e10cSrcweir An instance of the class RefVector< Type > stores elements of the type 39cdf0e10cSrcweir ::boost::shared_ptr< Type >. The new accessor functions has() and get() 40cdf0e10cSrcweir work correctly for indexes out of the current range, there is no need to 41cdf0e10cSrcweir check the passed index before. 42cdf0e10cSrcweir */ 43cdf0e10cSrcweir template< typename ObjType > 44cdf0e10cSrcweir class RefVector : public ::std::vector< ::boost::shared_ptr< ObjType > > 45cdf0e10cSrcweir { 46cdf0e10cSrcweir public: 47cdf0e10cSrcweir typedef ::std::vector< ::boost::shared_ptr< ObjType > > container_type; 48cdf0e10cSrcweir typedef typename container_type::value_type value_type; 49cdf0e10cSrcweir typedef typename container_type::size_type size_type; 50cdf0e10cSrcweir 51cdf0e10cSrcweir public: 52cdf0e10cSrcweir /** Returns true, if the object with the passed index exists. Returns 53cdf0e10cSrcweir false, if the vector element exists but is an empty reference. */ has(sal_Int32 nIndex) const54cdf0e10cSrcweir inline bool has( sal_Int32 nIndex ) const 55cdf0e10cSrcweir { 56cdf0e10cSrcweir const value_type* pxRef = getRef( nIndex ); 57cdf0e10cSrcweir return pxRef && pxRef->get(); 58cdf0e10cSrcweir } 59cdf0e10cSrcweir 60cdf0e10cSrcweir /** Returns a reference to the object with the passed index, or 0 on error. */ get(sal_Int32 nIndex) const61cdf0e10cSrcweir inline value_type get( sal_Int32 nIndex ) const 62cdf0e10cSrcweir { 63cdf0e10cSrcweir if( const value_type* pxRef = getRef( nIndex ) ) return *pxRef; 64cdf0e10cSrcweir return value_type(); 65cdf0e10cSrcweir } 66cdf0e10cSrcweir 67cdf0e10cSrcweir /** Returns the index of the last element, or -1, if the vector is empty. 68cdf0e10cSrcweir Does *not* check whether the last element is an empty reference. */ getLastIndex() const69cdf0e10cSrcweir inline sal_Int32 getLastIndex() const { return static_cast< sal_Int32 >( this->size() ) - 1; } 70cdf0e10cSrcweir 71cdf0e10cSrcweir /** Calls the passed functor for every contained object, automatically 72cdf0e10cSrcweir skips all elements that are empty references. */ 73cdf0e10cSrcweir template< typename FunctorType > forEach(FunctorType aFunctor) const74cdf0e10cSrcweir inline void forEach( FunctorType aFunctor ) const 75cdf0e10cSrcweir { 76cdf0e10cSrcweir ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( aFunctor ) ); 77cdf0e10cSrcweir } 78cdf0e10cSrcweir 79cdf0e10cSrcweir /** Calls the passed member function of ObjType on every contained object, 80cdf0e10cSrcweir automatically skips all elements that are empty references. */ 81cdf0e10cSrcweir template< typename FuncType > forEachMem(FuncType pFunc) const82cdf0e10cSrcweir inline void forEachMem( FuncType pFunc ) const 83cdf0e10cSrcweir { 84cdf0e10cSrcweir forEach( ::boost::bind( pFunc, _1 ) ); 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir /** Calls the passed member function of ObjType on every contained object, 88cdf0e10cSrcweir automatically skips all elements that are empty references. */ 89cdf0e10cSrcweir template< typename FuncType, typename ParamType > forEachMem(FuncType pFunc,ParamType aParam) const90cdf0e10cSrcweir inline void forEachMem( FuncType pFunc, ParamType aParam ) const 91cdf0e10cSrcweir { 92cdf0e10cSrcweir forEach( ::boost::bind( pFunc, _1, aParam ) ); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir 95cdf0e10cSrcweir /** Calls the passed member function of ObjType on every contained object, 96cdf0e10cSrcweir automatically skips all elements that are empty references. */ 97cdf0e10cSrcweir template< typename FuncType, typename ParamType1, typename ParamType2 > forEachMem(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2) const98cdf0e10cSrcweir inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 99cdf0e10cSrcweir { 100cdf0e10cSrcweir forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) ); 101cdf0e10cSrcweir } 102cdf0e10cSrcweir 103cdf0e10cSrcweir /** Calls the passed member function of ObjType on every contained object, 104cdf0e10cSrcweir automatically skips all elements that are empty references. */ 105cdf0e10cSrcweir template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > forEachMem(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2,ParamType3 aParam3) const106cdf0e10cSrcweir inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 107cdf0e10cSrcweir { 108cdf0e10cSrcweir forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) ); 109cdf0e10cSrcweir } 110cdf0e10cSrcweir 111cdf0e10cSrcweir /** Calls the passed functor for every contained object. Passes the index as 112cdf0e10cSrcweir first argument and the object reference as second argument to rFunctor. */ 113cdf0e10cSrcweir template< typename FunctorType > forEachWithIndex(const FunctorType & rFunctor) const114cdf0e10cSrcweir inline void forEachWithIndex( const FunctorType& rFunctor ) const 115cdf0e10cSrcweir { 116cdf0e10cSrcweir ::std::for_each( this->begin(), this->end(), ForEachFunctorWithIndex< FunctorType >( rFunctor ) ); 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir /** Calls the passed member function of ObjType on every contained object. 120cdf0e10cSrcweir Passes the vector index to the member function. */ 121cdf0e10cSrcweir template< typename FuncType > forEachMemWithIndex(FuncType pFunc) const122cdf0e10cSrcweir inline void forEachMemWithIndex( FuncType pFunc ) const 123cdf0e10cSrcweir { 124cdf0e10cSrcweir forEachWithIndex( ::boost::bind( pFunc, _2, _1 ) ); 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir /** Calls the passed member function of ObjType on every contained object. 128cdf0e10cSrcweir Passes the vector index as first argument to the member function. */ 129cdf0e10cSrcweir template< typename FuncType, typename ParamType > forEachMemWithIndex(FuncType pFunc,ParamType aParam) const130cdf0e10cSrcweir inline void forEachMemWithIndex( FuncType pFunc, ParamType aParam ) const 131cdf0e10cSrcweir { 132cdf0e10cSrcweir forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam ) ); 133cdf0e10cSrcweir } 134cdf0e10cSrcweir 135cdf0e10cSrcweir /** Calls the passed member function of ObjType on every contained object. 136cdf0e10cSrcweir Passes the vector index as first argument to the member function. */ 137cdf0e10cSrcweir template< typename FuncType, typename ParamType1, typename ParamType2 > forEachMemWithIndex(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2) const138cdf0e10cSrcweir inline void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 139cdf0e10cSrcweir { 140cdf0e10cSrcweir forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam1, aParam2 ) ); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir 143cdf0e10cSrcweir /** Calls the passed member function of ObjType on every contained object. 144cdf0e10cSrcweir Passes the vector index as first argument to the member function. */ 145cdf0e10cSrcweir template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > forEachMemWithIndex(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2,ParamType3 aParam3) const146cdf0e10cSrcweir inline void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 147cdf0e10cSrcweir { 148cdf0e10cSrcweir forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam1, aParam2, aParam3 ) ); 149cdf0e10cSrcweir } 150cdf0e10cSrcweir 151cdf0e10cSrcweir /** Searches for an element by using the passed functor that takes a 152cdf0e10cSrcweir constant reference of the object type (const ObjType&). */ 153cdf0e10cSrcweir template< typename FunctorType > findIf(const FunctorType & rFunctor) const154cdf0e10cSrcweir inline value_type findIf( const FunctorType& rFunctor ) const 155cdf0e10cSrcweir { 156cdf0e10cSrcweir typename container_type::const_iterator aIt = ::std::find_if( this->begin(), this->end(), FindFunctor< FunctorType >( rFunctor ) ); 157cdf0e10cSrcweir return (aIt == this->end()) ? value_type() : *aIt; 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir private: 161cdf0e10cSrcweir template< typename FunctorType > 162cdf0e10cSrcweir struct ForEachFunctor 163cdf0e10cSrcweir { 164cdf0e10cSrcweir FunctorType maFunctor; ForEachFunctoroox::RefVector::ForEachFunctor165cdf0e10cSrcweir inline explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} operator ()oox::RefVector::ForEachFunctor166cdf0e10cSrcweir inline void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( *rxValue ); } 167cdf0e10cSrcweir }; 168cdf0e10cSrcweir 169cdf0e10cSrcweir template< typename FunctorType > 170cdf0e10cSrcweir struct ForEachFunctorWithIndex 171cdf0e10cSrcweir { 172cdf0e10cSrcweir FunctorType maFunctor; 173cdf0e10cSrcweir sal_Int32 mnIndex; ForEachFunctorWithIndexoox::RefVector::ForEachFunctorWithIndex174cdf0e10cSrcweir inline explicit ForEachFunctorWithIndex( const FunctorType& rFunctor ) : maFunctor( rFunctor ), mnIndex( 0 ) {} operator ()oox::RefVector::ForEachFunctorWithIndex175cdf0e10cSrcweir inline void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( mnIndex, *rxValue ); ++mnIndex; } 176cdf0e10cSrcweir }; 177cdf0e10cSrcweir 178cdf0e10cSrcweir template< typename FunctorType > 179cdf0e10cSrcweir struct FindFunctor 180cdf0e10cSrcweir { 181cdf0e10cSrcweir FunctorType maFunctor; FindFunctoroox::RefVector::FindFunctor182cdf0e10cSrcweir inline explicit FindFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} operator ()oox::RefVector::FindFunctor183cdf0e10cSrcweir inline bool operator()( const value_type& rxValue ) { return rxValue.get() && maFunctor( *rxValue ); } 184cdf0e10cSrcweir }; 185cdf0e10cSrcweir getRef(sal_Int32 nIndex) const186cdf0e10cSrcweir inline const value_type* getRef( sal_Int32 nIndex ) const 187cdf0e10cSrcweir { 188cdf0e10cSrcweir return ((0 <= nIndex) && (static_cast< size_type >( nIndex ) < this->size())) ? 189cdf0e10cSrcweir &(*this)[ static_cast< size_type >( nIndex ) ] : 0; 190cdf0e10cSrcweir } 191cdf0e10cSrcweir }; 192cdf0e10cSrcweir 193cdf0e10cSrcweir // ============================================================================ 194cdf0e10cSrcweir 195cdf0e10cSrcweir } // namespace oox 196cdf0e10cSrcweir 197cdf0e10cSrcweir #endif 198