1 // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
2 
3 #if !defined(CPPLINQ_LINQ_WHERE_HPP)
4 #define CPPLINQ_LINQ_WHERE_HPP
5 #pragma once
6 
7 namespace cpplinq
8 {
9     template <class Collection, class Predicate>
10     class linq_where
11     {
12         typedef typename Collection::cursor
13             inner_cursor;
14     public:
15         struct cursor {
16             typedef typename util::min_iterator_category<
17                     bidirectional_cursor_tag,
18                     typename inner_cursor::cursor_category>::type
19                 cursor_category;
20             typedef typename inner_cursor::element_type
21                 element_type;
22             typedef typename inner_cursor::reference_type
23                 reference_type;
24 
cursorcpplinq::linq_where::cursor25             cursor(const inner_cursor& cur, const Predicate& p) : cur(cur), pred(p)
26             {
27                 if (!cur.empty() && !pred(cur.get())) {
28                     this->inc();
29                 }
30             }
31 
forgetcpplinq::linq_where::cursor32             void forget() { cur.forget(); }
emptycpplinq::linq_where::cursor33             bool empty() const { return cur.empty(); }
inccpplinq::linq_where::cursor34             void inc() {
35                 for (;;) {
36                     cur.inc();
37                     if (cur.empty() || pred(cur.get())) break;
38                 }
39             }
getcpplinq::linq_where::cursor40             reference_type get() const {
41                 return cur.get();
42             }
43 
atbegincpplinq::linq_where::cursor44             bool atbegin() const { return atbegin(cur); }
deccpplinq::linq_where::cursor45             void dec() {
46                 for (;;) {
47                     cur.dec();
48                     if (pred(cur.get())) break;
49                 }
50             }
51         private:
52             inner_cursor cur;
53             Predicate pred;
54         };
55 
linq_where(const Collection & c,Predicate pred)56         linq_where(const Collection& c, Predicate pred) : c(c), pred(pred) {}
57 
get_cursor() const58         cursor get_cursor() const {
59             return cursor(c.get_cursor(), pred);
60         }
61 
62     private:
63         Collection c;
64         Predicate   pred;
65     };
66 }
67 
68 #endif // !defined(CPPLINQ_LINQ_WHERE_HPP)
69 
70