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