#if !defined  HAVE_RULER_FUNC_H__
#define       HAVE_RULER_FUNC_H__

#include "fxttypes.h"


// If defined, an array is used instead of a pointer, this gives no speedup:
#define RULER_FUNC_MAX_ARRAY_LEN 64  // default off (slowdown!)

class ruler_func
// Ruler function sequence: 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 4 0 1 0 2 0 1 ...
// Loopless algorithm (specialization of Knuth's method for mixed radix Gray code).
{
public:
#ifndef RULER_FUNC_MAX_ARRAY_LEN
    ulong *f_;  // focus pointer
#else
    ulong f_[RULER_FUNC_MAX_ARRAY_LEN+2];
#endif
    ulong n_;

public:
    ruler_func(ulong n)
    {
#ifndef RULER_FUNC_MAX_ARRAY_LEN
        n_ = n;
        f_ = new ulong[n+2];
#else
        n_ = RULER_FUNC_MAX_ARRAY_LEN;
        n_ += (n ^ n); // avoid warning about unused variable n
#endif
        first();
    }

    ~ruler_func()
    {
#ifndef RULER_FUNC_MAX_ARRAY_LEN
        delete [] f_;
#endif
    }

    void first()  { for (ulong k=0; k<n_+2; ++k)  f_[k] = k; }

    ulong next()
    {
        const ulong j = f_[0];
//        if ( j==n_ )  { first(); return n_; }  // leave to user
        f_[0] = 0;
        const ulong j1 = j+1;
        f_[j] = f_[j1];
        f_[j1] = j1;
        return j;
    }
};
// -------------------------

//#undef RULER_FUNC_MAX_ARRAY_LEN  // better leave in


#endif  // !defined HAVE_RULER_FUNC_H__
