//
//! \file  libecc/bitset.h
//! \brief Fixed size bitset implementation.
//!
//! This header file declares <code>template<unsigned int n> class libecc::bitset</code> for a fixed number of \a n bits.
//
// This file is part of the libecc package.
// Copyright (C) 2002, by
//
// Carlo Wood, Run on IRC <carlo@alinoe.com>
// RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
// Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#ifndef LIBECC_BITS_H
#define LIBECC_BITS_H

#ifndef LIBECC_DEBUG_H
#error "You need to include the appropriate debug.h in the source file, before including this header file."
#endif

#include <libecc/config.h>
#include <iosfwd>
#include <cstddef>
#include <cstring>
#include <string>
#include <inttypes.h>

namespace libecc {

// Forward declaration.
template<unsigned int n, bool inverted>
  class bitset_invertible;

/**\typedef unsigned int bitset_digit_t
 *
 * \brief Internal data type, used to store the bits of class bitset.
 *
 * The number of bits in the builtin-type \c int will be equal to the size of the cpu's databus.
 * The internal type used to store the bits of a bitset is therefore an
 * <code>unsigned int</code> resulting in the most efficient code for bit manipulation.
 */
typedef	unsigned int bitset_digit_t;

/**\class bitset_base bitset.h libecc/bitset.h
 *
 * \brief Base class of libecc::bitset.
 *
 * This class is for internal use only.
 * It contains the actual data, an array of \link libecc::bitset_digit_t bitset_digit_t \endlink,
 * the meaning of which is determined by the derived classes;
 * direct access of the data is therefore useless and prohibited (\link bitset_base::vector vector \endlink is protected).
 */
template<unsigned int n>
  struct bitset_base {
    public:
      //! \brief The number of bits in the bitset.
      //!
      //! This constant is simply equal to \a n.
      static unsigned int const number_of_bits = n;

      //! The number of bits in a single digit.&nbsp; See also \link libecc::bitset_digit_t bitset_digit_t \endlink.
      static unsigned int const digit_bits = sizeof(bitset_digit_t) * 8;

      //! The minimum number of digits needed to store \a n bits.
      static unsigned int const digits = (n - 1) / digit_bits + 1;

      // ! The number of valid bits in the most significant digit.
      static unsigned int const number_of_valid_bits = digit_bits - (digits * digit_bits - n);

      //! A mask marking the valid bits in the most significant digit.
      static bitset_digit_t const valid_bits =
	  ((static_cast<bitset_digit_t>(1) << (number_of_valid_bits - 1)) << 1) - 1;

      //! True when not all bits in the most significant digit are valid.
      static bool const has_excess_bits = ((digits * digit_bits) != n);

    protected:
      //! \brief The actual bits, stored as an array of \link bitset::digits digits \endlink
      //! number of "digits" of type libecc::bitset_digit_t.
      //!
      //! The first digit is the <em>least significant</em> digit: printing is done from high index to low index.
      //! The bits in the array can represent the actual bits or the inverted bits of the bitset, depending on
      //! the type of the derived class.
      bitset_digit_t vector[digits];

      template<unsigned int n1, bool i1, unsigned int n2, bool i2>
	friend bool operator==(bitset_invertible<n1, i1> const&, bitset_invertible<n2, i2> const&);
  };

#ifndef HIDE_FROM_DOXYGEN
namespace Operator {

// Functors.

// Functor for '='.
struct bitsetAssign {
  static bool const sets_excess_bits = true;
  static bool const with_zero_sets_zero = true;
  static bool const with_ones_sets_ones = true;
  static bool const with_ones_inverts = false;
  static inline void exec(bitset_digit_t& out, bitset_digit_t in) { out = in; }
};

// Functor for '&='.
struct bitsetANDAssign {
  static bool const sets_excess_bits = false;
  static bool const with_zero_sets_zero = true;
  static bool const with_ones_sets_ones = false;
  static bool const with_ones_inverts = false;
  static inline void exec(bitset_digit_t& out, bitset_digit_t in) { out &= in; }
};

// Functor for '|='.
struct bitsetORAssign {
  static bool const sets_excess_bits = true;
  static bool const with_zero_sets_zero = false;
  static bool const with_ones_sets_ones = true;
  static bool const with_ones_inverts = false;
  static inline void exec(bitset_digit_t& out, bitset_digit_t in) { out |= in; }
};

// Functor for '^='.
struct bitsetXORAssign {
  static bool const sets_excess_bits = true;
  static bool const with_zero_sets_zero = false;
  static bool const with_ones_sets_ones = false;
  static bool const with_ones_inverts = true;
  static inline void exec(bitset_digit_t& out, bitset_digit_t in) { out ^= in; }
};

// Functor for '&'.
struct bitsetAND {
  static inline bitset_digit_t exec(bitset_digit_t digit1, bitset_digit_t digit2) { return digit1 & digit2; }
};

// Functor for '|'.
struct bitsetOR {
  static inline bitset_digit_t exec(bitset_digit_t digit1, bitset_digit_t digit2) { return digit1 | digit2; }
};

// Functor for '^'.
struct bitsetXOR {
  static inline bitset_digit_t exec(bitset_digit_t digit1, bitset_digit_t digit2) { return digit1 ^ digit2; }
};

template<unsigned int n, bool inverted1, bool inverted2, typename OP>
  struct expression
  {
    bitset_invertible<n, inverted1> const& first;
    bitset_invertible<n, inverted2> const& second;
    OP op;
    expression(bitset_invertible<n, inverted1> const& arg1, bitset_invertible<n, inverted2> const& arg2) : first(arg1), second(arg2) { }
  };

} // namespace Operator
#endif // HIDE_FROM_DOXYGEN

/**\class bitset_invertible bitset.h libecc/bitset.h
 *
 * \brief A bitset with a fixed number of bits, having possibly an infinite number of leading virtual 1's.
 *
 * When dealing with expressions, short bitsets are assumed to have leading zeros.
 * This class however can represent an 'inverted' bitset, meaning that it has an
 * infinite number of leading ones.
 *
 * The use of this class should be restricted to (optimized out) temporaries in expressions
 * like <code>a = ~b;</code> or <code>a |= b & ~c</code>.  The user should
 * not use this class directly.
 *
 * \see libecc::operator~(bitset_invertible<n, inverted> const& bits)
 *
 * \param n The number of bits in the bitset.
 * \param inverted True when each internal bit has the opposite meaning.
 */
template<unsigned int n, bool inverted>
  class bitset_invertible : public bitset_base<n> {
    public:
      // Constructors
      bitset_invertible(void);
      template<typename Expression>
	explicit bitset_invertible<n, inverted>(Expression const&);

