1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/string/public/nsStringIterator.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,327 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsStringIterator_h___ 1.10 +#define nsStringIterator_h___ 1.11 + 1.12 +#include "nsCharTraits.h" 1.13 +#include "nsAlgorithm.h" 1.14 +#include "nsDebug.h" 1.15 + 1.16 + /** 1.17 + * @see nsTAString 1.18 + */ 1.19 + 1.20 +template <class CharT> 1.21 +class nsReadingIterator 1.22 + { 1.23 + public: 1.24 + typedef nsReadingIterator<CharT> self_type; 1.25 + typedef ptrdiff_t difference_type; 1.26 + typedef CharT value_type; 1.27 + typedef const CharT* pointer; 1.28 + typedef const CharT& reference; 1.29 + 1.30 + private: 1.31 + friend class nsAString; 1.32 + friend class nsACString; 1.33 + 1.34 + // unfortunately, the API for nsReadingIterator requires that the 1.35 + // iterator know its start and end positions. this was needed when 1.36 + // we supported multi-fragment strings, but now it is really just 1.37 + // extra baggage. we should remove mStart and mEnd at some point. 1.38 + 1.39 + const CharT* mStart; 1.40 + const CharT* mEnd; 1.41 + const CharT* mPosition; 1.42 + 1.43 + public: 1.44 + nsReadingIterator() { } 1.45 + // nsReadingIterator( const nsReadingIterator<CharT>& ); // auto-generated copy-constructor OK 1.46 + // nsReadingIterator<CharT>& operator=( const nsReadingIterator<CharT>& ); // auto-generated copy-assignment operator OK 1.47 + 1.48 + inline void normalize_forward() {} 1.49 + inline void normalize_backward() {} 1.50 + 1.51 + pointer 1.52 + start() const 1.53 + { 1.54 + return mStart; 1.55 + } 1.56 + 1.57 + pointer 1.58 + end() const 1.59 + { 1.60 + return mEnd; 1.61 + } 1.62 + 1.63 + pointer 1.64 + get() const 1.65 + { 1.66 + return mPosition; 1.67 + } 1.68 + 1.69 + CharT 1.70 + operator*() const 1.71 + { 1.72 + return *get(); 1.73 + } 1.74 + 1.75 +#if 0 1.76 + // An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2) 1.77 + // don't like this when |CharT| is a type without members. 1.78 + pointer 1.79 + operator->() const 1.80 + { 1.81 + return get(); 1.82 + } 1.83 +#endif 1.84 + 1.85 + self_type& 1.86 + operator++() 1.87 + { 1.88 + ++mPosition; 1.89 + return *this; 1.90 + } 1.91 + 1.92 + self_type 1.93 + operator++( int ) 1.94 + { 1.95 + self_type result(*this); 1.96 + ++mPosition; 1.97 + return result; 1.98 + } 1.99 + 1.100 + self_type& 1.101 + operator--() 1.102 + { 1.103 + --mPosition; 1.104 + return *this; 1.105 + } 1.106 + 1.107 + self_type 1.108 + operator--( int ) 1.109 + { 1.110 + self_type result(*this); 1.111 + --mPosition; 1.112 + return result; 1.113 + } 1.114 + 1.115 + difference_type 1.116 + size_forward() const 1.117 + { 1.118 + return mEnd - mPosition; 1.119 + } 1.120 + 1.121 + difference_type 1.122 + size_backward() const 1.123 + { 1.124 + return mPosition - mStart; 1.125 + } 1.126 + 1.127 + self_type& 1.128 + advance( difference_type n ) 1.129 + { 1.130 + if (n > 0) 1.131 + { 1.132 + difference_type step = XPCOM_MIN(n, size_forward()); 1.133 + 1.134 + NS_ASSERTION(step>0, "can't advance a reading iterator beyond the end of a string"); 1.135 + 1.136 + mPosition += step; 1.137 + } 1.138 + else if (n < 0) 1.139 + { 1.140 + difference_type step = XPCOM_MAX(n, -size_backward()); 1.141 + 1.142 + NS_ASSERTION(step<0, "can't advance (backward) a reading iterator beyond the end of a string"); 1.143 + 1.144 + mPosition += step; 1.145 + } 1.146 + return *this; 1.147 + } 1.148 + }; 1.149 + 1.150 + /** 1.151 + * @see nsTAString 1.152 + */ 1.153 + 1.154 +template <class CharT> 1.155 +class nsWritingIterator 1.156 + { 1.157 + public: 1.158 + typedef nsWritingIterator<CharT> self_type; 1.159 + typedef ptrdiff_t difference_type; 1.160 + typedef CharT value_type; 1.161 + typedef CharT* pointer; 1.162 + typedef CharT& reference; 1.163 + 1.164 + private: 1.165 + friend class nsAString; 1.166 + friend class nsACString; 1.167 + 1.168 + // unfortunately, the API for nsWritingIterator requires that the 1.169 + // iterator know its start and end positions. this was needed when 1.170 + // we supported multi-fragment strings, but now it is really just 1.171 + // extra baggage. we should remove mStart and mEnd at some point. 1.172 + 1.173 + CharT* mStart; 1.174 + CharT* mEnd; 1.175 + CharT* mPosition; 1.176 + 1.177 + public: 1.178 + nsWritingIterator() { } 1.179 + // nsWritingIterator( const nsWritingIterator<CharT>& ); // auto-generated copy-constructor OK 1.180 + // nsWritingIterator<CharT>& operator=( const nsWritingIterator<CharT>& ); // auto-generated copy-assignment operator OK 1.181 + 1.182 + inline void normalize_forward() {} 1.183 + inline void normalize_backward() {} 1.184 + 1.185 + pointer 1.186 + start() const 1.187 + { 1.188 + return mStart; 1.189 + } 1.190 + 1.191 + pointer 1.192 + end() const 1.193 + { 1.194 + return mEnd; 1.195 + } 1.196 + 1.197 + pointer 1.198 + get() const 1.199 + { 1.200 + return mPosition; 1.201 + } 1.202 + 1.203 + reference 1.204 + operator*() const 1.205 + { 1.206 + return *get(); 1.207 + } 1.208 + 1.209 +#if 0 1.210 + // An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2) 1.211 + // don't like this when |CharT| is a type without members. 1.212 + pointer 1.213 + operator->() const 1.214 + { 1.215 + return get(); 1.216 + } 1.217 +#endif 1.218 + 1.219 + self_type& 1.220 + operator++() 1.221 + { 1.222 + ++mPosition; 1.223 + return *this; 1.224 + } 1.225 + 1.226 + self_type 1.227 + operator++( int ) 1.228 + { 1.229 + self_type result(*this); 1.230 + ++mPosition; 1.231 + return result; 1.232 + } 1.233 + 1.234 + self_type& 1.235 + operator--() 1.236 + { 1.237 + --mPosition; 1.238 + return *this; 1.239 + } 1.240 + 1.241 + self_type 1.242 + operator--( int ) 1.243 + { 1.244 + self_type result(*this); 1.245 + --mPosition; 1.246 + return result; 1.247 + } 1.248 + 1.249 + difference_type 1.250 + size_forward() const 1.251 + { 1.252 + return mEnd - mPosition; 1.253 + } 1.254 + 1.255 + difference_type 1.256 + size_backward() const 1.257 + { 1.258 + return mPosition - mStart; 1.259 + } 1.260 + 1.261 + self_type& 1.262 + advance( difference_type n ) 1.263 + { 1.264 + if (n > 0) 1.265 + { 1.266 + difference_type step = XPCOM_MIN(n, size_forward()); 1.267 + 1.268 + NS_ASSERTION(step>0, "can't advance a writing iterator beyond the end of a string"); 1.269 + 1.270 + mPosition += step; 1.271 + } 1.272 + else if (n < 0) 1.273 + { 1.274 + difference_type step = XPCOM_MAX(n, -size_backward()); 1.275 + 1.276 + NS_ASSERTION(step<0, "can't advance (backward) a writing iterator beyond the end of a string"); 1.277 + 1.278 + mPosition += step; 1.279 + } 1.280 + return *this; 1.281 + } 1.282 + 1.283 + void 1.284 + write( const value_type* s, uint32_t n ) 1.285 + { 1.286 + NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!"); 1.287 + 1.288 + nsCharTraits<value_type>::move(mPosition, s, n); 1.289 + advance( difference_type(n) ); 1.290 + } 1.291 + }; 1.292 + 1.293 +template <class CharT> 1.294 +inline 1.295 +bool 1.296 +operator==( const nsReadingIterator<CharT>& lhs, const nsReadingIterator<CharT>& rhs ) 1.297 + { 1.298 + return lhs.get() == rhs.get(); 1.299 + } 1.300 + 1.301 +template <class CharT> 1.302 +inline 1.303 +bool 1.304 +operator!=( const nsReadingIterator<CharT>& lhs, const nsReadingIterator<CharT>& rhs ) 1.305 + { 1.306 + return lhs.get() != rhs.get(); 1.307 + } 1.308 + 1.309 + 1.310 + // 1.311 + // |nsWritingIterator|s 1.312 + // 1.313 + 1.314 +template <class CharT> 1.315 +inline 1.316 +bool 1.317 +operator==( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs ) 1.318 + { 1.319 + return lhs.get() == rhs.get(); 1.320 + } 1.321 + 1.322 +template <class CharT> 1.323 +inline 1.324 +bool 1.325 +operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs ) 1.326 + { 1.327 + return lhs.get() != rhs.get(); 1.328 + } 1.329 + 1.330 +#endif /* !defined(nsStringIterator_h___) */