| 17607 | } |
| 17608 | |
| 17609 | void destroy(value_t t) noexcept |
| 17610 | { |
| 17611 | // flatten the current json_value to a heap-allocated stack |
| 17612 | std::vector<basic_json> stack; |
| 17613 | |
| 17614 | // move the top-level items to stack |
| 17615 | if (t == value_t::array) |
| 17616 | { |
| 17617 | stack.reserve(array->size()); |
| 17618 | std::move(array->begin(), array->end(), std::back_inserter(stack)); |
| 17619 | } |
| 17620 | else if (t == value_t::object) |
| 17621 | { |
| 17622 | stack.reserve(object->size()); |
| 17623 | for (auto&& it : *object) |
| 17624 | { |
| 17625 | stack.push_back(std::move(it.second)); |
| 17626 | } |
| 17627 | } |
| 17628 | |
| 17629 | while (!stack.empty()) |
| 17630 | { |
| 17631 | // move the last item to local variable to be processed |
| 17632 | basic_json current_item(std::move(stack.back())); |
| 17633 | stack.pop_back(); |
| 17634 | |
| 17635 | // if current_item is array/object, move |
| 17636 | // its children to the stack to be processed later |
| 17637 | if (current_item.is_array()) |
| 17638 | { |
| 17639 | std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), |
| 17640 | std::back_inserter(stack)); |
| 17641 | |
| 17642 | current_item.m_value.array->clear(); |
| 17643 | } |
| 17644 | else if (current_item.is_object()) |
| 17645 | { |
| 17646 | for (auto&& it : *current_item.m_value.object) |
| 17647 | { |
| 17648 | stack.push_back(std::move(it.second)); |
| 17649 | } |
| 17650 | |
| 17651 | current_item.m_value.object->clear(); |
| 17652 | } |
| 17653 | |
| 17654 | // it's now safe that current_item get destructed |
| 17655 | // since it doesn't have any children |
| 17656 | } |
| 17657 | |
| 17658 | switch (t) |
| 17659 | { |
| 17660 | case value_t::object: |
| 17661 | { |
| 17662 | AllocatorType<object_t> alloc; |
| 17663 | std::allocator_traits<decltype(alloc)>::destroy(alloc, object); |
| 17664 | std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1); |
| 17665 | break; |
| 17666 | } |