R call(function<R(Args...)> const&func, Params<Args...> const¶ms) { return call_helper(func, params, index_sequence_for<Args...>{}); }
void call( void ( *fn )( argument_types ... ), const std::vector< argument > &args ) { if ( args.size() > m_argument_types.size() ) throw std::bad_function_call(); for ( const auto &arg : args ) std::cout << g_type_name_register[ arg.type() ] << std::endl; call_helper( fn, args, typename gens< sizeof...( argument_types ) >::type() ); }
/* This callback is only ever called for single operation, single key results */ static void callback_common(lcb_t instance, int cbtype, const lcb_RESPBASE *resp) { AV *resobj = NULL; PLCB_t *parent; SV *ctxrv = (SV *)resp->cookie; plcb_OPCTX *ctx = NUM2PTR(plcb_OPCTX*, SvIVX(SvRV(ctxrv))); if (cbtype == LCB_CALLBACK_STATS || cbtype == LCB_CALLBACK_OBSERVE || cbtype == LCB_CALLBACK_HTTP) { HE *tmp; hv_iterinit(ctx->docs); tmp = hv_iternext(ctx->docs); if (tmp && HeVAL(tmp) && SvROK(HeVAL(tmp))) { resobj = (AV *)SvRV(HeVAL(tmp)); } } else { SV **tmp = hv_fetch(ctx->docs, resp->key, resp->nkey, 0); if (tmp && SvROK(*tmp)) { resobj = (AV*)SvRV(*tmp); } } if (!resobj) { warn("Couldn't find matching object!"); return; } parent = (PLCB_t *)lcb_get_cookie(instance); plcb_doc_set_err(parent, resobj, resp->rc); switch (cbtype) { case LCB_CALLBACK_GET: { const lcb_RESPGET *gresp = (const lcb_RESPGET *)resp; if (resp->rc == LCB_SUCCESS) { SV *newval = plcb_convert_retrieval(parent, resobj, gresp->value, gresp->nvalue, gresp->itmflags); av_store(resobj, PLCB_RETIDX_VALUE, newval); plcb_doc_set_cas(parent, resobj, &resp->cas); } break; } case LCB_CALLBACK_TOUCH: case LCB_CALLBACK_REMOVE: case LCB_CALLBACK_UNLOCK: case LCB_CALLBACK_STORE: case LCB_CALLBACK_ENDURE: if (resp->cas && resp->rc == LCB_SUCCESS) { plcb_doc_set_cas(parent, resobj, &resp->cas); } if (cbtype == LCB_CALLBACK_STORE && resp->rc == LCB_SUCCESS && chain_endure(parent, resobj, (const lcb_RESPSTORE *)resp)) { return; /* Will be handled already */ } break; case LCB_CALLBACK_COUNTER: { const lcb_RESPCOUNTER *cresp = (const lcb_RESPCOUNTER*)resp; plcb_doc_set_numval(parent, resobj, cresp->value, resp->cas); break; } case LCB_CALLBACK_STATS: { const lcb_RESPSTATS *sresp = (const void *)resp; if (sresp->server) { call_helper(resobj, cbtype, (const lcb_RESPBASE *)sresp); return; } break; } case LCB_CALLBACK_OBSERVE: { const lcb_RESPOBSERVE *oresp = (const lcb_RESPOBSERVE*)resp; if (oresp->nkey) { call_helper(resobj, cbtype, (const lcb_RESPBASE*)oresp); return; } break; } case LCB_CALLBACK_HTTP: { const lcb_RESPHTTP *htresp = (const lcb_RESPHTTP *)resp; /* Store the CAS */ av_store(resobj, PLCB_HTIDX_STATUS, newSViv(htresp->htstatus)); if (htresp->headers) { const char * const * hdr_cur; HV *headers = newHV(); av_store(resobj, PLCB_HTIDX_HEADERS, newRV_noinc((SV*)headers)); for (hdr_cur = htresp->headers; *hdr_cur; hdr_cur += 2) { const char *hdrkey = hdr_cur[0]; const char *hdrval = hdr_cur[1]; SV *valsv = newSVpv(hdrval, 0); hv_store(headers, hdrkey, 0, valsv, 0); } } if (htresp->nbody) { lcb_U32 fmtflags = PLCB_CF_JSON; SV *body; SV *fmtspec = *av_fetch(resobj, PLCB_RETIDX_VALUE, 1); if (SvIOK(fmtspec)) { fmtflags = SvUV(fmtspec); } body = plcb_convert_retrieval_ex(parent, resobj, htresp->body, htresp->nbody, fmtflags, PLCB_CONVERT_NOCUSTOM); av_store(resobj, PLCB_RETIDX_VALUE, body); } break; } default: abort(); break; } ctx->nremaining--; if (parent->async) { call_async(ctx, resobj); } else if (ctx->flags & PLCB_OPCTXf_WAITONE) { av_push(ctx->u.ctxqueue, newRV_inc( (SV* )resobj)); plcb_kv_waitdone(parent); } if (!ctx->nremaining) { SvREFCNT_dec(ctxrv); plcb_kv_waitdone(parent); plcb_opctx_clear(parent); } }