stack.ipp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. #ifndef BOOST_JSON_DETAIL_IMPL_STACK_IPP
  10. #define BOOST_JSON_DETAIL_IMPL_STACK_IPP
  11. #include <boost/json/detail/stack.hpp>
  12. namespace boost {
  13. namespace json {
  14. namespace detail {
  15. stack::non_trivial<>*
  16. stack::non_trivial<>::destroy() noexcept
  17. {
  18. non_trivial* const result = next;
  19. rel(this, nullptr);
  20. return result;
  21. }
  22. stack::non_trivial<>*
  23. stack::non_trivial<>::relocate(void* dst) noexcept
  24. {
  25. return rel(this, dst);
  26. }
  27. stack::
  28. ~stack()
  29. {
  30. clear();
  31. if(base_ != buf_)
  32. sp_->deallocate(
  33. base_, cap_);
  34. }
  35. stack::
  36. stack(
  37. storage_ptr sp,
  38. unsigned char* buf,
  39. std::size_t buf_size) noexcept
  40. : sp_(std::move(sp))
  41. , cap_(buf_size)
  42. , base_(buf)
  43. , buf_(buf)
  44. {
  45. }
  46. void
  47. stack::
  48. clear() noexcept
  49. {
  50. while(head_)
  51. head_ = head_->destroy();
  52. size_ = 0;
  53. }
  54. void
  55. stack::
  56. reserve_impl(std::size_t n)
  57. {
  58. // caller checks this
  59. BOOST_ASSERT(n > cap_);
  60. auto const base = static_cast<unsigned char*>( sp_->allocate(n) );
  61. if(base_)
  62. {
  63. // copy trivials
  64. std::memcpy(base, base_, size_);
  65. // copy non-trivials
  66. non_trivial<>* src = head_;
  67. non_trivial<>** prev = &head_;
  68. while(src)
  69. {
  70. std::size_t const buf_offset =
  71. reinterpret_cast<unsigned char*>(src) - base_;
  72. non_trivial<>* dest = src->relocate(base + buf_offset);
  73. *prev = dest;
  74. prev = &dest->next;
  75. src = dest->next;
  76. }
  77. if(base_ != buf_)
  78. sp_->deallocate(base_, cap_);
  79. }
  80. base_ = base;
  81. cap_ = n;
  82. }
  83. } // detail
  84. } // namespace json
  85. } // namespace boost
  86. #endif