    protected:
      template<typename OP, unsigned int x, bool invertedx>
	void assign(bitset_invertible<x, invertedx> const&, OP);
      template<typename OP1, unsigned int x, bool inverted1, bool inverted2, typename OP2>
	void assign(Operator::expression<x, inverted1, inverted2, OP2> const&, OP1);

    private:
      template<unsigned int m, bool i>
	friend class bitset_invertible;
      bitset_digit_t digit(unsigned int d) const { return inverted ? ~(vector[d]) : vector[d]; }
  };

// Default constructor.
template<unsigned int n, bool inverted>
  inline
  bitset_invertible<n, inverted>::bitset_invertible(void)
  {
    if (has_excess_bits)
      vector[digits - 1] = 0; 			// Reset the excess bits!
  }

// Copy constructor.
template<unsigned int n, bool inverted>
  template<typename Expression>
    inline
    bitset_invertible<n, inverted>::bitset_invertible(Expression const& expr)
    {
      this->assign(expr, Operator::bitsetAssign());
    }

//
// Assignment function.
// This function handles:
//
// a = b;
// a = ~b;
// a &= b;
// a &= ~b;
// a |= b;
// a |= ~b;
// a ^= b;
// a ^= ~b;
//
// ASSIGNMENT_OPERATOR is one of bitsetAssign, bitsetANDAssign, bitsetORAssign or bitsetXORAssign.
//
template<unsigned int n, bool inverted>
  template<typename ASSIGNMENT_OPERATOR, unsigned int x, bool inverted_argument>
    inline void
    bitset_invertible<n, inverted>::assign(bitset_invertible<x, inverted_argument> const& bits, ASSIGNMENT_OPERATOR)
    {
      // Handle excess digits.
      if (digits > bitset_base<x>::digits)
      {
	if (!inverted_argument)
	{
	  // Fill excess digits with 0's when needed.
	  if (ASSIGNMENT_OPERATOR::with_zero_sets_zero)
	  {
            unsigned int count = digits - bitset_base<x>::digits;
	    do { vector[count + bitset_base<x>::digits - 1] = 0; } while (--count);
	  }
	}
	else
	{
	  // Fill excess digits with 1's when needed.
	  if (ASSIGNMENT_OPERATOR::with_ones_sets_ones)
	  {
	    vector[digits - 1] = valid_bits;
            unsigned int count = digits - bitset_base<x>::digits;
	    while(--count) { vector[count + bitset_base<x>::digits - 1] = ~static_cast<bitset_digit_t>(0); }
	  }
	  // Or invert them.
	  if (ASSIGNMENT_OPERATOR::with_ones_inverts)
	  {
	    vector[digits - 1] ^= valid_bits;
            unsigned int count = digits - bitset_base<x>::digits;
	    while(--count) { vector[count + bitset_base<x>::digits - 1] ^= ~static_cast<bitset_digit_t>(0); }
	  }
	}
      }

      // Handle other digits.
      unsigned int d;
      if (digits < bitset_base<x>::digits)
	d = digits - 1;
      else
	d = bitset_base<x>::digits - 1;
      ASSIGNMENT_OPERATOR::exec(vector[d], bits.digit(d));
      while(d) { --d; ASSIGNMENT_OPERATOR::exec(vector[d], bits.digit(d)); }

      // Reset excess bits if needed.
      if (((!inverted_argument && x > n) ||
	    (inverted_argument && digits <= bitset_base<x>::digits)) &&
	  has_excess_bits && ASSIGNMENT_OPERATOR::sets_excess_bits)
        vector[digits - 1] &= valid_bits;
    }

//
// Assignment function for expressions.
// This function handles:
//
// a = b & c;
// a = b & ~c;
// a = ~b & c;
// a = ~b & ~b;
// a = b | c;
// a = b | ~c;
// a = ~b | c;
// a = ~b | ~b;
// a = b ^ c;
// a = b ^ ~c;
// a = ~b ^ c;
// a = ~b ^ ~b;
// a &= b & c;
// a &= b & ~c;
// a &= ~b & c;
// a &= ~b & ~b;
// a &= b | c;
// a &= b | ~c;
// a &= ~b | c;
// a &= ~b | ~b;
// a &= b ^ c;
// a &= b ^ ~c;
// a &= ~b ^ c;
// a &= ~b ^ ~b;
// a |= b & c;
// a |= b & ~c;
// a |= ~b & c;
// a |= ~b & ~b;
// a |= b | c;
// a |= b | ~c;
// a |= ~b | c;
// a |= ~b | ~b;
// a |= b ^ c;
// a |= b ^ ~c;
// a |= ~b ^ c;
// a |= ~b ^ ~b;
// a ^= b & c;
// a ^= b & ~c;
// a ^= ~b & c;
// a ^= ~b & ~b;
// a ^= b | c;
// a ^= b | ~c;
// a ^= ~b | c;
// a ^= ~b | ~b;
// a ^= b ^ c;
// a ^= b ^ ~c;
// a ^= ~b ^ c;
// a ^= ~b ^ ~b;
//
// ASSIGNMENT_OPERATOR is one of bitsetAssign, bitsetANDAssign, bitsetORAssign or bitsetXORAssign.
// OPERATOR is one of bitsetAND, bitsetOR or bitsetXOR.
//
template<unsigned int n, bool inverted>
  template<typename ASSIGNMENT_OPERATOR, unsigned int x, bool inverted1, bool inverted2, typename OPERATOR>
    inline void
    bitset_invertible<n, inverted>::assign(Operator::expression<x, inverted1, inverted2, OPERATOR> const& expr, ASSIGNMENT_OPERATOR)
    {
      static bool const argument_has_leading_ones = OPERATOR::exec(inverted1, inverted2);

      // Handle excess digits.
      if (digits > bitset_base<x>::digits)
      {
	if (!argument_has_leading_ones)
	{
	  // Fill excess digits with 0's when needed.
	  if (ASSIGNMENT_OPERATOR::with_zero_sets_zero)
	  {
            unsigned int count = digits - bitset_base<x>::digits;
	    do { vector[count + bitset_base<x>::digits - 1] = 0; } while (--count);
	  }
	}
	else
	{
	  // Fill excess digits with 1's when needed.
	  if (ASSIGNMENT_OPERATOR::with_ones_sets_ones)
	  {
	    vector[digits - 1] = valid_bits;
            unsigned int count = digits - bitset_base<x>::digits;
	    while(--count) { vector[count + bitset_base<x>::digits - 1] = ~static_cast<bitset_digit_t>(0); }
	  }
	  if (ASSIGNMENT_OPERATOR::with_ones_inverts)
	  {
	    vector[digits - 1] ^= valid_bits;
            unsigned int count = digits - bitset_base<x>::digits;
	    while(--count) { vector[count + bitset_base<x>::digits - 1] ^= ~static_cast<bitset_digit_t>(0); }
	  }
	}
      }

      // Handle other digits.
      unsigned int d;
      if (digits < bitset_base<x>::digits)
	d = digits - 1;
      else
	d = bitset_base<x>::digits - 1;
      ASSIGNMENT_OPERATOR::exec(vector[d], OPERATOR::exec(expr.first.digit(d), expr.second.digit(d)));
      while(d) { --d; ASSIGNMENT_OPERATOR::exec(vector[d], OPERATOR::exec(expr.first.digit(d), expr.second.digit(d))); }

      // Reset excess bits if needed.
      if (((!argument_has_leading_ones && x > n) ||
	    (argument_has_leading_ones && digits <= bitset_base<x>::digits)) &&
	  has_excess_bits && ASSIGNMENT_OPERATOR::sets_excess_bits)
        vector[digits - 1] &= valid_bits;
    }

/** \brief Invert a bitset.
 *
 * This operator is just a cast and doesn't actually do anything
 * until you assign the expression that it is part of to another bitset.
 *
 * For example:
 *
 * \code
 * x = ~y;
 * x ^= ~y & ~z;
 * \endcode
 *
 * Both cases will run over the digits of bitset x just once
 * and apply the given formula (and any like it) directly on
 * the digits of the bitsets involved.
 *
 * Inversion can also be used together with the equivalence
 * operators.  For example:
 *
 * \code
 * if (x == ~y) ...
 * \endcode
 *
 * will only run once over the digits of both bitset and compare
 * the digits once by one using <code>x.digit(d) == ~y.digit(d)</code>.
 */
template<unsigned int n, bool inverted>
  inline bitset_invertible<n, !inverted> const&
  operator~(bitset_invertible<n, inverted> const& bits)
  {
    return *reinterpret_cast<bitset_invertible<n, !inverted> const*>(&bits);
  }

/**\class bitset bitset.h libecc/bitset.h
 *
 * \brief A bitset with a fixed number of bits.
 *
 * \param n The number of bits in the bitset.
 */
template<unsigned int n>
  class bitset : public bitset_invertible<n, false> {
    public:
      // Constructors.
      bitset(void);
      bitset(std::string const&);
      // This definition must be here, inside the template class declaration because
      // otherwise the compiler (2.95 - 3.1) barfs.
      /**
       * \brief Construct a bitset directly from an array of \ref bitset_digit_t.
       *
       * The excess bits of the most significant digit (if any) must be zero.
       */
      bitset(bitset_digit_t const (&v)[bitset_base<n>::digits])
      {
#if ECC_DEBUG
	LIBCWD_ASSERT( (v[digits - 1] & ~valid_bits) == 0 );
#endif
	memcpy(vector, v, sizeof(vector));
      }

