[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); } """ handler = """ template struct TypeHandler> { using type = types::st::Sum::type..., types::st::Unit>; static types::st::Unit getSizeType( const %1%& container, typename TypeHandler>::type returnArg) { return getSizeTypeRecursive(container, returnArg); } private: template static types::st::Unit getSizeTypeRecursive( const %1%& container, typename TypeHandler>::type returnArg) { if constexpr (I < sizeof...(Types)) { if (I == container.index()) { return returnArg.template delegate([&container](auto ret) { return OIInternal::getSizeType(std::get(container), ret); }); } else { return getSizeTypeRecursive(container, returnArg); } } else { return returnArg.template delegate(std::identity()); } } }; """