From ee78f1816172f35c86b97279c56d5cc672436572 Mon Sep 17 00:00:00 2001 From: Dmitry Arkhipov Date: Wed, 11 Oct 2023 16:18:20 +0300 Subject: [PATCH] detail::stack grows by powers of 2 --- include/boost/json/detail/impl/stack.hpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/include/boost/json/detail/impl/stack.hpp b/include/boost/json/detail/impl/stack.hpp index e334e9fa2..058f0998c 100644 --- a/include/boost/json/detail/impl/stack.hpp +++ b/include/boost/json/detail/impl/stack.hpp @@ -46,15 +46,25 @@ reserve_impl(std::size_t n) // caller checks this BOOST_ASSERT(n > cap_); - if(BOOST_JSON_UNLIKELY( n > std::numeric_limits::max() - n )) + constexpr std::size_t max = std::numeric_limits::max(); + std::size_t cap = cap_ ? cap_ : 32 ; + do + { + if(BOOST_JSON_UNLIKELY( cap > max - cap )) + throw_exception( std::bad_alloc(), BOOST_CURRENT_LOCATION ); + cap *= 2; + } + while(cap < n); + + if(BOOST_JSON_UNLIKELY( cap > max - cap )) throw_exception( std::bad_alloc(), BOOST_CURRENT_LOCATION ); - auto const base = static_cast( sp_->allocate(n * 2) ); + auto const base = static_cast( sp_->allocate(cap * 2) ); if(base_) { // copy trivials if(size1_ > 0) - std::memcpy(base + n - size1_, base_ + cap_ - size1_, size1_); + std::memcpy(base + cap - size1_, base_ + cap_ - size1_, size1_); // copy non-trivials if(head_) @@ -85,7 +95,7 @@ reserve_impl(std::size_t n) sp_->deallocate(base_, cap_ * 2); } base_ = base; - cap_ = n; + cap_ = cap; } template