Equivalence of complicated for and if condition in C++ to Scala - c++

I need to write the following code in Scala (it is actually in C++). I have tried many ways but it still doesn't work. Any ideas?
pair<HashClosed::const_iterator, HashClosed::const_iterator> p =
closedItemsets.equal_range(pos1->second.myTidSum);
for ( HashClosed::const_iterator pos = p.first; pos != p.second; ++pos ) {
if ( pos->second.first == x->second.first ){}

Thx everyone , I have find the solution , this code in c++ is written as following in scala
for (pos <-pos.get(p._1) if pos != p._2)
{
pos._2.toMap
x._2.toMap
if(pos._1 == x._1)
{}
}

Related

Remove what's in one list from the other list

I have two lists which contain a bunch of elements of the same type:
std::list<Part> allParts = step.getSubParts();
std::list<Part> toRemove;
for (Part part : allParts)
{
for (Part partTwo : allParts) {
if (part.getEdges() == partTwo.getEdges())
if (part.getFaces() == partTwo.getFaces())
if (part.getShells() == partTwo.getShells())
if (part.getVertices() == partTwo.getVertices())
if (part.getWires() == partTwo.getWires())
{
part.addAmount(1);
toRemove.push_back(partTwo);
}
}
}
I have tried iterating through both and remove from the one but I'm constantly getting the list iterators are incompatible error. This is my latest attempt:
std::list<Part>::iterator it;
for (it = step.getSubParts().begin(); it != step.getSubParts().end();)
{
std::list<Part>::iterator i;
for (i = toRemove.begin(); i != toRemove.end();)
{
if (it->getEdges() == i->getEdges())
if (it->getFaces() == i->getFaces())
if (it->getShells() == i->getShells())
if (it->getVertices() == i->getVertices())
if (it->getWires() == i->getWires())
{
it = step.getSubParts().erase(it);
}
else
{
it++;
}
i++;
}
}
Everything I have tried doesn't work. What is the correct way to do this?
You should consider remove_if or erase_if rather than doing your own erase with the hazard of making iterator invalid within a loop.
By the way, you should write predicate like:
if (it->getEdges() == i->getEdges() &&
it->getFaces() == i->getFaces() &&
it->getShells() == i->getShells() &&
it->getVertices() == i->getVertices() &&
it->getWires() == i->getWires()) {
// do something
}
Your code makes people difficult to understand your purpose(at least me).
erase and erase_if
First of all, it would be a good idea to follow the Don't Repeat Yourself principle and write a comparison function for future use:
auto compare_parts = [](const Part& p1, const Part& p2) -> bool {
return ( (p1.getEdges() == p2.getEdges())
and (p1.getFaces() == p2.getFaces())
and (p1.getShells() == p2.getShells())
and (p1.getVertices() == p2.getVertices())
and (p1.getWires() == p2.getWires()) );
}
You would rewrite the first cycle using it and see how much more simple it looks.
Then why not use c++ built-in methods to erase the elements from the list using the function we wrote? This uses new feature in c++ called binding parameters that would aid us here
#include <functional>
using namespace std::placeholders;
for (auto&& badPart : toRemove) {
auto isBad = std::bind(compare_parts, badPart, _1);
step.getSubParts().remove_if(isBad);
}
And that's how you remove special entries from the list.
I think the cleanest way would be:
1. Implement equality operator for the class Part
You can either put it inside or outside the class, it would look like this if you implement it as an external function
inline bool operator==(const Part& lhs, const Part& rhs) {
return lhs.getEdges() == rhs.getEdges() &&
lhs.getFaces() == rhs.getFaces() &&
lhs.getShells() == rhs.getShells() &&
lhs.getVertices() == rhs.getVertices() &&
lhs.getWires() == rhs.getWires();
}
2. Implement the loop, I would recommend using iterators
This is just one way of doing it
if (allParts.size() > 1) {
for(auto partIt = std::begin(allParts); partIt != std::end(allParts); partIt++) {
for(auto partIt2 = std::next(partIt); partIt2 != std::end(allParts);) { // Manual increasing because we erase stuff
if(*partIt == *partIt2) { // Previously implemented equility operator
partIt->AddAmount(1);
partIt2 = allParts.erase(partIt2); // If erase, use the returned iterator as your next `Part`
} else {
partIt2++; // Only increment if nothing was erased (when you erase iterators get invalidated)
}
}
}
}

OpenMP through std::set using iterator

I have a mesh with huge number of segments, I want to apply filter and fill std::set set_, which is private member of class A. There is function called fill_vec() which is going to fill the vector using a for loop:
fill_set()
{
for(mesh::SegIterator it = A.beginSeg(); it != A.endSeg(); ++it )
{
mesh::Segment Seg_ = *it;
int SignP = 0;
int SignN = 0;
for(mesh::PointIterator itp = Seg_.beginPoint(); itp != Seg_.endPoint(); ++itp )
{
double old_, new_;
...
...
if( old_ > 0.0 && new_ > 0.0 )
SignP++;
if( old_ < 0.0 && new_ < 0.0 )
SignN++;
}
if( (SignP == 1 && SignN == 1) || (SignP == 1 && SignN == 2) )
{
set_.insert(Seg_);
}
}
I am trying peform above code in parallel using OpenMP and C++03. I saw some solutions like as this. Any other safe and neat solution?
Try changing from it != A.endSeg() to it < A.endSeg(). The problem with != is the loop is not countable. The compiler can't know for sure that the loop will ever end. Switching it to < should make it countable.

How to convert C++ 11 loop in to traditional loop?

I am having this error in my program error C2143: syntax error : missing ',' before ':', I am using Visual c++ express 2010 and i think C++11 dosent support in VC 2010.
Can somone please modify this code and explain how to revert this for loop in traditional for loop ? ouFlexSignalInfo is a list data type from c++ stl
for(auto ouSignalInfo : ouFlexSignalInfo) //C++11;
{
SSignalInfo ouSignal;
ouSignal.m_omEnggValue = ouSignalInfo.m_omEnggValue.c_str();
ouSignal.m_omRawValue = ouSignalInfo.m_omRawValue.c_str();
ouSignal.m_omSigName = ouSignalInfo.m_omSigName.c_str();
ouSignal.m_omUnit = ouSignalInfo.m_omUnit.c_str();
ouSignal.m_msgName=ouFrame.m_strFrameName.c_str();
SigInfoArray.Add(ouSignal);
}
it is roughly equivalent to:
auto iterBegin = std::begin(ouFlexSignalInfo);
auto iterEnd = std::end(ouFlexSignalInfo);
for(; iterBegin != iterEnd; ++iterBegin)
{
auto ouSignalInfo = *iterBegin;
//the rest of body
}
the iterBegin and iterEnd are iterators returned from the ouFlexSignalInfo members begin and end.
This kind of loop works for everything that has begin and end members
If you use MS VC++ 2010 then the compiler supports a MS language extension for the range-based for loop. The code will look the following way
for each ( auto ouSignalInfo in ouFlexSignalInfo )
{
SSignalInfo ouSignal;
ouSignal.m_omEnggValue = ouSignalInfo.m_omEnggValue.c_str();
ouSignal.m_omRawValue = ouSignalInfo.m_omRawValue.c_str();
ouSignal.m_omSigName = ouSignalInfo.m_omSigName.c_str();
ouSignal.m_omUnit = ouSignalInfo.m_omUnit.c_str();
ouSignal.m_msgName=ouFrame.m_strFrameName.c_str();
SigInfoArray.Add(ouSignal);
}
Or it would be better to write
for each ( const auto &ouSignalInfo in ouFlexSignalInfo )
{
SSignalInfo ouSignal;
ouSignal.m_omEnggValue = ouSignalInfo.m_omEnggValue.c_str();
ouSignal.m_omRawValue = ouSignalInfo.m_omRawValue.c_str();
ouSignal.m_omSigName = ouSignalInfo.m_omSigName.c_str();
ouSignal.m_omUnit = ouSignalInfo.m_omUnit.c_str();
ouSignal.m_msgName=ouFrame.m_strFrameName.c_str();
SigInfoArray.Add(ouSignal);
}
As the type of ouFlexSignalInfo is unknown then you can use iterators. For example
#include <iterator>
for ( auto it = std::begin( ouFlexSignalInfo ); it != std::end( ouFlexSignalInfo ); ++it )
{
SSignalInfo ouSignal;
ouSignal.m_omEnggValue = it->m_omEnggValue.c_str();
ouSignal.m_omRawValue = it->m_omRawValue.c_str();
ouSignal.m_omSigName = it->m_omSigName.c_str();
ouSignal.m_omUnit = it->m_omUnit.c_str();
ouSignal.m_msgName = ouFrame.m_strFrameName.c_str();
SigInfoArray.Add( ouSignal );
}

Replacing the operand of an LLVM instruction

In the following code, I try to replace operand(s) of an LLVM instructions. However it doesn't work and nothing is changed. Any idea how to solve this?
for (OI = insn->op_begin(), OE = insn->op_end(); OI != OE; ++OI)
{
Value *val = *OI;
iter = mapClonedAndOrg.find( val );
if( iter != mapClonedAndOrg.end( ) )
{
// Here I try to replace the operand, to no effect!
val = (Value*)iter->second.PN;
}
}
You should use the iterator OI to replace it, instead of the local pointer val. So it should be like this.
for (OI = insn->op_begin(), OE = insn->op_end(); OI != OE; ++OI)
{
Value *val = *OI;
iter = mapClonedAndOrg.find( val );
if( iter != mapClonedAndOrg.end( ) )
{
*OI = (Value*)iter->second.PN;
}
}
What you are doing is simply making a local pointer point to something else, you don't actually change what it points to. For that you need to use the dereferencing operator *:
*val = *((Value*) iter->second.PN);

Pointers with STL maps and lists

I did do a good search on the 'net about this and turned up lots of help regarding vectors but not really anything on STL lists. I am attempting to erase a pointer from a list within a map. (a little tricky). I really want to use pointers and not revert to another (worse) system of doing things. I will show the code
bool RoomDB::removePlayer( int socketid, int roomid ) {
list<GamePlayer>::iterator itit;
for( itit == roomlist[roomid].playerlist.begin(); itit != itit.end(); itit++ ) {
if( itit.socketno == socketid )
itit.erase( itit );
}
I think it should just be like this:
roomlist[roomid].playerlist.remove_if(
[socketid](GamePlayer const & gp) { return gp.socketno == socketid; }
);
If you don't have lambdas, you'll have to write a little predicate yourself, or you go the manual way; but now beware of the loop:
for (std::list<GamePlayer>::iterator it = roomlist[roomid].playerlist.begin();
it != roomlist[roomid].playerlist.end(); /* no increment */ )
{
if (it->socketno == socketid)
{
it = roomlist[roomid].playerlist.erase(it);
}
else
{
++it;
}
}
There are a bunch of things wrong. I will try to list all of them, though I may miss some:
It should be list<GamePlayer*>::iterator itit; if, as you say, your lists contain pointers
It should be itit = roomlist[roomid].playerlist.begin();, not itit = ..., like KerrekSB said
It should be itit != roomlist[roomid].playerlist.end(), not itit != itit.end()
It should be if( (*itit)->socketno == socketid ), not if( itit.socketno == socketid ) (again, if your list contains pointers)
It should be roomlist[roomid].playerlist.erase(itit), not itit.erase(itit).