      // Copy constructors.
      template<unsigned int m, bool inverted>
	bitset(bitset_invertible<m, inverted> const&);
      template<unsigned int m, bool i1, bool i2, typename OP>
	bitset(Operator::expression<m, i1, i2, OP> const& expr);

      // Assignment operator.
      template<typename Expression>
	bitset& operator=(Expression const&);

      // Perform AND, OR, XOR operations
      template<typename Expression>
	bitset& operator&=(Expression const&);
      template<typename Expression>
	bitset& operator|=(Expression const&);
      template<typename Expression>
	bitset& operator^=(Expression const&);

    public:
      // Shift bitset left or right and perform operation with result.
      template<unsigned int shift, class DIRECTION, class OPERATION>
	void shift_op(bitset& result) const;

      // Rotate left or right
      template<unsigned int shift, class DIRECTION>			// Return a copy rotated `shift' bits in `DIRECTION'.
	void rotate(bitset& result) const;

      // Single bit operations
      bool test(size_t n) const;					// Return true if bit `n' is set.
      bool odd(void) const;						// Return true if the vector has an odd number of bits set.
      void set(size_t n);						// Set bit `n'.
      void clear(size_t n);						// Clear bit `n'.
      void flip(size_t n);						// Toggle bit `n'.

      // Single bit operations at a constant position
      template<unsigned int pos>
	bool test(void) const;						// Return true if bit `pos' is set.
      template<unsigned int pos>
	void set(void);							// Set bit `pos'.
      template<unsigned int pos>
	void clear(void);						// Clear bit `pos'.
      template<unsigned int pos>
	void flip(void);						// Toggle bit `pos'.
      template<unsigned int pos>
	void digitset(unsigned int d, bool value);			// Set bit `pos' of digit `d' to `value'.

