I'm looking for an efficient way to check if a POD variable is altered between two cycles. I've come up with this solution:
class Foo {
public:
template<typename T>
bool isChanged(T& entry);
void endCycle();
private:
std::map<void*,size_t> entryMap; // <Address orig.,Size>
std::map<void*,void*>oldVals; // <Address orig., Address cpy.>
};
template<typename T> bool Foo::isChanged(T& entry)
{
entryMap[&entry] = sizeof(T);
if(oldVals[&entry] == NULL)
return false;
if(memcmp(&entry, oldVals[&entry], entryMap[&entry]))
return true;
else
return false;
}
void Foo::endCycle()
{
// Copy all the bytes to save them for the next cycle
for( std::map<void*,size_t>::iterator entryIt = entryMap.begin();
entryIt != entryMap.end();
++entryIt)
{
if(oldVals[entryIt->first] == NULL)
oldVals[entryIt->first] = malloc(entryIt->second);
memcpy(oldVals[entryIt->first], entryIt->first, entryIt->second);
}
}
Now i can use it like this:
Foo gBar;
void aFunction()
{
int ar;
char ba[3][3];
// Some code where ar and ba are filled
if(gBar.isChanged(ar))
// Do Something
if(gBar.isChanged(ba))
// Do Something
gBar.endCycle();
}
Is this an efficient way? My goal was a method which is very easy to use inside various cyclically called functions. I cleaned all the init and free logic from the code. Any suggestions? I especially don't like the oldshool malloc, memcpy and memcmp stuff but i don't know any other way how to do it.
Edit: Found a good solution based on Red Alerts suggestions.
I think you can use templates a little more effectively here.
This way you get one
map
per type, and you don't have to worry about inadvertently messing up an alias. You do need to defineoperator !=
and have a working copy constructor for your types, but that is much better than blindly usingmemcmp
andmemcpy
.You can also make further template specializations for arrays if you need to compare those (will be a bit more code, but nothing very complicated)
Edit: To get you started, this is what your template signature should look like:
Or you can use char* to alias all of your values. This will let you use a single map for everything (like you were doing before, but this has no
memcpy
/memcmp
). It will only work for POD. We could manually call the destructor when overwriting the buffer, but since there is no good way to do this in the class's destructor, it's probably best to leave out heap allocated data altogether.