5 * Created by Christian Brunschen on 12/05/2008.
6 * Copyright 2008 Google UK. All rights reserved.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 #include "BitMatrix.h"
22 #include "IllegalArgumentException.h"
28 static unsigned int logDigits(unsigned digits) {
31 while (val < digits) {
38 static const unsigned int bitsPerWord_ =
39 numeric_limits<unsigned int>::digits;
40 static const unsigned int logBits_ = logDigits(bitsPerWord_);
41 static const unsigned int bitsMask_ = (1 << logBits_) - 1;
43 static size_t wordsForDimension(size_t dimension) {
44 size_t bits = dimension * dimension;
45 int arraySize = bits >> logBits_;
46 if (bits - (arraySize << logBits_) != 0) {
52 BitMatrix::BitMatrix(size_t dimension) :
53 dimension_(dimension),
54 bits_((const unsigned int)0, wordsForDimension(dimension)) {
57 BitMatrix::~BitMatrix() {
61 bool BitMatrix::get(size_t i, size_t j) {
62 size_t offset = i + dimension_ * j;
63 return ((bits_[offset >> logBits_] >> (offset & bitsMask_)) & 0x01) != 0;
66 void BitMatrix::set(size_t i, size_t j) {
67 size_t offset = i + dimension_ * j;
68 bits_[offset >> logBits_] |= 1 << (offset & bitsMask_);
71 void BitMatrix::setRegion(size_t topI,
75 if (topI < 0 || leftJ < 0) {
76 throw new IllegalArgumentException("topI and leftJ must be nonnegative");
78 if (height < 1 || width < 1) {
79 throw new IllegalArgumentException("height and width must be at least 1");
81 size_t maxJ = leftJ + width;
82 size_t maxI = topI + height;
83 if (maxI > dimension_ || maxJ > dimension_) {
84 throw new IllegalArgumentException
85 ("topI + height and leftJ + width must be <= matrix dimension");
87 for (size_t j = leftJ; j < maxJ; j++) {
88 int jOffset = dimension_ * j;
89 for (size_t i = topI; i < maxI; i++) {
90 size_t offset = i + jOffset;
91 bits_[offset >> logBits_] |= 1 << (offset & bitsMask_);
96 size_t BitMatrix::getDimension() {
100 valarray<unsigned int> &BitMatrix::getBits() {
104 ostream& operator<<(ostream &out, BitMatrix &bm) {
105 for (size_t i = 0; i < bm.dimension_; i++) {
106 for (size_t j = 0; j < bm.dimension_; j++) {
107 out << (bm.get(i, j) ? "* " : "- ");
113 const char *BitMatrix::description() {
116 return out.str().c_str();