| 17690 | } |
| 17691 | |
| 17692 | void destroy(value_t t) noexcept |
| 17693 | { |
| 17694 | // flatten the current json_value to a heap-allocated stack |
| 17695 | std::vector<basic_json> stack; |
| 17696 | |
| 17697 | // move the top-level items to stack |
| 17698 | if (t == value_t::array) |
| 17699 | { |
| 17700 | stack.reserve(array->size()); |
| 17701 | std::move(array->begin(), array->end(), std::back_inserter(stack)); |
| 17702 | } |
| 17703 | else if (t == value_t::object) |
| 17704 | { |
| 17705 | stack.reserve(object->size()); |
| 17706 | for (auto&& it : *object) |
| 17707 | { |
| 17708 | stack.push_back(std::move(it.second)); |
| 17709 | } |
| 17710 | } |
| 17711 | |
| 17712 | while (!stack.empty()) |
| 17713 | { |
| 17714 | // move the last item to local variable to be processed |
| 17715 | basic_json current_item(std::move(stack.back())); |
| 17716 | stack.pop_back(); |
| 17717 | |
| 17718 | // if current_item is array/object, move |
| 17719 | // its children to the stack to be processed later |
| 17720 | if (current_item.is_array()) |
| 17721 | { |
| 17722 | std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), |
| 17723 | std::back_inserter(stack)); |
| 17724 | |
| 17725 | current_item.m_value.array->clear(); |
| 17726 | } |
| 17727 | else if (current_item.is_object()) |
| 17728 | { |
| 17729 | for (auto&& it : *current_item.m_value.object) |
| 17730 | { |
| 17731 | stack.push_back(std::move(it.second)); |
| 17732 | } |
| 17733 | |
| 17734 | current_item.m_value.object->clear(); |
| 17735 | } |
| 17736 | |
| 17737 | // it's now safe that current_item get destructed |
| 17738 | // since it doesn't have any children |
| 17739 | } |
| 17740 | |
| 17741 | switch (t) |
| 17742 | { |
| 17743 | case value_t::object: |
| 17744 | { |
| 17745 | AllocatorType<object_t> alloc; |
| 17746 | std::allocator_traits<decltype(alloc)>::destroy(alloc, object); |
| 17747 | std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1); |
| 17748 | break; |
| 17749 | } |