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.1 % 69 67 2
Test Date: 2026-02-25 20:43:10 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/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 HIT         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 MIS           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.3