Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <exception>
- #include <iostream>
- #include <iterator>
- #include <list>
- #include <sstream>
- #include <vector>
- template<typename ForwardIterator, typename IndexIterator>
- class indirection_iterator {
- public:
- indirection_iterator(ForwardIterator element_begin,
- ForwardIterator element_end,
- IndexIterator index_begin,
- IndexIterator index_end)
- :
- m_element_begin{element_begin},
- m_element_end{element_end},
- m_index_begin{index_begin},
- m_index_end{index_end},
- m_index_current{index_begin},
- m_elements{std::distance(element_begin, element_end)}
- {}
- indirection_iterator begin()
- {
- return indirection_iterator{m_element_begin,
- m_element_end,
- m_index_begin,
- m_index_end,
- m_index_begin};
- }
- indirection_iterator end()
- {
- return indirection_iterator{m_element_begin,
- m_element_end,
- m_index_begin,
- m_index_end,
- m_index_end};
- }
- auto operator*()
- {
- auto index = *m_index_current;
- check_index(index, m_elements);
- auto element_iterator = m_element_begin;
- std::advance(element_iterator, index);
- return *element_iterator;
- }
- void operator++()
- {
- std::advance(m_index_current, 1);
- }
- bool operator!=(indirection_iterator const& other)
- {
- return m_index_current != other.m_index_current;
- }
- private:
- indirection_iterator(ForwardIterator element_begin,
- ForwardIterator element_end,
- IndexIterator index_begin,
- IndexIterator index_end,
- IndexIterator index_current)
- :
- m_element_begin{element_begin},
- m_element_end{element_end},
- m_index_begin{index_begin},
- m_index_end{index_end},
- m_index_current{index_current},
- m_elements{std::distance(element_begin, element_end)}
- {}
- template<typename IndexIter>
- using index_type = typename std::iterator_traits<IndexIter>::value_type;
- ForwardIterator m_element_begin;
- ForwardIterator m_element_end;
- IndexIterator m_index_begin;
- IndexIterator m_index_end;
- IndexIterator m_index_current;
- typename std::iterator_traits<ForwardIterator>::difference_type m_elements;
- template<typename index_type>
- void check_index(index_type index, size_t elements)
- {
- if (index < 0)
- {
- std::stringstream ss;
- ss << "index(" << index << ") < 0";
- throw std::runtime_error{ss.str()};
- }
- if (index >= elements)
- {
- std::stringstream ss;
- ss << "index(" << index << ") >= elements(" << elements << ")";
- throw std::runtime_error{ss.str()};
- }
- }
- };
- static std::vector<char> get_alphabet() {
- std::vector<char> alphabet;
- for (char ch = 'a'; ch <= 'z'; ch++)
- {
- alphabet.push_back(ch);
- }
- for (char ch = 'A'; ch <= 'Z'; ch++)
- {
- alphabet.push_back(ch);
- }
- alphabet.push_back(',');
- alphabet.push_back(' ');
- alphabet.push_back('!');
- alphabet.push_back('n');
- return alphabet;
- }
- int main(int argc, const char * argv[]) {
- std::vector<char> alphabet = get_alphabet();
- std::list<int> char_indices =
- { 33, 4, 11, 11, 14, 52, 53, 48, 14, 17, 11, 3, 54, 55 };
- indirection_iterator<decltype(alphabet.cbegin()),
- decltype(char_indices.cbegin())> indirection_iter {
- alphabet.cbegin(),
- alphabet.cend(),
- char_indices.cbegin(),
- char_indices.cend()
- };
- std::copy(indirection_iter.begin(),
- indirection_iter.end(),
- std::ostream_iterator<char>{std::cout});
- return 0;
- }
Add Comment
Please, Sign In to add comment