Scid  4.6.5
hfilter.h
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2016 Fulvio Benini
3 
4 * This file is part of Scid (Shane's Chess Information Database).
5 *
6 * Scid is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation.
9 *
10 * Scid is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Scid. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef SCID_HFILTER_H
20 #define SCID_HFILTER_H
21 
22 #include "filter.h"
23 #include <iterator>
24 
25 /*
26  * A database can be searched according to different criteria and the list of
27  * matching games is stored into a Filter object.
28  * This class abstracts its internal representation providing an interface
29  * equivalent to a pointer to a std::map<gamenumT, uint8_t> object, where the
30  * keys are the gamenumT of matching games and the mapped_types are the number
31  * of half-moves necessary to reach the matching position.
32  * Searches that use only header informations (player names, dates, ...) match
33  * at the starting position (0 half-moves).
34  *
35  * It is also possible to combine two filters in an efficient and transparent
36  * way. If a secondary "mask" filter is supplied, the functions get(), size()
37  * and the const_iterator consider only the games included in both filters.
38  * Their behavior is equal to:
39  * using Filter = std::map<gamenumT, uint8_t>;
40  * Filter tmp_combined;
41  * std::set_intersection(mask->begin(), mask->end(), main->begin(), main->end(),
42  * std::inserter(tmp_combined, tmp_combined.end()),
43  * [](auto& a, auto& b) { return a.first < b.first; });
44  * return HFilter(&tmp_combined).begin/get/size();
45 */
46 class HFilter {
47  Filter* main_;
48  const Filter* mask_;
49 
50 public:
51  /**
52  * class const_iterator - iterator for HFilter objects
53  *
54  * This class and the relative functions begin() and end() allow to use
55  * HFilter objects with STL algorithms and c++11 for-ranged loops.
56  * For example:
57  * for (auto& gnum : *hfilter_obj) {}
58  * is equal to:
59  * for (gamenumT gnum = 0, gnum < scidBaseT::numGames(); gnum++) {
60  * if (hfilter_obj->get(gnum) == 0) continue;
61  * }
62  */
64  gamenumT gnum_;
65  gamenumT end_;
66  const HFilter* hfilter_;
67  bool inFilter_;
68 
69  public:
70  typedef std::forward_iterator_tag iterator_category;
71  typedef std::ptrdiff_t difference_type;
73  typedef const gamenumT* pointer;
74  typedef const gamenumT& reference;
75 
76  const_iterator(gamenumT gnum, gamenumT end, const HFilter* hfilter,
77  bool inFilter = true)
78  : gnum_(gnum), end_(end), hfilter_(hfilter), inFilter_(inFilter) {
79  ASSERT(hfilter != 0);
80  if (gnum_ != end_) {
81  bool included = (hfilter_->get(gnum_) != 0);
82  if (included != inFilter_) operator++();
83  }
84  }
85 
86  reference operator*() const { return gnum_; }
87 
89  while (++gnum_ != end_) {
90  bool included = (hfilter_->get(gnum_) != 0);
91  if (included == inFilter_) break;
92  }
93  return *this;
94  }
95 
96  bool operator!=(const const_iterator& b) const {
97  return gnum_ != b.gnum_ || hfilter_ != b.hfilter_;
98  }
99  bool operator==(const const_iterator& b) const {
100  return ! operator!=(b);
101  }
102  };
103 
105  return const_iterator(0, main_->Size(), this);
106  }
107  const_iterator end() const {
108  return const_iterator(main_->Size(), main_->Size(), this);
109  }
111  return const_iterator(0, main_->Size(), this, false);
112  }
114  return const_iterator(main_->Size(), main_->Size(), this, false);
115  }
116  size_t sizeInverted() const {
117  return main_->Size() - size();
118  }
119 
120 public: // Pointer interface
121  bool operator==(const Filter* b) const { return main_ == b; }
122  bool operator!=(const Filter* b) const { return main_ != b; }
123  HFilter* operator->() { return this; }
124  const HFilter* operator->() const { return this; }
125  HFilter& operator*() { return *this; }
126  const HFilter& operator*() const { return *this; }
127 
128 public:
129  explicit HFilter(Filter* main = 0, const Filter* mask = 0)
130  : main_(main), mask_(mask) {}
131 
132  void clear() { return main_->Fill(0); }
133  void erase(gamenumT gnum) { return main_->Set(gnum, 0); }
134  void insert_or_assign(gamenumT gnum, uint8_t ply) {
135  return main_->Set(gnum, ply + 1);
136  }
137  size_t size() const;
138 
139  /* Convenience function, behave like:
140  * for (gamenumT gnum = 0; gnum < scidBaseT::numGames(); gnum++)
141  * std:map::insert_or_assign(gnum, 0);
142  */
143  void includeAll() { return main_->Fill(1); }
144 
145  /* Convenience function, behave like:
146  * auto it = std::map::find(gnum);
147  * if (it == std::map::end()) return 0;
148  * return 1 + it->second;
149  */
150  byte get(gamenumT gnum) const;
151 
152  /* Convenience function, behave like:
153  * if (value == 0)
154  * erase(gnum);
155  * else
156  * insert_or_assign(gnum, value - 1);
157  */
158  void set(gamenumT gnum, byte value) { return main_->Set(gnum, value); }
159 };
160 
161 inline size_t HFilter::size() const {
162  if (mask_ == 0) return main_->Count();
163  if (main_->isWhole()) return mask_->Count();
164  const_iterator::difference_type res = std::distance(begin(), end());
165  return static_cast<size_t>(res);
166 }
167 
168 inline byte HFilter::get(gamenumT gnum) const {
169  byte res = main_->Get(gnum);
170  if (res != 0 && mask_ != 0)
171  res = mask_->Get(gnum);
172 
173  return res;
174 }
175 
176 /**
177  * class HFilterInverted - iterate through games excluded from a filter
178  *
179  * This class allow to iterate through games not included in HFilter objects
180  * using STL algorithms and c++11 for-ranged loops.
181  * For example:
182  * for (auto& gnum : HFilterInverted(hfilter_obj)) {}
183  * is equal to:
184  * for (gamenumT gnum = 0, gnum < scidBaseT::numGames(); gnum++) {
185  * if (hfilter_obj->get(gnum) != 0) continue;
186  * }
187  */
189  const HFilter& hfilter_;
190 
191 public:
192  explicit HFilterInverted(const HFilter& hfilter) : hfilter_(hfilter) {
193  ASSERT(hfilter != 0);
194  }
195  HFilter::const_iterator begin() const { return hfilter_.beginInverted(); }
196  HFilter::const_iterator end() const { return hfilter_.endInverted(); }
197  size_t size() const { return hfilter_.sizeInverted(); }
198 };
199 
200 #endif
unsigned char byte
Definition: common.h:97
HFilter::const_iterator begin() const
Definition: hfilter.h:195
void clear()
Definition: hfilter.h:132
void Fill(byte value)
Definition: filter.h:145
size_t sizeInverted() const
Definition: hfilter.h:116
HFilter::const_iterator end() const
Definition: hfilter.h:196
const_iterator end() const
Definition: hfilter.h:107
#define ASSERT(f)
Definition: common.h:67
bool operator!=(const Filter *b) const
Definition: hfilter.h:122
void includeAll()
Definition: hfilter.h:143
void erase(gamenumT gnum)
Definition: hfilter.h:133
HFilter & operator*()
Definition: hfilter.h:125
HFilter(Filter *main=0, const Filter *mask=0)
Definition: hfilter.h:129
int main(int argc, char *argv[])
Definition: tkscid.cpp:81
uint Size() const
Definition: filter.h:52
const_iterator beginInverted() const
Definition: hfilter.h:110
const_iterator begin() const
Definition: hfilter.h:104
bool operator==(const const_iterator &b) const
Definition: hfilter.h:99
const gamenumT * pointer
Definition: hfilter.h:73
size_t size() const
Definition: hfilter.h:161
void Set(gamenumT index, byte value)
Definition: filter.h:126
const gamenumT & reference
Definition: hfilter.h:74
reference operator*() const
Definition: hfilter.h:86
const_iterator(gamenumT gnum, gamenumT end, const HFilter *hfilter, bool inFilter=true)
Definition: hfilter.h:76
const_iterator endInverted() const
Definition: hfilter.h:113
const HFilter & operator*() const
Definition: hfilter.h:126
std::ptrdiff_t difference_type
Definition: hfilter.h:71
byte get(gamenumT gnum) const
Definition: hfilter.h:168
const HFilter * operator->() const
Definition: hfilter.h:124
Definition: filter.h:32
bool operator==(const Filter *b) const
Definition: hfilter.h:121
class const_iterator - iterator for HFilter objects
Definition: hfilter.h:63
void insert_or_assign(gamenumT gnum, uint8_t ply)
Definition: hfilter.h:134
uint gamenumT
Definition: common.h:159
bool operator!=(const const_iterator &b) const
Definition: hfilter.h:96
std::forward_iterator_tag iterator_category
Definition: hfilter.h:70
HFilter * operator->()
Definition: hfilter.h:123
const_iterator & operator++()
Definition: hfilter.h:88
HFilterInverted(const HFilter &hfilter)
Definition: hfilter.h:192
size_t size() const
Definition: hfilter.h:197
class HFilterInverted - iterate through games excluded from a filter
Definition: hfilter.h:188