[info] type_name = "folly::small_vector" ctype = "SMALL_VEC_TYPE" header = "folly/small_vector.h" stub_template_params = [2] # Old: typeName = "folly::small_vector<" ns = ["folly::small_vector_policy::policy_size_type", "folly::small_vector"] numTemplateParams = 1 replaceTemplateParamIndex = [] [codegen] decl = """ template void getSizeType(const %1% &container, size_t& returnArg); """ func = """ template void getSizeType(const %1% &container, size_t& returnArg) { SAVE_SIZE(sizeof(%1%)); bool dataInlined = isStorageInline(container); if (dataInlined) { // Don't double count inlined elements SAVE_SIZE(-(container.size() * sizeof(V))); } else { // Account for wasted space in the buffer SAVE_SIZE((container.capacity() - container.size()) * sizeof(V)); } SAVE_DATA((uintptr_t)(N)); SAVE_DATA((uintptr_t)container.capacity()); SAVE_DATA((uintptr_t)container.size()); for (auto & it: container) { getSizeType(it, returnArg); } } """ traversal_func = """ bool uses_intern_storage = isStorageInline(container); auto tail = returnArg .write((uintptr_t)uses_intern_storage) .write(container.capacity()) .write(container.size()); for (auto &&it: container) { tail = tail.delegate([&ctx, &it](typename TypeHandler::type ret) { return OIInternal::getSizeType(ctx, it, ret); }); } return tail.finish(); """ [[codegen.processor]] type = "types::st::VarInt" func = """ // Using the container's pointer to temporarily store the uses_intern_storage boolean. // TODO: Is there another way to pass a value across processors? el.pointer = std::get(d.val).value; """ [[codegen.processor]] type = "types::st::VarInt" func = """ el.container_stats.emplace(result::Element::ContainerStats { .capacity = std::get(d.val).value, }); """ [[codegen.processor]] type = "types::st::List::type>" func = """ // Reading the `uses_intern_storage` boolean that was stored in `pointer` by the processor above. bool uses_intern_storage = std::exchange(el.pointer.value(), (uintptr_t)0); auto list = std::get(d.val); el.container_stats->length = list.length; if (uses_intern_storage) { // The storage is inlined, so don't double count for items using the intern storage. el.exclusive_size -= list.length * sizeof(T0); } else { // The storage is heap allocated, so add any unused capacity. el.exclusive_size += (el.container_stats->capacity - el.container_stats->length) * sizeof(T0); } static constexpr auto childField = make_field("[]"); for (size_t i = 0; i < list.length; i++) stack_ins(childField); """