@private
| 113 | |
| 114 | /// @private |
| 115 | class SublistGenerator final : public IGenerator<vector<int>> { |
| 116 | |
| 117 | // list of all possible (unique) elements |
| 118 | vector<int> list; |
| 119 | |
| 120 | // output sublist of user-specified length |
| 121 | int sublen; |
| 122 | vector<int> sublist; |
| 123 | |
| 124 | // indicates which elements of list are in sublist |
| 125 | vector<bool> featured; |
| 126 | |
| 127 | private: |
| 128 | |
| 129 | void prepareSublist() { |
| 130 | |
| 131 | // choose the next combination |
| 132 | int j=0; |
| 133 | for (size_t i=0; i<list.size(); i++) |
| 134 | if (featured[i]) |
| 135 | sublist[j++] = list[i]; |
| 136 | |
| 137 | // prepare for permuting |
| 138 | std::sort(sublist.begin(), sublist.end()); |
| 139 | } |
| 140 | |
| 141 | public: |
| 142 | |
| 143 | SublistGenerator(vector<int> list, int sublen): |
| 144 | list(list), |
| 145 | sublen(sublen) |
| 146 | { |
| 147 | // ensure sublist would not be longer than list |
| 148 | DEMAND( sublen <= list.size() ); |
| 149 | |
| 150 | // populate sublist with first elements |
| 151 | sublist.resize(sublen); |
| 152 | featured.resize(list.size()); |
| 153 | fill(featured.end() - sublen, featured.end(), true); |
| 154 | |
| 155 | prepareSublist(); |
| 156 | } |
| 157 | |
| 158 | vector<int> const& get() const override { |
| 159 | |
| 160 | // return a copy of sublist |
| 161 | return sublist; |
| 162 | } |
| 163 | |
| 164 | bool next() override { |
| 165 | |
| 166 | // offer next permutation of the current combination |
| 167 | if (std::next_permutation(sublist.begin(), sublist.end())) |
| 168 | return true; |
| 169 | |
| 170 | // else generate the next combination |
| 171 | if (std::next_permutation(featured.begin(), featured.end())) { |
| 172 |
nothing calls this directly
no outgoing calls
no test coverage detected