Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49172 - in branches/release: boost/algorithm/string/detail libs/algorithm/string/test
From: droba_at_[hidden]
Date: 2008-10-07 17:59:58


Author: pavol_droba
Date: 2008-10-07 17:59:57 EDT (Tue, 07 Oct 2008)
New Revision: 49172
URL: http://svn.boost.org/trac/boost/changeset/49172

Log:
Memory management fixes for is_any_of predicate merged from the trunk

Text files modified:
   branches/release/boost/algorithm/string/detail/classification.hpp | 101 ++++++++++++++++++++++++++++-----------
   branches/release/libs/algorithm/string/test/predicate_test.cpp | 23 ++++++++
   2 files changed, 92 insertions(+), 32 deletions(-)

Modified: branches/release/boost/algorithm/string/detail/classification.hpp
==============================================================================
--- branches/release/boost/algorithm/string/detail/classification.hpp (original)
+++ branches/release/boost/algorithm/string/detail/classification.hpp 2008-10-07 17:59:57 EDT (Tue, 07 Oct 2008)
@@ -28,11 +28,7 @@
 
 // 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<is_classifiedF>
             {
@@ -42,7 +38,6 @@
                 // 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<typename CharT>
                 bool operator()( CharT Ch ) const
@@ -59,13 +54,10 @@
                 #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 @@
             {
             private:
                 // set cannot operate on const value-type
- typedef typename remove_const<CharT>::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<CharT>::type set_value_type;
 
             public:
                 // Boost.Lambda support
@@ -96,7 +86,7 @@
                     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 @@
                     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 @@
                 // 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<Other.m_Size*2)
+ {
+ // Reuse the current storage
+ DestStorage=m_Storage.m_dynSet;
+ m_Size=Other.m_Size;
+ }
+ else
+ {
+ // Allocate the new one
+ set_value_type* pTemp=new set_value_type[Other.m_Size];
+ DestStorage=pTemp;
+
+ // Delete old storage if necessary
+ if(m_Storage.m_dynSet!=0)
+ {
+ delete [] m_Storage.m_dynSet;
+ }
+ // Store the new storage
+ m_Storage.m_dynSet=pTemp;
+ // Set new size
+ m_Size=Other.m_Size;
+ }
+ }
                     }
 
- // Use fixed storage
+ // Copy the data
                     ::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
 
                     return *this;
@@ -182,12 +216,19 @@
                 bool operator()( Char2T Ch ) const
                 {
                     const set_value_type* Storage=
- (m_Size<=FIXED_STORAGE_SIZE)
+ (use_fixed_storage(m_Size))
                         ? &m_Storage.m_fixSet[0]
                         : m_Storage.m_dynSet;
 
                     return ::std::binary_search(Storage, Storage+m_Size, Ch);
                 }
+ private:
+ // check if the size is eligible for fixed storage
+ static bool use_fixed_storage(std::size_t size)
+ {
+ return size<=sizeof(set_value_type*)*2;
+ }
+
 
             private:
                 // storage
@@ -195,7 +236,7 @@
                 union
                 {
                     set_value_type* m_dynSet;
- set_value_type m_fixSet[FIXED_STORAGE_SIZE];
+ set_value_type m_fixSet[sizeof(set_value_type*)*2];
                 }
                 m_Storage;
         

Modified: branches/release/libs/algorithm/string/test/predicate_test.cpp
==============================================================================
--- branches/release/libs/algorithm/string/test/predicate_test.cpp (original)
+++ branches/release/libs/algorithm/string/test/predicate_test.cpp 2008-10-07 17:59:57 EDT (Tue, 07 Oct 2008)
@@ -96,10 +96,29 @@
 
 }
 
+template<typename Pred, typename Input>
+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()


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk