| 15540 | } |
| 15541 | |
| 15542 | void destroy(value_t t) noexcept |
| 15543 | { |
| 15544 | // flatten the current json_value to a heap-allocated stack |
| 15545 | std::vector<basic_json> stack; |
| 15546 | |
| 15547 | // move the top-level items to stack |
| 15548 | if (t == value_t::array) |
| 15549 | { |
| 15550 | stack.reserve(array->size()); |
| 15551 | std::move(array->begin(), array->end(), std::back_inserter(stack)); |
| 15552 | } |
| 15553 | else if (t == value_t::object) |
| 15554 | { |
| 15555 | stack.reserve(object->size()); |
| 15556 | for (auto&& it : *object) |
| 15557 | { |
| 15558 | stack.push_back(std::move(it.second)); |
| 15559 | } |
| 15560 | } |
| 15561 | |
| 15562 | while (not stack.empty()) |
| 15563 | { |
| 15564 | // move the last item to local variable to be processed |
| 15565 | basic_json current_item(std::move(stack.back())); |
| 15566 | stack.pop_back(); |
| 15567 | |
| 15568 | // if current_item is array/object, move |
| 15569 | // its children to the stack to be processed later |
| 15570 | if (current_item.is_array()) |
| 15571 | { |
| 15572 | std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), |
| 15573 | std::back_inserter(stack)); |
| 15574 | |
| 15575 | current_item.m_value.array->clear(); |
| 15576 | } |
| 15577 | else if (current_item.is_object()) |
| 15578 | { |
| 15579 | for (auto&& it : *current_item.m_value.object) |
| 15580 | { |
| 15581 | stack.push_back(std::move(it.second)); |
| 15582 | } |
| 15583 | |
| 15584 | current_item.m_value.object->clear(); |
| 15585 | } |
| 15586 | |
| 15587 | // it's now safe that current_item get destructed |
| 15588 | // since it doesn't have any children |
| 15589 | } |
| 15590 | |
| 15591 | switch (t) |
| 15592 | { |
| 15593 | case value_t::object: |
| 15594 | { |
| 15595 | AllocatorType<object_t> alloc; |
| 15596 | std::allocator_traits<decltype(alloc)>::destroy(alloc, object); |
| 15597 | std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1); |
| 15598 | break; |
| 15599 | } |