|
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