1 #ifndef GENESIS_POPULATION_WINDOW_SLIDING_INTERVAL_WINDOW_ITERATOR_H_
2 #define GENESIS_POPULATION_WINDOW_SLIDING_INTERVAL_WINDOW_ITERATOR_H_
40 #include <type_traits>
44 namespace population {
65 template<
class ForwardIterator,
class DataType =
typename ForwardIterator::value_type>
79 using InputType =
typename ForwardIterator::value_type;
103 ForwardIterator, DataType
107 ForwardIterator, DataType
139 if( parent_->width_ == 0 ) {
140 throw std::runtime_error(
"Cannot use SlidingIntervalWindowIterator of width 0." );
142 if( parent_->stride_ == 0 ) {
143 parent_->stride_ = parent_->width_;
145 if( parent_->stride_ > parent_->width_ ) {
146 throw std::runtime_error(
147 "Cannot use SlidingIntervalWindowIterator with stride > width."
174 void init_chromosome_()
177 if( base_iterator_type::current_ == base_iterator_type::end_ ) {
184 base_iterator_type::is_first_window_ =
true;
185 base_iterator_type::is_last_window_ =
false;
188 if( parent_->emit_leading_empty_windows_ ) {
194 current_start_ = pos - (( pos - 1 ) % parent_->stride_ );
198 void increment_() override final
204 if( base_iterator_type::current_ == base_iterator_type::end_ ) {
208 if( ! base_iterator_type::is_last_window_ ) {
209 throw std::runtime_error(
210 "SlidingIntervalWindowIterator: Incrementing past the end"
226 current_start_ += parent_->stride_;
227 base_iterator_type::is_first_window_ =
false;
241 window_.
entries().size() > 0 &&
242 window_.
entries().back().position < current_start_
247 window_.
entries().size() > 0 &&
248 window_.
entries().front().position < current_start_
255 while( base_iterator_type::current_ != base_iterator_type::end_ ) {
256 auto const cur_pos = parent_->
position_function( *base_iterator_type::current_ );
262 *base_iterator_type::current_
264 cur_pos >= current_start_ + parent_->width_
272 assert( cur_pos >= current_start_ );
273 assert( cur_pos < current_start_ + parent_->width_ );
278 window_.
size() > 0 &&
279 window_.
entries().back().position >= cur_pos
281 throw std::runtime_error(
282 "Invalid entry in sliding window that not in sequence with other entries. "
283 "Previous entry is " + window_.
chromosome() +
":" +
285 ", current (invalid) entry is " + window_.
chromosome() +
":" +
291 window_.
entries().emplace_back(
297 ++base_iterator_type::current_;
303 base_iterator_type::current_ == base_iterator_type::end_ ||
306 base_iterator_type::is_last_window_ =
true;
311 window_.
last_position( current_start_ + parent_->width_ - 1 );
314 value_type& get_current_window_() const override final
319 BaseWindowIterator<ForwardIterator, DataType>
const* get_parent_() const override final
331 size_t current_start_ = 1;
332 size_t next_index_ = 0;
345 ForwardIterator
begin, ForwardIterator
end
411 emit_leading_empty_windows_ = value;
417 return emit_leading_empty_windows_;
426 std::unique_ptr<typename BaseWindowIterator<ForwardIterator, DataType>::BaseIterator>
435 std::unique_ptr<typename BaseWindowIterator<ForwardIterator, DataType>::BaseIterator>
438 return std::unique_ptr<DerivedIterator>(
new DerivedIterator(
nullptr ));
450 mutable size_t stride_ = 0;
452 bool emit_leading_empty_windows_ =
true;
472 template<
class ForwardIterator,
class DataType =
typename ForwardIterator::value_type>
473 SlidingIntervalWindowIterator<ForwardIterator, DataType>
475 ForwardIterator begin, ForwardIterator end,
size_t width = 0,
size_t stride = 0
493 template<
class ForwardIterator>
494 SlidingIntervalWindowIterator<ForwardIterator>
496 ForwardIterator begin, ForwardIterator end,
size_t width = 0,
size_t stride = 0
498 using DataType =
typename ForwardIterator::value_type;
502 it.entry_input_function = []( DataType
const& variant ) {
505 it.chromosome_function = []( DataType
const& variant ) {
506 return variant.chromosome;
508 it.position_function = []( DataType
const& variant ) {
509 return variant.position;
521 #endif // include guard