LCOV - code coverage report
Current view: top level - json/impl - monotonic_resource.ipp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 97.2 % 71 69
Test Date: 2025-12-23 17:20:51 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/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          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            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.1