source: src/Common/FilterCombos.h@ 6fa409e

new-env
Last change on this file since 6fa409e was 9160cb2, checked in by Aaron Moss <a3moss@…>, 7 years ago

Breadth-first assertion resolution builds, eats all the memory

  • Property mode set to 100644
File size: 3.3 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// FilterCombos.h --
8//
9// Author : Aaron B. Moss
10// Created On : Mon Jul 23 16:05:00 2018
11// Last Modified By : Aaron B. Moss
12// Last Modified On : Mon Jul 23 16:05:00 2018
13// Update Count : 1
14//
15
16#pragma once
17
18#include <vector>
19
20/// Type of index vector for combinations
21typedef std::vector<unsigned> Indices;
22
23/// Result of a combo iteration -- one of reject this combination, reject all following
24/// combinations, or accept this combination.
25enum class ComboResult { REJECT_THIS, REJECT_AFTER, ACCEPT };
26
27/// Combo iterator that simply collects values into a vector, marking all values as valid.
28/// Prefer combos in typeops.h to use of IntoVectorComboIter with filterCombos
29/// @param T The element type of the vector.
30template<typename T>
31class IntoVectorComboIter {
32 std::vector<T> crnt_combo;
33public:
34 /// Outputs a vector of T
35 using OutType = std::vector<T>;
36
37 /// Adds the element to the current combination, always returning true for valid.
38 ComboResult append( const T& x ) {
39 crnt_combo.push_back( x );
40 return ComboResult::ACCEPT;
41 }
42
43 /// Removes the last element of the current combination.
44 void backtrack() { crnt_combo.pop_back(); }
45
46 /// Returns a copy of the current combination.
47 OutType finalize() { return crnt_combo; }
48};
49
50/// Filters combinations from qs by the given combo iterator. If the iterator rejects some prefix
51/// of a combination, it will not accept any combination with that prefix.
52/// qs should not be empty
53template<typename Q, typename ComboIter>
54auto filterCombos( const std::vector<Q>& qs, ComboIter&& iter )
55 -> std::vector<typename ComboIter::OutType> {
56 unsigned n = qs.size(); // number of queues to combine
57
58 std::vector<typename ComboIter::OutType> out; // filtered output
59 for ( auto& q : qs ) if ( q.empty() ) return out; // return empty if any empty queue
60
61 Indices inds;
62 inds.reserve( n );
63 inds.push_back( 0 );
64
65 while (true) {
66 unsigned i = inds.size() - 1;
67
68 ComboResult flag = iter.append( qs[i][inds.back()] );
69
70 if ( flag == ComboResult::ACCEPT ) {
71 if ( i + 1 == n ) {
72 // keep successful match of entire combination and continue iterating final place
73 out.push_back( iter.finalize() );
74 iter.backtrack();
75 } else {
76 // try to extend successful prefix
77 inds.push_back( 0 );
78 continue;
79 }
80 }
81
82 if ( flag != ComboResult::REJECT_AFTER ) {
83 ++inds.back();
84 // Try next combination if done with this one
85 if ( inds.back() < qs[i].size() ) continue;
86 // Otherwise done with the current row
87 }
88
89 // At this point, an invalid prefix is stored in inds and iter is in a state looking at
90 // all but the final value in inds. Now backtrack to next prefix:
91 inds.pop_back();
92 while ( ! inds.empty() ) {
93 // try the next value at the previous index
94 ++inds.back();
95 iter.backtrack();
96 if ( inds.back() < qs[inds.size()-1].size() ) break;
97 // if the previous index is finished, backtrack out
98 inds.pop_back();
99 }
100
101 // Done if backtracked the entire array
102 if ( inds.empty() ) return out;
103 }
104}
105
106// Local Variables: //
107// tab-width: 4 //
108// mode: c++ //
109// compile-command: "make install" //
110// End: //
Note: See TracBrowser for help on using the repository browser.