Example #1
0
cl_int
clReleaseMemObject(cl_mem d_memobj)
{
    auto memobj = pobj(d_memobj);

    if (!memobj->isA(Coal::Object::T_MemObject))
        return CL_INVALID_MEM_OBJECT;

    if (memobj->dereference())
        delete memobj;

    return CL_SUCCESS;
}
Example #2
0
cl_int
clReleaseDevice(cl_device_id d_device)
{
    auto device = pobj(d_device);

    if (!device->isA(Coal::Object::T_Device))
        return CL_INVALID_DEVICE;

    if (device->dereference())
        delete device;

    return CL_SUCCESS;
}
Example #3
0
cl_int
clReleaseSampler(cl_sampler d_sampler)
{
    auto sampler = pobj(d_sampler);

    if (!sampler->isA(Coal::Object::T_Sampler))
        return CL_INVALID_SAMPLER;

    if (sampler->dereference())
        delete sampler;

    return CL_SUCCESS;
}
Example #4
0
void preconditiont::compute_rec(exprt &dest)
{
  if(dest.id()==ID_address_of)
  {
    // only do index!
    assert(dest.operands().size()==1);
    compute_address_of(dest.op0());
  }
  else if(dest.id()==ID_dereference)
  {
    assert(dest.operands().size()==1);

    const irep_idt &lhs_identifier=SSA_step.ssa_lhs.get_object_name();

    // aliasing may happen here

    value_setst::valuest expr_set;
    value_sets.get_values(target, dest.op0(), expr_set);
    std::unordered_set<irep_idt, irep_id_hash> symbols;

    for(value_setst::valuest::const_iterator
        it=expr_set.begin();
        it!=expr_set.end();
        it++)
      find_symbols(*it, symbols);

    if(symbols.find(lhs_identifier)!=symbols.end())
    {
      // may alias!
      exprt tmp;
      tmp.swap(dest.op0());
      dereference(target, tmp, ns, value_sets);
      dest.swap(tmp);
      compute_rec(dest);
    }
    else
    {
      // nah, ok
      compute_rec(dest.op0());
    }
  }
  else if(dest==SSA_step.ssa_lhs.get_original_expr())
  {
    dest=SSA_step.ssa_rhs;
    s.get_original_name(dest);
  }
  else
    Forall_operands(it, dest)
      compute_rec(*it);
}
Example #5
0
File: utils.c Project: UPPMAX/irods
ExprType* unifyTVarR(ExprType *type, ExprType* expected, Hashtable *varTypes, Region *r) {
    char buf[128];
    if(T_VAR_NUM_DISJUNCTS(expected)==0) { /* free */
    	if(occursIn(expected, type)) {
    		return NULL;
    	}
        insertIntoHashTable(varTypes, getTVarName(T_VAR_ID(expected), buf), type);
        return dereference(expected, varTypes, r);
    } else { /* union type */
        int i;
        ExprType *ty = NULL;
        for(i=0;i<T_VAR_NUM_DISJUNCTS(expected);i++) {
            if(getNodeType(type) == getNodeType(T_VAR_DISJUNCT(expected,i))) { /* union types can only include primitive types */
                ty = type;
            }
        }
        if(ty != NULL) {
            insertIntoHashTable(varTypes, getTVarName(T_VAR_ID(expected), buf), ty);
            return dereference(expected, varTypes, r);
        }
        return ty;
    }

}
Example #6
0
cl_int
clReleaseCommandQueue(cl_command_queue d_command_queue)
{
    auto command_queue = pobj(d_command_queue);

    if (!command_queue->isA(Coal::Object::T_CommandQueue))
        return CL_INVALID_COMMAND_QUEUE;

    command_queue->flush();

    if (command_queue->dereference())
        delete command_queue;

    return CL_SUCCESS;
}
Example #7
0
static
subscript(stream, node, need_lval) {
    auto type = node[3][2];  /* type being subscripted */

    /* For (hopefully temporary) compatibility with stage-4, we allow an 
     * implicit int to be dereferenced as an int*. */
    extern compat_flag;
    auto elt_sz = compat_flag && type == implct_int() ? 4 
        : type_size( type[3] );        /* remove * or [] from type */

    auto sz = type_size( node[2] );

    scale_elt(stream, elt_sz, 1);
    pop_add(stream, 0, 4);
    dereference(stream, sz, need_lval);
}
Example #8
0
void Designator::add_key(const std::string& key_param,
      const Location& loc) {
   dereference(loc);
   if (!at) {
      throw Exception(loc, "null cannot be used as dictionary");
   }
   if (at->get_type() == Attribute::tree) {
      at = at->get_node()->get_attribute();
   } else if (at->get_type() == Attribute::flow_graph_node) {
      at = at->get_fgnode()->get_attribute();
   }
   if (at->get_type() != Attribute::dictionary) {
      throw Exception(loc, "is not a dictionary");
   }
   key = key_param; lvalue = true;
}
Example #9
0
symbol * name(int dcl)
{
  symbol * q = NULL;
  if(sym_exists(token) || dcl)
  {
    int c = 0;
    int v = 0;
    int l = 0;
    l = caddr(sym_addr(token, &c, &v, &q));
    scan();
    g_mov_bx(l);
    g_push_bx();
    dereference();
  } else
  {
    error("Expected identifier");
  }
  return q;
}
Example #10
0
void Designator::add_index(AttributePtr indexAt,
      const Location& loc) {
   dereference(loc);
   if (!at) {
      throw Exception(loc, "cannot index null value");
   }
   Attribute::Type attype = at->get_type();
   unsigned long indexVal = indexAt?
      indexAt->convert_to_integer(loc)->get_unsigned_int(loc): 0;
   switch (attype) {
      case Attribute::list:
	 if (indexVal >= at->size()) {
	    throw Exception(loc, "index out of range");
	 }
	 index = indexVal;
	 lvalue = true;
	 break;

      case Attribute::match_result:
	 if (indexVal >= at->size()) {
	    throw Exception(loc, "index out of range");
	 }
	 at = at->get_value(indexVal);
	 lvalue = false;
	 break;

      case Attribute::tree: {
	    NodePtr node = at->get_node();
	    if (node->is_leaf()) {
	       throw Exception(loc, "a leaf node cannot be indexed");
	    }
	    if (indexVal >= node->size()) {
	       throw Exception(loc, "index out of range");
	    }
	    at = std::make_shared<Attribute>(node->get_operand(indexVal));
	 }
	 break;

      default:
	 throw Exception(loc, "is not a list");
   }
}
Example #11
0
static
binary_op(stream, node, need_lval) {
    auto op = node[0], sz = type_size( node[2] );

    expr_code( stream, node[3], is_assop(op) );
    asm_push( stream );
    expr_code( stream, node[4], 0 );

    if      ( op == '[]'  ) subscript(stream, node, need_lval);
    else if ( op == '*'   ) pop_mult(stream, 0, node[2][5]);
    else if ( op == '/'   ) pop_div(stream, 0, node[2][5]);
    else if ( op == '%'   ) pop_mod(stream, 0, node[2][5]);
    else if ( op == '+'   ) add_op(stream, node, 0, sz);
    else if ( op == '-'   ) add_op(stream, node, 0, sz);
    else if ( op == '<<'  ) pop_lshift(stream, 0);
    else if ( op == '>>'  ) pop_rshift(stream, 0);
    else if ( op == '&'   ) pop_bitand(stream, 0, sz);
    else if ( op == '|'   ) pop_bitor(stream, 0, sz);
    else if ( op == '^'   ) pop_bitxor(stream, 0, sz);

    else if ( op == '='   ) pop_assign(stream, sz);
    else if ( op == '*='  ) pop_mult(stream, 1);
    else if ( op == '/='  ) pop_div(stream, 1);
    else if ( op == '%='  ) pop_mod(stream, 1);
    else if ( op == '+='  ) add_op(stream, node, 1, sz);
    else if ( op == '-='  ) add_op(stream, node, 1, sz);
    else if ( op == '<<=' ) pop_lshift(stream, 1);
    else if ( op == '>>=' ) pop_rshift(stream, 1);
    else if ( op == '&='  ) pop_bitand(stream, 1, sz);
    else if ( op == '|='  ) pop_bitor(stream, 1, sz);
    else if ( op == '^='  ) pop_bitxor(stream, 1, sz);

    else int_error("Unknown operator: '%Mc'", op);

    /* The assignment operators are implemented to return lvalues, but
     * the C standard says they're not lvalues.  (The C++ standard has
     * them as lvalues.)  */
    if ( is_assop(op) )
        dereference(stream, type_size(node[2]), 0);
}
Example #12
0
File: swapper.c Project: gz/aos10
/**
 * Second chance select implementation for choosing pages to
 * swap out. This will loop through the queue and find the
 * oldest unreferenced page.
 * Note: Since we use software emulated reference bits, in case
 * everything is mapped in the HW page table this degenerates
 * to pure FIFO.
 *
 * @param page_queue
 * @return oldest unreferenced page (removed from the queue)
 */
