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 2185850 : stack::
35 : ~stack()
36 : {
37 2185850 : clear();
38 2185850 : if(base_ != buf_)
39 118086 : sp_->deallocate(
40 118086 : base_, cap_);
41 2185850 : }
42 :
43 21245 : stack::
44 : stack(
45 : storage_ptr sp,
46 : unsigned char* buf,
47 21245 : std::size_t buf_size) noexcept
48 21245 : : sp_(std::move(sp))
49 21245 : , cap_(buf_size)
50 21245 : , base_(buf)
51 21245 : , buf_(buf)
52 : {
53 21245 : }
54 :
55 : void
56 6360224 : stack::
57 : clear() noexcept
58 : {
59 6360225 : while(head_)
60 1 : head_ = head_->destroy();
61 6360224 : size_ = 0;
62 6360224 : }
63 :
64 : void
65 124748 : stack::
66 : reserve_impl(std::size_t n)
67 : {
68 : // caller checks this
69 124748 : BOOST_ASSERT(n > cap_);
70 :
71 124748 : auto const base = static_cast<unsigned char*>( sp_->allocate(n) );
72 124746 : if(base_)
73 : {
74 : // copy trivials
75 6660 : std::memcpy(base, base_, size_);
76 :
77 : // copy non-trivials
78 6660 : non_trivial<>* src = head_;
79 6660 : non_trivial<>** prev = &head_;
80 6663 : 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 6660 : if(base_ != buf_)
91 6660 : sp_->deallocate(base_, cap_);
92 : }
93 124746 : base_ = base;
94 124746 : cap_ = n;
95 124746 : }
96 :
97 : } // detail
98 : } // namespace json
99 : } // namespace boost
100 :
101 : #endif
|