diff options
Diffstat (limited to 'boost/xpressive/detail/utility/sequence_stack.hpp')
-rw-r--r-- | boost/xpressive/detail/utility/sequence_stack.hpp | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/boost/xpressive/detail/utility/sequence_stack.hpp b/boost/xpressive/detail/utility/sequence_stack.hpp index aa251b64a8..baef2f209a 100644 --- a/boost/xpressive/detail/utility/sequence_stack.hpp +++ b/boost/xpressive/detail/utility/sequence_stack.hpp @@ -9,7 +9,7 @@ #define BOOST_XPRESSIVE_DETAIL_SEQUENCE_STACK_HPP_EAN_10_04_2005 // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once # pragma warning(push) # pragma warning(disable : 4127) // conditional expression constant @@ -31,22 +31,29 @@ struct fill_t {} const fill = {}; template<typename T> struct sequence_stack { -private: - static T *allocate(std::size_t size, T const &t) + struct allocate_guard_t; + friend struct allocate_guard_t; + struct allocate_guard_t { - std::size_t i = 0; - T *p = (T *)::operator new(size * sizeof(T)); - try + std::size_t i; + T *p; + bool dismissed; + ~allocate_guard_t() { - for(; i < size; ++i) - ::new((void *)(p+i)) T(t); + if(!this->dismissed) + sequence_stack::deallocate(this->p, this->i); } - catch(...) - { - deallocate(p, i); - throw; - } - return p; + }; +private: + static T *allocate(std::size_t size, T const &t) + { + allocate_guard_t guard = {0, (T *)::operator new(size * sizeof(T)), false}; + + for(; guard.i < size; ++guard.i) + ::new((void *)(guard.p + guard.i)) T(t); + guard.dismissed = true; + + return guard.p; } static void deallocate(T *p, std::size_t i) @@ -115,7 +122,10 @@ private: } // grow exponentially - std::size_t new_size = (std::max)(count, static_cast<std::size_t>(this->current_chunk_->size() * 1.5)); + std::size_t new_size = (std::max)( + count + , static_cast<std::size_t>(static_cast<double>(this->current_chunk_->size()) * 1.5) + ); // Create a new expr and insert it into the list this->current_chunk_ = new chunk(new_size, t, count, this->current_chunk_, this->current_chunk_->next_); @@ -252,7 +262,7 @@ public: }}} // namespace boost::xpressive::detail -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma warning(pop) #endif |