// =============================================================== // // // // File : SEC_iter.hxx // // Purpose : secondary structure iterators // // // // Coded by Ralf Westram (coder@reallysoft.de) in August 2007 // // Institute of Microbiology (Technical University Munich) // // http://www.arb-home.de/ // // // // =============================================================== // #ifndef SEC_ITER_HXX #define SEC_ITER_HXX // iterates over all parts of the structure (segments/strands) class SEC_base_part_iterator { SEC_base_part *start; SEC_base_part *curr; public: SEC_base_part_iterator(SEC_root *root) : start(root->get_root_loop()->get_fixpoint_strand()), curr(start) {} SEC_base_part& operator*() { return *curr; } SEC_base_part* operator->() { return curr; } SEC_base_part_iterator& operator++() { if (curr) { curr = curr->next(); if (curr == start) curr = NULp; } return *this; } operator bool() const { return curr; } }; // iterates over all bases of the structure (loops/helices) class SEC_base_iterator { SEC_base_part_iterator part; // always points to an outgoing strand bool do_loop; // true -> curr is origin loop, false -> curr is helix SEC_base *curr() { SEC_helix_strand& strand = static_cast(*part); return do_loop ? static_cast(strand.get_origin_loop()) : static_cast(strand.get_helix()); } public: SEC_base_iterator(SEC_root *root) : part(root), do_loop(true) {} SEC_base& operator*() { return *curr(); } SEC_base* operator->() { return curr(); } SEC_base_iterator& operator++() { if (part) { if (do_loop) do_loop = false; else { // skip over all strands pointing to root int steps = 0; do { ++++part; ++steps; } while (part && static_cast(*part).pointsToRoot()); do_loop = (steps == 1); } } return *this; } operator bool() const { return part; } }; // iterates over all strands in one loop (starting with fixpoint strand) class SEC_strand_iterator { SEC_helix_strand *start; SEC_helix_strand *curr; public: SEC_strand_iterator(SEC_loop *loop) : start(loop->get_fixpoint_strand()), curr(start) {} SEC_helix_strand& operator*() { return *curr; } SEC_helix_strand* operator->() { return curr; } SEC_strand_iterator& operator++() { sec_assert(curr); SEC_segment *seg = curr->get_next_segment(); if (seg) { curr = seg->get_next_strand(); if (curr == start) curr = NULp; } else { curr = NULp; } return *this; } operator bool() const { return curr; } }; // iterates over all segments in one loop (starting with segment behind fixpoint strand) class SEC_segment_iterator : private SEC_strand_iterator { const SEC_strand_iterator& strand_iter() const { return static_cast(*this); } SEC_strand_iterator& strand_iter() { return static_cast(*this); } public: SEC_segment_iterator(SEC_loop *loop) : SEC_strand_iterator(loop) {} SEC_segment& operator*() { return *strand_iter()->get_next_segment(); } SEC_segment* operator->() { return strand_iter()->get_next_segment(); } SEC_segment_iterator& operator++() { SEC_strand_iterator& si = strand_iter(); ++si; return *this; } operator bool() const { return strand_iter(); } SEC_helix_strand *get_previous_strand() { return &*strand_iter(); } }; // const versions class SEC_strand_const_iterator : private SEC_strand_iterator { const SEC_strand_iterator& strand_iter() const { return static_cast(*this); } SEC_strand_iterator& strand_iter() { return static_cast(*this); } public: SEC_strand_const_iterator(const SEC_loop *loop) : SEC_strand_iterator(const_cast(loop)) {} const SEC_helix_strand& operator*() { return *strand_iter(); } const SEC_helix_strand* operator->() { return strand_iter().operator->(); } SEC_strand_const_iterator& operator++() { return static_cast(++strand_iter()); } operator bool() const { return bool(strand_iter()); } }; #else #error SEC_iter.hxx included twice #endif // SEC_ITER_HXX