      // Other functions
      bitset& reset(void);
      void setall(void);
      bool any(void) const;

      // Digit representation
      bitset_digit_t digit(unsigned int d) const { return vector[d]; }
      bitset_digit_t& digit(unsigned int d) { return vector[d]; }
      bitset_digit_t const* digits_ptr(void) const { return vector; }
      uint32_t digit32(unsigned int d32) const
      {
	if (sizeof(bitset_digit_t) == 4)
	  return vector[d32];
	else
	{
	  unsigned int d = d32 / (sizeof(bitset_digit_t) / 4);
	  unsigned int r = d32 % (sizeof(bitset_digit_t) / 4);
	  return (vector[d] >> (r * 32)) & 0xffffffff;
	}
      }
  };

/**
 * \brief Construct an uninitialized bitset of \a n bits.
 */
template<unsigned int n>
  inline
  bitset<n>::bitset(void)
  {
  }

/**
 * \brief Set all bits to 1.
 */
template<unsigned int n>
  void
  bitset<n>::setall(void)
  {
    vector[digits - 1] = valid_bits;
    if (digits > 1)
    {
      int d = digits - 2;
      do { vector[d] = ~static_cast<bitset_digit_t>(0); } while(--d >= 0);
    }
  }

/**
 * \brief Assignment operator.
 *
 * The least significant bits (at position 0) of \a expr and this bitset are lined up.
 * If \a expr is wider than this bitset then excess bits are lost;
 * if narrower then missing bits are set to zero or one depending on whether the
 * expression contains inversion bits.
 *
 * For example, when x is "0000000010001111" (16 bits), y is "10000000" (8 bits)
 * and z is "11110110" (8 bits), then
 *
 * \code
 * x ^= ~y;
 * \endcode
 *
 * results in x being "1111111111110000".
 * And
 *
 * \code
 * x |= ~y ^ ~z;
 * \endcode
 *
 * results in x being "0000000001110110".
 */
template<unsigned int n>
  template<typename Expression>
    inline bitset<n>& bitset<n>::operator=(Expression const& expr)
    {
      this->assign(expr, Operator::bitsetAssign());
      return *this;
    }

/**
 * \brief Copy constructor.
 *
 * The least significant bit (at position 0) of \a bits and the constructed bitset are lined up.
 * If \a bits is wider than the constructed bitset then excess bits are lost;
 * if narrower then missing bits are set to \a inverted.  That is, set to zero when \a bits
 * is not inverted and set to one when \a bits represents an inverted bitset.
 *
 * For example, when x is "0000000010001111" (16 bits), y is "10000000" (8 bits), then
 *
 * \code
 * x ^= ~y;
 * \endcode
 *
 * results in x being "1111111111110000".
 */
template<unsigned int n>
  template<unsigned int m, bool inverted>
    inline bitset<n>::bitset(bitset_invertible<m, inverted> const& bits) : bitset_invertible<n, false>(bits)
    {
    }

/**
 * \brief Construct a bitset from an expression.
 *
 * \see bitset::operator=
 */
template<unsigned int n>
  template<unsigned int m, bool i1, bool i2, typename OP>
    inline bitset<n>::bitset(Operator::expression<m, i1, i2, OP> const& expr) : bitset_invertible<n, false>(expr)
    {
    }

/**
 * \brief Equivalence operator.
 *
 * This operator can only compare bitsets and inverted bitsets with eachother.
 *
 * For example:
 *
 * \code
 * if (x == ~y) ...
 * \endcode
 */
template<unsigned int n1, bool inverted1, unsigned int n2, bool inverted2>
  bool operator==(bitset_invertible<n1, inverted1> const& bits1, bitset_invertible<n2, inverted2> const& bits2)
  {
    unsigned int d;
    if (bitset_invertible<n1, inverted1>::digits > bitset_invertible<n2, inverted2>::digits)
    {
      d = bitset_base<n1>::digits - 1;
      do
      {
	if (bits1.vector[d] != (inverted1 == inverted2 ? 0 : ~static_cast<bitset_digit_t>(0)))
	  return false;
      }
      while (--d != bitset_base<n2>::digits - 1);
    }
    if (bitset_base<n2>::digits > bitset_base<n1>::digits)
    {
      d = bitset_base<n2>::digits - 1;
      do
      {
	if (bits2.vector[d] != (inverted1 == inverted2 ? 0 : ~static_cast<bitset_digit_t>(0)))
	  return false;
      }
      while (--d != bitset_base<n1>::digits - 1);
    }
    if (bitset_base<n1>::digits > 1 && bitset_base<n2>::digits > 1)
    {
      if (bitset_base<n1>::digits == bitset_base<n2>::digits)
	d = bitset_base<n1>::digits - 1;
      do
      {
	if (inverted1 == inverted2)
	{
	  if (bits1.vector[d] != bits2.vector[d])
	    return false;
	}
	else
	{
	  if (bits1.vector[d] != ~(bits2.vector[d]))
	    return false;
	}
      }
      while(--d != 0);
    }
    if (inverted1 != inverted2)
      return (bits1.vector[0] == ~(bits2.vector[0]));
    return (bits1.vector[0] == bits2.vector[0]);
  }

/**
 * \brief Unequivalence operator.
 *
 * \returns <code>!(expr1 == expr2)</code>
 */
template<typename Expression1, typename Expression2>
  inline bool
  operator!=(Expression1 const& expr1, Expression2 const& expr2)
  {
    return !(expr1 == expr2);
  }

/** \brief Assignment operator with bitwise AND.
 *
 * \see bitset::operator=
 */
template<unsigned int n>
  template<typename Expression>
    inline bitset<n>&
    bitset<n>::operator&=(Expression const& expr)
    {
      this->assign(expr, Operator::bitsetANDAssign());
      return *this;
    }

/** \brief Assignment operator with bitwise OR.
 *
 * \see bitset::operator=
 */
template<unsigned int n>
  template<typename Expression>
    inline bitset<n>&
    bitset<n>::operator|=(Expression const& expr)
    {
      this->assign(expr, Operator::bitsetORAssign());
      return *this;
    }

/** \brief Assignment operator with bitwise XOR.
 *
 * \see bitset::operator=
 */
template<unsigned int n>
  template<typename Expression>
    inline bitset<n>&
    bitset<n>::operator^=(Expression const& expr)
    {
      this->assign(expr, Operator::bitsetXORAssign());
      return *this;
    }

/** \brief Assignment operator with bitwise AND for expressions.
 *
 * \see bitset::operator=
 */
template<unsigned int m, bool inverted1, bool inverted2>
  Operator::expression<m, inverted1, inverted2, Operator::bitsetAND>
  operator&(bitset_invertible<m, inverted1> const& arg1, bitset_invertible<m, inverted2> const& arg2)
    {
      return Operator::expression<m, inverted1, inverted2, Operator::bitsetAND>(arg1, arg2);
    }

/** \brief Assignment operator with bitwise OR for expressions.
 *
 * \see bitset::operator=
 */
template<unsigned int m, bool inverted1, bool inverted2>
  Operator::expression<m, inverted1, inverted2, Operator::bitsetOR>
  operator|(bitset_invertible<m, inverted1> const& arg1, bitset_invertible<m, inverted2> const& arg2)
    {
      return Operator::expression<m, inverted1, inverted2, Operator::bitsetOR>(arg1, arg2);
    }

/** \brief Assignment operator with bitwise XOR for expressions.
 *
 * \see bitset::operator=
 */
template<unsigned int m, bool inverted1, bool inverted2>
  Operator::expression<m, inverted1, inverted2, Operator::bitsetXOR>
  operator^(bitset_invertible<m, inverted1> const& arg1, bitset_invertible<m, inverted2> const& arg2)
    {
      return Operator::expression<m, inverted1, inverted2, Operator::bitsetXOR>(arg1, arg2);
    }

/** \brief Perform a shift operation followed by a bit operation.
 *
 * Shift this object \a shift bits in \a DIRECTION and then
 * perform operation \a OPERATION on \a result with it.
 *
 * \param shift the number of bits to shift this object.
 * \param DIRECTION can be libecc::left or libecc::right.
 * \param OPERATION can be either libecc::assign or libecc::exor.
 * \param result The bitset that is used to XOR with, or to assign to.
 */
template<unsigned int n>
  template<unsigned int shift, class DIRECTION, class OPERATION>
    void
    bitset<n>::shift_op(bitset& result) const
    {
      static unsigned int const digit_shift = shift / digit_bits;
      static unsigned int const bit_shift = shift % digit_bits;

      static unsigned int const zeroed_digits =
	DIRECTION::__left ? ((shift < n) ? digit_shift : digits)
	                  : ((digit_bits - number_of_valid_bits + shift) / digit_bits);

      if (zeroed_digits < digits)
      {
	static unsigned int const complement_shift = (bit_shift == 0) ? 0 : digit_bits - bit_shift;
	static unsigned int const initial_to = DIRECTION::__right ? 0 : digits - 1;
	static unsigned int const initial_from = initial_to + DIRECTION::direction * digit_shift;
	static unsigned int const final_from = DIRECTION::__left ? 0 : digits - 1;

	register bitset_digit_t digit = vector[initial_from];
	if (initial_from != final_from)
	{
	  register bitset_digit_t next_digit;
	  unsigned int to = initial_to;
	  unsigned int from = initial_from + DIRECTION::direction;
	  if (from != final_from)
	    do
	    {
	      next_digit = vector[from];
	      if (bit_shift != 0)
	      {
		DIRECTION::shift(digit, bit_shift);
		digit |= DIRECTION::reverse_shift_copy(next_digit, complement_shift);
	      }
	      OPERATION::op(result.vector[to], digit);
	      digit = next_digit;
	      to += DIRECTION::direction;
	      from += DIRECTION::direction;
	    }
	    while (from != final_from);
	  if (DIRECTION::__left || bit_shift < number_of_valid_bits || bit_shift != 0)
	    next_digit = vector[final_from];
	  if (bit_shift != 0)
	  {
	    DIRECTION::shift(digit, bit_shift);
	    digit |= DIRECTION::reverse_shift_copy(next_digit, complement_shift);
	  }
	  if (DIRECTION::__left || bit_shift < number_of_valid_bits)
	  {
	    OPERATION::op(result.vector[final_from - DIRECTION::direction * (digit_shift + 1)], digit);
	    digit = DIRECTION::shift_copy(next_digit, bit_shift);
	  }
	}
	else
          DIRECTION::shift(digit, bit_shift);
	static bool const have_mixed_digit = shift != 0 && (DIRECTION::__left ? shift : (n - shift)) % digit_bits != 0;
	static unsigned int const last_digit = (DIRECTION::__left ? shift : (n - 1 - shift)) / digit_bits;
	if (have_mixed_digit)
	  OPERATION::mixed_op(result.vector[last_digit], digit);
	else
	  OPERATION::op(result.vector[last_digit], digit);
	if (DIRECTION::__left && has_excess_bits)
	  result.vector[digits - 1] &= valid_bits;
      }
      if (OPERATION::__clear && zeroed_digits > 0)
      {
	static unsigned int const final_to = DIRECTION::__left ? 0 : digits - 1;
	static unsigned int const initial_to = final_to - DIRECTION::direction * (zeroed_digits - 1);
	unsigned int to = initial_to;
	if (to != final_to)
	  do
	  {
	    result.vector[to] = 0;
	    to += DIRECTION::direction;
	  }
	  while(to != final_to);
	result.vector[to] = 0;
      }
    }

/**
 * \brief Construct a bitset of \a n bits and initialize it with the string \a input, a hexadecimal value in ASCII representation.
 *
 * \a Input is a string of alphanumeric characters ([0-9A-F]) not case sensitive.
 * The input string is read right to left. Any non-space character that is not a hexadecimal digit will terminate reading.
 *
 * Spaces will be ignored, allowing one to write for example
 * "<CODE>C20 93B0D12C F78A9001 F6E2841F 0A918FCD</CODE>" instead of
 * the less readable "<CODE>C2093B0D12CF78A9001F6E2841F0A918FCD</CODE>".
 * It is common practise to let each "word" represent an internal digit (32 bits in this example).
 *
 * If the value passed is larger than fits in the bitset then the most significant bits (the left most characters)
 * are ignored as if the value \em did fit and then a bit-wise AND was performed with a bitset of \a n 1's.
 *
 * \param input A hexadecimal value in ASCII representation.
 */
template<unsigned int n>
  bitset<n>::bitset(std::string const& input)
  {
    reset();						// Reset internal digits to zero.
    unsigned int d = 0;					// Current index of internal digit.
    unsigned int u = 0;					// Current bit-shift of input digit relative to internal digit.

    for (std::string::const_reverse_iterator iter = input.rbegin(); iter != input.rend(); ++iter)	// Read right to left.
    {
      bitset_digit_t c = toupper(*iter);		// Get next hexadecimal input character.
      if (c == ' ')					// Skip spaces.
	continue;
      if (c < '0')					// Terminate reading when not a hexadecimal character.
	break;
      if (c <= '9')
	c -= '0';					// Set c to the value that the input character represents.
      else
      {
	if (c > 'F')
	  break;
	if (c >= 'A')
	  c -= ('A' - 10);
	else
	  break;
      }
      vector[d] |= c << u;				// Set internal bits.
      if ((u += 4) == digit_bits)			// Update bit/digit 'pointers'.
      {
	u = 0;
	if (++d == digits)				// Terminate reading when bitset is full.
	  break;
      }
    }
    if (has_excess_bits)
      vector[digits - 1] &= valid_bits;			// Reset possibly set excess bits.
  }

/**
 * \brief Read bitset from istream.
 */
template<unsigned int n>
  std::istream&
  operator>>(std::istream& is, bitset<n>& bitsetx)
  {
    std::string tmp;
    is >> tmp;
    bitsetx.bitset(tmp);
    return is;
  }

/**
 * \brief Write bitset to ostream.
 */
template<unsigned int n>
  std::ostream&
  operator<<(std::ostream& os, bitset<n> const& bits)
  {
#if 0
    // Binary representation
    for (int d = bitset<n>::digits - 1; d >= 0; --d)
      for (bitset_digit_t mask = (~static_cast<bitset_digit_t>(0) >> 1) + 1; mask != 0; mask >>= 1)
	if (d != bitset<n>::digits - 1 || (mask & bitset<n>::valid_bits))
	  if (bits.digit(d) & mask)
	    os << '1';
	  else
	    os << '0';
#else
    // Hexadecimal representation
    os.fill('0');
    os << std::hex;
    for (int d = bitset<n>::digits - 1; d >= 0; --d)
    {
      os.width((d == bitset<n>::digits - 1 && bitset<n>::has_excess_bits) ?
          (((n % bitset<n>::digit_bits) - 1) / 4 + 1) :
	  (bitset<n>::digit_bits / 4));
      os << bits.digit(d);
      if (d > 0)
	os << ' ';
    }
#endif
    return os;
  }

/**
 * \brief Reset all bits to 0.
 */
template<unsigned int n>
  bitset<n>&
  bitset<n>::reset(void)
  {
    bitset_digit_t* const least_significant_digit = &vector[0];
    if (digits > 1)
    {
      bitset_digit_t* digit_pointer = &vector[digits];
      int count = digits - 1;
      do { *--digit_pointer = 0; } while(--count);
    }
    *least_significant_digit = 0;
    return *this;
  }

/**
 * \brief Test bit at position \a pos.
 */
template<unsigned int n>
  bool
  bitset<n>::test(size_t pos) const
  {
    unsigned int d = pos / digit_bits;
    bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
    return (vector[d] & mask);
  }

/**
 * \brief Test a bit at a fixed position.
 */
template<unsigned int n>
  template<unsigned int pos>
    bool
    bitset<n>::test(void) const
    {
      static unsigned int const d = pos / digit_bits;
      static bitset_digit_t const mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
      return (vector[d] & mask);
    }

/**
 * \brief Set bit at position \a pos.
 */
template<unsigned int n>
  void
  bitset<n>::set(size_t pos)
  {
    unsigned int d = pos / digit_bits;
    bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
    vector[d] |= mask;
  }

/**
 * \brief Set a bit at a fixed position.
 */
template<unsigned int n>
  template<unsigned int pos>
    void
    bitset<n>::set(void)
    {
      static unsigned int const d = pos / digit_bits;
      static bitset_digit_t const mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
      vector[d] |= mask;
    }

/**
 * \brief Set or reset a bit in digit \a d.
 */
template<unsigned int n>
  template<unsigned int pos>
    void
    bitset<n>::digitset(unsigned int d, bool value)
    {
      bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
      if (value)
	vector[d] |= mask;
      else
        vector[d] &= ~mask;
    }

/**
 * \brief Clear bit at position \a pos.
 */
template<unsigned int n>
  void
  bitset<n>::clear(size_t pos)
  {
    unsigned int d = pos / digit_bits;
    bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
    vector[d] &= ~mask;
  }

/**
 * \brief Clear a bit at a fixed position.
 */
template<unsigned int n>
  template<unsigned int pos>
    void
    bitset<n>::clear(void)
    {
      static unsigned int const d = pos / digit_bits;
      static bitset_digit_t const mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
      vector[d] &= ~mask;
    }

/**
 * \brief Toggle bit at position \a pos.
 */
template<unsigned int n>
  void
  bitset<n>::flip(size_t pos)
  {
    unsigned int d = pos / digit_bits;
    bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
    vector[d] ^= mask;
  }

/**
 * \brief Toggle a bit at a fixed position.
 */
template<unsigned int n>
  template<unsigned int pos>
    void
    bitset<n>::flip(void)
    {
      static unsigned int const d = pos / digit_bits;
      static bitset_digit_t const mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
      vector[d] ^= mask;
    }

/**
 * \brief Return true if any bit is set.
 */
template<unsigned int n>
  bool
  bitset<n>::any(void) const
  {
    unsigned int to = digits - 1;
    if (digits > 1)
      do
      {
	if (vector[to] != 0)
	  return true;
	--to;
      }
      while(to != 0);
    return (vector[0] != 0);
  }

static bool const oddnumberofbits[] = {
  false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
  true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
  true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
  false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
  true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
  false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
  false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
  true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
  true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
  false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
  false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
  true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
  false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
  true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
  true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
  false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false };

/**
 * \brief Returns true when the bitset contains an odd number of bits.
 */
template<unsigned int n>
  bool
  bitset<n>::odd(void) const
  {
    unsigned int from = digits - 1;
    bitset_digit_t sum = vector[0];
    if (digits > 1)
      do
      {
	sum ^= vector[from];
	--from;
      }
      while(from != 0);
    bitset_digit_t ssum = sum;
    if (sizeof(bitset_digit_t) >= 2)
    {
      ssum >>= (digit_bits / 2);
      sum ^= ssum;
    }
    if (sizeof(bitset_digit_t) >= 4)
    {
      ssum = sum;
      ssum >>= (digit_bits / 4);
      sum ^= ssum;
    }
    if (sizeof(bitset_digit_t) >= 8)
    {
      ssum = sum;
      ssum >>= (digit_bits / 8);
      sum ^= ssum;
    }
    if (sizeof(bitset_digit_t) == 16)
    {
      ssum = sum;
      ssum >>= (digit_bits / 16);
      sum ^= ssum;
    }
    return oddnumberofbits[sum & 0xff];
  }

/**
 * \brief Shift direction used with libecc::bitset::shift_op
 */
struct left {
public:
  typedef struct right inverse;
  static int const direction = -1;
  static bool const __left = true;
  static bool const __right = false;
  static inline void shift(bitset_digit_t& digit, unsigned int shift) { digit <<= shift; }
  static inline bitset_digit_t shift_copy(bitset_digit_t digit, unsigned int shift) { return digit << shift; }
  static inline bitset_digit_t reverse_shift_copy(bitset_digit_t digit, unsigned int shift) { return digit >> shift; }
};

/**
 * \brief Shift direction used with libecc::bitset::shift_op
 */
struct right {
public:
  typedef struct left inverse;
  static int const direction = 1;
  static bool const __left = false;
  static bool const __right = true;
  static inline void shift(bitset_digit_t& digit, unsigned int shift) { digit >>= shift; }
  static inline bitset_digit_t shift_copy(bitset_digit_t digit, unsigned int shift) { return digit >> shift; }
  static inline bitset_digit_t reverse_shift_copy(bitset_digit_t digit, unsigned int shift) { return digit << shift; }
};

/**
 * \brief Operation used with libecc::bitset::shift_op
 */
struct assign {
public:
  static bool const __clear = true;
  static inline void op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
  static inline void mixed_op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
};

/**
 * \brief Operation used with libecc::bitset::shift_op
 */
struct exor {
public:
  static bool const __clear = false;
  static inline void op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 ^= digit2; }
  static inline void mixed_op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 ^= digit2; }
};

#ifndef HIDE_FROM_DOXYGEN
struct rotate_phase1 {
public:
  static bool const __clear = false;
  static inline void op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
  static inline void mixed_op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
};

struct rotate_phase2 {
public:
  static bool const __clear = false;
  static inline void op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
  static inline void mixed_op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 |= digit2; }
};
#endif

/** \brief Rotate bitset.
 *
 * Rotate bitset \a shift bits in \a DIRECTION.
 *
 * \param shift The number of bits to rotate this bitset.
 * \param DIRECTION The direction into which this bitset must be rotated, can be libecc::left or libecc::right.
 * \param result The result of the rotation.
 */
template<unsigned int n>
  template<unsigned int shift, class DIRECTION>
    void
    bitset<n>::rotate(bitset<n>& result) const
    {
      shift_op<shift % n, DIRECTION, rotate_phase1>(result);
      shift_op<n - (shift % n), typename DIRECTION::inverse, rotate_phase2>(result);
    }

} // namespace libecc

#endif // LIBECC_BITS_H
