Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:01

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/json
0009 //
0010 
0011 #ifndef BOOST_JSON_IMPL_MONOTONIC_RESOURCE_IPP
0012 #define BOOST_JSON_IMPL_MONOTONIC_RESOURCE_IPP
0013 
0014 #include <boost/json/monotonic_resource.hpp>
0015 #include <boost/json/detail/except.hpp>
0016 #include <boost/align/align.hpp>
0017 #include <boost/core/max_align.hpp>
0018 
0019 #include <memory>
0020 
0021 namespace boost {
0022 namespace json {
0023 
0024 struct alignas(core::max_align_t)
0025     monotonic_resource::block : block_base
0026 {
0027 };
0028 
0029 constexpr
0030 std::size_t
0031 monotonic_resource::
0032 max_size()
0033 {
0034     return std::size_t(-1) - sizeof(block);
0035 }
0036 
0037 // lowest power of 2 greater than or equal to n
0038 std::size_t
0039 monotonic_resource::
0040 round_pow2(
0041     std::size_t n) noexcept
0042 {
0043     if(n & (n - 1))
0044         return next_pow2(n);
0045     return n;
0046 }
0047 
0048 // lowest power of 2 greater than n
0049 std::size_t
0050 monotonic_resource::
0051 next_pow2(
0052     std::size_t n) noexcept
0053 {
0054     std::size_t result = min_size_;
0055     while(result <= n)
0056     {
0057         if(result >= max_size() - result)
0058         {
0059             // overflow
0060             result = max_size();
0061             break;
0062         }
0063         result *= 2;
0064     }
0065     return result;
0066 }
0067 
0068 //----------------------------------------------------------
0069 
0070 monotonic_resource::
0071 ~monotonic_resource()
0072 {
0073     release();
0074 }
0075 
0076 monotonic_resource::
0077 monotonic_resource(
0078     std::size_t initial_size,
0079     storage_ptr upstream) noexcept
0080     : buffer_{
0081         nullptr, 0, 0, nullptr}
0082     , next_size_(round_pow2(initial_size))
0083     , upstream_(std::move(upstream))
0084 {
0085 }
0086 
0087 monotonic_resource::
0088 monotonic_resource(
0089     unsigned char* buffer,
0090     std::size_t size,
0091     storage_ptr upstream) noexcept
0092     : buffer_{
0093         buffer, size, size, nullptr}
0094     , next_size_(next_pow2(size))
0095     , upstream_(std::move(upstream))
0096 {
0097 }
0098 
0099 void
0100 monotonic_resource::
0101 release() noexcept
0102 {
0103     auto p = head_;
0104     while(p != &buffer_)
0105     {
0106         auto next = p->next;
0107         upstream_->deallocate(p, p->size);
0108         p = next;
0109     }
0110     buffer_.p = reinterpret_cast<
0111         unsigned char*>(buffer_.p) - (
0112             buffer_.size - buffer_.avail);
0113     buffer_.avail = buffer_.size;
0114     head_ = &buffer_;
0115 }
0116 
0117 void*
0118 monotonic_resource::
0119 do_allocate(
0120     std::size_t n,
0121     std::size_t align)
0122 {
0123     auto p = alignment::align(
0124         align, n, head_->p, head_->avail);
0125     if(p)
0126     {
0127         head_->p = reinterpret_cast<
0128             unsigned char*>(p) + n;
0129         head_->avail -= n;
0130         return p;
0131     }
0132 
0133     if(next_size_ < n)
0134         next_size_ = round_pow2(n);
0135     auto b = ::new(upstream_->allocate(
0136         sizeof(block) + next_size_)) block;
0137     b->p = b + 1;
0138     b->avail = next_size_;
0139     b->size = next_size_;
0140     b->next = head_;
0141     head_ = b;
0142     next_size_ = next_pow2(next_size_);
0143 
0144     p = alignment::align(
0145         align, n, head_->p, head_->avail);
0146     BOOST_ASSERT(p);
0147     head_->p = reinterpret_cast<
0148         unsigned char*>(p) + n;
0149     head_->avail -= n;
0150     return p;
0151 }
0152 
0153 void
0154 monotonic_resource::
0155 do_deallocate(
0156     void*,
0157     std::size_t,
0158     std::size_t)
0159 {
0160     // do nothing
0161 }
0162 
0163 bool
0164 monotonic_resource::
0165 do_is_equal(
0166     memory_resource const& mr) const noexcept
0167 {
0168     return this == &mr;
0169 }
0170 
0171 } // namespace json
0172 } // namespace boost
0173 
0174 #endif