Changeset 1541 for trunk/yat/utility/iterator_traits.h
- Timestamp:
- Sep 30, 2008, 7:40:41 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/yat/utility/iterator_traits.h
r1487 r1541 27 27 28 28 #include <iterator> 29 #include <vector>30 29 31 30 namespace theplu { … … 47 46 struct weighted_iterator_tag {}; 48 47 48 49 /** 50 \internal 51 52 used in weighted_iterator_traits 53 */ 54 template <typename T> 55 struct weighted_iterator_traits_detail { 56 /** 57 default is a iterator unweighted 58 */ 59 typedef unweighted_iterator_tag type; 60 }; 61 62 /** 63 \internal 64 65 specialization for iterators with value type DataWeight 66 */ 67 template <> 68 struct weighted_iterator_traits_detail<DataWeight> { 69 /** 70 Iterators with value type DataWeight is weighted 71 */ 72 typedef weighted_iterator_tag type; 73 }; 74 49 75 /** 50 All iterators default to unweighted type. If you want your 51 iterator to behave as weighted, you need to provide a 52 specialization. 53 54 \see Iterator and StrideIterator 76 Metafunction to decide whether an iterator is weighted or 77 non-weighted. This (default) implementation return unweighted, 78 unless value_type of iterator is DataWeight in which case 79 weighted is returned. 55 80 */ 56 81 template <class T> 57 struct weighted_iterator_traits { 58 /** 59 All iterators default to unweighted type 60 */ 61 typedef unweighted_iterator_tag type; 62 }; 63 64 /** 65 Specialization for std::vector<DataWeight>::iterator 66 */ 67 template<> 68 struct weighted_iterator_traits<std::vector<DataWeight>::iterator> { 69 /** 70 iterator to vector<DataWeight> is weighted 71 */ 72 typedef weighted_iterator_tag type; 73 }; 74 75 76 /** 77 Specialization for std::vector<DataWeight>::const_iterator 78 */ 79 template<> 80 struct weighted_iterator_traits<std::vector<DataWeight>::const_iterator> { 81 /** 82 const_iterator to vector<DataWeight> is weighted 83 */ 84 typedef weighted_iterator_tag type; 82 struct weighted_iterator_traits 83 { 84 private: 85 typedef typename std::iterator_traits<T>::value_type value; 86 public: 87 /** 88 \return weighted if value_type is DataWeight 89 */ 90 typedef typename weighted_iterator_traits_detail<value>::type type; 85 91 }; 86 92 … … 158 164 159 165 /** 160 \brief traits to make unweighted iterator work as in a weighted 161 162 This class must be implemented for every iterator that can be weighted. 163 164 \see StrideIterator and Container2DIterator 166 \internal 167 168 This class is used in iterator_traits to separate different cases. 169 170 This the default implementation that could be used for unweighted 171 iterators. 172 */ 173 template <typename Iter, typename T > 174 struct iterator_traits_detail 175 { 176 /** 177 for unweighted data_reference is reference 178 */ 179 typedef typename std::iterator_traits<Iter>::reference data_reference; 180 181 /** 182 for unweighted weight_reference is a double 183 */ 184 typedef double weight_reference; 185 186 /** 187 Constructor just checking that iterator is unweighted 188 */ 189 iterator_traits_detail(void) 190 { check_iterator_is_unweighted(typename 191 weighted_iterator_traits<Iter>::type()); 192 } 193 194 /** 195 \return * \a iter 196 */ 197 data_reference data(Iter iter) const { return *iter; } 198 199 /** 200 \return 1.0 201 */ 202 weight_reference weight(Iter iter) const { return 1.0; } 203 }; 204 205 206 /** 207 specialization for weighted iterator with reference DataWeight& 208 */ 209 template <typename Iter> 210 struct iterator_traits_detail<Iter, DataWeight&> { 211 /** 212 for mutable weighted iterator data_reference is double& 213 */ 214 typedef double& data_reference; 215 216 /** 217 for mutable weighted iterator weight_reference is double& 218 */ 219 typedef double& weight_reference; 220 221 /** 222 \return reference to data of iterator 223 */ 224 data_reference data(Iter iter) const { return iter->data(); } 225 226 /** 227 \return reference to weight of iterator 228 */ 229 weight_reference weight(Iter iter) const { return iter->weight(); } 230 }; 231 232 233 /** 234 specialization for weighted iterator with reference const DataWeight& 235 */ 236 template <typename Iter> 237 struct iterator_traits_detail<Iter, const DataWeight&> { 238 /** 239 for read-only weighted iterator data_reference is const double& 240 */ 241 typedef const double& data_reference; 242 243 /** 244 for read-only weighted iterator data_reference is const double& 245 */ 246 typedef const double& weight_reference; 247 248 /** 249 \return const reference to data of iterator 250 */ 251 data_reference data(Iter iter) const { return iter->data(); } 252 253 /** 254 \return const reference to weight of iterator 255 */ 256 weight_reference weight(Iter iter) const { return iter->weight(); } 257 }; 258 259 260 /** 261 The purpose of this class is to allow polymorphism between 262 weighted and unweighted iterators. It allows to access data and 263 weight for both weighted and unweighted iterators. 264 265 This class works for unweighted iterators as well as weighted 266 iterators as long as they have reference type DataWeight& or 267 const DataWeight&. 268 269 For others, such as WeightedIterator for which reference type is 270 a proxy class, this class should be specialized. For adaptors 271 that have an underlying iterator (e.g. StrideIterator), this 272 class should be specialized, so the class also works when the 273 underlying is an iterator that is not overed by this class 274 e.g. WeightedIterator. 165 275 */ 166 template < classIter>276 template <typename Iter> 167 277 struct iterator_traits { 168 /** 169 \brief Default constructor 170 171 Does nothing but check that Iter is unweighted (at compile time). 172 */ 173 iterator_traits(void) 174 { 175 check_iterator_is_unweighted(typename weighted_iterator_traits<Iter>::type()); } 176 177 /** 178 An unweighted iterator has data_reference = reference 179 */ 180 typedef typename std::iterator_traits<Iter>::reference data_reference; 181 182 /** 183 An unweighted iterator has a weight = 1.0 and since this is a 184 temporary it is returned by value and weight_reference is double 185 */ 186 typedef double weight_reference; 187 188 /** 189 \return data that is *iter 278 private: 279 typedef typename std::iterator_traits<Iter>::reference reference; 280 typedef iterator_traits_detail<Iter, reference> traits; 281 public: 282 /** 283 data_reference (type returned by data(void) is determined by 284 iterator_traits_detail 285 */ 286 typedef typename traits::data_reference data_reference; 287 288 /** 289 data_reference (type returned by data(void) is determined by 290 iterator_traits_detail 291 */ 292 typedef typename traits::weight_reference weight_reference; 293 294 /** 295 \return data 190 296 */ 191 297 data_reference data(Iter iter) const 192 { check_iterator_is_unweighted(iter); return *iter; }193 194 /** 195 \return 1.0196 */298 { return traits().data(iter); } 299 300 /** 301 \return 302 */ 197 303 weight_reference weight(Iter iter) const 198 { check_iterator_is_unweighted(iter); return 1.0; } 199 200 }; 201 202 203 /** 204 Specialization for std::vector<DataWeight>::iterator 205 */ 206 template <> 207 struct iterator_traits<std::vector<DataWeight>::iterator> { 208 /** 209 mutable iterator 210 */ 211 typedef double& data_reference; 212 213 /** 214 mutable iterator 215 */ 216 typedef double& weight_reference; 217 218 /** 219 \return data using DataWeight::data() 220 */ 221 data_reference data(std::vector<DataWeight>::iterator iter) const 222 { return iter->data(); } 223 224 /** 225 \return weight using DataWeight::weight() 226 */ 227 weight_reference weight(std::vector<DataWeight>::iterator iter) const 228 { return iter->weight(); } 229 230 }; 231 232 233 /** 234 Specialization for std::vector<DataWeight>::const_iterator 235 */ 236 template <> 237 struct iterator_traits<std::vector<DataWeight>::const_iterator> { 238 /** 239 const iterator 240 */ 241 typedef const double& data_reference; 242 243 /** 244 const iterator 245 */ 246 typedef const double& weight_reference; 247 248 /** 249 \return data using DataWeight::data() 250 */ 251 data_reference data(std::vector<DataWeight>::iterator iter) const 252 { return iter->data(); } 253 254 /** 255 \return weight using DataWeight::weight() 256 */ 257 weight_reference weight(std::vector<DataWeight>::iterator iter) const 258 { return iter->weight(); } 259 260 }; 304 { return traits().weight(iter); } 305 306 }; 307 261 308 262 309 }}} // of namespace utility, yat, and theplu
Note: See TracChangeset
for help on using the changeset viewer.