998951619f
We did not intend to imply our copyrights last forever Closes #759
186 linhas
6.4 KiB
C++
186 linhas
6.4 KiB
C++
/*
|
|
+----------------------------------------------------------------------+
|
|
| HipHop for PHP |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available through the world-wide-web at the following url: |
|
|
| http://www.php.net/license/3_01.txt |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#ifndef incl_HPHP_BIT_SET_VEC_H_
|
|
#define incl_HPHP_BIT_SET_VEC_H_
|
|
|
|
#include <limits.h>
|
|
#include <stddef.h>
|
|
#include "hphp/util/assertions.h"
|
|
|
|
namespace HPHP {
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class BitSetBlock;
|
|
class BitSetRow;
|
|
|
|
class BitOps {
|
|
public:
|
|
typedef size_t Bits;
|
|
static const size_t elemSize = CHAR_BIT * sizeof(BitOps::Bits);
|
|
|
|
#define BITOP_DECLARE1(name, op) \
|
|
private: \
|
|
static void name##_func(Bits *out, Bits *in1) { \
|
|
*out = op; \
|
|
} \
|
|
public: \
|
|
static void name(size_t width, Bits *out, Bits *in1);
|
|
|
|
#define BITOP_DECLARE2(name, op) \
|
|
private: \
|
|
static void name##_func(Bits *out, Bits *in1, Bits *in2) { \
|
|
*out = op; \
|
|
} \
|
|
public: \
|
|
static void name(size_t width, Bits *out, Bits *in1, Bits *in2);
|
|
|
|
#define BITOP_DECLARE3(name, op) \
|
|
private: \
|
|
static void name##_func(Bits *out, \
|
|
Bits *in1, Bits *in2, Bits *in3) { \
|
|
*out = op; \
|
|
} \
|
|
public: \
|
|
static void name(size_t width, Bits *out, \
|
|
Bits *in1, Bits *in2, Bits *in3);
|
|
|
|
#define BITOP_DEFINE1(name) \
|
|
void BitOps::name(size_t width, Bits *out, Bits *in1) { \
|
|
bit_op1(name##_func, width, out, in1); \
|
|
}
|
|
|
|
#define BITOP_DEFINE2(name) \
|
|
void BitOps::name(size_t width, Bits *out, \
|
|
Bits *in1, Bits *in2) { \
|
|
bit_op2(name##_func, width, out, in1, in2); \
|
|
}
|
|
|
|
#define BITOP_DEFINE3(name) \
|
|
void BitOps::name(size_t width, Bits *out, \
|
|
Bits *in1, Bits *in2, Bits *in3) { \
|
|
bit_op3(name##_func, width, out, in1, in2, in3); \
|
|
}
|
|
|
|
BITOP_DECLARE1(bit_copy, *in1);
|
|
BITOP_DECLARE1(bit_complement, ~*in1);
|
|
|
|
BITOP_DECLARE2(bit_and, *in1 & *in2);
|
|
BITOP_DECLARE2(bit_or, *in1 | *in2);
|
|
BITOP_DECLARE2(bit_xor, *in1 ^ *in2);
|
|
|
|
BITOP_DECLARE3(bit_and_and, *in1 & *in2 & *in3);
|
|
BITOP_DECLARE3(bit_or_or, *in1 | *in2 | *in3);
|
|
BITOP_DECLARE3(bit_and_or, (*in1 & *in2) | *in3);
|
|
BITOP_DECLARE3(bit_or_and, (*in1 | *in2) & *in3);
|
|
BITOP_DECLARE3(bit_or_andc, (*in1 | *in2) & ~*in3);
|
|
BITOP_DECLARE3(bit_andc_or, (*in1 & ~*in2) | *in3);
|
|
|
|
public:
|
|
static bool bit_equal(size_t width, Bits *in1, Bits *in2);
|
|
static bool get_bit(size_t bit, Bits *bits);
|
|
static void set_bit(size_t bit, Bits *bits, bool value);
|
|
static void set(size_t width, Bits *in, Bits value);
|
|
|
|
private:
|
|
template <typename OP>
|
|
static void bit_op1(OP func, size_t width, Bits *out, Bits *in1) {
|
|
width += elemSize - 1;
|
|
while (width >= elemSize) {
|
|
func(out++, in1++);
|
|
width -= elemSize;
|
|
}
|
|
}
|
|
|
|
template <typename OP>
|
|
static void bit_op2(OP func, size_t width, Bits *out, Bits *in1, Bits *in2) {
|
|
width += elemSize - 1;
|
|
while (width >= elemSize) {
|
|
func(out++, in1++, in2++);
|
|
width -= elemSize;
|
|
}
|
|
}
|
|
|
|
template <typename OP>
|
|
static void bit_op3(OP func, size_t width,
|
|
Bits *out, Bits *in1, Bits *in2, Bits *in3) {
|
|
width += elemSize - 1;
|
|
while (width >= elemSize) {
|
|
func(out++, in1++, in2++, in3++);
|
|
width -= elemSize;
|
|
}
|
|
}
|
|
};
|
|
|
|
class BitSetVec {
|
|
public:
|
|
static const size_t elemSize = BitOps::elemSize;
|
|
BitSetVec() : m_maxId(0), m_idOffsets(0), m_bits(0) {}
|
|
BitSetVec(int blocks, size_t width, int rows, int *rowIds) {
|
|
alloc(blocks, width, rows, rowIds);
|
|
}
|
|
void alloc(int blocks, size_t width, int rows, int *rowIds);
|
|
~BitSetVec() { reset(); }
|
|
|
|
static BitOps::Bits *add(BitOps::Bits *base, size_t offset) {
|
|
return (BitOps::Bits*)((char*)base + offset);
|
|
}
|
|
|
|
BitSetBlock getBlock(int block);
|
|
size_t width() const { return m_width; }
|
|
size_t rowOffset(int row) const {
|
|
always_assert((unsigned)row < (unsigned)m_maxId);
|
|
size_t offset = m_idOffsets[row];
|
|
return offset - 1;
|
|
}
|
|
bool rowExists(int row) const {
|
|
return ((unsigned)row < (unsigned)m_maxId) &&
|
|
m_idOffsets[row];
|
|
}
|
|
|
|
BitOps::Bits *getTempBits(int id) const;
|
|
|
|
private:
|
|
void reset();
|
|
|
|
size_t m_width;
|
|
int m_maxId;
|
|
size_t *m_idOffsets;
|
|
size_t m_rowSize;
|
|
size_t m_blockSize;
|
|
BitOps::Bits *m_bits;
|
|
};
|
|
|
|
class BitSetBlock {
|
|
friend class BitSetVec;
|
|
public:
|
|
BitSetBlock() : m_bits(0), m_owner(0) {}
|
|
BitOps::Bits *getRow(int row) const;
|
|
void setBit(int row, int id, bool v);
|
|
bool getBit(int row, int id) const;
|
|
|
|
private:
|
|
BitSetBlock(BitOps::Bits *bits, const BitSetVec &owner) :
|
|
m_bits(bits), m_owner(&owner) {}
|
|
|
|
BitOps::Bits *m_bits;
|
|
const BitSetVec *m_owner;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
}
|
|
#endif // __BIT_SET_VEC_H__
|