当前位置: 首页>>代码示例>>C++>>正文


C++ multimap::empty方法代码示例

本文整理汇总了C++中std::multimap::empty方法的典型用法代码示例。如果您正苦于以下问题:C++ multimap::empty方法的具体用法?C++ multimap::empty怎么用?C++ multimap::empty使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在std::multimap的用法示例。


在下文中一共展示了multimap::empty方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: frame

void DFHack::Lua::Core::onUpdate(color_ostream &out)
{
    using df::global::world;

    if (frame_timers.empty() && tick_timers.empty())
        return;

    Lua::StackUnwinder frame(State);
    lua_rawgetp(State, LUA_REGISTRYINDEX, &DFHACK_TIMEOUTS_TOKEN);

    run_timers(out, State, frame_timers, frame[1], ++frame_idx);
    run_timers(out, State, tick_timers, frame[1], world->frame_counter);
}
开发者ID:Elvang,项目名称:dfhack,代码行数:13,代码来源:LuaTools.cpp

示例2: setBarIndexes

void setBarIndexes(
            std::multimap<ReducedFraction, MidiChord> &chords,
            const ReducedFraction &basicQuant,
            const ReducedFraction &lastTick,
            const TimeSigMap *sigmap)
      {
      if (chords.empty())
            return;
      auto it = chords.begin();
      for (int barIndex = 0;; ++barIndex) {       // iterate over all measures by indexes
            const auto endBarTick = ReducedFraction::fromTicks(sigmap->bar2tick(barIndex + 1, 0));
            if (endBarTick <= it->first)
                  continue;
            for (; it != chords.end(); ++it) {
                  const auto onTime = Quantize::findQuantizedChordOnTime(*it, basicQuant);
#ifdef QT_DEBUG
                  const auto barStart = ReducedFraction::fromTicks(sigmap->bar2tick(barIndex, 0));
                  Q_ASSERT_X(!(it->first >= barStart && onTime < barStart),
                             "MChord::setBarIndexes", "quantized on time cannot be in previous bar");
#endif
                  if (onTime < endBarTick) {
                        it->second.barIndex = barIndex;
                        continue;
                        }
                  break;
                  }
            if (it == chords.end() || endBarTick > lastTick)
                  break;
            }

      Q_ASSERT_X(areBarIndexesSet(chords),
                 "MChord::setBarIndexes", "Not all bar indexes were set");
      Q_ASSERT_X(areBarIndexesSuccessive(chords),
                 "MChord::setBarIndexes", "Bar indexes are not successive");
      }
开发者ID:chenlung,项目名称:MuseScore,代码行数:35,代码来源:importmidi_chord.cpp

示例3: putData

void GroupTransformer::putData(RddPartition* output,
    std::multimap<PbMessagePtr, PbMessagePtr, idgs::store::less>& localCache) {
  if (!localCache.empty()) {
    PbMessagePtr key;
    std::vector<PbMessagePtr> values;
    for (auto it = localCache.begin(); it != localCache.end(); ++it) {
      if (idgs::store::equals_to()(const_cast<PbMessagePtr&>(it->first), key)) {
        values.push_back(it->second);
      } else {
        if (!values.empty()) {
          output->put(key, values);
          values.clear();
        }
        values.clear();
        key = it->first;
        values.push_back(it->second);
      }
    }
    if (!values.empty()) {
      output->put(key, values);
      values.clear();
    }

    localCache.clear();
  }
}
开发者ID:XiaominZhang,项目名称:raf,代码行数:26,代码来源:group_transformer.cpp

示例4: while

std::vector<std::multimap<ReducedFraction, MidiChord>::const_iterator>
findChordsForTimeRange(
            int voice,
            const ReducedFraction &onTime,
            const ReducedFraction &offTime,
            const std::multimap<ReducedFraction, MidiChord> &chords,
            const ReducedFraction &maxChordLength)
      {
      std::vector<std::multimap<ReducedFraction, MidiChord>::const_iterator> result;

      if (chords.empty())
            return result;

      auto it = chords.lower_bound(offTime);
      if (it == chords.begin())
            return result;
      --it;

      while (it->first + maxChordLength > onTime) {
            const MidiChord &chord = it->second;
            if (chord.voice == voice) {
                  const auto chordInterval = std::make_pair(it->first, maxNoteOffTime(chord.notes));
                  const auto durationInterval = std::make_pair(onTime, offTime);

                  if (MidiTuplet::haveIntersection(chordInterval, durationInterval))
                        result.push_back(it);
                  }
            if (it == chords.begin())
                  break;
            --it;
            }

      return result;
      }
