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