1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 #if !defined(STLHELPERS_HEADER_GUARD_1357924680)
19 #define STLHELPERS_HEADER_GUARD_1357924680
20
21
22
23 // Base include file. Must be first.
24 #include <xalanc/Include/PlatformDefinitions.hpp>
25
26
27
28 #include <algorithm>
29 #include <functional>
30
31
32
33 #include <xalanc/Include/XalanMap.hpp>
34
35
36
37 namespace XALAN_CPP_NAMESPACE {
38
39
40
41 template<class Type>
42 struct
43 XalanDestroyFunctor
44 {
45 void
operator ()XALAN_CPP_NAMESPACE::XalanDestroyFunctor46 operator()(Type& theArg)
47 {
48 theArg.~Type();
49 }
50
51 void
operator ()XALAN_CPP_NAMESPACE::XalanDestroyFunctor52 operator()(Type* theArg)
53 {
54 theArg->~Type();
55 }
56
57 void
operator ()XALAN_CPP_NAMESPACE::XalanDestroyFunctor58 operator()(const Type* theArg)
59 {
60 (*this)(const_cast<Type*>(theArg));
61 }
62
63 void
operator ()XALAN_CPP_NAMESPACE::XalanDestroyFunctor64 operator()(
65 Type* theArg,
66 MemoryManager& theMemoryManager)
67 {
68 if (theArg != 0)
69 {
70 (*this)(*theArg);
71
72 theMemoryManager.deallocate(theArg);
73 }
74 }
75
76 void
operator ()XALAN_CPP_NAMESPACE::XalanDestroyFunctor77 operator()(
78 const Type* theArg,
79 MemoryManager& theMemoryManager)
80 {
81 (*this)(const_cast<Type*>(theArg), theMemoryManager);
82 }
83 };
84
85
86
87 template<class Type>
88 XalanDestroyFunctor<Type>
makeXalanDestroyFunctor(const Type *)89 makeXalanDestroyFunctor(const Type* /* theType */)
90 {
91 return XalanDestroyFunctor<Type>();
92 }
93
94
95
96 /**
97 * Functor to delete objects, used in STL iteration algorithms.
98 */
99 template <class Type>
100 struct DeleteFunctor
101 {
DeleteFunctorXALAN_CPP_NAMESPACE::DeleteFunctor102 DeleteFunctor(MemoryManager& theManager) :
103 m_memoryManager(theManager)
104 {
105 }
106
107 /**
108 * Delete the object pointed to by argument.
109 *
110 * @param thePointer pointer to object to be deleted
111 */
112 void
operator ()XALAN_CPP_NAMESPACE::DeleteFunctor113 operator()(const Type* thePointer) const
114 {
115 return makeXalanDestroyFunctor(thePointer)(thePointer, m_memoryManager);
116 }
117
118 private:
119
120 MemoryManager& m_memoryManager;
121 };
122
123
124 /**
125 * Functor to call a clear() member function on its argument.
126 */
127 template <class Type>
128 struct ClearFunctor
129 {
130 /**
131 * Retrieve the value of a key-value pair.
132 *
133 * @param thePair key-value pair
134 * @return value
135 */
136 void
operator ()XALAN_CPP_NAMESPACE::ClearFunctor137 operator()(Type& theArg) const
138 {
139 return theArg.clear();
140 }
141 };
142
143
144
145 /**
146 * Functor to delete value objects in maps, used in STL iteration algorithms.
147 */
148 template <class T>
149 struct MapValueDeleteFunctor
150 {
MapValueDeleteFunctorXALAN_CPP_NAMESPACE::MapValueDeleteFunctor151 MapValueDeleteFunctor(MemoryManager& theManager) :
152 m_memoryManager(theManager)
153 {
154 }
155
156 /**
157 * Delete the value object in a map value pair. The value of the pair must
158 * be of pointer type.
159 *
160 * @param thePair key-value pair
161 */
162 void
operator ()XALAN_CPP_NAMESPACE::MapValueDeleteFunctor163 operator()(const typename T::value_type& thePair) const
164 {
165 return makeXalanDestroyFunctor(thePair.second)(thePair.second, m_memoryManager);
166 }
167
168 private:
169
170 MemoryManager& m_memoryManager;
171 };
172
173
174
175 template<class MapType>
176 MapValueDeleteFunctor<MapType>
makeMapValueDeleteFunctor(MapType & theMap)177 makeMapValueDeleteFunctor(MapType& theMap)
178 {
179 return MapValueDeleteFunctor<MapType>(theMap.getMemoryManager());
180 }
181
182
183
184 /**
185 * This functor is designed to compare 0-terminated arrays. It substitutes
186 * for the default less<type*> so that pointers to arrays can be compared,
187 * rather than copies of arrays. For example, you might want to use C-style
188 * strings as keys in a map, rather than string objects. The default
189 * algorithm less<const char*> would just compare the pointers, and not the
190 * vector of characters to which it points. Using this algorithm instead of
191 * the default will allow the map to work as expected.
192 */
193 template<class T>
194 struct less_null_terminated_arrays
195 {
196 /**
197 * Compare the values of two objects.
198 *
199 *
200 * @param theLHS first object to compare
201 * @param theRHS second object to compare
202 * @return true if objects are the same
203 */
204 bool
operator ()XALAN_CPP_NAMESPACE::less_null_terminated_arrays205 operator()(
206 const T* theLHS,
207 const T* theRHS) const
208 {
209 while(*theLHS && *theRHS)
210 {
211 if (*theLHS != *theRHS)
212 {
213 break;
214 }
215 else
216 {
217 theLHS++;
218 theRHS++;
219 }
220 }
221
222 return *theLHS < *theRHS ? true : false;
223 }
224 };
225
226
227
228 template<class T>
229 struct equal_null_terminated_arrays
230 {
231 /**
232 * Compare the values of two objects.
233 *
234 *
235 * @param theLHS first object to compare
236 * @param theRHS second object to compare
237 * @return true if objects are the same
238 */
239 bool
operator ()XALAN_CPP_NAMESPACE::equal_null_terminated_arrays240 operator()(
241 const T* theLHS,
242 const T* theRHS) const
243 {
244 while(*theLHS && *theRHS)
245 {
246 if (*theLHS != *theRHS)
247 {
248 return false;
249 }
250 else
251 {
252 ++theLHS;
253 ++theRHS;
254 }
255 }
256
257 if (*theLHS || *theRHS)
258 {
259 return false;
260 }
261 else
262 {
263 return true;
264 }
265 }
266 };
267
268
269
270 template <class ScalarType>
271 inline size_t
XalanScalarHash(ScalarType theValue,size_t theResult)272 XalanScalarHash(
273 ScalarType theValue,
274 size_t theResult)
275 {
276 return (theResult * 37) + (theResult >> 24) + size_type(theValue);
277 }
278
279
280
281 template <class T>
282 struct hash_non_terminated_array
283 {
284 size_t
operator ()XALAN_CPP_NAMESPACE::hash_non_terminated_array285 operator() (
286 const T* theKey,
287 size_t theLength,
288 size_t theInitialValue = 0) const
289 {
290 size_t theHashValue = theInitialValue;
291
292 const T* theEnd =
293 theKey + theLength;
294
295 while (theKey != theEnd)
296 {
297 theHashValue += XalanScalarHash(*theKey, theHashValue);
298
299 ++theKey;
300 }
301
302 return ++theHashValue;
303 }
304 };
305
306
307
308 template <class T>
309 struct hash_null_terminated_array
310 {
311 size_t
operator ()XALAN_CPP_NAMESPACE::hash_null_terminated_array312 operator() (
313 const T* theKey,
314 size_t theInitialValue = 0) const
315 {
316 size_t theHashValue = theInitialValue;
317
318 while (*theKey)
319 {
320 theHashValue += XalanScalarHash(*theKey, theHashValue);
321
322 ++theKey;
323 }
324
325 return ++theHashValue;
326 }
327 };
328
329
330
331 template<>
332 struct XalanMapKeyTraits<const XalanDOMChar*>
333 {
334 typedef hash_null_terminated_array<XalanDOMChar> Hasher;
335 typedef equal_null_terminated_arrays<XalanDOMChar> Comparator;
336 };
337
338
339
340 template<class CollectionType>
341 class CollectionClearGuard
342 {
343 public:
344
CollectionClearGuard(CollectionType & theCollection)345 CollectionClearGuard(CollectionType& theCollection) :
346 m_collection(&theCollection)
347 {
348 }
349
~CollectionClearGuard()350 ~CollectionClearGuard()
351 {
352 if (m_collection != 0)
353 {
354 m_collection->clear();
355 }
356 }
357
358 void
release()359 release()
360 {
361 m_collection = 0;
362 }
363
364 private:
365
366 // Not implemented...
367 CollectionClearGuard(const CollectionClearGuard<CollectionType>&);
368
369 CollectionClearGuard<CollectionType>&
370 operator=(const CollectionClearGuard<CollectionType>&);
371
372 // Data members...
373 CollectionType* m_collection;
374 };
375
376
377
378 template<class CollectionType, class DeleteFunctorType>
379 class CollectionDeleteGuard
380 {
381 public:
382
CollectionDeleteGuard(CollectionType & theCollection)383 CollectionDeleteGuard(CollectionType& theCollection) :
384 m_collection(&theCollection)
385 {
386 }
387
~CollectionDeleteGuard()388 ~CollectionDeleteGuard()
389 {
390 if (m_collection != 0)
391 {
392 using std::for_each;
393
394 // Delete all of the objects in the temp vector.
395 for_each(m_collection->begin(),
396 m_collection->end(),
397 DeleteFunctorType(m_collection->getMemoryManager()));
398 }
399 }
400
401 void
release()402 release()
403 {
404 m_collection = 0;
405 }
406
407 private:
408
409 // Not implemented...
410 CollectionDeleteGuard(const CollectionDeleteGuard<CollectionType, DeleteFunctorType>&);
411
412 CollectionDeleteGuard<CollectionType, DeleteFunctorType>&
413 operator=(const CollectionDeleteGuard<CollectionType, DeleteFunctorType>&);
414
415 // Data members...
416 CollectionType* m_collection;
417 };
418
419
420
421 template<class T>
422 struct pointer_equals
423 {
424 bool
operator ()XALAN_CPP_NAMESPACE::pointer_equals425 operator()(
426 const T* theLHS,
427 const T* theRHS) const
428 {
429 assert(theLHS != 0 && theRHS != 0);
430
431 return *theLHS == *theRHS;
432 }
433 };
434
435
436
437 template<class T>
438 struct pointer_equals_predicate
439 {
pointer_equals_predicateXALAN_CPP_NAMESPACE::pointer_equals_predicate440 pointer_equals_predicate(const T* theArg) :
441 m_arg(theArg)
442 {
443 }
444
445 bool
operator ()XALAN_CPP_NAMESPACE::pointer_equals_predicate446 operator()(
447 const T* theOther) const
448 {
449 assert(theOther != 0);
450
451 return *theOther == *m_arg;
452 }
453
454 private:
455
456 const T* m_arg;
457 };
458
459
460
461 template<class T>
462 struct pointer_less
463 {
464 bool
operator ()XALAN_CPP_NAMESPACE::pointer_less465 operator()(
466 const T* theLHS,
467 const T* theRHS) const
468 {
469 assert(theLHS != 0 && theRHS != 0);
470
471 using std::less;
472
473 return less<T>()(*theLHS, *theRHS);
474 }
475 };
476
477
478
479 template<class T>
480 struct pointer_equal
481 {
482 bool
operator ()XALAN_CPP_NAMESPACE::pointer_equal483 operator()(
484 const T* theLHS,
485 const T* theRHS) const
486 {
487 assert(theLHS != 0 && theRHS != 0);
488 return std::equal_to<T>()(*theLHS, *theRHS);
489 }
490 };
491
492
493
494
495 }
496
497
498
499 #endif // STLHELPERS_HEADER_GUARD_1357924680
500