Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/boostorg/json
8 : //
9 :
10 : #ifndef BOOST_JSON_DETAIL_IMPL_STACK_IPP
11 : #define BOOST_JSON_DETAIL_IMPL_STACK_IPP
12 :
13 : #include <boost/json/detail/stack.hpp>
14 :
15 : namespace boost {
16 : namespace json {
17 : namespace detail {
18 :
19 : stack::non_trivial<>*
20 1 : stack::non_trivial<>::destroy() noexcept
21 : {
22 1 : non_trivial* const result = next;
23 1 : rel(this, nullptr);
24 1 : return result;
25 : }
26 :
27 : stack::non_trivial<>*
28 3 : stack::non_trivial<>::relocate(void* dst) noexcept
29 : {
30 3 : return rel(this, dst);
31 : }
32 :
33 :
34 2185890 : stack::
35 : ~stack()
36 : {
37 2185890 : clear();
38 2185890 : if(base_ != buf_)
39 118106 : sp_->deallocate(
40 118106 : base_, cap_);
41 2185890 : }
42 :
43 21250 : stack::
44 : stack(
45 : storage_ptr sp,
46 : unsigned char* buf,
47 21250 : std::size_t buf_size) noexcept
48 21250 : : sp_(std::move(sp))
49 21250 : , cap_(buf_size)
50 21250 : , base_(buf)
51 21250 : , buf_(buf)
52 : {
53 21250 : }
54 :
55 : void
56 6360269 : stack::
57 : clear() noexcept
58 : {
59 6360270 : while(head_)
60 1 : head_ = head_->destroy();
61 6360269 : size_ = 0;
62 6360269 : }
63 :
64 : void
65 124772 : stack::
66 : reserve_impl(std::size_t n)
67 : {
68 : // caller checks this
69 124772 : BOOST_ASSERT(n > cap_);
70 :
71 124772 : auto const base = static_cast<unsigned char*>( sp_->allocate(n) );
72 124770 : if(base_)
73 : {
74 : // copy trivials
75 6664 : std::memcpy(base, base_, size_);
76 :
77 : // copy non-trivials
78 6664 : non_trivial<>* src = head_;
79 6664 : non_trivial<>** prev = &head_;
80 6667 : while(src)
81 : {
82 3 : std::size_t const buf_offset =
83 3 : reinterpret_cast<unsigned char*>(src) - base_;
84 3 : non_trivial<>* dest = src->relocate(base + buf_offset);
85 3 : *prev = dest;
86 3 : prev = &dest->next;
87 3 : src = dest->next;
88 : }
89 :
90 6664 : if(base_ != buf_)
91 6664 : sp_->deallocate(base_, cap_);
92 : }
93 124770 : base_ = base;
94 124770 : cap_ = n;
95 124770 : }
96 :
97 : } // detail
98 : } // namespace json
99 : } // namespace boost
100 :
101 : #endif
|