summaryrefslogtreecommitdiff
path: root/boost/xpressive/detail/utility/sequence_stack.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/xpressive/detail/utility/sequence_stack.hpp')
-rw-r--r--boost/xpressive/detail/utility/sequence_stack.hpp42
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