diff options
author | David Robillard <d@drobilla.net> | 2018-08-19 09:50:54 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-09-29 14:47:40 +0200 |
commit | 131fc7924fe5d30c4605aa158ef5564352a0f626 (patch) | |
tree | 7f7dda433ea35ba4f242ea6bcafe867d1a416b3f | |
parent | 13720ea9fff1322ffd6dc6c825bc3183d62c6f68 (diff) | |
download | chilbert-131fc7924fe5d30c4605aa158ef5564352a0f626.tar.gz chilbert-131fc7924fe5d30c4605aa158ef5564352a0f626.tar.bz2 chilbert-131fc7924fe5d30c4605aa158ef5564352a0f626.zip |
Factor out bit vector iterators
-rw-r--r-- | chilbert/BigBitVec.hpp | 69 | ||||
-rw-r--r-- | chilbert/BitVecIterator.hpp | 98 |
2 files changed, 102 insertions, 65 deletions
diff --git a/chilbert/BigBitVec.hpp b/chilbert/BigBitVec.hpp index 7038662..5862f31 100644 --- a/chilbert/BigBitVec.hpp +++ b/chilbert/BigBitVec.hpp @@ -19,6 +19,7 @@ #ifndef CHILBERT_BIGBITVEC_HPP #define CHILBERT_BIGBITVEC_HPP +#include "chilbert/BitVecIterator.hpp" #include "chilbert/BitVecMask.hpp" #include "chilbert/Operations.hpp" @@ -39,6 +40,9 @@ public: using Rack = uintptr_t; using Mask = BitVecMask<Rack>; + using iterator = BitVecIterator<CBigBitVec>; + using const_iterator = ConstBitVecIterator<CBigBitVec>; + static constexpr size_t bits_per_rack = sizeof(Rack) * CHAR_BIT; explicit CBigBitVec(const size_t bits) @@ -437,71 +441,6 @@ public: /// Return the number of racks size_t rackCount() const { return num_racks(m_size); } - template <class BitVec> - class iterator_base : public Mask - { - public: - iterator_base& operator++() - { - Mask::operator++(); - return *this; - } - - iterator_base& operator--() - { - Mask::operator--(); - return *this; - } - - bool operator==(const iterator_base& iterator_base) const - { - return m_vec == iterator_base.m_vec && - Mask::operator==(iterator_base); - } - - bool operator!=(const iterator_base& iterator_base) const - { - return !operator==(iterator_base); - } - - bool operator*() const { return m_vec->test(*this); } - - protected: - iterator_base(BitVec& vec, const size_t index) - : Mask{index} - , m_vec{&vec} - { - } - - BitVec* m_vec; - }; - - class iterator : public iterator_base<CBigBitVec> - { - public: - void set() { m_vec->set(*this); } - void reset() { m_vec->reset(*this); } - - private: - friend class CBigBitVec; - - iterator(CBigBitVec& vec, const size_t index) - : iterator_base{vec, index} - { - } - }; - - class const_iterator : public iterator_base<const CBigBitVec> - { - private: - friend class CBigBitVec; - - const_iterator(const CBigBitVec& vec, const size_t index) - : iterator_base{vec, index} - { - } - }; - Mask mask(const size_t i = 0) const { assert(i <= size()); diff --git a/chilbert/BitVecIterator.hpp b/chilbert/BitVecIterator.hpp new file mode 100644 index 0000000..bbafd42 --- /dev/null +++ b/chilbert/BitVecIterator.hpp @@ -0,0 +1,98 @@ +/* + Copyright (C) 2018 David Robillard <d@drobilla.net> + Copyright (C) 2006-2007 Chris Hamilton <chamilton@cs.dal.ca> + + This program is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation, either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +#ifndef CHILBERT_BITVECITERATOR_HPP +#define CHILBERT_BITVECITERATOR_HPP + +#include "chilbert/BitVecMask.hpp" + +#include <cstddef> + +namespace chilbert { + +template <class BitVec> +class BitVecIteratorBase : public BitVecMask<typename BitVec::Rack> +{ +public: + using Mask = typename BitVec::Mask; + + BitVecIteratorBase& operator++() + { + Mask::operator++(); + return *this; + } + + BitVecIteratorBase& operator--() + { + Mask::operator--(); + return *this; + } + + bool operator==(const BitVecIteratorBase& rhs) const + { + return m_vec == rhs.m_vec && Mask::operator==(rhs); + } + + bool operator!=(const BitVecIteratorBase& rhs) const + { + return !operator==(rhs); + } + + bool operator*() const { return m_vec->test(*this); } + +protected: + BitVecIteratorBase(BitVec& vec, const size_t index) + : Mask{index} + , m_vec{&vec} + { + } + + BitVec* m_vec; +}; + +template <class BitVec> +class BitVecIterator : public BitVecIteratorBase<BitVec> +{ +public: + void set() { this->m_vec->set(*this); } + void reset() { this->m_vec->reset(*this); } + +private: + friend BitVec; + + BitVecIterator(BitVec& vec, const size_t index) + : BitVecIteratorBase<BitVec>{vec, index} + { + } +}; + +template <class BitVec> +class ConstBitVecIterator : public BitVecIteratorBase<const BitVec> +{ +private: + friend BitVec; + + ConstBitVecIterator(const BitVec& vec, const size_t index) + : BitVecIteratorBase<const BitVec>{vec, index} + { + } +}; + +} // namespace chilbert + +#endif |