void test_sequence_n(Sequence & seq, mpl::int_<0>) { // Function Objects fobj f; COMPARE_EFFECT(f (), fusion::invoke_procedure(f , seq )); COMPARE_EFFECT(f (), fusion::invoke_procedure(f , const_(seq))); // Note: The function object is taken by value, so we request the copy // to be const with an explicit template argument. We can also request // the function object to be pased by reference... COMPARE_EFFECT(const_(f)(), fusion::invoke_procedure<fobj const >(const_(f), seq )); COMPARE_EFFECT(const_(f)(), fusion::invoke_procedure<fobj const &>(const_(f), const_(seq))); fobj_nc nc_f; // ...and we further ensure there is no copying in this case, using a // noncopyable function object. COMPARE_EFFECT(nc_f (), fusion::invoke_procedure<fobj_nc &>(nc_f , seq )); COMPARE_EFFECT(nc_f (), fusion::invoke_procedure<fobj_nc &>(nc_f , const_(seq))); COMPARE_EFFECT(const_(nc_f)(), fusion::invoke_procedure<fobj_nc const &>(const_(nc_f), seq )); COMPARE_EFFECT(const_(nc_f)(), fusion::invoke_procedure<fobj_nc const &>(const_(nc_f), const_(seq))); // Builtin Functions // Call through ref/ptr to function COMPARE_EFFECT(nullary(), fusion::invoke_procedure<int (&)()>(nullary, seq)); COMPARE_EFFECT(nullary(), fusion::invoke_procedure(& nullary, seq)); // Call through ptr to member function // Note: The non-const function members::nullary can't be invoked with // fusion::join(sv_obj_ctx,seq)), which is const and so is its first element COMPARE_EFFECT(that.nullary(), fusion::invoke_procedure(& members::nullary, fusion::join(sv_ref_ctx,seq))); COMPARE_EFFECT(that.nullary(), fusion::invoke_procedure(& members::nullary, fusion::join(sv_ptr_ctx,seq))); COMPARE_EFFECT(that.nullary(), fusion::invoke_procedure(& members::nullary, fusion::join(sv_spt_ctx,seq))); COMPARE_EFFECT(that.nullary_c(), fusion::invoke_procedure(& members::nullary_c, fusion::join(sv_obj_ctx,seq))); COMPARE_EFFECT(that.nullary_c(), fusion::invoke_procedure(& members::nullary_c, fusion::join(sv_ref_ctx,seq))); COMPARE_EFFECT(that.nullary_c(), fusion::invoke_procedure(& members::nullary_c, fusion::join(sv_ptr_ctx,seq))); COMPARE_EFFECT(that.nullary_c(), fusion::invoke_procedure(& members::nullary_c, fusion::join(sv_spt_ctx,seq))); COMPARE_EFFECT(that.nullary_c(), fusion::invoke_procedure(& members::nullary_c, fusion::join(sv_obj_c_ctx,seq))); COMPARE_EFFECT(that.nullary_c(), fusion::invoke_procedure(& members::nullary_c, fusion::join(sv_ref_c_ctx,seq))); COMPARE_EFFECT(that.nullary_c(), fusion::invoke_procedure(& members::nullary_c, fusion::join(sv_ptr_c_ctx,seq))); COMPARE_EFFECT(that.nullary_c(), fusion::invoke_procedure(& members::nullary_c, fusion::join(sv_spt_c_ctx,seq))); }
bool MicroCode::execute(VM* vm, Opcode opcode) const { const size_t stackSize = vm->stackSize(); Value v1 = Value::INVALID, v2 = Value::INVALID, v3 = Value::INVALID; if (opcodeData[opcode].hasTernary && stackSize >= 3) { v3 = vm->pop(); v2 = vm->pop(); v1 = vm->pop(); auto function = findBestOverload({ opcode, v1.type, v2.type, v3.type }); if (function) { function->ternary(vm, v1, v2, v3); return true; } } if (opcodeData[opcode].hasBinary && stackSize >= 2) { if (v3.valid()) { v2 = v3; v1 = v2; } else { v2 = vm->pop(); v1 = vm->pop(); } auto function = findBestOverload({ opcode, v1.type, v2.type, TYPE_NONE }); if (function) { function->binary(vm, v1, v2); return true; } } if (opcodeData[opcode].hasUnary && stackSize >= 1) { if (v3.valid()) v1 = v3; else if (v2.valid()) v1 = v2; else v1 = vm->pop(); auto function = findBestOverload({ opcode, v1.type, TYPE_NONE, TYPE_NONE }); if (function) { function->unary(vm, v1); return true; } } auto function = findBestOverload({ opcode, TYPE_NONE, TYPE_NONE, TYPE_NONE }); if (function) { function->nullary(vm); return true; } /* push values back */ if (v1.valid()) vm->push(v1); if (v2.valid()) vm->push(v2); if (v3.valid()) vm->push(v3); return false; }