(svn r10790) [NewGRF_ports] -Codechange: constify the fsmblockmaps where possible.
[NewGRF_ports] -Fix: a memleak.
/* $Id$ */
/** @file FSMblockmap.h Definition of FSMblockmap class for use in state machines*/
#ifndef FSMBLOCKMAP_H
#define FSMBLOCKMAP_H
#include "stdafx.h"
uint64 inline GetBlockAsBits(byte blocknumber)
{
if (blocknumber == 0) return 0ULL;
if (blocknumber > 63) blocknumber -= 64;
uint64 result = 1ULL << blocknumber;
return result;
}
/**
* This class provides functions and internal storage for blockmaps used in Finite State Machine
*
*/
struct FSMblockmap {
public:
void inline ResetAll()
{
block_lower = 0x0000000000000000;
block_upper = 0x0000000000000000;
};
void Initialise(const byte *blocklist, int num_bytes)
{
ResetAll();
for (int i = 0; i < num_bytes; i++)
{
if (blocklist[i] < 64) {
block_lower |= GetBlockAsBits(blocklist[i]);
} else {
block_upper |= GetBlockAsBits(blocklist[i]);
}
}
}
uint64 inline GetLower() const
{
return block_lower;
}
uint64 inline GetUpper() const
{
return block_upper;
}
void inline ReserveBlocks(const FSMblockmap *blockmap)
{
/* OR with blockmap to reserve blocks */
block_lower |= blockmap->GetLower();
block_upper |= blockmap->GetUpper();
}
void inline ReleaseBlocks(const FSMblockmap *blockmap)
{
/* AND with ones-complement to clear set bits in blockmap from block_lower and block_upper */
block_lower &= ~blockmap->GetLower();
block_upper &= ~blockmap->GetUpper();
}
bool inline BlocksAreFree(const FSMblockmap *blockmap) const
{
uint64 test_lower = blockmap->GetLower();
uint64 test_upper = blockmap->GetUpper();
if ((~block_lower & test_lower) != test_lower) return false;
if ((~block_upper & test_upper) != test_upper) return false;
return true;
}
bool inline HasBlocks(const FSMblockmap *blockmap) const
{
uint64 test_lower = blockmap->GetLower();
uint64 test_upper = blockmap->GetUpper();
if ((block_lower & test_lower) != test_lower) return false;
if ((block_upper & test_upper) != test_upper) return false;
return true;
}
bool inline HasBlock(byte blocknumber) const
{
FSMblockmap test_blockmap;
test_blockmap.Initialise(&blocknumber, 1);
return HasBlocks(&test_blockmap);
}
//bool inline HasBlock(byte blocknumber)
//{
// uint64 test_block = GetBlockAsBits(blocknumber);
// if (blocknumber < 64) return ((block_lower & test_block) == test_block);
// return ((block_upper & test_block) == test_block);
//}
bool inline IsNotZero(void) const
{
return ((block_lower != 0) || (block_upper != 0));
}
void PrintBlock(bool newline = true) const;
private:
uint64 block_lower;
uint64 block_upper;
};
FSMblockmap* SetFSMSingleBlock(const byte *blocklist);
#endif /* FSMBLOCKMAP_H */