static page_queue_item* second_chance_select(struct pages_head* page_queue) {

	page_queue_item* page;

	// do a second chance search for a page over all currently active pages
    for(page = page_queue->tqh_first; page != NULL; page = page_queue->tqh_first) {

    	if(is_referenced(page)) {
    		TAILQ_REMOVE(page_queue, page, entries); // remove oldest page
    		dereference(page);
    		TAILQ_INSERT_TAIL(page_queue, page, entries); // insert at front
    	}
    	else {
    		// remove the page from the working set
    		TAILQ_REMOVE(page_queue, page, entries);
    		return page;
    	}

    }

    return NULL; // no pages in queue (bad)
}
Example #13
0
exprt local_SSAt::read_lhs(
  const exprt &expr,
  locationt loc) const
{
  // dereference first
  exprt tmp1=dereference(expr, loc);

  ssa_objectt object(tmp1, ns);

  // is this an object we track?
  if(ssa_objects.objects.find(object)!=
     ssa_objects.objects.end())
  {
    // yes, it is
    if(assignments.assigns(loc, object))
      return name(object, OUT, loc);
    else
      return read_rhs(object, loc);
  }
  else
    return read_rhs(tmp1, loc);
}
Example #14
0
VisitResult ExpressionVisitor::Visit(IndexNode* node)
{
  node->Walk(this, false);
  ValueNode* leftSide = static_cast<ValueNode*>(node->mLeft.get());
  ValueNode* indexExpr = static_cast<ValueNode*>(node->mIndex.get());
  std::string leftSymbolName(leftSide->mToken.mText, leftSide->mToken.mLength);
  std::string indexSymbolName(indexExpr->mToken.mText, indexExpr->mToken.mLength);
  if(leftSide->mResolvedType->mMode == TypeMode::Pointer)
  {
    node->mResolvedType = dereference(leftSide->mResolvedType);
  }
  else
  {
    ErrorInvalidIndexer(node);
  }
  if(indexExpr->mResolvedType->mName != "Integer")
  {
    ErrorInvalidIndexer(node);
  }

  return VisitResult::Stop;

}
Example #15
0
static
unary_pre(stream, node, need_lval) {
    auto op = node[0];
    auto op_needs_lv = op == '++' || op == '--' || op == '&';
    auto sz = type_size(node[2]);
    expr_code( stream, node[3], op_needs_lv );

    if ( op == '+'  ) {
        /* Arrays degrade to pointers. */
        auto src_sz;
        if ( node[3][2][0] == '[]' ) src_sz = 4;
        else src_sz = type_size(node[3][2]);
        promote(stream, node[2][5], src_sz, sz);
    }
    else if ( op == '-'  ) arith_neg(stream);
    else if ( op == '~'  ) bit_not(stream);
    else if ( op == '!'  ) logic_not(stream);
    else if ( op == '&'  ) ;
    else if ( op == '*'  ) dereference(stream, sz, need_lval);
    else if ( op == '++' ) increment(stream, sz,  ptr_inc_sz(node[2]) );
    else if ( op == '--' ) increment(stream, sz, -ptr_inc_sz(node[2]) );
    else int_error("Unknown operator: '%Mc'", op);
}
Example #16
0
void Serializer::serialize(Any object, ITypeMeta* type)
{
    auto flags = type->getFlags();
    if (flags & ITypeMeta::IsCustomSerializing)
    {
        auto classMeta = static_cast<IClassMeta*>(type);
        classMeta->functions["serialize"]->invoke(object, this);
    }
    else if (flags & ITypeMeta::IsPointer)
    {
        lua_newtable(L);
        lua_pushinteger(L, 1);

        auto pointeeType = type->getRunTimePointeeType(object);
        object = pointeeType->dereference(object);
        serialize(object, pointeeType);

        lua_settable(L, -3);
    }
    else if (type == typeMetaOf<std::string>())
    {
        lua_pushstring(L, object.as<std::string>().c_str());
    }
    else if (flags & ITypeMeta::IsClass)
    {
        auto classMeta = static_cast<IClassMeta*>(type);
        serializeAsClass(object, classMeta);
    }
    else if (type == typeMetaOf<int>())
    {
        lua_pushinteger(L, object.as<int>());
    }
    else if (type == typeMetaOf<float>())
    {
        lua_pushnumber(L, object.as<float>());
    }
}
Example #17
0
bool Item::isTrue() const
{
   switch( dereference()->type() )
   {
      case FLC_ITEM_BOOL:
         return asBoolean() != 0;

      case FLC_ITEM_INT:
         return asInteger() != 0;

      case FLC_ITEM_NUM:
         return asNumeric() != 0.0;

      case FLC_ITEM_RANGE:
         return asRangeStart() != asRangeEnd() || asRangeIsOpen();

      case FLC_ITEM_STRING:
         return asString()->size() != 0;

      case FLC_ITEM_ARRAY:
         return asArray()->length() != 0;

      case FLC_ITEM_DICT:
         return asDict()->length() != 0;

      case FLC_ITEM_FUNC:
      case FLC_ITEM_OBJECT:
      case FLC_ITEM_CLASS:
      case FLC_ITEM_METHOD:
      case FLC_ITEM_MEMBUF:
      case FLC_ITEM_LBIND:
         // methods are always filled, so they are always true.
         return true;
   }

   return false;
}
Example #18
0
 T const* as(value const& v)
 {
     return boost::get<T>(&dereference(v));
 }
