1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef OOX_HELPER_REFVECTOR_HXX 29 #define OOX_HELPER_REFVECTOR_HXX 30 31 #include <vector> 32 #include <boost/bind.hpp> 33 #include <boost/shared_ptr.hpp> 34 #include <sal/types.h> 35 36 namespace oox { 37 38 // ============================================================================ 39 40 /** Template for a vector of ref-counted objects with additional accessor functions. 41 42 An instance of the class RefVector< Type > stores elements of the type 43 ::boost::shared_ptr< Type >. The new accessor functions has() and get() 44 work correctly for indexes out of the current range, there is no need to 45 check the passed index before. 46 */ 47 template< typename ObjType > 48 class RefVector : public ::std::vector< ::boost::shared_ptr< ObjType > > 49 { 50 public: 51 typedef ::std::vector< ::boost::shared_ptr< ObjType > > container_type; 52 typedef typename container_type::value_type value_type; 53 typedef typename container_type::size_type size_type; 54 55 public: 56 /** Returns true, if the object with the passed index exists. Returns 57 false, if the vector element exists but is an empty reference. */ 58 inline bool has( sal_Int32 nIndex ) const 59 { 60 const value_type* pxRef = getRef( nIndex ); 61 return pxRef && pxRef->get(); 62 } 63 64 /** Returns a reference to the object with the passed index, or 0 on error. */ 65 inline value_type get( sal_Int32 nIndex ) const 66 { 67 if( const value_type* pxRef = getRef( nIndex ) ) return *pxRef; 68 return value_type(); 69 } 70 71 /** Returns the index of the last element, or -1, if the vector is empty. 72 Does *not* check whether the last element is an empty reference. */ 73 inline sal_Int32 getLastIndex() const { return static_cast< sal_Int32 >( this->size() ) - 1; } 74 75 /** Calls the passed functor for every contained object, automatically 76 skips all elements that are empty references. */ 77 template< typename FunctorType > 78 inline void forEach( FunctorType aFunctor ) const 79 { 80 ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( aFunctor ) ); 81 } 82 83 /** Calls the passed member function of ObjType on every contained object, 84 automatically skips all elements that are empty references. */ 85 template< typename FuncType > 86 inline void forEachMem( FuncType pFunc ) const 87 { 88 forEach( ::boost::bind( pFunc, _1 ) ); 89 } 90 91 /** Calls the passed member function of ObjType on every contained object, 92 automatically skips all elements that are empty references. */ 93 template< typename FuncType, typename ParamType > 94 inline void forEachMem( FuncType pFunc, ParamType aParam ) const 95 { 96 forEach( ::boost::bind( pFunc, _1, aParam ) ); 97 } 98 99 /** Calls the passed member function of ObjType on every contained object, 100 automatically skips all elements that are empty references. */ 101 template< typename FuncType, typename ParamType1, typename ParamType2 > 102 inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 103 { 104 forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) ); 105 } 106 107 /** Calls the passed member function of ObjType on every contained object, 108 automatically skips all elements that are empty references. */ 109 template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > 110 inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 111 { 112 forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) ); 113 } 114 115 /** Calls the passed functor for every contained object. Passes the index as 116 first argument and the object reference as second argument to rFunctor. */ 117 template< typename FunctorType > 118 inline void forEachWithIndex( const FunctorType& rFunctor ) const 119 { 120 ::std::for_each( this->begin(), this->end(), ForEachFunctorWithIndex< FunctorType >( rFunctor ) ); 121 } 122 123 /** Calls the passed member function of ObjType on every contained object. 124 Passes the vector index to the member function. */ 125 template< typename FuncType > 126 inline void forEachMemWithIndex( FuncType pFunc ) const 127 { 128 forEachWithIndex( ::boost::bind( pFunc, _2, _1 ) ); 129 } 130 131 /** Calls the passed member function of ObjType on every contained object. 132 Passes the vector index as first argument to the member function. */ 133 template< typename FuncType, typename ParamType > 134 inline void forEachMemWithIndex( FuncType pFunc, ParamType aParam ) const 135 { 136 forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam ) ); 137 } 138 139 /** Calls the passed member function of ObjType on every contained object. 140 Passes the vector index as first argument to the member function. */ 141 template< typename FuncType, typename ParamType1, typename ParamType2 > 142 inline void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 143 { 144 forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam1, aParam2 ) ); 145 } 146 147 /** Calls the passed member function of ObjType on every contained object. 148 Passes the vector index as first argument to the member function. */ 149 template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > 150 inline void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 151 { 152 forEachWithIndex( ::boost::bind( pFunc, _2, _1, aParam1, aParam2, aParam3 ) ); 153 } 154 155 /** Searches for an element by using the passed functor that takes a 156 constant reference of the object type (const ObjType&). */ 157 template< typename FunctorType > 158 inline value_type findIf( const FunctorType& rFunctor ) const 159 { 160 typename container_type::const_iterator aIt = ::std::find_if( this->begin(), this->end(), FindFunctor< FunctorType >( rFunctor ) ); 161 return (aIt == this->end()) ? value_type() : *aIt; 162 } 163 164 private: 165 template< typename FunctorType > 166 struct ForEachFunctor 167 { 168 FunctorType maFunctor; 169 inline explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} 170 inline void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( *rxValue ); } 171 }; 172 173 template< typename FunctorType > 174 struct ForEachFunctorWithIndex 175 { 176 FunctorType maFunctor; 177 sal_Int32 mnIndex; 178 inline explicit ForEachFunctorWithIndex( const FunctorType& rFunctor ) : maFunctor( rFunctor ), mnIndex( 0 ) {} 179 inline void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( mnIndex, *rxValue ); ++mnIndex; } 180 }; 181 182 template< typename FunctorType > 183 struct FindFunctor 184 { 185 FunctorType maFunctor; 186 inline explicit FindFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} 187 inline bool operator()( const value_type& rxValue ) { return rxValue.get() && maFunctor( *rxValue ); } 188 }; 189 190 inline const value_type* getRef( sal_Int32 nIndex ) const 191 { 192 return ((0 <= nIndex) && (static_cast< size_type >( nIndex ) < this->size())) ? 193 &(*this)[ static_cast< size_type >( nIndex ) ] : 0; 194 } 195 }; 196 197 // ============================================================================ 198 199 } // namespace oox 200 201 #endif 202