开发者ID:chenlung,项目名称:MuseScore,代码行数:34,代码来源:importmidi_chord.cpp

示例5: tc_libcxx_containers_multimap_cons_compare

int tc_libcxx_containers_multimap_cons_compare(void)
{
    {
    typedef test_compare<std::less<int> > C;
    const std::multimap<int, double, C> m(C(3));
    TC_ASSERT_EXPR(m.empty());
    TC_ASSERT_EXPR(m.begin() == m.end());
    TC_ASSERT_EXPR(m.key_comp() == C(3));
    }
    TC_SUCCESS_RESULT();
    return 0;
}
开发者ID:drashti304,项目名称:TizenRT,代码行数:12,代码来源:compare.pass.cpp

示例6: it

inline void operator<< (object::with_zone& o, const std::multimap<K,V>& v)
{
	o.type = type::MAP;
	if(v.empty()) {
		o.via.map.ptr  = NULL;
		o.via.map.size = 0;
	} else {
		object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
		object_kv* const pend = p + v.size();
		o.via.map.ptr  = p;
		o.via.map.size = v.size();
		typename std::multimap<K,V>::const_iterator it(v.begin());
		do {
			p->key = object(it->first, o.zone);
			p->val = object(it->second, o.zone);
			++p;
			++it;
		} while(p < pend);
	}
}
开发者ID:RedSunCMX,项目名称:izenelib,代码行数:20,代码来源:map.hpp

示例7: checkIfTheListIsCorrect

/**
 * @brief check if the order of execution of Actions in the List, based on their Precedence attribute, is correct and if in the List there are all the Actions
 */
bool ActionPluginFinalCallback::checkIfTheListIsCorrect(
		const std::multimap<int, Tuple>& multimapOfExecution,
		const std::list<std::set<Tuple> >& listOfExecution) {

	if (multimapOfExecution.empty())
		if (listOfExecution.empty())
			return true;
		else
			return false;

	// used to create a List (listOfExecutionFromMultimap)
	// with Tuples ordered by their Precedence attribute
	std::multimap<int, Tuple>::const_iterator itMOE =
			multimapOfExecution.begin();
	int latestPrecedenceValue = itMOE->first;
	std::list < std::set<Tuple> > listOfExecutionFromMultimap;
	std::set < Tuple > currentSet;
	for (; itMOE != multimapOfExecution.end(); itMOE++) {
		if (itMOE->first != latestPrecedenceValue) {
			listOfExecutionFromMultimap.push_back(currentSet);
			currentSet.clear();
			latestPrecedenceValue = itMOE->first;
		}
		currentSet.insert(itMOE->second);
	}
	listOfExecutionFromMultimap.push_back(currentSet);

	if (listOfExecution.size() != listOfExecutionFromMultimap.size())
		return false;

	std::list<std::set<Tuple> >::const_iterator itLOE, itLOEFM;
	for (itLOE = listOfExecution.begin(), itLOEFM =
			listOfExecutionFromMultimap.begin();
			itLOE != listOfExecution.end(), itLOEFM
					!= listOfExecutionFromMultimap.end(); itLOE++, itLOEFM++)
		if (!checkIfThisSetsOfTupleContainsTheSameElements(*itLOEFM, *itLOE))
			return false;

	return true;

}
开发者ID:hexhex,项目名称:actionplugin,代码行数:44,代码来源:ActionPluginFinalCallback.cpp

示例8: run_timers

static void run_timers(color_ostream &out, lua_State *L,
                       std::multimap<int,int> &timers, int table, int bound)
{
    while (!timers.empty() && timers.begin()->first <= bound)
    {
        int id = timers.begin()->second;
        timers.erase(timers.begin());

        lua_rawgeti(L, table, id);

        if (lua_isnil(L, -1))
            lua_pop(L, 1);
        else
        {
            lua_pushnil(L);
            lua_rawseti(L, table, id);

            Lua::SafeCall(out, L, 0, 0);
        }
    }
}
开发者ID:mstram,项目名称:dfhack-40d,代码行数:21,代码来源:LuaTools.cpp