Example #19
0
 const T* operator->() const
 { return &(dereference()); }
Example #20
0
 const T& operator[](difference_type) const
 { return dereference(); }
Example #21
0
 const T& operator*() const
 { return dereference(); }
Example #22
0
 T& operator[] (Difference n) const
 { return dereference(); }
Example #23
0
int main(int argv, char** argc) {
    if (argv == 1) {
        std::cerr << "Must provide a command and arguments! Try parse, rewrite, compile, assemble\n";
        return 0;
    }
    std::string flag = "";
    std::string command = argc[1];
    std::string input;
    std::string secondInput;
    if (std::string(argc[1]) == "-s") {
        flag = command.substr(1);
        command = argc[2];
        input = "";
        std::string line;
        while (std::getline(std::cin, line)) {
            input += line + "\n";
        }
        secondInput = argv == 3 ? "" : argc[3];
    }
    else {
        if (argv == 2) {
            std::cerr << "Not enough arguments for serpent cmdline\n";
            throw(0);
        }
        input = argc[2];
        secondInput = argv == 3 ? "" : argc[3];
    }
    bool haveSec = secondInput.length() > 0;
    if (command == "parse" || command == "parse_serpent") {
        std::cout << printAST(parseSerpent(input), haveSec) << "\n";
    }
    else if (command == "rewrite") {
        std::cout << printAST(rewrite(parseLLL(input, true)), haveSec) << "\n";
    }
    else if (command == "compile_to_lll") {
        std::cout << printAST(compileToLLL(input), haveSec) << "\n";
    }
    else if (command == "build_fragtree") {
        std::cout << printAST(buildFragmentTree(parseLLL(input, true))) << "\n";
    }
    else if (command == "compile_lll") {
        std::cout << binToHex(compileLLL(parseLLL(input, true))) << "\n";
    }
    else if (command == "dereference") {
        std::cout << printAST(dereference(parseLLL(input, true)), haveSec) <<"\n";
    }
    else if (command == "pretty_assemble") {
        std::cout << printTokens(prettyAssemble(parseLLL(input, true))) <<"\n";
    }
    else if (command == "pretty_compile_lll") {
        std::cout << printTokens(prettyCompileLLL(parseLLL(input, true))) << "\n";
    }
    else if (command == "pretty_compile") {
        std::cout << printTokens(prettyCompile(input)) << "\n";
    }
    else if (command == "assemble") {
        std::cout << assemble(parseLLL(input, true)) << "\n";
    }
    else if (command == "serialize") {
        std::cout << binToHex(serialize(tokenize(input, Metadata(), false))) << "\n";
    }
    else if (command == "flatten") {
        std::cout << printTokens(flatten(parseLLL(input, true))) << "\n";
    }
    else if (command == "deserialize") {
        std::cout << printTokens(deserialize(hexToBin(input))) << "\n";
    }
    else if (command == "compile") {
        std::cout << binToHex(compile(input)) << "\n";
    }
    else if (command == "encode_datalist") {
        std::vector<Node> tokens = tokenize(input);
        std::vector<std::string> o;
        for (int i = 0; i < (int)tokens.size(); i++) {
            o.push_back(tokens[i].val);
        }
        std::cout << binToHex(encodeDatalist(o)) << "\n";
    }
    else if (command == "decode_datalist") {
        std::vector<std::string> o = decodeDatalist(hexToBin(input));
        std::vector<Node> tokens;
        for (int i = 0; i < (int)o.size(); i++)
            tokens.push_back(token(o[i]));
        std::cout << printTokens(tokens) << "\n";
    }
    else if (command == "tokenize") {
        std::cout << printTokens(tokenize(input));
    }
    else if (command == "biject") {
        if (argv == 3)
             std::cerr << "Not enough arguments for biject\n";
        int pos = decimalToUnsigned(secondInput);
        std::vector<Node> n = prettyCompile(input);
        if (pos >= (int)n.size())
             std::cerr << "Code position too high\n";
        Metadata m = n[pos].metadata;
        std::cout << "Opcode: " << n[pos].val << ", file: " << m.file << 
             ", line: " << m.ln << ", char: " << m.ch << "\n";
    }
}
 /// Dereference an iterator.
 const basic_resolver_entry<InternetProtocol>& operator*() const
 {
   return dereference();
 }
