LCOV - code coverage report
Current view: top level - json/impl - monotonic_resource.ipp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 97.1 % 69 67
Test Date: 2026-01-05 13:48:39 Functions: 81.8 % 11 9

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/boostorg/json
       9              : //
      10              : 
      11              : #ifndef BOOST_JSON_IMPL_MONOTONIC_RESOURCE_IPP
      12              : #define BOOST_JSON_IMPL_MONOTONIC_RESOURCE_IPP
      13              : 
      14              : #include <boost/json/monotonic_resource.hpp>
      15              : #include <boost/json/detail/except.hpp>
      16              : #include <boost/core/max_align.hpp>
      17              : 
      18              : #include <memory>
      19              : 
      20              : namespace boost {
      21              : namespace json {
      22              : 
      23              : struct alignas(core::max_align_t)
      24              :     monotonic_resource::block : block_base
      25              : {
      26              : };
      27              : 
      28              : constexpr
      29              : std::size_t
      30          164 : monotonic_resource::
      31              : max_size()
      32              : {
      33          164 :     return std::size_t(-1) - sizeof(block);
      34              : }
      35              : 
      36              : // lowest power of 2 greater than or equal to n
      37              : std::size_t
      38           39 : monotonic_resource::
      39              : round_pow2(
      40              :     std::size_t n) noexcept
      41              : {
      42           39 :     if(n & (n - 1))
      43            7 :         return next_pow2(n);
      44           32 :     return n;
      45              : }
      46              : 
      47              : // lowest power of 2 greater than n
      48              : std::size_t
      49           51 : monotonic_resource::
      50              : next_pow2(
      51              :     std::size_t n) noexcept
      52              : {
      53           51 :     std::size_t result = min_size_;
      54          213 :     while(result <= n)
      55              :     {
      56          163 :         if(result >= max_size() - result)
      57              :         {
      58              :             // overflow
      59            1 :             result = max_size();
      60            1 :             break;
      61              :         }
      62          162 :         result *= 2;
      63              :     }
      64           51 :     return result;
      65              : }
      66              : 
      67              : //----------------------------------------------------------
      68              : 
      69           47 : monotonic_resource::
      70           47 : ~monotonic_resource()
      71              : {
      72           47 :     release();
      73           47 : }
      74              : 
      75           37 : monotonic_resource::
      76              : monotonic_resource(
      77              :     std::size_t initial_size,
      78           37 :     storage_ptr upstream) noexcept
      79           37 :     : buffer_{
      80              :         nullptr, 0, 0, nullptr}
      81           74 :     , next_size_(round_pow2(initial_size))
      82           37 :     , upstream_(std::move(upstream))
      83              : {
      84           37 : }
      85              : 
      86           10 : monotonic_resource::
      87              : monotonic_resource(
      88              :     unsigned char* buffer,
      89              :     std::size_t size,
      90           10 :     storage_ptr upstream) noexcept
      91           10 :     : buffer_{
      92              :         buffer, size, size, nullptr}
      93           20 :     , next_size_(next_pow2(size))
      94           10 :     , upstream_(std::move(upstream))
      95              : {
      96           10 : }
      97              : 
      98              : void
      99           48 : monotonic_resource::
     100              : release() noexcept
     101              : {
     102           48 :     auto p = head_;
     103           82 :     while(p != &buffer_)
     104              :     {
     105           34 :         auto next = p->next;
     106           34 :         upstream_->deallocate(p, p->size);
     107           34 :         p = next;
     108              :     }
     109           48 :     buffer_.p = reinterpret_cast<
     110           48 :         unsigned char*>(buffer_.p) - (
     111           48 :             buffer_.size - buffer_.avail);
     112           48 :     buffer_.avail = buffer_.size;
     113           48 :     head_ = &buffer_;
     114           48 : }
     115              : 
     116              : void*
     117       129498 : monotonic_resource::
     118              : do_allocate(
     119              :     std::size_t n,
     120              :     std::size_t align)
     121              : {
     122       129498 :     auto p = std::align(align, n, head_->p, head_->avail);
     123       129498 :     if(p)
     124              :     {
     125       129464 :         head_->p = reinterpret_cast<
     126       129464 :             unsigned char*>(p) + n;
     127       129464 :         head_->avail -= n;
     128       129464 :         return p;
     129              :     }
     130              : 
     131           34 :     if(next_size_ < n)
     132            2 :         next_size_ = round_pow2(n);
     133           34 :     auto b = ::new(upstream_->allocate(
     134           34 :         sizeof(block) + next_size_)) block;
     135           34 :     b->p = b + 1;
     136           34 :     b->avail = next_size_;
     137           34 :     b->size = next_size_;
     138           34 :     b->next = head_;
     139           34 :     head_ = b;
     140           34 :     next_size_ = next_pow2(next_size_);
     141              : 
     142           34 :     p = std::align(align, n, head_->p, head_->avail);
     143           34 :     BOOST_ASSERT(p);
     144           34 :     head_->p = reinterpret_cast<
     145           34 :         unsigned char*>(p) + n;
     146           34 :     head_->avail -= n;
     147           34 :     return p;
     148              : }
     149              : 
     150              : void
     151           29 : monotonic_resource::
     152              : do_deallocate(
     153              :     void*,
     154              :     std::size_t,
     155              :     std::size_t)
     156              : {
     157              :     // do nothing
     158           29 : }
     159              : 
     160              : bool
     161            0 : monotonic_resource::
     162              : do_is_equal(
     163              :     memory_resource const& mr) const noexcept
     164              : {
     165            0 :     return this == &mr;
     166              : }
     167              : 
     168              : } // namespace json
     169              : } // namespace boost
     170              : 
     171              : #endif
        

Generated by: LCOV version 2.1