/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_BASE_BIT_VECTOR_INL_H_
#define ART_RUNTIME_BASE_BIT_VECTOR_INL_H_

#include "bit_vector.h"
#include "logging.h"
#include "utils.h"

namespace art {

inline bool BitVector::IndexIterator::operator==(const IndexIterator& other) const {
  DCHECK(bit_storage_ == other.bit_storage_);
  DCHECK_EQ(storage_size_, other.storage_size_);
  return bit_index_ == other.bit_index_;
}

inline int BitVector::IndexIterator::operator*() const {
  DCHECK_LT(bit_index_, BitSize());
  return bit_index_;
}

inline BitVector::IndexIterator& BitVector::IndexIterator::operator++() {
  DCHECK_LT(bit_index_, BitSize());
  bit_index_ = FindIndex(bit_index_ + 1u);
  return *this;
}

inline BitVector::IndexIterator BitVector::IndexIterator::operator++(int) {
  IndexIterator result(*this);
  ++*this;
  return result;
}

inline uint32_t BitVector::IndexIterator::FindIndex(uint32_t start_index) const {
  DCHECK_LE(start_index, BitSize());
  uint32_t word_index = start_index / kWordBits;
  if (UNLIKELY(word_index == storage_size_)) {
    return start_index;
  }
  uint32_t word = bit_storage_[word_index];
  // Mask out any bits in the first word we've already considered.
  word &= static_cast<uint32_t>(-1) << (start_index & 0x1f);
  while (word == 0u) {
    ++word_index;
    if (UNLIKELY(word_index == storage_size_)) {
      return BitSize();
    }
    word = bit_storage_[word_index];
  }
  return word_index * 32u + CTZ(word);
}

inline void BitVector::ClearAllBits() {
  memset(storage_, 0, storage_size_ * kWordBytes);
}

inline bool BitVector::Equal(const BitVector* src) const {
  return (storage_size_ == src->GetStorageSize()) &&
    (expandable_ == src->IsExpandable()) &&
    (memcmp(storage_, src->GetRawStorage(), storage_size_ * sizeof(uint32_t)) == 0);
}

}  // namespace art

#endif  // ART_RUNTIME_BASE_BIT_VECTOR_INL_H_