Example #25
0
 operator_arrow_proxy<typename UnaryFunction::result_type>
    operator->() const
 { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference());  }
Example #26
0
 typename UnaryFunction::result_type operator*() const
 { return dereference(); }
Example #27
0
VisitResult ExpressionVisitor::Visit(UnaryOperatorNode* node)
{
  node->Walk(this, false);
  ValueNode* valNode = static_cast<ValueNode*>(node->mRight.get());
  if(valNode->mResolvedType->mMode == TypeMode::Pointer)
  {
    switch(node->mOperator.mEnumTokenType)
    {
      case TokenType::Decrement:
      case TokenType::Increment:
      {
        node->mResolvedType = valNode->mResolvedType;
        break;
      }
      case TokenType::BitwiseAndAddressOf:
      {
        node->mResolvedType = library_->GetPointerType(valNode->mResolvedType, 1);
        break;
      }
      case TokenType::Asterisk:
      {
        node->mResolvedType = dereference(valNode->mResolvedType);
        break;
      }
      case TokenType::LogicalNot:
      {
        node->mResolvedType = static_cast<Type*>(find_symbol_by_name("Boolean", dependencies_, library_, symbol_stack_));
        break;
      }
      default:
        ErrorInvalidUnaryOperator(node);
    }
  }
  else if(valNode->mResolvedType->mName == "Integer" ||
          valNode->mResolvedType->mName == "Float" ||
          valNode->mResolvedType->mName == "Byte")
  {
    switch(node->mOperator.mEnumTokenType)
    {
      case TokenType::Plus:
      case TokenType::Minus:
      case TokenType::Decrement:
      case TokenType::Increment:
      {
        node->mResolvedType = valNode->mResolvedType;
        break;
      }
      case TokenType::BitwiseAndAddressOf:
      {
        node->mResolvedType = library_->GetPointerType(valNode->mResolvedType, 1);
        break;
      }
      default:
        ErrorInvalidUnaryOperator(node);
    }
  }
  else if(valNode->mResolvedType->mName == "Boolean")
  {
    switch(node->mOperator.mEnumTokenType)
    {
      case TokenType::BitwiseAndAddressOf:
      {
        node->mResolvedType = library_->GetPointerType(valNode->mResolvedType, 1);
        break;
      }
      case TokenType::LogicalNot:
      {
        node->mResolvedType = valNode->mResolvedType;
        break;
      }
      default:
        ErrorInvalidUnaryOperator(node);
    }
  }
  else
  {
    ErrorInvalidUnaryOperator(node);
  }
  
  
  return VisitResult::Stop;

}
Example #28
0
    /** parse tokens */
    const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const
    {
        if (Token::Match(tok.previous(), "[;{}] const| struct| %type% * %var% ;"))
        {
            const Token * vartok = tok.tokAt(2);

            if (tok.str() == "const")
                vartok = vartok->next();

            if (tok.str() == "struct")
                vartok = vartok->next();

            if (vartok->varId() != 0)
                checks.push_back(new Nullpointer(owner, vartok->varId(), vartok->str()));
            return vartok->next();
        }

        // Template pointer variable..
        if (Token::Match(tok.previous(), "[;{}] %type% ::|<"))
        {
            const Token * vartok = &tok;
            while (Token::Match(vartok, "%type% ::"))
                vartok = vartok->tokAt(2);
            if (Token::Match(vartok, "%type% < %type%"))
            {
                vartok = vartok->tokAt(3);
                while (vartok && (vartok->str() == "*" || vartok->isName()))
                    vartok = vartok->next();
            }
            if (vartok
                && (vartok->str() == ">" || vartok->isName())
                && Token::Match(vartok->next(), "* %var% ;|="))
            {
                vartok = vartok->tokAt(2);
                checks.push_back(new Nullpointer(owner, vartok->varId(), vartok->str()));
                if (Token::simpleMatch(vartok->next(), "= 0 ;"))
                    setnull(checks, vartok->varId());
                return vartok->next();
            }
        }

        if (Token::simpleMatch(&tok, "try {"))
        {
            // Bail out all used variables
            unsigned int indentlevel = 0;
            for (const Token *tok2 = &tok; tok2; tok2 = tok2->next())
            {
                if (tok2->str() == "{")
                    ++indentlevel;
                else if (tok2->str() == "}")
                {
                    if (indentlevel == 0)
                        break;
                    if (indentlevel == 1 && !Token::simpleMatch(tok2,"} catch ("))
                        return tok2;
                    --indentlevel;
                }
                else if (tok2->varId())
                    bailOutVar(checks,tok2->varId());
            }
        }

        if (Token::Match(&tok, "%var% ("))
        {
            if (tok.str() == "sizeof")
                return tok.next()->link();

            // parse usage..
            std::list<const Token *> var;
            CheckNullPointer::parseFunctionCall(tok, var, 0);
            for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
                dereference(checks, *it);
        }

        else if (Token::simpleMatch(&tok, "( 0 &&"))
            return tok.link();

        if (tok.varId() != 0)
        {
            // unknown : not really used. it is passed to isPointerDeRef.
            //           if isPointerDeRef fails to determine if there
            //           is a dereference the this will be set to true.
            bool unknown = false;

            if (Token::Match(tok.previous(), "[;{}=] %var% = 0 ;"))
                setnull(checks, tok.varId());
            else if (CheckNullPointer::isPointerDeRef(&tok, unknown))
                dereference(checks, &tok);
            else
                // TODO: Report debug warning that it's unknown if a
                // pointer is dereferenced
                bailOutVar(checks, tok.varId());
        }

        else if (tok.str() == "delete")
        {
            const Token *ret = tok.next();
            if (Token::simpleMatch(ret, "[ ]"))
                ret = ret->tokAt(2);
            if (Token::Match(ret, "%var% ;"))
                return ret->next();
        }

        return &tok;
    }
Example #29
0
		using index_sequence = std::index_sequence_for<args...>;

		template<size_t... index>
		[[nodiscard]]
		static auto dereference_impl(std::index_sequence<index...>, const pointer& Tuple)
		{
			return std::tie(*std::get<index>(Tuple)...);
		}

		[[nodiscard]]
		static auto dereference(const pointer& Tuple)
		{
			return dereference_impl(index_sequence{}, Tuple);
		}

		using reference = decltype(dereference(pointer()));
		using value_type = reference;

		template<size_t... index, typename predicate>
		static void unary_for_each_impl(std::index_sequence<index...>, predicate Predicate, pointer& Tuple)
		{
			(..., Predicate(std::get<index>(Tuple)));
		}

		template<typename predicate>
		static void unary_for_each(predicate Predicate, pointer& Tuple)
		{
			unary_for_each_impl(index_sequence{}, Predicate, Tuple);
		}

		template<size_t... index, typename predicate>
 /// Dereference an iterator.
 const basic_resolver_entry<InternetProtocol>* operator->() const
 {
   return &dereference();
 }