#if !defined HAVE_BITCYCLIC_MATCH_H__
#define      HAVE_BITCYCLIC_MATCH_H__


#include "fxttypes.h"
#include "bits/bitsperlong.h"
#include "bits/bitrotate.h"
#include "bits/bit2pow.h"  // one_bit_q()


static inline ulong bit_cyclic_match(ulong x, ulong y)
// Return  r if x==rotate_right(y, r) else return ~0UL.
// In other words: return
//   how often the right arg must be rotated right (to match the left)
// or, equivalently:
//   how often the left arg must be rotated left (to match the right)
{
    ulong r = 0;
    do
    {
        if ( x==y )  return r;
        y = bit_rotate_right(y, 1);
    }
    while ( ++r < BITS_PER_LONG );

    return ~0UL;
}
// -------------------------

static inline ulong bit_cyclic_match(ulong x, ulong y, ulong ldn)
// Return  r if x==rotate_right(y, r, ldn) else return ~0UL
//  (using ldn-bit words)
{
    ulong r = 0;
    do
    {
        if ( x==y )  return r;
        y = bit_rotate_right(y, 1, ldn);
    }
    while ( ++r < ldn );

    return ~0UL;
}
// -------------------------


static inline ulong bit_cyclic_dist1_match(ulong x, ulong y)
// Return  the minimal r so that
//   c = (x ^ rotate_right(y, r, ldn)) is a one-bit word.
// Return ~0UL if there is no such r.
{
    ulong r = 0;
    do
    {
        ulong c = x^y;
        if ( one_bit_q(c) )  return r;
        y = bit_rotate_right(y, 1);
    }
    while ( ++r < BITS_PER_LONG );

    return ~0UL;
}
// -------------------------

static inline ulong bit_cyclic_dist1_match(ulong x, ulong y, ulong ldn)
// Return  the minimal r so that
//   c = (x ^ rotate_right(y, r, ldn)) is a one-bit word.
// Return ~0UL if there is no such r.
//  (using ldn-bit words)
{
    ulong r = 0;
    do
    {
        ulong c = x^y;
        if ( one_bit_q(c) )  return r;
        y = bit_rotate_right(y, 1, ldn);  // could used optimized version
    }
    while ( ++r < ldn );

    return ~0UL;
}
// -------------------------


#endif  // !defined HAVE_BITCYCLIC_MATCH_H__
