Generating permutation of indices from seed ID In my OpenCL kernel, I have the following logic:

size_t id = get_global_id(0);
uchar index0 = (id / 32760) % 16;
uchar index1 = (id / 2184) % 15;
uchar index2 = (id / 156) % 14;
uchar index3 = (id / 12) % 13;
uchar index4 = (id / 1) % 12;



if (index1 &gt;= index0) 
    ++index1;


if(index2 &gt;= index0 || 
   index2 &gt;= index1) 
    ++index2; 
if(index2 &gt;= index1 &amp;&amp; index2 &gt;= index0) 
    ++index2;


if(index3 &gt;= index0 || 
   index3 &gt;= index1 || 
   index3 &gt;= index2) 
    ++index3;
if(index3 &gt;= index0 &amp;&amp; index3 &gt;= index1 || 
   index3 &gt;= index1 &amp;&amp; index3 &gt;= index2 || 
   index3 &gt;= index2 &amp;&amp; index3 &gt;= index0) 
    ++index3;
if(index3 &gt;= index0 &amp;&amp; index3 &gt;= index1 &amp;&amp; index3 &gt;= index2) 
    ++index3;


if(index4 &gt;= index0 || 
   index4 &gt;= index1 || 
   index4 &gt;= index2 || 
   index4 &gt;= index3) 
    ++index4;
if(index4 &gt;= index0 &amp;&amp; index4 &gt;= index1 || 
   index4 &gt;= index0 &amp;&amp; index4 &gt;= index2 || 
   index4 &gt;= index0 &amp;&amp; index4 &gt;= index3 || 
   index4 &gt;= index1 &amp;&amp; index4 &gt;= index2 || 
   index4 &gt;= index1 &amp;&amp; index4 &gt;= index3 || 
   index4 &gt;= index2 &amp;&amp; index4 &gt;= index3) 
    ++index4;
if(index4 &gt;= index0 &amp;&amp; index4 &gt;= index1 &amp;&amp; index4 &gt;= index2 || 
   index4 &gt;= index1 &amp;&amp; index4 &gt;= index2 &amp;&amp; index4 &gt;= index3 || 
   index4 &gt;= index2 &amp;&amp; index4 &gt;= index3 &amp;&amp; index4 &gt;= index0 || 
   index4 &gt;= index3 &amp;&amp; index4 &gt;= index0 &amp;&amp; index4 &gt;= index1) 
    ++index4;
if(index4 &gt;= index0 &amp;&amp; index4 &gt;= index1 &amp;&amp; index4 &gt;= index2 &amp;&amp; index4 &gt;= index3) 
    ++index4;


Now, in my testing, I've verified that this logic is correct and applies correct behavior to my variables. However, it is extremely cumbersome to read and maintain, and I'm looking for a way to optimize it such that it's much easier to read and understand. How can I rewrite this logic so that it's much easier to read, and possibly faster to execute?

The intent of this code is to take an input integer in the range [0, 16*15*14*13*12), and convert it into a permutation of 5 unique indices ranged [0,16). Like I said, this code works, but it's very confusing to read.

There are a few restrictions:


No Recursion. I'm aware that most OpenCL compilers will allow limited degrees of recursion by in-lining away recursive function calls, but I want this code to be as portable as possible, and that means adhering to the specifications set by the Official OpenCL spec.
Readability is more important than speed. Obviously, getting the algorithm faster would be ideal, but what I really care about is making this code less cumbersome to maintain, particularly if I expand it to add more variables to this algorithm.
I have limited access to OOP related functionality. This is OpenCL, so anything object-oriented needs to be compatible with OpenCL 2.0.
Use your words

Let's start with what you're actually accomplishing in all those if statements. It looks like what you're doing is incrementing each index by the number of smaller indices, for each possible such count. 

That translates itself naturally to using arrays:

uchar index[5] = {(id / 32760) % 16,
                  (id / 2184) % 15,
                  (id / 156) % 14,
                  (id / 12) % 13,
                  (id / 1) % 12};


And writing that idea as a loop:

// for each index
for (int i=1; i&lt;5; ++i) {
    // for each possible count of smaller indices
    for (int cnt=1; cnt&lt;=i; ++cnt) {
       // count the number of smaller indices
       int k=0;
       for (int j=0; j&lt;i; ++j) {
           k += (index[i] &gt;= index[j]);
       }

       // and increment if necessary
       if (k &gt;= cnt) {
           ++index[i];
       }
    }
}


This can be translated into the sort-of-more/sort-of-less readable (YMMV) C++11 version:

for (int&amp; i : index) {
    for (int cnt=1; cnt &lt;= std::distance(index, &amp;i); ++cnt) {
        i += std::count_if(index, &amp;i, [i](int j){return i &gt;= j; }) &gt;= cnt;
    }
}