#include "aps.hpp"
#include "search.h"

namespace search {

Part::Part(ShapeId ashapeid, SitId ahedid, SitId asitid)
	: shapeid(ashapeid), hedid(ahedid), sitid(asitid)
{
}

std::ostream &operator<<(std::ostream &output, const Part &part)
{
	output << '(' << part.shapeid << ',' <<
			part.hedid << ',' << part.sitid << ')';
	return (output);
}

void PosVariable::resize(SitId ansit)
{
	nsit = ansit;
	val.resize(nsit + bits - 1 >> bitsbits);
	clear();
}

SitId PosVariable::size(void) const
{
	return (nsit);
}

SitId PosVariable::firstzero(void) const
{
	Val j;
	int i, k, l;

	j = 0;
	for (i = 0; i < val.size() - 1; i++)
		if (!!(j = val[i] ^ ~(~0 << bits - 1 << 1))) break;
	if (i == val.size() - 1 && !(j = val[i] ^ ~(~0 << (nsit - 1 & bits - 1) + 1)))
		return (val.size());
	for (k = bits; k >>= 1; i <<= 1, i |= l)
		if (!!(l = !(j & ~(~0 << k)))) j >>= k;
	return (i);
}

bool PosVariable::isand(const PosVariable &src) const
{
	int i;

	for (i = 0; i < val.size(); i++)
		if (val[i] & src.val[i]) return (true);
	return (false);
}

PosVariable &PosVariable::setor(const PosVariable &src1, const PosVariable &src2)
{
	int i;

	for (i = 0; i < val.size(); i++)
		val[i] = src1.val[i] | src2.val[i];
	return (*this);
}

PosVariable &PosVariable::clear(void)
{
	int i;

	for (i = 0; i < val.size() - 1; i++) val[i] = 0;
	return (*this);
}

PosVariable &PosVariable::set(SitId sit)
{
	val[sit >> bitsbits] |= 1 << (sit & bits - 1);
	return (*this);
}

bool PosVariable::get(SitId sit) const
{
	return (val[sit >> bitsbits] >> (sit & bits - 1) & 1);
}

std::ostream &operator<<(std::ostream &output, const PosVariable &pos)
{
	LocId i;

	for (i = 0; i < pos.nsit; i++) output << pos.get(i);
	return (output);
}

} // end of namespace search
