| 208 | |
| 209 | template <class Mutex> |
| 210 | void Soft_Ring_Buffer_Ex<Mutex>::grow_(size_t atleastcap) |
| 211 | { |
| 212 | size_t oldcap = rb_.capacity(); |
| 213 | size_t newcap = (oldcap < 16) ? 16 : oldcap; |
| 214 | while (newcap < atleastcap) { |
| 215 | if (newcap > std::numeric_limits<size_t>::max() / 3) |
| 216 | throw std::bad_alloc(); |
| 217 | newcap = newcap * 3 / 2; |
| 218 | } |
| 219 | |
| 220 | size_t len = rb_.size_used(); |
| 221 | std::unique_ptr<uint8_t[]> newdata(new uint8_t[newcap + 1]); |
| 222 | |
| 223 | { |
| 224 | const size_t rp = rb_.rp_; |
| 225 | const uint8_t *src = rb_.rbdata_.get(); |
| 226 | uint8_t *dst = newdata.get(); |
| 227 | |
| 228 | const size_t taillen = std::min(len, oldcap + 1 - rp); |
| 229 | std::copy_n(&src[rp], taillen, dst); |
| 230 | std::copy_n(src, len - taillen, dst + taillen); |
| 231 | } |
| 232 | |
| 233 | rb_.cap_ = newcap + 1; |
| 234 | rb_.rp_ = 0; |
| 235 | rb_.wp_ = len; |
| 236 | rb_.rbdata_ = std::move(newdata); |
| 237 | } |
| 238 | |
| 239 | #if defined(__cpp_lib_shared_mutex) |
| 240 | template class Soft_Ring_Buffer_Ex<std::shared_mutex>; |