1 #ifndef GENESIS_POPULATION_WINDOW_BASE_WINDOW_STREAM_H_
2 #define GENESIS_POPULATION_WINDOW_BASE_WINDOW_STREAM_H_
43 #include <type_traits>
48 namespace population {
115 class InputStreamIterator,
116 class Data =
typename InputStreamIterator::value_type,
117 class WindowType = typename ::genesis::population::Window<Data>
131 using InputType =
typename InputStreamIterator::value_type;
205 static_assert( std::is_same<Iterator, self_type>::value,
"Iterator != self_type" );
213 std::unique_ptr<BaseIterator> base_iterator
215 : base_parent_( parent )
216 , pimpl_( std::move( base_iterator ))
222 if( !base_parent_ ) {
225 assert( base_parent_ );
228 execute_begin_callbacks_();
229 execute_on_enter_observers_();
233 if( !pimpl_->get_parent_() ) {
234 execute_end_callbacks_();
248 base_parent_ = other.base_parent_;
249 pimpl_ = std::move( other.pimpl_ );
253 other.base_parent_ =
nullptr;
254 other.pimpl_ =
nullptr;
263 base_parent_ = other.base_parent_;
264 pimpl_ = std::move( other.pimpl_ );
265 other.base_parent_ =
nullptr;
266 other.pimpl_ =
nullptr;
289 return pimpl_->is_first_window_;
305 return pimpl_->is_last_window_;
315 return pimpl_->get_current_window_();
321 return pimpl_->get_current_window_();
327 return &( pimpl_->get_current_window_() );
333 return &( pimpl_->get_current_window_() );
343 assert( base_parent_ );
352 execute_on_leave_observers_();
353 pimpl_->increment_();
358 execute_on_enter_observers_();
361 assert( base_parent_ );
362 if( !pimpl_->get_parent_() ) {
363 execute_end_callbacks_();
387 assert( other.pimpl_ );
391 return pimpl_->get_parent_() == other.pimpl_->get_parent_();
396 return !(*
this == other);
405 void execute_on_enter_observers_()
410 if( pimpl_->get_parent_() ) {
411 auto& window = pimpl_->get_current_window_();
412 for(
auto const& observer : pimpl_->get_parent_()->on_enter_observers_ ) {
418 void execute_on_leave_observers_()
423 if( pimpl_->get_parent_() ) {
424 auto& window = pimpl_->get_current_window_();
425 for(
auto const& observer : pimpl_->get_parent_()->on_leave_observers_ ) {
431 void execute_begin_callbacks_()
const
433 assert( base_parent_ );
434 for(
auto const& cb : base_parent_->begin_callbacks_ ) {
439 void execute_end_callbacks_()
const
441 assert( base_parent_ );
442 for(
auto const& cb : base_parent_->end_callbacks_ ) {
461 std::unique_ptr<BaseIterator> pimpl_;
497 static_assert( std::is_same<BaseIterator, self_type>::value,
"BaseIterator != self_type" );
551 throw std::runtime_error(
552 "Need to set BaseWindowStream::entry_input_function "
553 "before iterating over Windows with a Window Iterator."
557 throw std::runtime_error(
558 "Need to set BaseWindowStream::chromosome_function "
559 "before iterating over Windows with a Window Iterator."
563 throw std::runtime_error(
564 "Need to set BaseWindowStream::position_function "
565 "before iterating over Windows with a Window Iterator."
654 on_enter_observers_.push_back( observer );
673 on_leave_observers_.push_back( observer );
684 on_enter_observers_.clear();
685 on_leave_observers_.clear();
701 throw std::runtime_error(
702 "Window Stream: Cannot change callbacks after iteration has started."
705 begin_callbacks_.push_back( callback );
719 throw std::runtime_error(
720 "Window Stream: Cannot change callbacks after iteration has started."
723 end_callbacks_.push_back( callback );
734 throw std::runtime_error(
735 "Window Stream: Cannot change callbacks after iteration has started."
738 begin_callbacks_.clear();
739 end_callbacks_.clear();
750 throw std::runtime_error(
751 "Window Stream is an input iterator (single pass), "
752 "but begin() has been called multiple times."
796 InputStreamIterator begin_;
797 InputStreamIterator end_;
798 mutable bool started_ =
false;
801 std::vector<std::function<void(WindowType
const&)>> on_enter_observers_;
802 std::vector<std::function<void(WindowType
const&)>> on_leave_observers_;
805 std::vector<std::function<void()>> begin_callbacks_;
806 std::vector<std::function<void()>> end_callbacks_;
813 #endif // include guard