LCOV - code coverage report
Current view: top level - json/impl - monotonic_resource.ipp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 97.2 % 71 69 2
Test Date: 2026-03-05 09:04:27 Functions: 81.8 % 11 9 2

           TLA  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/align/align.hpp>
      17                 : #include <boost/core/max_align.hpp>
      18                 : 
      19                 : #include <memory>
      20                 : 
      21                 : namespace boost {
      22                 : namespace json {
      23                 : 
      24                 : struct alignas(core::max_align_t)
      25                 :     monotonic_resource::block : block_base
      26                 : {
      27                 : };
      28                 : 
      29                 : constexpr
      30                 : std::size_t
      31 HIT         164 : monotonic_resource::
      32                 : max_size()
      33                 : {
      34             164 :     return std::size_t(-1) - sizeof(block);
      35                 : }
      36                 : 
      37                 : // lowest power of 2 greater than or equal to n
      38                 : std::size_t
      39              39 : monotonic_resource::
      40                 : round_pow2(
      41                 :     std::size_t n) noexcept
      42                 : {
      43              39 :     if(n & (n - 1))
      44               7 :         return next_pow2(n);
      45              32 :     return n;
      46                 : }
      47                 : 
      48                 : // lowest power of 2 greater than n
      49                 : std::size_t
      50              51 : monotonic_resource::
      51                 : next_pow2(
      52                 :     std::size_t n) noexcept
      53                 : {
      54              51 :     std::size_t result = min_size_;
      55             213 :     while(result <= n)
      56                 :     {
      57             163 :         if(result >= max_size() - result)
      58                 :         {
      59                 :             // overflow
      60               1 :             result = max_size();
      61               1 :             break;
      62                 :         }
      63             162 :         result *= 2;
      64                 :     }
      65              51 :     return result;
      66                 : }
      67                 : 
      68                 : //----------------------------------------------------------
      69                 : 
      70              47 : monotonic_resource::
      71              47 : ~monotonic_resource()
      72                 : {
      73              47 :     release();
      74              47 : }
      75                 : 
      76              37 : monotonic_resource::
      77                 : monotonic_resource(
      78                 :     std::size_t initial_size,
      79              37 :     storage_ptr upstream) noexcept
      80              37 :     : buffer_{
      81                 :         nullptr, 0, 0, nullptr}
      82              74 :     , next_size_(round_pow2(initial_size))
      83              37 :     , upstream_(std::move(upstream))
      84                 : {
      85              37 : }
      86                 : 
      87              10 : monotonic_resource::
      88                 : monotonic_resource(
      89                 :     unsigned char* buffer,
      90                 :     std::size_t size,
      91              10 :     storage_ptr upstream) noexcept
      92              10 :     : buffer_{
      93                 :         buffer, size, size, nullptr}
      94              20 :     , next_size_(next_pow2(size))
      95              10 :     , upstream_(std::move(upstream))
      96                 : {
      97              10 : }
      98                 : 
      99                 : void
     100              48 : monotonic_resource::
     101                 : release() noexcept
     102                 : {
     103              48 :     auto p = head_;
     104              82 :     while(p != &buffer_)
     105                 :     {
     106              34 :         auto next = p->next;
     107              34 :         upstream_->deallocate(p, p->size);
     108              34 :         p = next;
     109                 :     }
     110              48 :     buffer_.p = reinterpret_cast<
     111              48 :         unsigned char*>(buffer_.p) - (
     112              48 :             buffer_.size - buffer_.avail);
     113              48 :     buffer_.avail = buffer_.size;
     114              48 :     head_ = &buffer_;
     115              48 : }
     116                 : 
     117                 : void*
     118          129498 : monotonic_resource::
     119                 : do_allocate(
     120                 :     std::size_t n,
     121                 :     std::size_t align)
     122                 : {
     123          129498 :     auto p = alignment::align(
     124          129498 :         align, n, head_->p, head_->avail);
     125          129498 :     if(p)
     126                 :     {
     127          129464 :         head_->p = reinterpret_cast<
     128          129464 :             unsigned char*>(p) + n;
     129          129464 :         head_->avail -= n;
     130          129464 :         return p;
     131                 :     }
     132                 : 
     133              34 :     if(next_size_ < n)
     134               2 :         next_size_ = round_pow2(n);
     135              34 :     auto b = ::new(upstream_->allocate(
     136              34 :         sizeof(block) + next_size_)) block;
     137              34 :     b->p = b + 1;
     138              34 :     b->avail = next_size_;
     139              34 :     b->size = next_size_;
     140              34 :     b->next = head_;
     141              34 :     head_ = b;
     142              34 :     next_size_ = next_pow2(next_size_);
     143                 : 
     144              34 :     p = alignment::align(
     145              34 :         align, n, head_->p, head_->avail);
     146              34 :     BOOST_ASSERT(p);
     147              34 :     head_->p = reinterpret_cast<
     148              34 :         unsigned char*>(p) + n;
     149              34 :     head_->avail -= n;
     150              34 :     return p;
     151                 : }
     152                 : 
     153                 : void
     154              29 : monotonic_resource::
     155                 : do_deallocate(
     156                 :     void*,
     157                 :     std::size_t,
     158                 :     std::size_t)
     159                 : {
     160                 :     // do nothing
     161              29 : }
     162                 : 
     163                 : bool
     164 MIS           0 : monotonic_resource::
     165                 : do_is_equal(
     166                 :     memory_resource const& mr) const noexcept
     167                 : {
     168               0 :     return this == &mr;
     169                 : }
     170                 : 
     171                 : } // namespace json
     172                 : } // namespace boost
     173                 : 
     174                 : #endif
        

Generated by: LCOV version 2.3