/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined(STLHELPERS_HEADER_GUARD_1357924680) #define STLHELPERS_HEADER_GUARD_1357924680 // Base include file. Must be first. #include #include #include #include namespace XALAN_CPP_NAMESPACE { template struct XalanDestroyFunctor { void operator()(Type& theArg) { theArg.~Type(); } void operator()(Type* theArg) { theArg->~Type(); } void operator()(const Type* theArg) { (*this)(const_cast(theArg)); } void operator()( Type* theArg, MemoryManager& theMemoryManager) { if (theArg != 0) { (*this)(*theArg); theMemoryManager.deallocate(theArg); } } void operator()( const Type* theArg, MemoryManager& theMemoryManager) { (*this)(const_cast(theArg), theMemoryManager); } }; template XalanDestroyFunctor makeXalanDestroyFunctor(const Type* /* theType */) { return XalanDestroyFunctor(); } /** * Functor to delete objects, used in STL iteration algorithms. */ template struct DeleteFunctor { DeleteFunctor(MemoryManager& theManager) : m_memoryManager(theManager) { } /** * Delete the object pointed to by argument. * * @param thePointer pointer to object to be deleted */ void operator()(const Type* thePointer) const { return makeXalanDestroyFunctor(thePointer)(thePointer, m_memoryManager); } private: MemoryManager& m_memoryManager; }; /** * Functor to call a clear() member function on its argument. */ template struct ClearFunctor { /** * Retrieve the value of a key-value pair. * * @param thePair key-value pair * @return value */ void operator()(Type& theArg) const { return theArg.clear(); } }; /** * Functor to delete value objects in maps, used in STL iteration algorithms. */ template struct MapValueDeleteFunctor { MapValueDeleteFunctor(MemoryManager& theManager) : m_memoryManager(theManager) { } /** * Delete the value object in a map value pair. The value of the pair must * be of pointer type. * * @param thePair key-value pair */ void operator()(const typename T::value_type& thePair) const { return makeXalanDestroyFunctor(thePair.second)(thePair.second, m_memoryManager); } private: MemoryManager& m_memoryManager; }; template MapValueDeleteFunctor makeMapValueDeleteFunctor(MapType& theMap) { return MapValueDeleteFunctor(theMap.getMemoryManager()); } /** * This functor is designed to compare 0-terminated arrays. It substitutes * for the default less so that pointers to arrays can be compared, * rather than copies of arrays. For example, you might want to use C-style * strings as keys in a map, rather than string objects. The default * algorithm less would just compare the pointers, and not the * vector of characters to which it points. Using this algorithm instead of * the default will allow the map to work as expected. */ template struct less_null_terminated_arrays { /** * Compare the values of two objects. * * * @param theLHS first object to compare * @param theRHS second object to compare * @return true if objects are the same */ bool operator()( const T* theLHS, const T* theRHS) const { while(*theLHS && *theRHS) { if (*theLHS != *theRHS) { break; } else { theLHS++; theRHS++; } } return *theLHS < *theRHS ? true : false; } }; template struct equal_null_terminated_arrays { /** * Compare the values of two objects. * * * @param theLHS first object to compare * @param theRHS second object to compare * @return true if objects are the same */ bool operator()( const T* theLHS, const T* theRHS) const { while(*theLHS && *theRHS) { if (*theLHS != *theRHS) { return false; } else { ++theLHS; ++theRHS; } } if (*theLHS || *theRHS) { return false; } else { return true; } } }; template inline size_t XalanScalarHash( ScalarType theValue, size_t theResult) { return (theResult * 37) + (theResult >> 24) + size_type(theValue); } template struct hash_non_terminated_array { size_t operator() ( const T* theKey, size_t theLength, size_t theInitialValue = 0) const { size_t theHashValue = theInitialValue; const T* theEnd = theKey + theLength; while (theKey != theEnd) { theHashValue += XalanScalarHash(*theKey, theHashValue); ++theKey; } return ++theHashValue; } }; template struct hash_null_terminated_array { size_t operator() ( const T* theKey, size_t theInitialValue = 0) const { size_t theHashValue = theInitialValue; while (*theKey) { theHashValue += XalanScalarHash(*theKey, theHashValue); ++theKey; } return ++theHashValue; } }; template<> struct XalanMapKeyTraits { typedef hash_null_terminated_array Hasher; typedef equal_null_terminated_arrays Comparator; }; template class CollectionClearGuard { public: CollectionClearGuard(CollectionType& theCollection) : m_collection(&theCollection) { } ~CollectionClearGuard() { if (m_collection != 0) { m_collection->clear(); } } void release() { m_collection = 0; } private: // Not implemented... CollectionClearGuard(const CollectionClearGuard&); CollectionClearGuard& operator=(const CollectionClearGuard&); // Data members... CollectionType* m_collection; }; template class CollectionDeleteGuard { public: CollectionDeleteGuard(CollectionType& theCollection) : m_collection(&theCollection) { } ~CollectionDeleteGuard() { if (m_collection != 0) { using std::for_each; // Delete all of the objects in the temp vector. for_each(m_collection->begin(), m_collection->end(), DeleteFunctorType(m_collection->getMemoryManager())); } } void release() { m_collection = 0; } private: // Not implemented... CollectionDeleteGuard(const CollectionDeleteGuard&); CollectionDeleteGuard& operator=(const CollectionDeleteGuard&); // Data members... CollectionType* m_collection; }; template struct pointer_equals { bool operator()( const T* theLHS, const T* theRHS) const { assert(theLHS != 0 && theRHS != 0); return *theLHS == *theRHS; } }; template struct pointer_equals_predicate { pointer_equals_predicate(const T* theArg) : m_arg(theArg) { } bool operator()( const T* theOther) const { assert(theOther != 0); return *theOther == *m_arg; } private: const T* m_arg; }; template struct pointer_less { bool operator()( const T* theLHS, const T* theRHS) const { assert(theLHS != 0 && theRHS != 0); using std::less; return less()(*theLHS, *theRHS); } }; template struct pointer_equal { bool operator()( const T* theLHS, const T* theRHS) const { assert(theLHS != 0 && theRHS != 0); return std::equal_to()(*theLHS, *theRHS); } }; } #endif // STLHELPERS_HEADER_GUARD_1357924680