xref: /trunk/main/oox/inc/oox/helper/refmap.hxx (revision cdf0e10c)
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_REFMAP_HXX
29 #define OOX_HELPER_REFMAP_HXX
30 
31 #include <map>
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 map of ref-counted objects with additional accessor functions.
41 
42     An instance of the class RefMap< Type > stores elements of the type
43     ::boost::shared_ptr< Type >. The new accessor functions has() and get()
44     work correctly for nonexisting keys, there is no need to check the passed
45     key before.
46  */
47 template< typename KeyType, typename ObjType, typename CompType = ::std::less< KeyType > >
48 class RefMap : public ::std::map< KeyType, ::boost::shared_ptr< ObjType >, CompType >
49 {
50 public:
51     typedef ::std::map< KeyType, ::boost::shared_ptr< ObjType >, CompType > container_type;
52     typedef typename container_type::key_type                               key_type;
53     typedef typename container_type::mapped_type                            mapped_type;
54     typedef typename container_type::value_type                             value_type;
55     typedef typename container_type::key_compare                            key_compare;
56 
57 public:
58     /** Returns true, if the object accossiated to the passed key exists.
59         Returns false, if the key exists but points to an empty reference. */
60     inline bool         has( key_type nKey ) const
61                         {
62                             const mapped_type* pxRef = getRef( nKey );
63                             return pxRef && pxRef->get();
64                         }
65 
66     /** Returns a reference to the object accossiated to the passed key, or an
67         empty reference on error. */
68     inline mapped_type  get( key_type nKey ) const
69                         {
70                             if( const mapped_type* pxRef = getRef( nKey ) ) return *pxRef;
71                             return mapped_type();
72                         }
73 
74     /** Calls the passed functor for every contained object, automatically
75         skips all elements that are empty references. */
76     template< typename FunctorType >
77     inline void         forEach( const FunctorType& rFunctor ) const
78                         {
79                             ::std::for_each( this->begin(), this->end(), ForEachFunctor< FunctorType >( rFunctor ) );
80                         }
81 
82     /** Calls the passed member function of ObjType on every contained object,
83         automatically skips all elements that are empty references. */
84     template< typename FuncType >
85     inline void         forEachMem( FuncType pFunc ) const
86                         {
87                             forEach( ::boost::bind( pFunc, _1 ) );
88                         }
89 
90     /** Calls the passed member function of ObjType on every contained object,
91         automatically skips all elements that are empty references. */
92     template< typename FuncType, typename ParamType >
93     inline void         forEachMem( FuncType pFunc, ParamType aParam ) const
94                         {
95                             forEach( ::boost::bind( pFunc, _1, aParam ) );
96                         }
97 
98     /** Calls the passed member function of ObjType on every contained object,
99         automatically skips all elements that are empty references. */
100     template< typename FuncType, typename ParamType1, typename ParamType2 >
101     inline void         forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const
102                         {
103                             forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) );
104                         }
105 
106     /** Calls the passed member function of ObjType on every contained object,
107         automatically skips all elements that are empty references. */
108     template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 >
109     inline void         forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const
110                         {
111                             forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) );
112                         }
113     /** Calls the passed functor for every contained object. Passes the key as
114         first argument and the object reference as second argument to rFunctor. */
115     template< typename FunctorType >
116     inline void         forEachWithKey( const FunctorType& rFunctor ) const
117                         {
118                             ::std::for_each( this->begin(), this->end(), ForEachFunctorWithKey< FunctorType >( rFunctor ) );
119                         }
120 
121     /** Calls the passed member function of ObjType on every contained object.
122         Passes the object key as argument to the member function. */
123     template< typename FuncType >
124     inline void         forEachMemWithKey( FuncType pFunc ) const
125                         {
126                             forEachWithKey( ::boost::bind( pFunc, _2, _1 ) );
127                         }
128 
129     /** Calls the passed member function of ObjType on every contained object.
130         Passes the object key as first argument to the member function. */
131     template< typename FuncType, typename ParamType >
132     inline void         forEachMemWithKey( FuncType pFunc, ParamType aParam ) const
133                         {
134                             forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam ) );
135                         }
136 
137     /** Calls the passed member function of ObjType on every contained object.
138         Passes the object key as first argument to the member function. */
139     template< typename FuncType, typename ParamType1, typename ParamType2 >
140     inline void         forEachMemWithKey( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const
141                         {
142                             forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam1, aParam2 ) );
143                         }
144 
145     /** Calls the passed member function of ObjType on every contained object.
146         Passes the object key as first argument to the member function. */
147     template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3 >
148     inline void         forEachMemWithKey( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3 ) const
149                         {
150                             forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam1, aParam2, aParam3 ) );
151                         }
152 
153 private:
154     template< typename FunctorType >
155     struct ForEachFunctor
156     {
157         FunctorType         maFunctor;
158         inline explicit     ForEachFunctor( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {}
159         inline void         operator()( const value_type& rValue ) { if( rValue.second.get() ) maFunctor( *rValue.second ); }
160     };
161 
162     template< typename FunctorType >
163     struct ForEachFunctorWithKey
164     {
165         FunctorType         maFunctor;
166         inline explicit     ForEachFunctorWithKey( const FunctorType& rFunctor ) : maFunctor( rFunctor ) {}
167         inline void         operator()( const value_type& rValue ) { if( rValue.second.get() ) maFunctor( rValue.first, *rValue.second ); }
168     };
169 
170     inline const mapped_type* getRef( key_type nKey ) const
171                         {
172                             typename container_type::const_iterator aIt = find( nKey );
173                             return (aIt == this->end()) ? 0 : &aIt->second;
174                         }
175 };
176 
177 // ============================================================================
178 
179 } // namespace oox
180 
181 #endif
182