xref: /trunk/main/oox/inc/oox/helper/refvector.hxx (revision 67e470da)
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