[info] type_name = "std::variant" ctype = "STD_VARIANT_TYPE" header = "variant" # Old: typeName = "std::variant" ns = ["namespace std"] [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%)); SAVE_DATA(container.index()); // This check should be `container.valueless_by_exception()` but it doesn't // work with the variable sized integers used in `std::variant`. For fewer // than 256 options it uses a `uint8_t` index but checks against -1 of // `uintptr_t`. Manually check for any out of bounds indices as a workaround. if (container.index() >= sizeof...(Types)) { return; } std::visit([&returnArg](auto &&arg) { // Account for inline contents SAVE_SIZE(-sizeof(arg)); getSizeType(arg, returnArg); }, container); } """ scoped_extra = """ template static types::st::Unit getSizeTypeRecursive( Ctx& ctx, const container_type& container, typename TypeHandler::type returnArg ) { if constexpr (I < sizeof...(Types)) { if (I == container.index()) { return returnArg.template delegate([&ctx, &container](auto ret) { return OIInternal::getSizeType(ctx, std::get(container), ret); }); } else { return getSizeTypeRecursive(ctx, container, returnArg); } } else { return returnArg.template delegate(std::identity()); } } """ handler_header = """ template struct TypeHandler> """ traversal_func = """ return getSizeTypeRecursive(ctx, container, returnArg); """ [[codegen.processor]] type = "types::st::Sum::type..., types::st::Unit>" func = """ static constexpr std::array children{ make_field("*")..., }; auto sum = std::get(d.val); el.container_stats = result::Element::ContainerStats { .capacity = 1, .length = sum.index == sizeof...(Types) ? 0u : 1u, }; if (el.container_stats->length == 0) return; el.exclusive_size -= children[sum.index].static_size; stack_ins(children[sum.index]); """