多重ループのループ変数を外で使う

何のことかと思うかもしれないが今仕事で必要になった(’’ 案外難しかった。

普通、ループを回したい時は以下のようになるだろう。

for( int z = 0; z < sizeZ; ++z ){
	for( int y = 0; y < sizeY; ++y ){
		for( int x = 0; x < sizeX; ++x ){
			Funct( z, y, x );
		}
	}
}

しかしとある事情により、Functをループの中に入れるのが無理な状況がでてきて、ループ変数を随時返すような関数の実装が必要になった。具体的には以下のような状況である。

int z(0), y(0), x(0);
do{
	Funct( z, y, x );
}while( Loop3( z, y, x ) );

なんで後評価なんだとか言われそうだがただ単にstd::next_permutationっぽくしたかっただけ(ぇー んで、このLoop3をどう実装すれば言いかというのが問題である。
あんまり粘れないで申し訳ないが答えは以下の通り

bool Loop3( int& z, int& y, int& x )
{
	++x;
	if( !( x < sizeX ) ){
		++y;
		if( !( y < sizeY ) ){
			++z;
			if( !( z < sizeZ ) ){
				return false;
			}
			y = 0;
		}
		x = 0;
	}
	return true;
}

試してみればわかるが同じ結果が返るはず。これ見つけるの、結構苦労しました(’’ まだまだですな・・。

んで、ただ単にループ変数を返すだけなら計算で出せてしまう。

bool Loop3( int& z, int& y, int& x )
{
	static t = 0;
	++t;
	x = t % sizeX;
	y = ( t / sizeX ) % sizeY;
	z = ( ( t / sizeX ) / sizeY ) % sizeZ;
	return true;
}

しかしこれ、ループ条件がその前のループ変数に依存する場合、激烈に難しくなる・・・ていうか無理。

for( int z = minZ; z < maxZ; ++z ){
	for( int y = minY( z ); y < max( z ); ++y ){
		for( int x = minX( z,y ); x < maxX( z,y ); ++x ){
			Funct( z, y, x );
		}
	}
}

だけれども、最初の方法だったらあんまり変更なく出来ちゃいます。

bool Loop3( int& z, int& y, int& x )
{
	++x;
	if( !( x < maxX(z,y) ) ){
		++y;
		if( !( y < maxY(z) ) ){
			++z;
			if( !( z < maxZ ) ){
				return false;
			}
			y = minY(z);
		}
		x = minX(z,y);
	}
	return true;
}

int z(minZ), y(minY(z)), x(minX(z,y));
do{
	Funct( z, y, x );
}while( Loop3( z, y, x ) );

というわけで漸く仕事が進みそうです。疲れたorz