From 98a8b08afb9c3b5779c0f88ceec24f02ad38a444 Mon Sep 17 00:00:00 2001 From: Pavol Droba Date: Tue, 7 Oct 2008 21:59:57 +0000 Subject: [PATCH] Memory management fixes for is_any_of predicate merged from the trunk [SVN r49172] --- .../string/detail/classification.hpp | 101 ++++++++++++------ string/test/predicate_test.cpp | 23 +++- 2 files changed, 92 insertions(+), 32 deletions(-) diff --git a/include/boost/algorithm/string/detail/classification.hpp b/include/boost/algorithm/string/detail/classification.hpp index 2fa3b6d..1db5d29 100644 --- a/include/boost/algorithm/string/detail/classification.hpp +++ b/include/boost/algorithm/string/detail/classification.hpp @@ -28,11 +28,7 @@ namespace boost { // classification functors -----------------------------------------------// -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) -#pragma warning(push) -#pragma warning(disable:4512) //assignment operator could not be generated -#endif - // is_classified functor + // is_classified functor struct is_classifiedF : public predicate_facade { @@ -42,7 +38,6 @@ namespace boost { // Constructor from a locale is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : m_Type(Type), m_Locale(Loc) {} - // Operation template bool operator()( CharT Ch ) const @@ -59,13 +54,10 @@ namespace boost { #endif private: - const std::ctype_base::mask m_Type; - const std::locale m_Locale; + std::ctype_base::mask m_Type; + std::locale m_Locale; }; -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) -#pragma warning(pop) -#endif // is_any_of functor /* @@ -77,9 +69,7 @@ namespace boost { { private: // set cannot operate on const value-type - typedef typename remove_const::type set_value_type; - // Size of the static storage (size of pointer*2) - static const ::std::size_t FIXED_STORAGE_SIZE = sizeof(set_value_type*)*2; + typedef typename ::boost::remove_const::type set_value_type; public: // Boost.Lambda support @@ -96,7 +86,7 @@ namespace boost { m_Size=Size; set_value_type* Storage=0; - if(m_Size<=FIXED_STORAGE_SIZE) + if(use_fixed_storage(m_Size)) { // Use fixed storage Storage=&m_Storage.m_fixSet[0]; @@ -121,7 +111,7 @@ namespace boost { const set_value_type* SrcStorage=0; set_value_type* DestStorage=0; - if(m_Size<=FIXED_STORAGE_SIZE) + if(use_fixed_storage(m_Size)) { // Use fixed storage DestStorage=&m_Storage.m_fixSet[0]; @@ -142,36 +132,80 @@ namespace boost { // Destructor ~is_any_ofF() { - if(m_Size>FIXED_STORAGE_SIZE && m_Storage.m_dynSet!=0) + if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) { - delete m_Storage.m_dynSet; + delete [] m_Storage.m_dynSet; } } // Assignment is_any_ofF& operator=(const is_any_ofF& Other) { - // Prepare storage - m_Storage.m_dynSet=0; - m_Size=Other.m_Size; - const set_value_type* SrcStorage=0; - set_value_type* DestStorage=0; + // Handle self assignment + if(this==&Other) return *this; - if(m_Size<=FIXED_STORAGE_SIZE) + // Prepare storage + const set_value_type* SrcStorage; + set_value_type* DestStorage; + + if(use_fixed_storage(Other.m_Size)) { // Use fixed storage DestStorage=&m_Storage.m_fixSet[0]; SrcStorage=&Other.m_Storage.m_fixSet[0]; + + // Delete old storage if was present + if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) + { + delete [] m_Storage.m_dynSet; + } + + // Set new size + m_Size=Other.m_Size; } else { - // Use dynamic storage - m_Storage.m_dynSet=new set_value_type[m_Size]; - DestStorage=m_Storage.m_dynSet; + // Other uses dynamic storage SrcStorage=Other.m_Storage.m_dynSet; + + // Check what kind of storage are we using right now + if(use_fixed_storage(m_Size)) + { + // Using fixed storage, allocate new + set_value_type* pTemp=new set_value_type[Other.m_Size]; + DestStorage=pTemp; + m_Storage.m_dynSet=pTemp; + m_Size=Other.m_Size; + } + else + { + // Using dynamic storage, check if can reuse + if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size +void test_pred(const Pred& pred, const Input& input, bool bYes) +{ + // test assignment operator + Pred pred1=pred; + pred1=pred; + pred1=pred1; + if(bYes) + { + BOOST_CHECK( all( input, pred ) ); + BOOST_CHECK( all( input, pred1 ) ); + } + else + { + BOOST_CHECK( !all( input, pred ) ); + BOOST_CHECK( !all( input, pred1 ) ); + } +} + #define TEST_CLASS( Pred, YesInput, NoInput )\ {\ - BOOST_CHECK( all( string(YesInput), Pred ) );\ - BOOST_CHECK( !all( string(NoInput), Pred ) );\ + test_pred(Pred, YesInput, true); \ + test_pred(Pred, NoInput, false); \ } void classification_test()