@@ -253,7 +253,7 @@ inline Iterator prev_or_begin(Iterator it, Iterator begin) {
253
253
254
254
// / A range of iterators.
255
255
// / TODO: Add `llvm::iterator_range::empty()`, then remove this helper, along
256
- // / with the superfluous FilterIterator and TransformIterator.
256
+ // / with the superfluous TransformIterator.
257
257
template <typename Iterator>
258
258
class IteratorRange {
259
259
Iterator First, Last;
@@ -279,136 +279,6 @@ makeIteratorRange(Iterator first, Iterator last) {
279
279
return IteratorRange<Iterator>(first, last);
280
280
}
281
281
282
- // / An iterator that filters the results of an underlying forward
283
- // / iterator, only passing through those values that satisfy a predicate.
284
- // /
285
- // / \tparam Iterator the underlying iterator.
286
- // /
287
- // / \tparam Predicate A predicate that determines whether a value of the
288
- // / underlying iterator is available in the resulting sequence.
289
- template <typename Iterator, typename Predicate>
290
- class FilterIterator {
291
- Iterator Current, End;
292
-
293
- // / FIXME: Could optimize away this storage with EBCO tricks.
294
- Predicate Pred;
295
-
296
- // / Skip any non-matching elements.
297
- void skipNonMatching () {
298
- while (Current != End && !Pred (*Current))
299
- ++Current;
300
- }
301
-
302
- public:
303
- // / Used to indicate when the current iterator has already been
304
- // / "primed", meaning that it's at the end or points to a value that
305
- // / satisfies the predicate.
306
- enum PrimedT { Primed };
307
-
308
- using iterator_category = std::forward_iterator_tag;
309
- using value_type = typename std::iterator_traits<Iterator>::value_type;
310
- using reference = typename std::iterator_traits<Iterator>::reference;
311
- using pointer = typename std::iterator_traits<Iterator>::pointer;
312
- using difference_type =
313
- typename std::iterator_traits<Iterator>::difference_type;
314
-
315
- // / Construct a new filtering iterator for the given iterator range
316
- // / and predicate.
317
- FilterIterator (Iterator current, Iterator end, Predicate pred)
318
- : Current(current), End(end), Pred(pred)
319
- {
320
- // Prime the iterator.
321
- skipNonMatching ();
322
- }
323
-
324
- // / Construct a new filtering iterator for the given iterator range
325
- // / and predicate, where the iterator range has already been
326
- // / "primed" by ensuring that it is empty or the current iterator
327
- // / points to something that matches the predicate.
328
- FilterIterator (Iterator current, Iterator end, Predicate pred, PrimedT)
329
- : Current(current), End(end), Pred(pred)
330
- {
331
- // Assert that the iterators have already been primed.
332
- assert (Current == End || Pred (*Current) && " Not primed!" );
333
- }
334
-
335
- reference operator *() const {
336
- return *Current;
337
- }
338
-
339
- pointer operator ->() const {
340
- return Current.operator ->();
341
- }
342
-
343
- FilterIterator &operator ++() {
344
- ++Current;
345
- skipNonMatching ();
346
- return *this ;
347
- }
348
-
349
- FilterIterator operator ++(int ) {
350
- FilterIterator old = *this ;
351
- ++*this ;
352
- return old;
353
- }
354
-
355
- friend bool operator ==(FilterIterator lhs, FilterIterator rhs) {
356
- return lhs.Current == rhs.Current ;
357
- }
358
- friend bool operator !=(FilterIterator lhs, FilterIterator rhs) {
359
- return !(lhs == rhs);
360
- }
361
- };
362
-
363
- // / Create a new filter iterator.
364
- template <typename Iterator, typename Predicate>
365
- inline FilterIterator<Iterator, Predicate>
366
- makeFilterIterator (Iterator current, Iterator end, Predicate pred) {
367
- return FilterIterator<Iterator, Predicate>(current, end, pred);
368
- }
369
-
370
- // / A range filtered by a specific predicate.
371
- template <typename Range, typename Predicate>
372
- class FilterRange {
373
- using Iterator = typename Range::iterator;
374
-
375
- Iterator First, Last;
376
- Predicate Pred;
377
-
378
- public:
379
- using iterator = FilterIterator<Iterator, Predicate>;
380
-
381
- FilterRange (Range range, Predicate pred)
382
- : First(range.begin()), Last(range.end()), Pred(pred)
383
- {
384
- // Prime the sequence.
385
- while (First != Last && !Pred (*First))
386
- ++First;
387
- }
388
-
389
- iterator begin () const {
390
- return iterator (First, Last, Pred, iterator::Primed);
391
- }
392
-
393
- iterator end () const {
394
- return iterator (Last, Last, Pred, iterator::Primed);
395
- }
396
-
397
- bool empty () const { return First == Last; }
398
-
399
- typename std::iterator_traits<iterator>::value_type front () const {
400
- assert (!empty () && " Front of empty range" );
401
- return *begin ();
402
- }
403
- };
404
-
405
- // / Create a new filter range.
406
- template <typename Range, typename Predicate>
407
- inline FilterRange<Range, Predicate>
408
- makeFilterRange (Range range, Predicate pred) {
409
- return FilterRange<Range, Predicate>(range, pred);
410
- }
411
-
412
282
// / An iterator that transforms the result of an underlying bidirectional
413
283
// / iterator with a given operation.
414
284
// /
@@ -488,7 +358,7 @@ class TransformRange {
488
358
Operation Op;
489
359
490
360
public:
491
- using iterator = TransformIterator<typename Range::iterator , Operation>;
361
+ using iterator = TransformIterator<decltype (Rng.begin()) , Operation>;
492
362
493
363
TransformRange (Range range, Operation op)
494
364
: Rng(range), Op(op) { }
@@ -497,6 +367,20 @@ class TransformRange {
497
367
iterator end () const { return iterator (Rng.end (), Op); }
498
368
bool empty () const { return begin () == end (); }
499
369
370
+ // The dummy template parameter keeps 'size()' from being eagerly
371
+ // instantiated.
372
+ template <typename Dummy = Range>
373
+ typename function_traits<decltype (&Dummy::size)>::result_type
374
+ size () const {
375
+ return Rng.size ();
376
+ }
377
+
378
+ template <typename Index>
379
+ typename function_traits<Operation>::result_type
380
+ operator [](Index index) const {
381
+ return Op (Rng[index]);
382
+ }
383
+
500
384
typename std::iterator_traits<iterator>::value_type front () const {
501
385
assert (!empty () && " Front of empty range" );
502
386
return *begin ();
0 commit comments