From dfc466fc8758b7306c756f5874f40d73cf4dd48f Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 20 Mar 2020 14:33:42 +0100 Subject: [PATCH] Refactoring, allow iterating over blocks. --- src/cli/memcard.cpp | 14 +-- .../include/memcard/block_iterator.hpp | 45 +++++++++ .../memcard/include/memcard/memorycard.hpp | 13 +++ subprojects/memcard/meson.build | 1 + subprojects/memcard/src/block_iterator.cpp | 99 +++++++++++++++++++ subprojects/memcard/src/memorycard.cpp | 28 ++++++ 6 files changed, 188 insertions(+), 12 deletions(-) create mode 100644 subprojects/memcard/include/memcard/block_iterator.hpp create mode 100644 subprojects/memcard/src/block_iterator.cpp diff --git a/src/cli/memcard.cpp b/src/cli/memcard.cpp index 71a7fb1..06fd00b 100644 --- a/src/cli/memcard.cpp +++ b/src/cli/memcard.cpp @@ -17,24 +17,14 @@ void print_blocks (const std::string& mc_path) { } } - int adv = 1; - int used = 0; - for (int z = 0; z < 15; z += adv) { - mc::psx::ConstBlock blk = mc[z]; + for (const auto& blk : mc) { if (blk.has_magic()) { - std::cout << "Block " << std::setfill(' ') << std::setw(2) << z + 1 + std::cout << "Block " << std::setfill(' ') << std::setw(2) << 0 + 1 << ": \"" << blk.title() << '"'; if (blk.block_count() > 1) { std::cout << " [" << blk.block_count() << ']'; } std::cout << '\n'; - adv = blk.block_count(); - used += adv; - } - else { - adv = 1; } } - - std::cout << "Used blocks: " << used << "/15\n"; } diff --git a/subprojects/memcard/include/memcard/block_iterator.hpp b/subprojects/memcard/include/memcard/block_iterator.hpp new file mode 100644 index 0000000..cf31cf8 --- /dev/null +++ b/subprojects/memcard/include/memcard/block_iterator.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "memcard/block.hpp" +#include +#include + +namespace mc::psx { +class MemoryCard; + +template +class BlockIterator { + friend class BlockIterator; + typedef typename std::conditional::type* MemoryCardPtr; +public: + typedef std::random_access_iterator_tag iterator_category; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + BlockIterator (MemoryCardPtr mc, size_type index); + BlockIterator (const BlockIterator&) = default; + BlockIterator (BlockIterator&&) = default; + BlockIterator(); + + template + bool operator== (const BlockIterator& other) const; + template + bool operator!= (const BlockIterator& other) const; + template + bool operator< (const BlockIterator& other) const; + + BasicBlock operator*(); + BasicBlock operator*() const; + + BlockIterator& operator++(); + BlockIterator operator++(int); + BlockIterator& operator--(); + BlockIterator operator--(int); + template + difference_type operator- (const BlockIterator& other); + +private: + MemoryCardPtr m_mc; + size_type m_index; +}; +} //namespace mc::psx diff --git a/subprojects/memcard/include/memcard/memorycard.hpp b/subprojects/memcard/include/memcard/memorycard.hpp index c12f71a..deb1fa6 100644 --- a/subprojects/memcard/include/memcard/memorycard.hpp +++ b/subprojects/memcard/include/memcard/memorycard.hpp @@ -2,6 +2,7 @@ #include "memcard/block.hpp" #include "memcard/content_info.hpp" +#include "memcard/block_iterator.hpp" #include #include #include @@ -11,6 +12,9 @@ namespace mc::psx { class MemoryCard { public: + typedef BlockIterator iterator; + typedef BlockIterator const_iterator; + MemoryCard(); template explicit MemoryCard (IT beg, IT end); ~MemoryCard(); @@ -19,6 +23,15 @@ public: ConstBlock operator[] (std::size_t index) const; ContentInfo content_info() const; + std::size_t size() const; + + iterator begin(); + iterator end(); + const_iterator cbegin() const; + const_iterator begin() const; + const_iterator cend() const; + const_iterator end() const; + private: std::vector m_data; }; diff --git a/subprojects/memcard/meson.build b/subprojects/memcard/meson.build index aec07f9..2ff2115 100644 --- a/subprojects/memcard/meson.build +++ b/subprojects/memcard/meson.build @@ -13,6 +13,7 @@ memcard = shared_library('memcard', 'src/shiftjis_to_utf8.cpp', 'src/content_info.cpp', 'src/make_memory_card.cpp', + 'src/block_iterator.cpp', install: true, include_directories: [private_incl, library_incl], ) diff --git a/subprojects/memcard/src/block_iterator.cpp b/subprojects/memcard/src/block_iterator.cpp new file mode 100644 index 0000000..726e43c --- /dev/null +++ b/subprojects/memcard/src/block_iterator.cpp @@ -0,0 +1,99 @@ +#include "memcard/block_iterator.hpp" +#include "memcard/memorycard.hpp" +#include + +namespace mc::psx { +template +BlockIterator::BlockIterator() : + m_mc(nullptr), + m_index(0) +{ +} + +template +BlockIterator::BlockIterator (MemoryCardPtr mc, size_type index) : + m_mc(mc), + m_index(index) +{ +} + +template +template +bool BlockIterator::operator== (const BlockIterator& other) const { + assert(other.m_mc == this->m_mc); + return this->m_index == other.m_index; +} + +template +template +bool BlockIterator::operator!= (const BlockIterator& other) const { + assert(other.m_mc == this->m_mc); + return this->m_index != other.m_index; +} + +template +template +bool BlockIterator::operator< (const BlockIterator& other) const { + assert(other.m_mc == this->m_mc); + return this->m_index < other.m_index; +} + +template +BasicBlock BlockIterator::operator*() { + assert(m_mc); + return (*m_mc)[m_index]; +} + +template +BasicBlock BlockIterator::operator*() const { + assert(m_mc); + return const_cast(*m_mc)[m_index]; +} + +template +BlockIterator& BlockIterator::operator++() { + ++m_index; + return *this; +} + +template +BlockIterator BlockIterator::operator++(int) { + auto cpy = *this; + ++(*this); + return cpy; +} + +template +BlockIterator& BlockIterator::operator--() { + --m_index; + return *this; +} + +template +BlockIterator BlockIterator::operator--(int) { + auto cpy = *this; + --(*this); + return cpy; +} + +template +template +auto BlockIterator::operator- (const BlockIterator& other) -> difference_type { + return this->m_index - other.m_index; +} + +template class BlockIterator; +template class BlockIterator; +template bool BlockIterator::operator==(const BlockIterator&) const; +template bool BlockIterator::operator==(const BlockIterator&) const; +template bool BlockIterator::operator==(const BlockIterator&) const; +template bool BlockIterator::operator==(const BlockIterator&) const; +template bool BlockIterator::operator!=(const BlockIterator&) const; +template bool BlockIterator::operator!=(const BlockIterator&) const; +template bool BlockIterator::operator!=(const BlockIterator&) const; +template bool BlockIterator::operator!=(const BlockIterator&) const; +template bool BlockIterator::operator<(const BlockIterator&) const; +template bool BlockIterator::operator<(const BlockIterator&) const; +template bool BlockIterator::operator<(const BlockIterator&) const; +template bool BlockIterator::operator<(const BlockIterator&) const; +} //namespace mc::psx diff --git a/subprojects/memcard/src/memorycard.cpp b/subprojects/memcard/src/memorycard.cpp index 65dae8e..0059da4 100644 --- a/subprojects/memcard/src/memorycard.cpp +++ b/subprojects/memcard/src/memorycard.cpp @@ -29,6 +29,34 @@ ContentInfo MemoryCard::content_info() const { return {ConstBlock(m_data.data())}; } +std::size_t MemoryCard::size() const { + return 15; +} + +auto MemoryCard::begin() -> iterator { + return iterator(this, 0); +} + +auto MemoryCard::end() -> iterator { + return iterator(this, size()); +} + +auto MemoryCard::cbegin() const -> const_iterator { + return const_iterator(this, 0); +} + +auto MemoryCard::begin() const -> const_iterator { + return const_iterator(this, 0); +} + +auto MemoryCard::cend() const -> const_iterator { + return const_iterator(this, size()); +} + +auto MemoryCard::end() const -> const_iterator { + return const_iterator(this, size()); +} + std::vector block_group (const MemoryCard& mc, std::size_t index) { std::vector retval;