Пример #1
0
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)));
}
Пример #2
0
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;
}