示例9: step

    /**  advance in play loop by rtick_inc ticks, possibly generate some
     * csoundScoreEvent calls.
     */
    void step(MYFLT rtick_inc, MYFLT secs_per_tick , CSOUND * csound)
    {
        if (!playing) return;
        rtick += rtick_inc;
        int tick = (int)rtick % tickMax;
        if (tick == tick_prev) return;

        int events = 0;
        int loop0 = 0;
        int loop1 = 0;
        if (!ev.empty()) 
        {
            if (steps && (tick < tick_prev)) // should be true only after the loop wraps (not after insert)
            {
                while (ev_pos != ev.end())
                {
                    if (_debug && (VERBOSE > 3)) ev_pos->second->ev_print(_debug);
                    if (events < STEP_eventMax) ev_pos->second->event(csound, secs_per_tick);
                    ++ev_pos;
                    ++events;
                    ++loop0;
                }
                ev_pos = ev.begin();
            }
            while ((ev_pos != ev.end()) && (tick >= ev_pos->first))
            {
                if (_debug && (VERBOSE > 3)) ev_pos->second->ev_print(_debug);
                if (events < STEP_eventMax) ev_pos->second->event(csound, secs_per_tick);
                ++ev_pos;
                ++events;
                ++loop1;
            }
        }
        tick_prev = tick;
        if (_debug && (VERBOSE>1) && (events >= STEP_eventMax)) fprintf(_debug, "WARNING: %i/%i events at once (%i, %i)\n", events, (int)ev.size(),loop0,loop1);
        ++steps;
    }
开发者ID:godiard,项目名称:music-keyboard-activity,代码行数:40,代码来源:aclient.cpp

示例10: ResetTimer

    // Only call on io_service
    void ResetTimer()
    {
        const auto now = std::chrono::steady_clock::now();

        UniqueLock unique_lock(mutex_);

        while (running_ && !data_.empty())
        {
            auto map_front_it = data_.begin();
            const auto timeout = map_front_it->first;
            if ( timeout <= now )
            {
                // Effeciently extract the value so we can move it.
                auto event = std::move( map_front_it->second );
                data_.erase(map_front_it);

                // Unlock incase callback calls a TimedActions method.
                unique_lock.unlock();
                event_processor_(std::move(event), std::error_code());
                unique_lock.lock();
            }
            else
            {
                timeout_timer_.expires_at(timeout);

                timeout_timer_.async_wait(
                    boost::bind(
                        &TimedEvents<Event>::HandleTimeout,
                        this->shared_from_this(),
                        boost::asio::placeholders::error
                    )
                );
                break;
            }
        }
    }
开发者ID:dazw666,项目名称:mediafire-cpp-sdk,代码行数:37,代码来源:timed_events.hpp

示例11: Solver

/**
 * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
 */
