tbv2: add dynamic context passed through all functions

Previously for we had some shared state between all requests, noticeably the
pointers set. This change adds a by reference value to all requests which can
hold additional mutable state. The pointers set is moved into this mutable
state for OIL, which means each concurrent request will have its own pointer
set. Doing things this way allows more features to be added in the future
without such a big code modification.

Closes #404

Test plan:
- CI
This commit is contained in:
Jake Hillion 2023-11-15 06:14:52 -08:00
parent ba79e50fb4
commit 143805dfe2
34 changed files with 127 additions and 103 deletions

View File

@ -128,8 +128,9 @@ void addIncludes(const TypeGraph& typeGraph,
includes.emplace("oi/types/st.h"); includes.emplace("oi/types/st.h");
} }
if (features[Feature::Library]) { if (features[Feature::Library]) {
includes.emplace("vector"); includes.emplace("memory");
includes.emplace("oi/IntrospectionResult.h"); includes.emplace("oi/IntrospectionResult.h");
includes.emplace("vector");
} }
if (features[Feature::JitTiming]) { if (features[Feature::JitTiming]) {
includes.emplace("chrono"); includes.emplace("chrono");
@ -428,7 +429,7 @@ void addStandardGetSizeFuncDefs(std::string& code) {
JLOG("ptr val @"); JLOG("ptr val @");
JLOGPTR(s_ptr); JLOGPTR(s_ptr);
StoreData((uintptr_t)(s_ptr), returnArg); StoreData((uintptr_t)(s_ptr), returnArg);
if (s_ptr && pointers.add((uintptr_t)s_ptr)) { if (s_ptr && ctx.pointers.add((uintptr_t)s_ptr)) {
StoreData(1, returnArg); StoreData(1, returnArg);
getSizeType(*(s_ptr), returnArg); getSizeType(*(s_ptr), returnArg);
} else { } else {
@ -649,7 +650,8 @@ void CodeGen::genClassTraversalFunction(const Class& c, std::string& code) {
code += " static types::st::Unit<DB> "; code += " static types::st::Unit<DB> ";
code += funcName; code += funcName;
code += "(\n const "; code += "(\n Ctx& ctx,\n";
code += " const ";
code += c.name(); code += c.name();
code += "& t,\n typename TypeHandler<Ctx, "; code += "& t,\n typename TypeHandler<Ctx, ";
code += c.name(); code += c.name();
@ -683,7 +685,8 @@ void CodeGen::genClassTraversalFunction(const Class& c, std::string& code) {
} else { } else {
code += "delegate"; code += "delegate";
} }
code += "([&t](auto ret) { return OIInternal::getSizeType<Ctx>(t."; code +=
"([&ctx, &t](auto ret) { return OIInternal::getSizeType<Ctx>(ctx, t.";
code += member.name; code += member.name;
code += ", ret); })"; code += ", ret); })";
} }
@ -921,6 +924,7 @@ void genContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
code += ";\n"; code += ";\n";
code += " static types::st::Unit<DB> getSizeType(\n"; code += " static types::st::Unit<DB> getSizeType(\n";
code += " Ctx& ctx,\n";
code += " const "; code += " const ";
code += containerWithTypes; code += containerWithTypes;
code += "& container,\n"; code += "& container,\n";
@ -979,7 +983,7 @@ void addCaptureKeySupport(std::string& code) {
}; };
template <bool CaptureKeys, typename Ctx, typename T> template <bool CaptureKeys, typename Ctx, typename T>
auto maybeCaptureKey(const T& key, auto returnArg) { auto maybeCaptureKey(Ctx& ctx, const T& key, auto returnArg) {
if constexpr (CaptureKeys) { if constexpr (CaptureKeys) {
return returnArg.delegate([&key](auto ret) { return returnArg.delegate([&key](auto ret) {
return CaptureKeyHandler<Ctx, T>::captureKey(key, ret); return CaptureKeyHandler<Ctx, T>::captureKey(key, ret);
@ -1041,10 +1045,10 @@ void addStandardTypeHandlers(TypeGraph& typeGraph,
code += R"( code += R"(
template <typename Ctx, typename T> template <typename Ctx, typename T>
types::st::Unit<typename Ctx::DataBuffer> types::st::Unit<typename Ctx::DataBuffer>
getSizeType(const T &t, typename TypeHandler<Ctx, T>::type returnArg) { getSizeType(Ctx& ctx, const T &t, typename TypeHandler<Ctx, T>::type returnArg) {
JLOG("obj @"); JLOG("obj @");
JLOGPTR(&t); JLOGPTR(&t);
return TypeHandler<Ctx, T>::getSizeType(t, returnArg); return TypeHandler<Ctx, T>::getSizeType(ctx, t, returnArg);
} }
)"; )";
@ -1233,6 +1237,13 @@ void CodeGen::generate(
if (config_.features[Feature::CaptureThriftIsset]) { if (config_.features[Feature::CaptureThriftIsset]) {
genDefsThrift(typeGraph, code); genDefsThrift(typeGraph, code);
} }
if (!config_.features[Feature::TreeBuilderV2]) {
code += "namespace {\n";
code += "static struct Context {\n";
code += " PointerHashSet<(1 << 20) / sizeof(uintptr_t)> pointers;\n";
code += "} ctx;\n";
code += "} // namespace\n";
}
/* /*
* The purpose of the anonymous namespace within `OIInternal` is that * The purpose of the anonymous namespace within `OIInternal` is that

View File

@ -262,19 +262,24 @@ void __attribute__((used, retain)) introspect_%2$016x(
std::vector<uint8_t>& v) std::vector<uint8_t>& v)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
{ {
pointers.initialize();
pointers.add((uintptr_t)&t);
v.clear(); v.clear();
v.reserve(4096); v.reserve(4096);
auto pointers = std::make_unique<PointerHashSet<(1 << 20) / sizeof(uintptr_t)>>();
pointers->initialize();
struct Context { struct Context {
using DataBuffer = DataBuffer::BackInserter<std::vector<uint8_t>>; using DataBuffer = DataBuffer::BackInserter<std::vector<uint8_t>>;
PointerHashSet<(1 << 20) / sizeof(uintptr_t)>& pointers;
}; };
Context ctx{ .pointers = *pointers };
ctx.pointers.add((uintptr_t)&t);
using ContentType = OIInternal::TypeHandler<Context, OIInternal::__ROOT_TYPE__>::type; using ContentType = OIInternal::TypeHandler<Context, OIInternal::__ROOT_TYPE__>::type;
ContentType ret{Context::DataBuffer{v}}; ContentType ret{Context::DataBuffer{v}};
OIInternal::getSizeType<Context>(t, ret); OIInternal::getSizeType<Context>(ctx, t, ret);
} }
)"; )";
@ -319,8 +324,8 @@ void FuncGen::DefineTopLevelGetSizeRef(std::string& testCode,
func += " const auto startTime = std::chrono::steady_clock::now();\n"; func += " const auto startTime = std::chrono::steady_clock::now();\n";
} }
func += R"( func += R"(
pointers.initialize(); ctx.pointers.initialize();
pointers.add((uintptr_t)&t); ctx.pointers.add((uintptr_t)&t);
auto data = reinterpret_cast<uintptr_t*>(dataBase); auto data = reinterpret_cast<uintptr_t*>(dataBase);
size_t dataSegOffset = 0; size_t dataSegOffset = 0;
@ -417,7 +422,7 @@ void FuncGen::DefineTopLevelGetSizeSmartPtr(std::string& testCode,
func += " const auto startTime = std::chrono::steady_clock::now();\n"; func += " const auto startTime = std::chrono::steady_clock::now();\n";
} }
func += R"( func += R"(
pointers.initialize(); ctx.pointers.initialize();
auto data = reinterpret_cast<uintptr_t*>(dataBase); auto data = reinterpret_cast<uintptr_t*>(dataBase);
size_t dataSegOffset = 0; size_t dataSegOffset = 0;
@ -670,13 +675,14 @@ void FuncGen::DefineBasicTypeHandlers(std::string& code, FeatureSet features) {
} }
code += R"( code += R"(
static types::st::Unit<DB> getSizeType( static types::st::Unit<DB> getSizeType(
Ctx& ctx,
const T& t, const T& t,
typename TypeHandler<Ctx, T>::type returnArg) { typename TypeHandler<Ctx, T>::type returnArg) {
if constexpr(std::is_pointer_v<T>) { if constexpr(std::is_pointer_v<T>) {
JLOG("ptr val @"); JLOG("ptr val @");
JLOGPTR(t); JLOGPTR(t);
auto r0 = returnArg.write((uintptr_t)t); auto r0 = returnArg.write((uintptr_t)t);
if (t && pointers.add((uintptr_t)t)) { if (t && ctx.pointers.add((uintptr_t)t)) {
return r0.template delegate<1>([&t](auto ret) { return r0.template delegate<1>([&t](auto ret) {
if constexpr (!std::is_void<std::remove_pointer_t<T>>::value) { if constexpr (!std::is_void<std::remove_pointer_t<T>>::value) {
return TypeHandler<Ctx, std::remove_pointer_t<T>>::getSizeType(*t, ret); return TypeHandler<Ctx, std::remove_pointer_t<T>>::getSizeType(*t, ret);
@ -719,8 +725,8 @@ ContainerInfo FuncGen::GetOiArrayContainerInfo() {
oiArray.codegen.traversalFunc = R"( oiArray.codegen.traversalFunc = R"(
auto tail = returnArg.write(N0); auto tail = returnArg.write(N0);
for (size_t i=0; i<N0; i++) { for (size_t i=0; i<N0; i++) {
tail = tail.delegate([&container, i](auto ret) { tail = tail.delegate([&ctx, &container, i](auto ret) {
return TypeHandler<Ctx, T0>::getSizeType(container.vals[i], ret); return TypeHandler<Ctx, T0>::getSizeType(ctx, container.vals[i], ret);
}); });
} }
return tail.finish(); return tail.finish();

View File

@ -3049,6 +3049,12 @@ bool OICodeGen::generateJitCode(std::string& code) {
#define SAVE_DATA(val) StoreData(val, returnArg) #define SAVE_DATA(val) StoreData(val, returnArg)
)"); )");
code.append("namespace {\n");
code.append("static struct Context {\n");
code.append(" PointerHashSet<(1 << 20) / sizeof(uintptr_t)> pointers;\n");
code.append("} ctx;\n");
code.append("} // namespace\n");
FuncGen::DefineJitLog(code, config.features); FuncGen::DefineJitLog(code, config.features);
// The purpose of the anonymous namespace within `OIInternal` is that // The purpose of the anonymous namespace within `OIInternal` is that
@ -3267,7 +3273,7 @@ bool OICodeGen::generateJitCode(std::string& code) {
JLOG("ptr val @"); JLOG("ptr val @");
JLOGPTR(s_ptr); JLOGPTR(s_ptr);
StoreData((uintptr_t)(s_ptr), returnArg); StoreData((uintptr_t)(s_ptr), returnArg);
if (s_ptr && pointers.add((uintptr_t)s_ptr)) { if (s_ptr && ctx.pointers.add((uintptr_t)s_ptr)) {
StoreData(1, returnArg); StoreData(1, returnArg);
getSizeType(*(s_ptr), returnArg); getSizeType(*(s_ptr), returnArg);
} else { } else {

View File

@ -40,10 +40,11 @@ constexpr int oidMagicId = 0x01DE8;
namespace { namespace {
class { template <size_t Size>
class PointerHashSet {
private: private:
// 1 MiB of pointers // 1 MiB of pointers
std::array<uintptr_t, (1 << 20) / sizeof(uintptr_t)> data; std::array<uintptr_t, Size> data;
// twang_mix64 hash function, taken from Folly where it is used // twang_mix64 hash function, taken from Folly where it is used
// as the default hash function for 64-bit integers // as the default hash function for 64-bit integers
@ -84,7 +85,7 @@ class {
bool add(const auto* p) { bool add(const auto* p) {
return add((uintptr_t)p); return add((uintptr_t)p);
} }
} static pointers; };
} // namespace } // namespace

View File

@ -33,8 +33,8 @@ traversal_func = """
auto tail = returnArg.write(container.size()); auto tail = returnArg.write(container.size());
for (auto & it: container) { for (auto & it: container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return TypeHandler<Ctx, T0>::getSizeType(it, ret); return TypeHandler<Ctx, T0>::getSizeType(ctx, it, ret);
}); });
} }

View File

@ -38,8 +38,8 @@ auto tail = returnArg.write((uintptr_t)&container)
.write(container.size()); .write(container.size());
for (auto&& it : container) { for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }

View File

@ -43,11 +43,11 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&entry: container) { for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) { tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) { auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret); return OIInternal::getSizeType<Ctx>(ctx, key, ret);
}); });
return OIInternal::getSizeType<Ctx>(value, next); return OIInternal::getSizeType<Ctx>(ctx, value, next);
}); });
} }

View File

@ -42,8 +42,8 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&entry: container) { for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) { tail = tail.delegate([&ctx, &entry](auto ret) {
return OIInternal::getSizeType<Ctx>(entry, ret); return OIInternal::getSizeType<Ctx>(ctx, entry, ret);
}); });
} }

View File

@ -43,11 +43,11 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&entry: container) { for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) { tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) { auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret); return OIInternal::getSizeType<Ctx>(ctx, key, ret);
}); });
return OIInternal::getSizeType<Ctx>(value, next); return OIInternal::getSizeType<Ctx>(ctx, value, next);
}); });
} }

View File

@ -42,8 +42,8 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&entry: container) { for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) { tail = tail.delegate([&ctx, &entry](auto ret) {
return OIInternal::getSizeType<Ctx>(entry, ret); return OIInternal::getSizeType<Ctx>(ctx, entry, ret);
}); });
} }

View File

@ -43,11 +43,11 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&entry: container) { for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) { tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) { auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret); return OIInternal::getSizeType<Ctx>(ctx, key, ret);
}); });
return OIInternal::getSizeType<Ctx>(value, next); return OIInternal::getSizeType<Ctx>(ctx, value, next);
}); });
} }

View File

@ -42,8 +42,8 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&entry: container) { for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) { tail = tail.delegate([&ctx, &entry](auto ret) {
return OIInternal::getSizeType<Ctx>(entry, ret); return OIInternal::getSizeType<Ctx>(ctx, entry, ret);
}); });
} }

View File

@ -43,11 +43,11 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&entry: container) { for (auto &&entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) { tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) { auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret); return OIInternal::getSizeType<Ctx>(ctx, key, ret);
}); });
return OIInternal::getSizeType<Ctx>(value, next); return OIInternal::getSizeType<Ctx>(ctx, value, next);
}); });
} }

View File

@ -42,8 +42,8 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&entry: container) { for (auto &&entry: container) {
tail = tail.delegate([&entry](auto ret) { tail = tail.delegate([&ctx, &entry](auto ret) {
return OIInternal::getSizeType<Ctx>(entry, ret); return OIInternal::getSizeType<Ctx>(ctx, entry, ret);
}); });
} }

View File

@ -29,7 +29,7 @@ void getSizeType(const %1%<E, T, A, Storage> &container, size_t& returnArg)
&& &&
((uintptr_t)container.data() >= (uintptr_t)&container); ((uintptr_t)container.data() >= (uintptr_t)&container);
if (!inlined && pointers.add((uintptr_t)container.data())) { if (!inlined && ctx.pointers.add((uintptr_t)container.data())) {
SAVE_SIZE(container.capacity() * sizeof(T)); SAVE_SIZE(container.capacity() * sizeof(T));
SAVE_DATA(1); SAVE_DATA(1);
} else { } else {
@ -60,7 +60,7 @@ if (isStorageInline(container)) {
category = Category::InlinedStorage; category = Category::InlinedStorage;
} else if (capacity < minLargeSize) { } else if (capacity < minLargeSize) {
category = Category::OwnedHeapStorage; category = Category::OwnedHeapStorage;
} else if (pointers.add(container.data())) { } else if (ctx.pointers.add(container.data())) {
category = Category::ReferenceCountedStorage; category = Category::ReferenceCountedStorage;
} else { } else {
category = Category::AlreadyAttributed; category = Category::AlreadyAttributed;

View File

@ -22,7 +22,7 @@ void getSizeType(const %1% &container, size_t& returnArg)
const folly::IOBuf *head = container.front(); const folly::IOBuf *head = container.front();
SAVE_DATA((uintptr_t)head); SAVE_DATA((uintptr_t)head);
if (head && pointers.add((uintptr_t)head)) { if (head && ctx.pointers.add((uintptr_t)head)) {
SAVE_DATA(1); SAVE_DATA(1);
getSizeType(*head, returnArg); getSizeType(*head, returnArg);
} else { } else {

View File

@ -38,8 +38,8 @@ auto tail = returnArg.write((uintptr_t)&container)
.write(container.size()); .write(container.size());
for (auto&& it : container) { for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }

View File

@ -42,12 +42,12 @@ traversal_func = '''
.write(container.size()); .write(container.size());
for (const auto& kv : container) { for (const auto& kv : container) {
tail = tail.delegate([&kv](auto ret) { tail = tail.delegate([&ctx, &kv](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(kv.first, ret); auto start = maybeCaptureKey<captureKeys, Ctx, T0>(ctx, kv.first, ret);
auto next = start.delegate([&kv](typename TypeHandler<Ctx, T0>::type ret) { auto next = start.delegate([&ctx, &kv](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(kv.first, ret); return OIInternal::getSizeType<Ctx>(ctx, kv.first, ret);
}); });
return OIInternal::getSizeType<Ctx>(kv.second, next); return OIInternal::getSizeType<Ctx>(ctx, kv.second, next);
}); });
} }

View File

@ -39,11 +39,11 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (const auto &entry: container) { for (const auto &entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) { tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto next = ret.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) { auto next = ret.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret); return OIInternal::getSizeType<Ctx>(ctx, key, ret);
}); });
return OIInternal::getSizeType<Ctx>(value, next); return OIInternal::getSizeType<Ctx>(ctx, value, next);
}); });
} }

View File

@ -42,8 +42,8 @@ auto tail = returnArg.write((uintptr_t)&container)
// The double ampersand is needed otherwise this loop doesn't work with // The double ampersand is needed otherwise this loop doesn't work with
// vector<bool> // vector<bool>
for (auto&& it : container) { for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }

View File

@ -30,8 +30,8 @@ void getSizeType(const %1%<T>& container, size_t& returnArg) {
traversal_func = """ traversal_func = """
if (container.has_value()) { if (container.has_value()) {
return returnArg.template delegate<1>([&container](auto ret) { return returnArg.template delegate<1>([&ctx, &container](auto ret) {
return OIInternal::getSizeType<Ctx>(*container, ret); return OIInternal::getSizeType<Ctx>(ctx, *container, ret);
}); });
} else { } else {
return returnArg.template delegate<0>(std::identity()); return returnArg.template delegate<0>(std::identity());

View File

@ -27,10 +27,10 @@ void getSizeType(const %1%<P,Q> &container, size_t& returnArg)
""" """
traversal_func = """ traversal_func = """
return OIInternal::getSizeType<Ctx>( return OIInternal::getSizeType<Ctx>(ctx,
container.second, container.second,
returnArg.delegate([&container](auto ret) { returnArg.delegate([&ctx, &container](auto ret) {
return OIInternal::getSizeType<Ctx>(container.first, ret); return OIInternal::getSizeType<Ctx>(ctx, container.first, ret);
}) })
); );
""" """

View File

@ -21,7 +21,7 @@ void getSizeType(const %1%<T> &ref, size_t& returnArg)
{ {
SAVE_SIZE(sizeof(%1%<T>)); SAVE_SIZE(sizeof(%1%<T>));
SAVE_DATA((uintptr_t)&(ref.get())); SAVE_DATA((uintptr_t)&(ref.get()));
if (pointers.add((uintptr_t)&ref.get())) { if (ctx.pointers.add((uintptr_t)&ref.get())) {
SAVE_DATA(1); SAVE_DATA(1);
getSizeType(ref.get(), returnArg); getSizeType(ref.get(), returnArg);
} else { } else {

View File

@ -43,8 +43,8 @@ auto tail = returnArg.write((uintptr_t)&container)
// The double ampersand is needed otherwise this loop doesn't work with // The double ampersand is needed otherwise this loop doesn't work with
// vector<bool> // vector<bool>
for (auto&& it : container) { for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }

View File

@ -43,8 +43,8 @@ auto tail = returnArg.write((uintptr_t)&container)
// The double ampersand is needed otherwise this loop doesn't work with // The double ampersand is needed otherwise this loop doesn't work with
// vector<bool> // vector<bool>
for (auto&& it : container) { for (auto&& it : container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }

View File

@ -24,7 +24,7 @@ void getSizeType(const %1%<T> &s_ptr, size_t& returnArg)
if constexpr (!std::is_void<T>::value) { if constexpr (!std::is_void<T>::value) {
SAVE_DATA((uintptr_t)(s_ptr.get())); SAVE_DATA((uintptr_t)(s_ptr.get()));
if (s_ptr && pointers.add((uintptr_t)(s_ptr.get()))) { if (s_ptr && ctx.pointers.add((uintptr_t)(s_ptr.get()))) {
SAVE_DATA(1); SAVE_DATA(1);
getSizeType(*(s_ptr.get()), returnArg); getSizeType(*(s_ptr.get()), returnArg);
} else { } else {
@ -40,12 +40,12 @@ auto tail = returnArg.write((uintptr_t)container.get());
if constexpr (std::is_void<T0>::value) { if constexpr (std::is_void<T0>::value) {
return tail.template delegate<0>(std::identity()); return tail.template delegate<0>(std::identity());
} else { } else {
bool do_visit = container && pointers.add((uintptr_t)container.get()); bool do_visit = container && ctx.pointers.add((uintptr_t)container.get());
if (!do_visit) if (!do_visit)
return tail.template delegate<0>(std::identity()); return tail.template delegate<0>(std::identity());
return tail.template delegate<1>([&container](auto ret) { return tail.template delegate<1>([&ctx, &container](auto ret) {
return OIInternal::getSizeType<Ctx>(*container, ret); return OIInternal::getSizeType<Ctx>(ctx, *container, ret);
}); });
} }
""" """

View File

@ -56,8 +56,8 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (auto &&it: container) { for (auto &&it: container) {
tail = tail.delegate([&it](typename TypeHandler<Ctx, T0>::type ret) { tail = tail.delegate([&ctx, &it](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }

View File

@ -37,8 +37,8 @@ auto tail = returnArg.write((uintptr_t)&container)
.write(container.size()); .write(container.size());
for (const auto& el : container) { for (const auto& el : container) {
tail = tail.delegate([&el](auto ret) { tail = tail.delegate([&ctx, &el](auto ret) {
return OIInternal::getSizeType<Ctx>(el, ret); return OIInternal::getSizeType<Ctx>(ctx, el, ret);
}); });
} }

View File

@ -43,12 +43,12 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (const auto &entry: container) { for (const auto &entry: container) {
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) { tail = tail.delegate([&ctx, &key = entry.first, &value = entry.second](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(key, ret); auto start = maybeCaptureKey<captureKeys, Ctx, T0>(ctx, key, ret);
auto next = start.delegate([&key](typename TypeHandler<Ctx, T0>::type ret) { auto next = start.delegate([&ctx, &key](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(key, ret); return OIInternal::getSizeType<Ctx>(ctx, key, ret);
}); });
return OIInternal::getSizeType<Ctx>(value, next); return OIInternal::getSizeType<Ctx>(ctx, value, next);
}); });
} }

View File

@ -46,12 +46,12 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (const auto& kv : container) { for (const auto& kv : container) {
tail = tail.delegate([&kv](auto ret) { tail = tail.delegate([&ctx, &kv](auto ret) {
auto start = maybeCaptureKey<captureKeys, Ctx, T0>(kv.first, ret); auto start = maybeCaptureKey<captureKeys, Ctx, T0>(ctx, kv.first, ret);
auto next = start.delegate([&kv](typename TypeHandler<Ctx, T0>::type ret) { auto next = start.delegate([&ctx, &kv](typename TypeHandler<Ctx, T0>::type ret) {
return OIInternal::getSizeType<Ctx>(kv.first, ret); return OIInternal::getSizeType<Ctx>(ctx, kv.first, ret);
}); });
return OIInternal::getSizeType<Ctx>(kv.second, next); return OIInternal::getSizeType<Ctx>(ctx, kv.second, next);
}); });
} }

View File

@ -46,8 +46,8 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (const auto &it : container) { for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }

View File

@ -25,7 +25,7 @@ void getSizeType(const %1%<T,Deleter> &u_ptr, size_t& returnArg)
if constexpr (!std::is_void<T>::value) { if constexpr (!std::is_void<T>::value) {
SAVE_DATA((uintptr_t)(u_ptr.get())); SAVE_DATA((uintptr_t)(u_ptr.get()));
if (u_ptr && pointers.add((uintptr_t)(u_ptr.get()))) { if (u_ptr && ctx.pointers.add((uintptr_t)(u_ptr.get()))) {
SAVE_DATA(1); SAVE_DATA(1);
getSizeType(*(u_ptr.get()), returnArg); getSizeType(*(u_ptr.get()), returnArg);
} else { } else {
@ -41,12 +41,12 @@ auto tail = returnArg.write((uintptr_t)container.get());
if constexpr (std::is_void<T0>::value) { if constexpr (std::is_void<T0>::value) {
return tail.template delegate<0>(std::identity()); return tail.template delegate<0>(std::identity());
} else { } else {
bool do_visit = container && pointers.add((uintptr_t)container.get()); bool do_visit = container && ctx.pointers.add((uintptr_t)container.get());
if (!do_visit) if (!do_visit)
return tail.template delegate<0>(std::identity()); return tail.template delegate<0>(std::identity());
return tail.template delegate<1>([&container](auto ret) { return tail.template delegate<1>([&ctx, &container](auto ret) {
return OIInternal::getSizeType<Ctx>(*container, ret); return OIInternal::getSizeType<Ctx>(ctx, *container, ret);
}); });
} }
""" """

View File

@ -44,8 +44,8 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (const auto &it : container) { for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }

View File

@ -44,8 +44,8 @@ auto tail = returnArg
.write(container.size()); .write(container.size());
for (const auto &it : container) { for (const auto &it : container) {
tail = tail.delegate([&it](auto ret) { tail = tail.delegate([&ctx, &it](auto ret) {
return OIInternal::getSizeType<Ctx>(it, ret); return OIInternal::getSizeType<Ctx>(ctx, it, ret);
}); });
} }