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