3 * \remark This file is part of VITA.
5 * \copyright Copyright (C) 2014-2021 EOS di Manlio Morini.
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
10 * You can obtain one at http://mozilla.org/MPL/2.0/
13#if !defined(VITA_I_MEP_H)
14# error "Don't include this file directly, include the specific .h instead"
17#if !defined(VITA_I_MEP_ITERATOR_TCC)
18#define VITA_I_MEP_ITERATOR_TCC
21/// Iterator to scan the active genes of an individual.
23template<bool is_const>
24class i_mep::basic_iterator
27 using iterator_category = std::forward_iterator_tag;
28 using difference_type = std::ptrdiff_t;
29 using value_type = gene;
30 using pointer = value_type *;
31 using const_pointer = const value_type *;
32 using reference = value_type &;
33 using const_reference = const value_type &;
35 using ptr = std::conditional_t<is_const, const_pointer, pointer>;
36 using ref = std::conditional_t<is_const, const_reference, reference>;
37 using ind = std::conditional_t<is_const, const i_mep, i_mep>;
39 /// Builds an empty iterator.
41 /// Empty iterator is used as sentry (it's the value returned by end()).
42 basic_iterator() : loci_(), ind_(nullptr) {}
44 /// \param[in] id an individual
45 explicit basic_iterator(ind &id) : loci_({id.best()}), ind_(&id)
49 /// \return iterator representing the next active gene
50 basic_iterator &operator++()
54 const auto args(operator*().arguments());
57 loci_.erase(loci_.begin());
60 auto node(loci_.extract(loci_.begin()));
61 node.value() = args.front();
62 loci_.insert(std::move(node));
64 loci_.insert(std::next(args.begin()), args.end());
71 /// \param[in] rhs second term of comparison
72 /// \return `true` if iterators point to the same locus or they are
74 bool operator==(const basic_iterator &rhs) const
76 Ensures(!ind_ || !rhs.ind_ || ind_ == rhs.ind_);
78 return (loci_.empty() && rhs.loci_.empty()) ||
79 loci_.cbegin() == rhs.loci_.cbegin();
82 bool operator!=(const basic_iterator &rhs) const
84 return !(*this == rhs);
87 /// \return reference to the current locus of the individual
90 return ind_->genome_(locus());
93 /// \return pointer to the current locus of the individual
94 ptr operator->() const
99 /// \return the locus of the current gene
100 vita::locus locus() const
102 return *loci_.cbegin();
106 // A partial set of active loci to be explored.
107 // We have tried with `std::vector<bool>` and `std::vector<uint8_t>` based
108 // iterators without measuring significant speed differences.
109 std::set<vita::locus> loci_;
111 // A pointer to the individual we are iterating on.
115#endif // include guard