Reputation: 10931
I have a class which represents a special file format. It stores discretized data of a 3D space. I want to print the data on the screen. But the problem is, I have to print the data in the given arbitrary order.
My class is something like this:
class MyFile
{
public:
// ...
enum SEQUENCE
{
SEQ_I = 200,
SEQ_J = 201,
SEQ_K = 202
};
enum INCREMENT
{
PLUS = 300,
MINUS = 301
};
double GetVariable(uint64_t i, uint64_t j, uint64_t k) const;
std::vector<SEQUENCE> Sequences;
std::vector<INCREMENT> Increments;
friend std::ostream & operator<<(std::ostream & os, const MyFile & mf);
// ...
private:
// ...
std::vector<double> Data;
// ...
}
I use it like this:
MyFile myfile;
// ...
// Load some data to "myfile".
// ...
myfile.Sequences.push_back(MyFile::SEQUENCE::SEQ_J);
myfile.Sequences.push_back(MyFile::SEQUENCE::SEQ_I);
myfile.Sequences.push_back(MyFile::SEQUENCE::SEQ_K);
myfile.Increments.push_back(MyFile::INCREMENT::MINUS);
myfile.Increments.push_back(MyFile::INCREMENT::MINUS);
myfile.Increments.push_back(MyFile::INCREMENT::PLUS);
std::cout << myfile;
And the mentioned for loop is in this method:
std::ostream & operator<<(std::ostream & os, const MyFile & mf)
{
// The loop variables.
uint64_t InnerMin = 0;
uint64_t MiddlMin = 0; // I spelled it "middl" to make
uint64_t OuterMin = 0; // the all variable names same length.
uint64_t InnerMax = 0;
uint64_t MiddlMax = 0;
uint64_t OuterMax = 0;
uint64_t InnerIndex = 0;
uint64_t MiddlIndex = 0;
uint64_t OuterIndex = 0;
uint64_t *i = &InnerIndex;
uint64_t *j = &MiddlIndex;
uint64_t *k = &OuterIndex;
int8_t InnerIncrement = +1;
int8_t MiddlIncrement = +1;
int8_t OuterIncrement = +1;
// Find out the variable of the out-most loop.
switch (mf.Sequences[0])
{
default:
case MyFile::SEQUENCE::SEQ_I:
i = &OuterIndex;
OuterMin = mf.IndexIMin;
OuterMax = mf.IndexIMax;
break;
case MyFile::SEQUENCE::SEQ_J:
j = &OuterIndex;
OuterMin = mf.IndexJMin;
OuterMax = mf.IndexJMax;
break;
case MyFile::SEQUENCE::SEQ_K:
k = &OuterIndex;
OuterMin = mf.IndexKMin;
OuterMax = mf.IndexKMax;
break;
}
break;
switch (mf.Increments[0])
{
case MyFile::INCREMENT::PLUS:
OuterIncrement = +1;
break;
case MyFile::INCREMENT::MINUS:
OuterIncrement = -1;
break;
}
break;
// The middle loop.
switch (mf.Sequences[1])
{
case MyFile::SEQUENCE::SEQ_I:
i = &MiddlIndex;
MiddlMin = mf.IndexIMin;
MiddlMax = mf.IndexIMax;
break;
default:
case MyFile::SEQUENCE::SEQ_J:
j = &MiddlIndex;
MiddlMin = mf.IndexJMin;
MiddlMax = mf.IndexJMax;
break;
case MyFile::SEQUENCE::SEQ_K:
k = &MiddlIndex;
MiddlMin = mf.IndexKMin;
MiddlMax = mf.IndexKMax;
break;
}
break;
switch (mf.Increments[1])
{
case MyFile::INCREMENT::PLUS:
MiddlIncrement = +1;
break;
case MyFile::INCREMENT::MINUS:
MiddlIncrement = -1;
break;
}
// The inner loop.
switch (mf.Sequences[2])
{
case MyFile::SEQUENCE::SEQ_I:
i = &InnerIndex;
InnerMin = mf.IndexIMin;
InnerMax = mf.IndexIMax;
break;
case MyFile::SEQUENCE::SEQ_J:
j = &InnerIndex;
InnerMin = mf.IndexJMin;
InnerMax = mf.IndexJMax;
break;
default:
case MyFile::SEQUENCE::SEQ_K:
k = &InnerIndex;
InnerMin = mf.IndexKMin;
InnerMax = mf.IndexKMax;
break;
}
break;
switch (mf.Increments[2]) // The third (inner) increment.
{
case MyFile::INCREMENT::PLUS:
InnerIncrement = +1;
break;
case MyFile::INCREMENT::MINUS:
InnerIncrement = -1;
break;
}
// Run the loop.
for (uint64_t OuterIndex=OuterMin; OuterIndex<=OuterMax; OuterIndex += OuterIncrement)
{
for (uint64_t MiddlIndex=MiddlMin; MiddlIndex<=MiddlMax; MiddlIndex += MiddlIncrement)
{
for (uint64_t InnerIndex=InnerMin; InnerIndex<=InnerMax; InnerIndex += InnerIncrement)
{
os << GetVariable(*i, *j, *k) << "\t";
}
}
os << std::endl;
}
return os;
}
Is this the correct way of manipulating the loop order? I find the way I implemented is too long and complex. Is there a better way of doing this?
Upvotes: 0
Views: 94
Reputation: 12413
The easiest way to improve your code would be to create a helper function getNextCoordinate
that takes a tuple (triple) of coordinates and order, returning next tuple in given order. Plus function getInitialCoordinates
that gives initial coordinates for given order.
Upvotes: 1