bool Solver(const CScript& scriptPubKeyIn, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet)
{
    // Templates
    static std::multimap<txnouttype, CScript> mTemplates;
    if (mTemplates.empty())
    {
        // Standard tx, sender provides pubkey, receiver adds signature
        mTemplates.insert(std::make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG));

        // Syscoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
        mTemplates.insert(std::make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG));

        // Sender provides N pubkeys, receivers provides M signatures
        mTemplates.insert(std::make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
    }

	// SYSCOIN check to see if this is a syscoin service transaction, if so get the scriptPubKey by extracting service specific script information
	CScript scriptPubKey;
	CScript scriptPubKeyOut;
	if (RemoveSyscoinScript(scriptPubKeyIn, scriptPubKeyOut))
		scriptPubKey = scriptPubKeyOut;
	else
		scriptPubKey = scriptPubKeyIn;
    vSolutionsRet.clear();

    // Shortcut for pay-to-script-hash, which are more constrained than the other types:
    // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
    if (scriptPubKey.IsPayToScriptHash())
    {
        typeRet = TX_SCRIPTHASH;
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    // Provably prunable, data-carrying output
    //
    // So long as script passes the IsUnspendable() test and all but the first
    // byte passes the IsPushOnly() test we don't care what exactly is in the
    // script.
    if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
        typeRet = TX_NULL_DATA;
        return true;
    }

    // Scan templates
    const CScript& script1 = scriptPubKey;
    BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
    {
        const CScript& script2 = tplate.second;
        vSolutionsRet.clear();

        opcodetype opcode1, opcode2;
        std::vector<unsigned char> vch1, vch2;

        // Compare
        CScript::const_iterator pc1 = script1.begin();
        CScript::const_iterator pc2 = script2.begin();
        while (true)
        {
            if (pc1 == script1.end() && pc2 == script2.end())
            {
                // Found a match
                typeRet = tplate.first;
                if (typeRet == TX_MULTISIG)
                {
                    // Additional checks for TX_MULTISIG:
                    unsigned char m = vSolutionsRet.front()[0];
                    unsigned char n = vSolutionsRet.back()[0];
                    if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n)
                        return false;
                }
                return true;
            }
            if (!script1.GetOp(pc1, opcode1, vch1))
                break;
            if (!script2.GetOp(pc2, opcode2, vch2))
                break;

            // Template matching opcodes:
            if (opcode2 == OP_PUBKEYS)
            {
                while (vch1.size() >= 33 && vch1.size() <= 65)
                {
                    vSolutionsRet.push_back(vch1);
                    if (!script1.GetOp(pc1, opcode1, vch1))
                        break;
                }
                if (!script2.GetOp(pc2, opcode2, vch2))
                    break;
                // Normal situation is to fall through
                // to other if/else statements
            }

            if (opcode2 == OP_PUBKEY)
            {
                if (vch1.size() < 33 || vch1.size() > 65)
//.........这里部分代码省略.........
开发者ID:syscoin,项目名称:syscoin2,代码行数:101,代码来源:standard.cpp

示例12: HasFinishedPath

///=====================================================
/// 
///=====================================================
inline bool Path::HasFinishedPath() const{
	return (m_path.empty() || (m_openList.empty() && !m_closedList.empty()));
}
开发者ID:asocha,项目名称:Dagger,代码行数:6,代码来源:Pathfinding.hpp

示例13: Write

bool Polish::Write(const std::string& filename, const std::multimap<int, Airspace>& airspaces) {
	if (airspaces.empty()) {
		AirspaceConverter::LogMessage("Polish output: no airspace, nothing to write", false);
		return false;
	}

	// Check if has the right extension
	if (!boost::iequals(boost::filesystem::path(filename).extension().string(), ".mp")) {
		AirspaceConverter::LogMessage("ERROR: Expected MP extension but found: " + boost::filesystem::path(filename).extension().string(), true);
		return false;
	}

	if (file.is_open()) file.close();
	file.open(filename, std::ios::out | std::ios::trunc | std::ios::binary);
	if (!file.is_open() || file.bad()) {
		AirspaceConverter::LogMessage("ERROR: Unable to open output file: " + filename, true);
		return false;
	}
	AirspaceConverter::LogMessage("Writing output file: " + filename, false);

	WriteHeader(filename);

	// Go trough all airspaces
	for (const std::pair<const int,Airspace>& pair : airspaces)
	{
		// Get the airspace
		const Airspace& a = pair.second;

		// Just a couple if assertions
		assert(a.GetNumberOfPoints() > 3);
		assert(a.GetFirstPoint()==a.GetLastPoint());

		// Determine if it's a POLYGON or a POLYLINE
		if (a.GetType() == Airspace::PROHIBITED || a.GetType() == Airspace::CTR || a.GetType() == Airspace::DANGER) {
			file << "[POLYGON]\n"
				//<< "Type="<< types[a.GetType()] <<"\n"; //TODO...
				<< "Type=0x18" <<"\n";
		} else {
			file << "[POLYLINE]\n"
				<< "Type=0x07\n"; //TODO....
		}

		// Add the label
		file << "Label="<<MakeLabel(a)<<"\n";

		file << "Levels=3\n";

		// Insert all the points
		file << "Data0=";
		double lat,lon;
		for (unsigned int i=0; i<a.GetNumberOfPoints()-1; i++) {
			a.GetPointAt(i).GetLatLon(lat,lon);
			file << "(" << lat << "," << lon << "),";
		}
		a.GetLastPoint().GetLatLon(lat,lon);
		file << "(" << lat << "," << lon << ")\n";

		//file<< "EndLevel=4\n";

		// Close the element
		file << "[END]\n\n";
	}
	file.close();
	return true;
}
开发者ID:alus-it,项目名称:AirspaceConverter,代码行数:65,代码来源:Polish.cpp

示例14: IV

/// visitGraph - Visit the functions in the specified graph, updating the
/// specified lattice values for all of their uses.
///
void StructureFieldVisitorBase::
visitGraph(DSGraph &DSG, std::multimap<DSNode*, LatticeValue*> &NodeLVs) {
  assert(!NodeLVs.empty() && "No lattice values to compute!");

  // To visit a graph, first step, we visit the instruction making up each
  // function in the graph, but ignore calls when processing them.  We handle
  // call nodes explicitly by looking at call nodes in the graph if needed.  We
  // handle instructions before calls to avoid interprocedural analysis if we
  // can drive lattice values to bottom early.
  //
  SFVInstVisitor IV(DSG, Callbacks, NodeLVs);

  for (DSGraph::retnodes_iterator FI = DSG.retnodes_begin(),
         E = DSG.retnodes_end(); FI != E; ++FI)
    for (Function::iterator BB = FI->first->begin(), E = FI->first->end();
         BB != E; ++BB)
      for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
        if (IV.visit(*I) && NodeLVs.empty())
          return;  // Nothing left to analyze.

  // Keep track of which actual direct callees are handled.
  std::set<Function*> CalleesHandled;

  // Once we have visited all of the instructions in the function bodies, if
  // there are lattice values that have not been driven to bottom, see if any of
  // the nodes involved are passed into function calls.  If so, we potentially
  // have to recursively traverse the call graph.
  for (DSGraph::fc_iterator CS = DSG.fc_begin(), E = DSG.fc_end();
       CS != E; ++CS) {
    // Figure out the mapping from a node in the caller (potentially several)
    // nodes in the callee.
    DSGraph::NodeMapTy CallNodeMap;

    Instruction *TheCall = CS->getCallSite().getInstruction();

    // If this is an indirect function call, assume nothing gets passed through
    // it. FIXME: THIS IS BROKEN!  Just get the ECG for the fn ptr if it's not
    // direct.
    if (CS->isIndirectCall())
      continue;

    // If this is an external function call, it cannot be involved with this
    // node, because otherwise the node would be marked incomplete!
    if (CS->getCalleeFunc()->isExternal())
      continue;

    // If we can handle this function call, remove it from the set of direct
    // calls found by the visitor.
    CalleesHandled.insert(CS->getCalleeFunc());

    std::vector<DSNodeHandle> Args;

    DSGraph *CG = &ECG.getDSGraph(*CS->getCalleeFunc());
    CG->getFunctionArgumentsForCall(CS->getCalleeFunc(), Args);

    if (!CS->getRetVal().isNull())
      DSGraph::computeNodeMapping(Args[0], CS->getRetVal(), CallNodeMap);
    for (unsigned i = 0, e = CS->getNumPtrArgs(); i != e; ++i) {
      if (i == Args.size()-1) break;
      DSGraph::computeNodeMapping(Args[i+1], CS->getPtrArg(i), CallNodeMap);
    }
    Args.clear();

    // The mapping we just computed maps from nodes in the callee to nodes in
    // the caller, so we can't query it efficiently.  Instead of going through
    // the trouble of inverting the map to do this (linear time with the size of
    // the mapping), we just do a linear search to see if any affected nodes are
    // passed into this call.
    bool CallCanModifyDataFlow = false;
    for (DSGraph::NodeMapTy::iterator MI = CallNodeMap.begin(),
           E = CallNodeMap.end(); MI != E; ++MI)
      if (NodeLVs.count(MI->second.getNode()))
        // Okay, the node is passed in, check to see if the call might do
        // something interesting to it (i.e. if analyzing the call can produce
        // anything other than "top").
        if ((CallCanModifyDataFlow = NodeCanPossiblyBeInteresting(MI->first,
                                                                  Callbacks)))
          break;

    // If this function call cannot impact the analysis (either because the
    // nodes we are tracking are not passed into the call, or the DSGraph for
    // the callee tells us that analysis of the callee can't provide interesting
    // information), ignore it.
    if (!CallCanModifyDataFlow)
      continue;

    // Okay, either compute analysis results for the callee function, or reuse
    // results previously computed.
    std::multimap<DSNode*, LatticeValue*> &CalleeFacts = getCalleeFacts(*CG);

    // Merge all of the facts for the callee into the facts for the caller.  If
    // this reduces anything in the caller to 'bottom', remove them.
    for (DSGraph::NodeMapTy::iterator MI = CallNodeMap.begin(),
           E = CallNodeMap.end(); MI != E; ++MI) {
      // If we have Lattice facts in the caller for this node in the callee,
      // merge any information from the callee into the caller.

//.........这里部分代码省略.........
开发者ID:brills,项目名称:pfpa,代码行数:101,代码来源:StructureFieldVisitor.cpp

示例15: ComputeInverseGraphFrom

/// ProcessNodesReachableFromGlobals - If we inferred anything about nodes
/// reachable from globals, we have to make sure that we incorporate data for
/// all graphs that include those globals due to the nature of the globals
/// graph.
///
void StructureFieldVisitorBase::
ProcessNodesReachableFromGlobals(DSGraph &DSG,
                                 std::multimap<DSNode*,LatticeValue*> &NodeLVs){
  // Start by marking all nodes reachable from globals.
  DSScalarMap &SM = DSG.getScalarMap();
  if (SM.global_begin() == SM.global_end()) return;

  hash_set<const DSNode*> Reachable;
  for (DSScalarMap::global_iterator GI = SM.global_begin(),
         E = SM.global_end(); GI != E; ++GI)
    SM[*GI].getNode()->markReachableNodes(Reachable);
  if (Reachable.empty()) return;
  
  // If any of the nodes with dataflow facts are reachable from the globals
  // graph, we have to do the GG processing step.
  bool MustProcessThroughGlobalsGraph = false;
  for (std::multimap<DSNode*, LatticeValue*>::iterator I = NodeLVs.begin(),
         E = NodeLVs.end(); I != E; ++I)
    if (Reachable.count(I->first)) {
      MustProcessThroughGlobalsGraph = true;
      break;
    }
  
  if (!MustProcessThroughGlobalsGraph) return;
  Reachable.clear();

  // Compute the mapping from DSG to the globals graph.
  DSGraph::NodeMapTy DSGToGGMap;
  DSG.computeGToGGMapping(DSGToGGMap);

  // Most of the times when we find facts about things reachable from globals we
  // we are in the main graph.  This means that we have *all* of the globals
  // graph in this DSG.  To be efficient, we compute the minimum set of globals
  // that can reach any of the NodeLVs facts.
  //
  // I'm not aware of any wonderful way of computing the set of globals that
  // points to the set of nodes in NodeLVs that is not N^2 in either NodeLVs or
  // the number of globals, except to compute the inverse of DSG.  As such, we
  // compute the inverse graph of DSG, which basically has the edges going from
  // pointed to nodes to pointing nodes.  Because we only care about one
  // connectedness properties, we ignore field info.  In addition, we only
  // compute inverse of the portion of the graph reachable from the globals.
  std::set<std::pair<DSNode*,DSNode*> > InverseGraph;

  for (DSScalarMap::global_iterator GI = SM.global_begin(),
         E = SM.global_end(); GI != E; ++GI)
    ComputeInverseGraphFrom(SM[*GI].getNode(), InverseGraph);

  // Okay, now that we have our bastardized inverse graph, compute the set of
  // globals nodes reachable from our lattice nodes.
  for (std::multimap<DSNode*, LatticeValue*>::iterator I = NodeLVs.begin(),
         E = NodeLVs.end(); I != E; ++I)
    ComputeNodesReachableFrom(I->first, InverseGraph, Reachable);
 
  // Now that we know which nodes point to the data flow facts, figure out which
  // globals point to the data flow facts.
  std::set<GlobalValue*> Globals;
  for (hash_set<const DSNode*>::iterator I = Reachable.begin(),
         E = Reachable.end(); I != E; ++I)
    Globals.insert((*I)->globals_begin(), (*I)->globals_end());

  // Finally, loop over all of the DSGraphs for the program, computing
  // information for the graph if not done already, mapping the result into our
  // context.
  for (hash_map<const Function*, DSGraph*>::iterator GI = ECG.DSInfo.begin(),
         E = ECG.DSInfo.end(); GI != E; ++GI) {
    DSGraph &FG = *GI->second;
    // Graphs can contain multiple functions, only process the graph once.
    if (GI->first != FG.retnodes_begin()->first ||
        // Also, do not bother reprocessing DSG.
        &FG == &DSG)
      continue;

    bool GraphUsesGlobal = false;
    for (std::set<GlobalValue*>::iterator I = Globals.begin(),
           E = Globals.end(); I != E; ++I)
      if (FG.getScalarMap().count(*I)) {
        GraphUsesGlobal = true;
        break;
      }

    // If this graph does not contain the global at all, there is no reason to
    // even think about it.
    if (!GraphUsesGlobal) continue;

    // Otherwise, compute the full set of dataflow effects of the function.
    std::multimap<DSNode*, LatticeValue*> &FGF = getCalleeFacts(FG);
    //std::cerr << "Computed: " << FG.getFunctionNames() << "\n";

#if 0
    for (std::multimap<DSNode*, LatticeValue*>::iterator I = FGF.begin(),
           E = FGF.end(); I != E; ++I)
      I->second->dump();
#endif
    // Compute the mapping of nodes in the globals graph to the function's
//.........这里部分代码省略.........
开发者ID:brills,项目名称:pfpa,代码行数:101,代码来源:StructureFieldVisitor.cpp


注:本文中的std::multimap::empty方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。