1 /* 2 Copyright (C) 2017-2018 by the Battle for Wesnoth Project https://www.wesnoth.org/ 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY. 10 11 See the COPYING file for more details. 12 */ 13 14 #pragma once 15 16 #include <iterator> //input_iterator_tag 17 #include <utility> //pair 18 #include <cstddef> //ptrdiff_t 19 #include <cassert> //assert 20 21 #include "unicode_types.hpp" 22 23 namespace ucs4 24 { 25 template<typename string_type, typename update_implementation> 26 class iterator_base 27 { 28 public: 29 typedef std::input_iterator_tag iterator_category; 30 typedef ucs4::char_t value_type; 31 typedef ptrdiff_t difference_type; 32 typedef ucs4::char_t* pointer; 33 typedef ucs4::char_t& reference; 34 iterator_base(const string_type & str)35 iterator_base(const string_type& str) 36 : current_char(0) 37 , string_end(str.end()) 38 , current_substr(std::make_pair(str.begin(), str.begin())) 39 { 40 update(); 41 } 42 iterator_base(typename string_type::const_iterator const & begin,typename string_type::const_iterator const & end)43 iterator_base(typename string_type::const_iterator const& begin, typename string_type::const_iterator const& end) 44 : current_char(0) 45 , string_end(end) 46 , current_substr(std::make_pair(begin, begin)) 47 { 48 update(); 49 } 50 begin(const string_type & str)51 static iterator_base begin(const string_type& str) 52 { 53 return iterator_base(str.begin(), str.end()); 54 } 55 end(const string_type & str)56 static iterator_base end(const string_type& str) 57 { 58 return iterator_base(str.end(), str.end()); 59 } 60 operator ==(const iterator_base & a) const61 bool operator==(const iterator_base& a) const 62 { 63 return current_substr.first == a.current_substr.first; 64 } 65 operator !=(const iterator_base & a) const66 bool operator!=(const iterator_base& a) const 67 { 68 return ! (*this == a); 69 } 70 operator ++()71 iterator_base& operator++() 72 { 73 current_substr.first = current_substr.second; 74 update(); 75 return *this; 76 } 77 operator *() const78 ucs4::char_t operator*() const 79 { 80 return current_char; 81 } 82 next_is_end() const83 bool next_is_end() const 84 { 85 if(current_substr.second == string_end) 86 return true; 87 return false; 88 } 89 substr() const90 const std::pair<typename string_type::const_iterator, typename string_type::const_iterator>& substr() const 91 { 92 return current_substr; 93 } 94 private: update()95 void update() 96 { 97 assert(current_substr.first == current_substr.second); 98 if(current_substr.first == string_end) 99 return; 100 current_char = update_implementation::read(current_substr.second, string_end); 101 } 102 103 ucs4::char_t current_char; 104 typename string_type::const_iterator string_end; 105 std::pair<typename string_type::const_iterator, typename string_type::const_iterator> current_substr; 106 }; 107 108 } 109