vector.h (Firebird-3.0.2.32703-0.tar.bz2) | : | vector.h (Firebird-3.0.4.33054-0.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 194 | skipping to change at line 194 | |||
} | } | |||
FB_SIZE_T add(const Value& item) | FB_SIZE_T add(const Value& item) | |||
{ | { | |||
FB_SIZE_T pos; | FB_SIZE_T pos; | |||
find(KeyOfValue::generate(this, item), pos); | find(KeyOfValue::generate(this, item), pos); | |||
this->insert(pos, item); | this->insert(pos, item); | |||
return pos; | return pos; | |||
} | } | |||
}; | }; | |||
// Templates to allow to iterate thru array\vector of values and process items | ||||
// in some way. Processed items are marked and skipped at next iteration circle. | ||||
// Idea is to not remove processed items from array and avoid costly memory | ||||
// moving. Also, iterator is able to move upper and lower bounds of array if | ||||
// last (or first) items are marked, making next iterations more efficient. | ||||
template <typename T> | ||||
class DefaultMarkValue | ||||
{ | ||||
public: | ||||
static T getMarkValue() | ||||
{ | ||||
return T(0); | ||||
} | ||||
}; | ||||
template <typename T, typename MarkValue = DefaultMarkValue<T> > | ||||
class DefaultMarker | ||||
{ | ||||
public: | ||||
static void mark(T* const item) | ||||
{ | ||||
*item = MarkValue::getMarkValue(); | ||||
}; | ||||
static bool isMarked(const T* const item) | ||||
{ | ||||
return *item == MarkValue::getMarkValue(); | ||||
}; | ||||
}; | ||||
template <typename T, typename Marker = DefaultMarker<T> > | ||||
class MarkIterator | ||||
{ | ||||
public: | ||||
MarkIterator(T* begin, FB_SIZE_T count) : | ||||
m_begin(begin), | ||||
m_end(begin + count), | ||||
m_curr(begin), | ||||
m_last(begin) | ||||
{ | ||||
} | ||||
// Mark current item as processed | ||||
void mark() | ||||
{ | ||||
Marker::mark(m_curr); | ||||
if (m_last == m_curr) | ||||
m_last--; | ||||
} | ||||
// Move iterator position to the first not processed item | ||||
void rewind() | ||||
{ | ||||
m_curr = m_begin; | ||||
m_end = m_last + 1; | ||||
m_last = m_begin; | ||||
} | ||||
T& operator*() const | ||||
{ | ||||
fb_assert(m_begin <= m_curr); | ||||
fb_assert(m_curr < m_end); | ||||
return *m_curr; | ||||
} | ||||
// Advance iterator to the next not processed item, if exist | ||||
void operator++() | ||||
{ | ||||
fb_assert(m_begin <= m_curr); | ||||
fb_assert(m_curr < m_end); | ||||
const bool at_begin = (m_begin == m_curr); | ||||
m_curr++; | ||||
while (m_curr < m_end && Marker::isMarked(m_curr)) | ||||
m_curr++; | ||||
if (m_curr == m_end) | ||||
return; | ||||
if (at_begin) | ||||
{ | ||||
if (Marker::isMarked(m_begin)) | ||||
m_begin = m_curr; | ||||
else if (m_begin != m_curr - 1) | ||||
{ | ||||
m_curr[-1] = *m_begin; | ||||
m_begin = m_curr - 1; | ||||
} | ||||
} | ||||
if (!Marker::isMarked(m_curr)) | ||||
m_last = m_curr; | ||||
return; | ||||
} | ||||
// Show if current position is valid | ||||
bool isEof() const | ||||
{ | ||||
return m_curr >= m_end; | ||||
} | ||||
// Show if not processed items still exists | ||||
bool isEmpty() const | ||||
{ | ||||
return (m_begin >= m_end); | ||||
} | ||||
private: | ||||
T* m_begin; | ||||
T* m_end; | ||||
T* m_curr; | ||||
T* m_last; | ||||
}; | ||||
} // namespace Firebird | } // namespace Firebird | |||
#endif | #endif | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 118 lines changed or added |