1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #ifndef INCLUDED_OOX_HELPER_REFVECTOR_HXX 21 #define INCLUDED_OOX_HELPER_REFVECTOR_HXX 22 23 #include <algorithm> 24 #include <functional> 25 #include <memory> 26 #include <vector> 27 28 #include <sal/types.h> 29 30 namespace oox { 31 32 33 /** Template for a vector of ref-counted objects with additional accessor functions. 34 35 An instance of the class RefVector< Type > stores elements of the type 36 std::shared_ptr< Type >. The new accessor functions has() and get() 37 work correctly for indexes out of the current range, there is no need to 38 check the passed index before. 39 */ 40 template< typename ObjType > 41 class RefVector : public ::std::vector< std::shared_ptr< ObjType > > 42 { 43 public: 44 typedef ::std::vector< std::shared_ptr< ObjType > > container_type; 45 typedef typename container_type::value_type value_type; 46 typedef typename container_type::size_type size_type; 47 48 public: 49 50 /** Returns a reference to the object with the passed index, or 0 on error. */ get(sal_Int32 nIndex) const51 value_type get( sal_Int32 nIndex ) const 52 { 53 if( const value_type* pxRef = getRef( nIndex ) ) return *pxRef; 54 return value_type(); 55 } 56 57 /** Calls the passed functor for every contained object, automatically 58 skips all elements that are empty references. */ 59 template< typename FunctorType > forEach(FunctorType aFunctor) const60 void forEach( FunctorType aFunctor ) const 61 { 62 ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( aFunctor ) ); 63 } 64 65 /** Calls the passed member function of ObjType on every contained object, 66 automatically skips all elements that are empty references. */ 67 template< typename FuncType > forEachMem(FuncType pFunc) const68 void forEachMem( FuncType pFunc ) const 69 { 70 forEach( ::std::bind( pFunc, std::placeholders::_1 ) ); 71 } 72 73 /** Calls the passed member function of ObjType on every contained object, 74 automatically skips all elements that are empty references. */ 75 template< typename FuncType, typename ParamType > forEachMem(FuncType pFunc,ParamType aParam) const76 void forEachMem( FuncType pFunc, ParamType aParam ) const 77 { 78 forEach( ::std::bind( pFunc, std::placeholders::_1, aParam ) ); 79 } 80 81 /** Calls the passed member function of ObjType on every contained object, 82 automatically skips all elements that are empty references. */ 83 template< typename FuncType, typename ParamType1, typename ParamType2 > forEachMem(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2) const84 void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 85 { 86 forEach( ::std::bind( pFunc, std::placeholders::_1, aParam1, aParam2 ) ); 87 } 88 89 /** Calls the passed member function of ObjType on every contained object, 90 automatically skips all elements that are empty references. */ 91 template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 > forEachMem(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2,ParamType3 aParam3) const92 void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const 93 { 94 forEach( ::std::bind( pFunc, std::placeholders::_1, aParam1, aParam2, aParam3 ) ); 95 } 96 97 /** Calls the passed functor for every contained object. Passes the index as 98 first argument and the object reference as second argument to rFunctor. */ 99 template< typename FunctorType > forEachWithIndex(const FunctorType & rFunctor) const100 void forEachWithIndex( const FunctorType& rFunctor ) const 101 { 102 ::std::for_each( this->begin(), this->end(), ForEachFunctorWithIndex< FunctorType >( rFunctor ) ); 103 } 104 105 /** Calls the passed member function of ObjType on every contained object. 106 Passes the vector index as first argument to the member function. */ 107 template< typename FuncType, typename ParamType1, typename ParamType2 > forEachMemWithIndex(FuncType pFunc,ParamType1 aParam1,ParamType2 aParam2) const108 void forEachMemWithIndex( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const 109 { 110 forEachWithIndex( ::std::bind( pFunc, std::placeholders::_2, std::placeholders::_1, aParam1, aParam2 ) ); 111 } 112 113 /** Searches for an element by using the passed functor that takes a 114 constant reference of the object type (const ObjType&). */ 115 template< typename FunctorType > findIf(const FunctorType & rFunctor) const116 value_type findIf( const FunctorType& rFunctor ) const 117 { 118 typename container_type::const_iterator aIt = ::std::find_if( this->begin(), this->end(), FindFunctor< FunctorType >( rFunctor ) ); 119 return (aIt == this->end()) ? value_type() : *aIt; 120 } 121 122 private: 123 template< typename FunctorType > 124 struct ForEachFunctor 125 { 126 FunctorType maFunctor; ForEachFunctoroox::RefVector::ForEachFunctor127 explicit ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} operator ()oox::RefVector::ForEachFunctor128 void operator()( const value_type& rxValue ) { if( rxValue.get() ) maFunctor( *rxValue ); } 129 }; 130 131 template< typename FunctorType > 132 struct ForEachFunctorWithIndex 133 { 134 FunctorType maFunctor; 135 sal_Int32 mnIndex; ForEachFunctorWithIndexoox::RefVector::ForEachFunctorWithIndex136 explicit ForEachFunctorWithIndex( const FunctorType& rFunctor ) : maFunctor( rFunctor ), mnIndex( 0 ) {} operator ()oox::RefVector::ForEachFunctorWithIndex137 void operator()( const value_type& rxValue ) { 138 if( rxValue.get() ) maFunctor( mnIndex, *rxValue ); 139 ++mnIndex; 140 } 141 }; 142 143 template< typename FunctorType > 144 struct FindFunctor 145 { 146 FunctorType maFunctor; FindFunctoroox::RefVector::FindFunctor147 explicit FindFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {} operator ()oox::RefVector::FindFunctor148 bool operator()( const value_type& rxValue ) { return rxValue.get() && maFunctor( *rxValue ); } 149 }; 150 getRef(sal_Int32 nIndex) const151 const value_type* getRef( sal_Int32 nIndex ) const 152 { 153 return ((0 <= nIndex) && (static_cast< size_type >( nIndex ) < this->size())) ? 154 &(*this)[ static_cast< size_type >( nIndex ) ] : 0; 155 } 156 }; 157 158 159 } // namespace oox 160 161 #endif 162 163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 164