11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_BASE_BITS_ITERATOR_H_
61cb0ef41Sopenharmony_ci#define V8_BASE_BITS_ITERATOR_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <type_traits>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "src/base/bits.h"
111cb0ef41Sopenharmony_ci#include "src/base/iterator.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace base {
151cb0ef41Sopenharmony_cinamespace bits {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_citemplate <typename T, bool kMSBFirst = false>
181cb0ef41Sopenharmony_ciclass BitsIterator : public iterator<std::forward_iterator_tag, int> {
191cb0ef41Sopenharmony_ci  STATIC_ASSERT(std::is_integral<T>::value);
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci public:
221cb0ef41Sopenharmony_ci  explicit BitsIterator(T bits) : bits_(bits) {}
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci  int operator*() const {
251cb0ef41Sopenharmony_ci    return kMSBFirst ? 8 * sizeof(T) - 1 - CountLeadingZeros(bits_)
261cb0ef41Sopenharmony_ci                     : CountTrailingZeros(bits_);
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci  BitsIterator& operator++() {
301cb0ef41Sopenharmony_ci    bits_ &= ~(T{1} << **this);
311cb0ef41Sopenharmony_ci    return *this;
321cb0ef41Sopenharmony_ci  }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  bool operator==(BitsIterator other) { return bits_ == other.bits_; }
351cb0ef41Sopenharmony_ci  bool operator!=(BitsIterator other) { return bits_ != other.bits_; }
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci private:
381cb0ef41Sopenharmony_ci  T bits_;
391cb0ef41Sopenharmony_ci};
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci// Returns an iterable over the bits in {bits}, from LSB to MSB.
421cb0ef41Sopenharmony_citemplate <typename T>
431cb0ef41Sopenharmony_ciauto IterateBits(T bits) {
441cb0ef41Sopenharmony_ci  return make_iterator_range(BitsIterator<T>{bits}, BitsIterator<T>{0});
451cb0ef41Sopenharmony_ci}
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci// Returns an iterable over the bits in {bits}, from MSB to LSB.
481cb0ef41Sopenharmony_citemplate <typename T>
491cb0ef41Sopenharmony_ciauto IterateBitsBackwards(T bits) {
501cb0ef41Sopenharmony_ci  return make_iterator_range(BitsIterator<T, true>{bits},
511cb0ef41Sopenharmony_ci                             BitsIterator<T, true>{0});
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci}  // namespace bits
551cb0ef41Sopenharmony_ci}  // namespace base
561cb0ef41Sopenharmony_ci}  // namespace v8
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci#endif  // V8_BASE_BITS_ITERATOR_H_
59