add all_tracks_reverse_iterator
This commit is contained in:
+48
-18
@@ -897,10 +897,31 @@ void NoteData::LoadFromNode( const XNode* pNode )
|
|||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ND, typename iter, typename TN>
|
NoteData::reverse_iterator NoteData::rlower_bound( int iTrack, int iRow )
|
||||||
void NoteData::_all_tracks_iterator<ND, iter, TN>::Find()
|
{
|
||||||
|
// TODO: optimize this
|
||||||
|
reverse_iterator i = m_TapNotes[iTrack].rbegin();
|
||||||
|
for( ; i != m_TapNotes[iTrack].rend(); ++i )
|
||||||
|
{
|
||||||
|
int first = i->first;
|
||||||
|
if( i->first <= iRow )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
NoteData::const_reverse_iterator NoteData::rlower_bound( int iTrack, int iRow ) const
|
||||||
|
{
|
||||||
|
NoteData::reverse_iterator iter = ((NoteData*)this)->rlower_bound( iTrack, iRow );
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ND, typename iter, typename TN, bool bReverse, typename iterMethodInt, iterMethodInt mybegin, iterMethodInt myend, typename iterMethodIntInt, iterMethodIntInt mylower_bound>
|
||||||
|
void NoteData::_all_tracks_iterator<ND, iter, TN, bReverse, iterMethodInt, mybegin, myend, iterMethodIntInt, mylower_bound>::Find()
|
||||||
{
|
{
|
||||||
int iMinRow = m_iEndRow+1;
|
int iMinRow = m_iEndRow+1;
|
||||||
|
int iMaxRow = m_iStartRow-1;
|
||||||
|
|
||||||
// If no notes can be found in the range, m_iTrack will stay -1 and IsAtEnd() will return true.
|
// If no notes can be found in the range, m_iTrack will stay -1 and IsAtEnd() will return true.
|
||||||
m_iTrack = -1;
|
m_iTrack = -1;
|
||||||
@@ -908,46 +929,55 @@ void NoteData::_all_tracks_iterator<ND, iter, TN>::Find()
|
|||||||
{
|
{
|
||||||
iter &i = m_vIters[iTrack];
|
iter &i = m_vIters[iTrack];
|
||||||
if( m_Cond )
|
if( m_Cond )
|
||||||
while( i != m_NoteData.end(iTrack) && i->first < iMinRow && !m_Cond(i->second) )
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if( i != m_NoteData.end(iTrack) && i->first < iMinRow )
|
|
||||||
{
|
{
|
||||||
iMinRow = i->first;
|
while( i != (m_NoteData.*myend)(iTrack) && (bReverse ? (i->first > iMaxRow) : (i->first < iMinRow)) && !m_Cond(i->second) )
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( i != (m_NoteData.*myend)(iTrack) && (bReverse ? (i->first > iMaxRow) : (i->first < iMinRow)) )
|
||||||
|
{
|
||||||
|
bReverse ? iMaxRow : iMinRow = i->first;
|
||||||
m_iTrack = iTrack;
|
m_iTrack = iTrack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ND, typename iter, typename TN>
|
template<typename ND, typename iter, typename TN, bool bReverse, typename iterMethodInt, iterMethodInt mybegin, iterMethodInt myend, typename iterMethodIntInt, iterMethodIntInt mylower_bound>
|
||||||
NoteData::_all_tracks_iterator<ND, iter, TN>::_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, NoteData::IteratorCond cond ) :
|
NoteData::_all_tracks_iterator<ND, iter, TN, bReverse, iterMethodInt, mybegin, myend, iterMethodIntInt, mylower_bound>::_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, NoteData::IteratorCond cond ) :
|
||||||
m_NoteData(nd), m_iTrack(0), m_iEndRow(iEndRow), m_Cond(cond)
|
m_NoteData(nd), m_iTrack(0), m_iStartRow(iStartRow), m_iEndRow(iEndRow), m_Cond(cond)
|
||||||
{
|
{
|
||||||
ASSERT( m_NoteData.GetNumTracks() > 0 );
|
ASSERT( m_NoteData.GetNumTracks() > 0 );
|
||||||
for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack )
|
for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack )
|
||||||
m_vIters.push_back( m_NoteData.lower_bound(iTrack, iStartRow) );
|
{
|
||||||
|
iter i = (m_NoteData.*mylower_bound)(iTrack, bReverse?iEndRow:iStartRow);
|
||||||
|
iter end = (m_NoteData.*myend)(iTrack);
|
||||||
|
m_vIters.push_back( i );
|
||||||
|
}
|
||||||
Find();
|
Find();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ND, typename iter, typename TN>
|
template<typename ND, typename iter, typename TN, bool bReverse, typename iterMethodInt, iterMethodInt mybegin, iterMethodInt myend, typename iterMethodIntInt, iterMethodIntInt mylower_bound>
|
||||||
NoteData::_all_tracks_iterator<ND, iter, TN> &NoteData::_all_tracks_iterator<ND, iter, TN>::operator++() // preincrement
|
NoteData::_all_tracks_iterator<ND, iter, TN, bReverse, iterMethodInt, mybegin, myend, iterMethodIntInt, mylower_bound> &NoteData::_all_tracks_iterator<ND, iter, TN, bReverse, iterMethodInt, mybegin, myend, iterMethodIntInt, mylower_bound>::operator++() // preincrement
|
||||||
{
|
{
|
||||||
++m_vIters[m_iTrack];
|
++m_vIters[m_iTrack];
|
||||||
Find();
|
Find();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ND, typename iter, typename TN>
|
template<typename ND, typename iter, typename TN, bool bReverse, typename iterMethodInt, iterMethodInt mybegin, iterMethodInt myend, typename iterMethodIntInt, iterMethodIntInt mylower_bound>
|
||||||
NoteData::_all_tracks_iterator<ND, iter, TN> NoteData::_all_tracks_iterator<ND, iter, TN>::operator++( int dummy ) // postincrement
|
NoteData::_all_tracks_iterator<ND, iter, TN, bReverse, iterMethodInt, mybegin, myend, iterMethodIntInt, mylower_bound> NoteData::_all_tracks_iterator<ND, iter, TN, bReverse, iterMethodInt, mybegin, myend, iterMethodIntInt, mylower_bound>::operator++( int dummy ) // postincrement
|
||||||
{
|
{
|
||||||
_all_tracks_iterator<ND, iter, TN> ret(*this);
|
_all_tracks_iterator<ND, iter, TN, bReverse, iterMethodInt, mybegin, myend, iterMethodIntInt, mylower_bound> ret(*this);
|
||||||
operator++();
|
operator++();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Explicit instantiation.
|
// Explicit instantiation.
|
||||||
template class NoteData::_all_tracks_iterator<NoteData, NoteData::iterator, TapNote>;
|
template class NoteData::_all_tracks_iterator<NoteData, NoteData::iterator, TapNote, false, NoteData::iterator_method_int, NoteData::begin, NoteData::end, NoteData::iterator_method_int_int, NoteData::lower_bound>;
|
||||||
template class NoteData::_all_tracks_iterator<const NoteData, NoteData::const_iterator, const TapNote>;
|
template class NoteData::_all_tracks_iterator<const NoteData, NoteData::const_iterator, const TapNote, false, NoteData::const_iterator_method_int, NoteData::begin, NoteData::end, NoteData::const_iterator_method_int_int, NoteData::lower_bound>;
|
||||||
|
template class NoteData::_all_tracks_iterator<NoteData, NoteData::reverse_iterator, TapNote, true, NoteData::reverse_iterator_method_int, NoteData::rbegin, NoteData::rend, NoteData::reverse_iterator_method_int_int, NoteData::rlower_bound>;
|
||||||
|
template class NoteData::_all_tracks_iterator<const NoteData, NoteData::const_reverse_iterator, const TapNote, true, NoteData::const_reverse_iterator_method_int, NoteData::rbegin, NoteData::rend, NoteData::const_reverse_iterator_method_int_int, NoteData::rlower_bound>;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2001-2004 Chris Danford, Glenn Maynard
|
* (c) 2001-2004 Chris Danford, Glenn Maynard
|
||||||
|
|||||||
+43
-11
@@ -24,19 +24,48 @@ public:
|
|||||||
typedef map<int,TapNote> TrackMap;
|
typedef map<int,TapNote> TrackMap;
|
||||||
typedef map<int,TapNote>::iterator iterator;
|
typedef map<int,TapNote>::iterator iterator;
|
||||||
typedef map<int,TapNote>::const_iterator const_iterator;
|
typedef map<int,TapNote>::const_iterator const_iterator;
|
||||||
|
typedef map<int,TapNote>::reverse_iterator reverse_iterator;
|
||||||
|
typedef map<int,TapNote>::const_reverse_iterator const_reverse_iterator;
|
||||||
|
|
||||||
|
typedef iterator (NoteData::*iterator_method_int)(int);
|
||||||
|
typedef const_iterator (NoteData::*const_iterator_method_int)(int) const;
|
||||||
|
typedef reverse_iterator (NoteData::*reverse_iterator_method_int)(int);
|
||||||
|
typedef const_reverse_iterator (NoteData::*const_reverse_iterator_method_int)(int) const;
|
||||||
|
typedef iterator (NoteData::*iterator_method_int_int)(int,int);
|
||||||
|
typedef const_iterator (NoteData::*const_iterator_method_int_int)(int,int) const;
|
||||||
|
typedef reverse_iterator (NoteData::*reverse_iterator_method_int_int)(int,int);
|
||||||
|
typedef const_reverse_iterator (NoteData::*const_reverse_iterator_method_int_int)(int,int) const;
|
||||||
|
|
||||||
|
iterator begin( int iTrack ) { return m_TapNotes[iTrack].begin(); }
|
||||||
|
const_iterator begin( int iTrack ) const { return m_TapNotes[iTrack].begin(); }
|
||||||
|
reverse_iterator rbegin( int iTrack ) { return m_TapNotes[iTrack].rbegin(); }
|
||||||
|
const_reverse_iterator rbegin( int iTrack ) const { return m_TapNotes[iTrack].rbegin(); }
|
||||||
|
iterator end( int iTrack ) { return m_TapNotes[iTrack].end(); }
|
||||||
|
const_iterator end( int iTrack ) const { return m_TapNotes[iTrack].end(); }
|
||||||
|
reverse_iterator rend( int iTrack ) { return m_TapNotes[iTrack].rend(); }
|
||||||
|
const_reverse_iterator rend( int iTrack ) const { return m_TapNotes[iTrack].rend(); }
|
||||||
|
iterator lower_bound( int iTrack, int iRow ) { return m_TapNotes[iTrack].lower_bound( iRow ); }
|
||||||
|
const_iterator lower_bound( int iTrack, int iRow ) const { return m_TapNotes[iTrack].lower_bound( iRow ); }
|
||||||
|
reverse_iterator rlower_bound( int iTrack, int iRow );
|
||||||
|
const_reverse_iterator rlower_bound( int iTrack, int iRow ) const;
|
||||||
|
void swap( NoteData &nd ) { m_TapNotes.swap( nd.m_TapNotes ); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef bool (*IteratorCond)( const TapNote& );
|
typedef bool (*IteratorCond)( const TapNote& );
|
||||||
// This is ugly to make it templated but I don't want to have to write the same class twice.
|
// This is ugly to make it templated but I don't want to have to write the same class twice.
|
||||||
template<typename ND, typename iter, typename TN>
|
template<typename ND, typename iter, typename TN, bool bReverse, typename iterMethodInt, iterMethodInt mybegin, iterMethodInt myend, typename iterMethodIntInt, iterMethodIntInt mylower_bound>
|
||||||
class _all_tracks_iterator
|
class _all_tracks_iterator
|
||||||
{
|
{
|
||||||
ND &m_NoteData;
|
ND &m_NoteData;
|
||||||
vector<iter> m_vIters;
|
vector<iter> m_vIters;
|
||||||
int m_iTrack;
|
int m_iTrack;
|
||||||
|
const int m_iStartRow;
|
||||||
const int m_iEndRow;
|
const int m_iEndRow;
|
||||||
IteratorCond m_Cond;
|
IteratorCond m_Cond;
|
||||||
|
|
||||||
void Find();
|
void Find(); // point m_iTrack at the iterator with the smallest row that meets mCond and is within range
|
||||||
public:
|
public:
|
||||||
_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, IteratorCond cond );
|
_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, IteratorCond cond );
|
||||||
_all_tracks_iterator &operator++(); // preincrement
|
_all_tracks_iterator &operator++(); // preincrement
|
||||||
@@ -49,8 +78,10 @@ public:
|
|||||||
inline const TN &operator*() const { DEBUG_ASSERT( !IsAtEnd() ); return m_vIters[m_iTrack]->second; }
|
inline const TN &operator*() const { DEBUG_ASSERT( !IsAtEnd() ); return m_vIters[m_iTrack]->second; }
|
||||||
inline const TN *operator->() const { DEBUG_ASSERT( !IsAtEnd() ); return &m_vIters[m_iTrack]->second; }
|
inline const TN *operator->() const { DEBUG_ASSERT( !IsAtEnd() ); return &m_vIters[m_iTrack]->second; }
|
||||||
};
|
};
|
||||||
typedef _all_tracks_iterator<NoteData, iterator, TapNote> all_tracks_iterator;
|
typedef _all_tracks_iterator<NoteData, NoteData::iterator, TapNote, false, NoteData::iterator_method_int, NoteData::begin, NoteData::end, NoteData::iterator_method_int_int, NoteData::lower_bound> all_tracks_iterator;
|
||||||
typedef _all_tracks_iterator<const NoteData, const_iterator, const TapNote> all_tracks_const_iterator;
|
typedef _all_tracks_iterator<const NoteData, NoteData::const_iterator, const TapNote, false, NoteData::const_iterator_method_int, NoteData::begin, NoteData::end, NoteData::const_iterator_method_int_int, NoteData::lower_bound> all_tracks_const_iterator;
|
||||||
|
typedef _all_tracks_iterator<NoteData, NoteData::reverse_iterator, TapNote, true, NoteData::reverse_iterator_method_int, NoteData::rbegin, NoteData::rend, NoteData::reverse_iterator_method_int_int, NoteData::rlower_bound> all_tracks_reverse_iterator;
|
||||||
|
typedef _all_tracks_iterator<const NoteData, NoteData::const_reverse_iterator, const TapNote, true, NoteData::const_reverse_iterator_method_int, NoteData::rbegin, NoteData::rend, NoteData::const_reverse_iterator_method_int_int, NoteData::rlower_bound> all_tracks_const_reverse_iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// There's no point in inserting empty notes into the map.
|
// There's no point in inserting empty notes into the map.
|
||||||
@@ -78,13 +109,6 @@ public:
|
|||||||
return TAP_EMPTY;
|
return TAP_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin( int iTrack ) { return m_TapNotes[iTrack].begin(); }
|
|
||||||
const_iterator begin( int iTrack ) const { return m_TapNotes[iTrack].begin(); }
|
|
||||||
iterator end( int iTrack ) { return m_TapNotes[iTrack].end(); }
|
|
||||||
const_iterator end( int iTrack ) const { return m_TapNotes[iTrack].end(); }
|
|
||||||
iterator lower_bound( int iTrack, int iRow ) { return m_TapNotes[iTrack].lower_bound( iRow ); }
|
|
||||||
const_iterator lower_bound( int iTrack, int iRow ) const { return m_TapNotes[iTrack].lower_bound( iRow ); }
|
|
||||||
void swap( NoteData &nd ) { m_TapNotes.swap( nd.m_TapNotes ); }
|
|
||||||
|
|
||||||
inline iterator FindTapNote( unsigned iTrack, int iRow ) { return m_TapNotes[iTrack].find( iRow ); }
|
inline iterator FindTapNote( unsigned iTrack, int iRow ) { return m_TapNotes[iTrack].find( iRow ); }
|
||||||
inline const_iterator FindTapNote( unsigned iTrack, int iRow ) const { return m_TapNotes[iTrack].find( iRow ); }
|
inline const_iterator FindTapNote( unsigned iTrack, int iRow ) const { return m_TapNotes[iTrack].find( iRow ); }
|
||||||
@@ -101,6 +125,14 @@ public:
|
|||||||
{
|
{
|
||||||
return all_tracks_const_iterator( *this, iStartRow, iEndRow, cond );
|
return all_tracks_const_iterator( *this, iStartRow, iEndRow, cond );
|
||||||
}
|
}
|
||||||
|
all_tracks_reverse_iterator GetTapNoteRangeAllTracksReverse( int iStartRow, int iEndRow, IteratorCond cond = NULL )
|
||||||
|
{
|
||||||
|
return all_tracks_reverse_iterator( *this, iStartRow, iEndRow, cond );
|
||||||
|
}
|
||||||
|
all_tracks_const_reverse_iterator GetTapNoteRangeAllTracksReverse( int iStartRow, int iEndRow, IteratorCond cond = NULL) const
|
||||||
|
{
|
||||||
|
return all_tracks_const_reverse_iterator( *this, iStartRow, iEndRow, cond );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return an iterator range include iStartRow to iEndRow. Extend the range to include
|
/* Return an iterator range include iStartRow to iEndRow. Extend the range to include
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ int GetSuccessfulMines( const NoteData &in, int iStartIndex = 0, int iEndIndex =
|
|||||||
int iNumSuccessfulMinesNotes = 0;
|
int iNumSuccessfulMinesNotes = 0;
|
||||||
NoteData::all_tracks_const_iterator iter = in.GetTapNoteRangeAllTracks( iStartIndex, iEndIndex, AvoidedMines );
|
NoteData::all_tracks_const_iterator iter = in.GetTapNoteRangeAllTracks( iStartIndex, iEndIndex, AvoidedMines );
|
||||||
for( ; !iter.IsAtEnd(); ++iter )
|
for( ; !iter.IsAtEnd(); ++iter )
|
||||||
++iNumSuccessfulMinesNotes;
|
iNumSuccessfulMinesNotes++;
|
||||||
return iNumSuccessfulMinesNotes;
|
return iNumSuccessfulMinesNotes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user