/*
 * Copyright (C) 2015 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_LIBARTBASE_BASE_BIT_UTILS_ITERATOR_H_
#define ART_LIBARTBASE_BASE_BIT_UTILS_ITERATOR_H_

#include <iterator>
#include <limits>
#include <type_traits>

#include <android-base/logging.h>

#include "bit_utils.h"
#include "iteration_range.h"
#include "stl_util.h"

namespace art {

// Using the Curiously Recurring Template Pattern to implement everything shared
// by LowToHighBitIterator and HighToLowBitIterator, i.e. everything but operator*().
template <typename T, typename Iter>
class BitIteratorBase {
  static_assert(std::is_integral_v<T>, "T must be integral");
  static_assert(std::is_unsigned_v<T>, "T must be unsigned");

  static_assert(sizeof(T) == sizeof(uint32_t) || sizeof(T) == sizeof(uint64_t), "Unsupported size");

 public:
  using iterator_category = std::forward_iterator_tag;
  using value_type = uint32_t;
  using difference_type = ptrdiff_t;
  using pointer = void;
  using reference = void;

  BitIteratorBase() : bits_(0u) { }
  explicit BitIteratorBase(T bits) : bits_(bits) { }

  Iter& operator++() {
    DCHECK_NE(bits_, 0u);
    uint32_t bit = *static_cast<Iter&>(*this);
    bits_ &= ~(static_cast<T>(1u) << bit);
    return static_cast<Iter&>(*this);
  }

  Iter& operator++(int) {
    Iter tmp(static_cast<Iter&>(*this));
    ++*this;
    return tmp;
  }

 protected:
  T bits_;

  template <typename U, typename I>
  friend bool operator==(const BitIteratorBase<U, I>& lhs, const BitIteratorBase<U, I>& rhs);
};

template <typename T, typename Iter>
bool operator==(const BitIteratorBase<T, Iter>& lhs, const BitIteratorBase<T, Iter>& rhs) {
  return lhs.bits_ == rhs.bits_;
}

template <typename T, typename Iter>
bool operator!=(const BitIteratorBase<T, Iter>& lhs, const BitIteratorBase<T, Iter>& rhs) {
  return !(lhs == rhs);
}

template <typename T>
class LowToHighBitIterator : public BitIteratorBase<T, LowToHighBitIterator<T>> {
 public:
  using BitIteratorBase<T, LowToHighBitIterator<T>>::BitIteratorBase;

  uint32_t operator*() const {
    DCHECK_NE(this->bits_, 0u);
    return CTZ(this->bits_);
  }
};

template <typename T>
class HighToLowBitIterator : public BitIteratorBase<T, HighToLowBitIterator<T>> {
 public:
  using BitIteratorBase<T, HighToLowBitIterator<T>>::BitIteratorBase;

  uint32_t operator*() const {
    DCHECK_NE(this->bits_, 0u);
    static_assert(std::numeric_limits<T>::radix == 2, "Unexpected radix!");
    return std::numeric_limits<T>::digits - 1u - CLZ(this->bits_);
  }
};

template <typename T>
IterationRange<LowToHighBitIterator<T>> LowToHighBits(T bits) {
  return IterationRange<LowToHighBitIterator<T>>(
      LowToHighBitIterator<T>(bits), LowToHighBitIterator<T>());
}

template <typename T>
IterationRange<HighToLowBitIterator<T>> HighToLowBits(T bits) {
  return IterationRange<HighToLowBitIterator<T>>(
      HighToLowBitIterator<T>(bits), HighToLowBitIterator<T>());
}

}  // namespace art

#endif  // ART_LIBARTBASE_BASE_BIT_UTILS_ITERATOR_H_
