#ifndef OBSERVERS_HH #define OBSERVERS_HH #include #include template class Observers { public: Observers() : current_(0), protected_(0), removed_(0) { } void add(T* observer) { if (!observer) return; for (auto it = observers_.begin(); it != observers_.end(); ++it) { if (*it == observer) return; } observers_.push_back(observer); } void remove(T* observer) { if (!observer) return; size_t index = 0; for (; index < observers_.size(); ++index) { if (observers_[index] == observer) { if (index < protected_) { observers_[index] = nullptr; ++removed_; } else { observers_.erase(observers_.begin() + index); } break; } } } T* first() { if (protected_) return nullptr; if (observers_.empty()) return nullptr; protected_ = observers_.size(); return observers_[current_]; } T* next() { if (current_ >= protected_) return nullptr; ++current_; if (current_ >= protected_) { if (removed_) { for (size_t i = protected_; i > 0; --i) { if (!observers_[i - 1]) { observers_.erase(observers_.begin() + i - 1); if (--removed_ == 0) break; } } } protected_ = current_ = 0; return nullptr; } auto ret = observers_[current_]; return ret ? ret : next(); } private: size_t current_; size_t protected_; size_t removed_; std::vector observers_; }; #endif // OBSERVERS_HH