Refactoring, allow iterating over blocks.

This commit is contained in:
King_DuckZ 2020-03-20 14:33:42 +01:00
parent ee163a213a
commit dfc466fc87
6 changed files with 188 additions and 12 deletions

View file

@ -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";
}

View file

@ -0,0 +1,45 @@
#pragma once
#include "memcard/block.hpp"
#include <type_traits>
#include <iterator>
namespace mc::psx {
class MemoryCard;
template <bool Const>
class BlockIterator {
friend class BlockIterator<not Const>;
typedef typename std::conditional<Const, const MemoryCard, MemoryCard>::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 Const2>
bool operator== (const BlockIterator<Const2>& other) const;
template <bool Const2>
bool operator!= (const BlockIterator<Const2>& other) const;
template <bool Const2>
bool operator< (const BlockIterator<Const2>& other) const;
BasicBlock<Const> operator*();
BasicBlock<true> operator*() const;
BlockIterator& operator++();
BlockIterator operator++(int);
BlockIterator& operator--();
BlockIterator operator--(int);
template <bool Const2>
difference_type operator- (const BlockIterator<Const2>& other);
private:
MemoryCardPtr m_mc;
size_type m_index;
};
} //namespace mc::psx

View file

@ -2,6 +2,7 @@
#include "memcard/block.hpp"
#include "memcard/content_info.hpp"
#include "memcard/block_iterator.hpp"
#include <vector>
#include <cstdint>
#include <array>
@ -11,6 +12,9 @@
namespace mc::psx {
class MemoryCard {
public:
typedef BlockIterator<false> iterator;
typedef BlockIterator<true> const_iterator;
MemoryCard();
template <typename IT> 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<uint8_t> m_data;
};

View file

@ -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],
)

View file

@ -0,0 +1,99 @@
#include "memcard/block_iterator.hpp"
#include "memcard/memorycard.hpp"
#include <cassert>
namespace mc::psx {
template <bool Const>
BlockIterator<Const>::BlockIterator() :
m_mc(nullptr),
m_index(0)
{
}
template <bool Const>
BlockIterator<Const>::BlockIterator (MemoryCardPtr mc, size_type index) :
m_mc(mc),
m_index(index)
{
}
template <bool Const>
template <bool Const2>
bool BlockIterator<Const>::operator== (const BlockIterator<Const2>& other) const {
assert(other.m_mc == this->m_mc);
return this->m_index == other.m_index;
}
template <bool Const>
template <bool Const2>
bool BlockIterator<Const>::operator!= (const BlockIterator<Const2>& other) const {
assert(other.m_mc == this->m_mc);
return this->m_index != other.m_index;
}
template <bool Const>
template <bool Const2>
bool BlockIterator<Const>::operator< (const BlockIterator<Const2>& other) const {
assert(other.m_mc == this->m_mc);
return this->m_index < other.m_index;
}
template <bool Const>
BasicBlock<Const> BlockIterator<Const>::operator*() {
assert(m_mc);
return (*m_mc)[m_index];
}
template <bool Const>
BasicBlock<true> BlockIterator<Const>::operator*() const {
assert(m_mc);
return const_cast<const MemoryCard&>(*m_mc)[m_index];
}
template <bool Const>
BlockIterator<Const>& BlockIterator<Const>::operator++() {
++m_index;
return *this;
}
template <bool Const>
BlockIterator<Const> BlockIterator<Const>::operator++(int) {
auto cpy = *this;
++(*this);
return cpy;
}
template <bool Const>
BlockIterator<Const>& BlockIterator<Const>::operator--() {
--m_index;
return *this;
}
template <bool Const>
BlockIterator<Const> BlockIterator<Const>::operator--(int) {
auto cpy = *this;
--(*this);
return cpy;
}
template <bool Const>
template <bool Const2>
auto BlockIterator<Const>::operator- (const BlockIterator<Const2>& other) -> difference_type {
return this->m_index - other.m_index;
}
template class BlockIterator<true>;
template class BlockIterator<false>;
template bool BlockIterator<true>::operator==(const BlockIterator<true>&) const;
template bool BlockIterator<true>::operator==(const BlockIterator<false>&) const;
template bool BlockIterator<false>::operator==(const BlockIterator<true>&) const;
template bool BlockIterator<false>::operator==(const BlockIterator<false>&) const;
template bool BlockIterator<true>::operator!=(const BlockIterator<true>&) const;
template bool BlockIterator<true>::operator!=(const BlockIterator<false>&) const;
template bool BlockIterator<false>::operator!=(const BlockIterator<true>&) const;
template bool BlockIterator<false>::operator!=(const BlockIterator<false>&) const;
template bool BlockIterator<true>::operator<(const BlockIterator<true>&) const;
template bool BlockIterator<true>::operator<(const BlockIterator<false>&) const;
template bool BlockIterator<false>::operator<(const BlockIterator<true>&) const;
template bool BlockIterator<false>::operator<(const BlockIterator<false>&) const;
} //namespace mc::psx

View file

@ -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<std::size_t> block_group (const MemoryCard& mc, std::size_t index) {
std::vector<std::size_t> retval;