Changes in src/Tuples/TupleAssignment.cc [906e24d:6eb8948]
- File:
-
- 1 edited
-
src/Tuples/TupleAssignment.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleAssignment.cc
r906e24d r6eb8948 18 18 #include "ResolvExpr/typeops.h" 19 19 #include "SynTree/Expression.h" 20 #include "TupleAssignment.h" 20 #include "SynTree/Initializer.h" 21 #include "Tuples.h" 21 22 #include "Common/SemanticError.h" 22 23 … … 27 28 #include <cassert> 28 29 #include <set> 30 #include <unordered_set> 29 31 30 32 namespace Tuples { 31 TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder *f = 0 ) 32 : currentFinder(f), matcher(0), hasMatched( false ) {} 33 34 bool TupleAssignSpotter::pointsToTuple( Expression *expr ) { 33 class TupleAssignSpotter { 34 public: 35 // dispatcher for Tuple (multiple and mass) assignment operations 36 TupleAssignSpotter( ResolvExpr::AlternativeFinder & ); 37 void spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ); 38 39 private: 40 void match(); 41 // records for assignment generation 42 struct Options { 43 void print( std::ostream & ); 44 int size() const { return options.size(); } 45 bool empty() const { return options.empty(); } 46 typedef std::list< ResolvExpr::AltList >::iterator iterator; 47 iterator begin() { return options.begin(); } 48 iterator end() { return options.end(); } 49 50 std::list< ResolvExpr::AltList > options; 51 }; 52 53 struct Matcher { 54 public: 55 Matcher( TupleAssignSpotter &spotter, Expression *_lhs, Expression *_rhs ); 56 virtual ~Matcher() {} 57 virtual void match( std::list< Expression * > &out ) = 0; 58 std::list< Expression * > lhs, rhs; 59 TupleAssignSpotter &spotter; 60 std::list< ObjectDecl * > tmpDecls; 61 }; 62 63 struct MassAssignMatcher : public Matcher { 64 public: 65 MassAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) { 66 this->rhs.push_back( rhs ); 67 } 68 virtual void match( std::list< Expression * > &out ); 69 }; 70 71 struct MultipleAssignMatcher : public Matcher { 72 public: 73 MultipleAssignMatcher( TupleAssignSpotter &spot, Expression *lhs, Expression *rhs ); 74 virtual void match( std::list< Expression * > &out ); 75 }; 76 77 ResolvExpr::AlternativeFinder ¤tFinder; 78 // Expression *rhs, *lhs; 79 Matcher *matcher = nullptr; 80 Options options; 81 }; 82 83 bool isTupleVar( DeclarationWithType *decl ) { 84 return dynamic_cast< TupleType * >( decl->get_type() ); 85 } 86 87 /// true if expr is an expression of tuple type, i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function 88 bool isTuple( Expression *expr ) { 89 if ( ! expr ) return false; 90 91 // xxx - used to include cast to varExpr and call to isTupleVar, but this doesn't seem like it should be necessary 92 return dynamic_cast<TupleExpr *>(expr) || expr->get_results().size() > 1; 93 } 94 95 bool pointsToTuple( Expression *expr ) { 35 96 // also check for function returning tuple of reference types 36 if ( AddressExpr *addr = dynamic_cast<AddressExpr *>(expr) )37 if ( isTuple(addr->get_arg() ) )38 return true;97 if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) { 98 return isTuple( addr->get_arg() ); 99 } 39 100 return false; 40 101 } 41 102 42 bool TupleAssignSpotter::isTupleVar( DeclarationWithType *decl ) { 43 if ( dynamic_cast<TupleType *>(decl->get_type()) ) 44 return true; 45 return false; 46 } 47 48 bool TupleAssignSpotter::isTuple( Expression *expr, bool isRight ) { 49 // true if `expr' is an expression returning a tuple: tuple, tuple variable or MRV function 50 if ( ! expr ) return false; 51 52 if ( dynamic_cast<TupleExpr *>(expr) ) 53 return true; 54 else if ( VariableExpr *var = dynamic_cast<VariableExpr *>(expr) ) { 55 if ( isTupleVar(var->get_var()) ) 56 return true; 57 } 58 59 return false; 60 } 61 62 bool TupleAssignSpotter::match() { 63 assert ( matcher != 0 ); 64 65 std::list< Expression * > new_assigns; 66 if ( ! matcher->match(new_assigns) ) 67 return false; 68 69 if ( new_assigns.empty() ) return false; 70 /*return */matcher->solve( new_assigns ); 71 if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) { 72 // now resolve new assignments 73 std::list< Expression * > solved_assigns; 74 ResolvExpr::AltList solved_alts; 75 assert( currentFinder != 0 ); 76 77 ResolvExpr::AltList current; 78 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 79 //try { 80 ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() ); 81 finder.findWithAdjustment(*i); 82 // prune expressions that don't coincide with 83 ResolvExpr::AltList alts = finder.get_alternatives(); 84 assert( alts.size() == 1 ); 85 assert(alts.front().expr != 0 ); 86 current.push_back( finder.get_alternatives().front() ); 87 solved_assigns.push_back( alts.front().expr->clone() ); 88 //solved_assigns.back()->print(std::cerr); 89 /*} catch( ... ) { 90 continue; // no reasonable alternative found 91 }*/ 92 } 93 options.add_option( current ); 94 95 return true; 96 } else { // mass assignment 97 //if ( new_assigns.empty() ) return false; 98 std::list< Expression * > solved_assigns; 99 ResolvExpr::AltList solved_alts; 100 assert( currentFinder != 0 ); 101 102 ResolvExpr::AltList current; 103 if ( optMass.empty() ) { 104 for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i ) 105 optMass.push_back( ResolvExpr::AltList() ); 106 } 107 int cnt = 0; 108 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) { 109 110 ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() ); 111 finder.findWithAdjustment(*i); 112 ResolvExpr::AltList alts = finder.get_alternatives(); 113 assert( alts.size() == 1 ); 114 assert(alts.front().expr != 0 ); 115 current.push_back( finder.get_alternatives().front() ); 116 optMass[cnt].push_back( finder.get_alternatives().front() ); 117 solved_assigns.push_back( alts.front().expr->clone() ); 118 } 119 120 return true; 121 } 122 123 return false; 124 } 125 126 bool TupleAssignSpotter::isMVR( Expression *expr ) { 127 return isTuple( expr ); 128 } 129 130 bool TupleAssignSpotter::isTupleAssignment( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) { 103 bool isTupleExpr( Expression *expr ) { 104 return expr->get_results().size() > 1; 105 } 106 107 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) { 108 TupleAssignSpotter spotter( currentFinder ); 109 spotter.spot( expr, possibilities ); 110 } 111 112 TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder &f ) 113 : currentFinder(f) {} 114 115 void TupleAssignSpotter::spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) { 131 116 if ( NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) { 132 133 117 if ( assgnop->get_name() == std::string("?=?") ) { 134 135 118 for ( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 136 119 assert( ali->size() == 2 ); 137 ResolvExpr::AltList::iterator opit = ali->begin(); 138 ResolvExpr::Alternative op1 = *opit, op2 = *(++opit); 139 120 ResolvExpr::Alternative op1 = ali->front(), op2 = ali->back(); 121 122 MultipleAssignMatcher multiMatcher( *this, op1.expr, op2.expr ); 123 MassAssignMatcher massMatcher( *this, op1.expr, op2.expr ); 140 124 if ( pointsToTuple(op1.expr) ) { // also handles tuple vars 141 if ( isTuple( op2.expr, true ) ) 142 matcher = new MultipleAssignMatcher(op1.expr, op2.expr); 143 else if ( isMVR( op2.expr ) ) { 144 // handle MVR differently 145 } else 125 if ( isTuple( op2.expr ) ) { 126 matcher = &multiMatcher; 127 } else { 146 128 // mass assignment 147 matcher = new MassAssignMatcher(op1.expr, op2.expr); 148 149 std::list< ResolvExpr::AltList > options; 150 if ( match() ) 151 /* 152 if ( hasMatched ) { 153 // throw SemanticError("Ambiguous tuple assignment"); 154 } else {*/ 155 // Matched for the first time 156 hasMatched = true; 157 /*} */ 158 } /* else if ( isTuple( op2 ) ) 159 throw SemanticError("Inapplicable tuple assignment."); 160 */ 161 } 162 163 if ( hasMatched ) { 164 if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) { 165 //options.print( std::cerr ); 166 std::list< ResolvExpr::AltList >best = options.get_best(); 167 if ( best.size() == 1 ) { 168 std::list<Expression *> solved_assigns; 169 for ( ResolvExpr::AltList::iterator i = best.front().begin(); i != best.front().end(); ++i ) { 170 solved_assigns.push_back( i->expr ); 171 } 172 /* assigning cost zero? */ 173 currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MULTIPLE*/), currentFinder->get_environ(), ResolvExpr::Cost() ) ); 129 matcher = &massMatcher; 174 130 } 175 } else { 176 assert( ! optMass.empty() ); 177 ResolvExpr::AltList winners; 178 for ( std::vector< ResolvExpr::AltList >::iterator i = optMass.begin(); i != optMass.end(); ++i ) 179 findMinCostAlt( i->begin(), i->end(), back_inserter(winners) ); 180 181 std::list< Expression *> solved_assigns; 182 for ( ResolvExpr::AltList::iterator i = winners.begin(); i != winners.end(); ++i ) 183 solved_assigns.push_back( i->expr ); 184 currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MASS*/), currentFinder->get_environ(), ResolvExpr::Cost() ) ); 131 match(); 132 } else if ( isTuple( op2.expr ) ) { 133 throw SemanticError("Cannot assign a tuple value into a non-tuple lvalue.", expr); 185 134 } 186 135 } 187 136 } 188 137 } 189 return hasMatched; 190 } 191 192 void TupleAssignSpotter::Matcher::init( Expression *_lhs, Expression *_rhs ) { 193 lhs.clear(); 194 if (AddressExpr *addr = dynamic_cast<AddressExpr *>(_lhs) ) 138 } 139 140 void TupleAssignSpotter::match() { 141 assert ( matcher != 0 ); 142 143 std::list< Expression * > new_assigns; 144 matcher->match( new_assigns ); 145 146 if ( new_assigns.empty() ) return; 147 ResolvExpr::AltList current; 148 // now resolve new assignments 149 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 150 ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() ); 151 finder.findWithAdjustment(*i); 152 // prune expressions that don't coincide with 153 ResolvExpr::AltList alts = finder.get_alternatives(); 154 assert( alts.size() == 1 ); 155 assert( alts.front().expr != 0 ); 156 current.push_back( alts.front() ); 157 } 158 159 // extract expressions from the assignment alternatives to produce a list of assignments that 160 // together form a single alternative 161 std::list< Expression *> solved_assigns; 162 for ( ResolvExpr::Alternative & alt : current ) { 163 solved_assigns.push_back( alt.expr->clone() ); 164 } 165 // xxx - need to do this?? 166 // TypeEnvironment compositeEnv; 167 // simpleCombineEnvironments( i->begin(), i->end(), compositeEnv ); 168 currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), currentFinder.get_environ(), ResolvExpr::sumCost( current ) ) ); 169 } 170 171 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : spotter(spotter) { 172 // xxx - shouldn't need to be &<tuple-expr>, just &<lvalue-tuple-type> 173 if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs) ) 195 174 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) ) 196 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(lhs) ); 197 198 rhs.clear(); 199 } 200 201 TupleAssignSpotter::Matcher::Matcher( /*TupleAssignSpotter &spot,*/ Expression *_lhs, Expression *_rhs ) /*: own_spotter(spot) */{ 202 init(_lhs,_rhs); 203 } 204 205 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( Expression *_lhs, Expression *_rhs )/* : own_spotter(spot) */{ 206 init(_lhs,_rhs); 207 208 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(_rhs) ) 209 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(rhs) ); 210 } 211 212 UntypedExpr *TupleAssignSpotter::Matcher::createAssgn( Expression *left, Expression *right ) { 213 if ( left && right ) { 214 std::list< Expression * > args; 215 args.push_back(new AddressExpr(left->clone())); args.push_back(right->clone()); 216 return new UntypedExpr(new NameExpr("?=?"), args); 217 } else 218 throw 0; // xxx - diagnose the problem 219 } 220 221 bool TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) { 222 if ( lhs.empty() || (rhs.size() != 1) ) return false; 223 224 for ( std::list< Expression * >::iterator l = lhs.begin(); l != lhs.end(); l++ ) { 225 std::list< Expression * > args; 226 args.push_back( new AddressExpr(*l) ); 227 args.push_back( rhs.front() ); 228 out.push_back( new UntypedExpr(new NameExpr("?=?"), args) ); 229 } 230 231 return true; 232 } 233 234 bool TupleAssignSpotter::MassAssignMatcher::solve( std::list< Expression * > &assigns ) { 235 /* 236 std::list< Expression * > solved_assigns; 237 ResolvExpr::AltList solved_alts; 238 assert( currentFinder != 0 ); 239 240 ResolvExpr::AltList current; 241 if ( optMass.empty() ) { 242 for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i ) 243 optMass.push_back( ResolvExpr::AltList() ); 244 } 245 int cnt = 0; 246 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) { 247 248 ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() ); 249 finder.findWithAdjustment(*i); 250 ResolvExpr::AltList alts = finder.get_alternatives(); 251 assert( alts.size() == 1 ); 252 assert(alts.front().expr != 0 ); 253 current.push_back( finder.get_alternatives().front() ); 254 optMass[cnt].push_back( finder.get_alternatives().front() ); 255 solved_assigns.push_back( alts.front().expr->clone() ); 256 } 257 */ 258 return true; 259 } 260 261 bool TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) { 262 // need more complicated matching 175 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->lhs) ); 176 } 177 178 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) { 179 180 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(rhs) ) 181 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->rhs) ); 182 } 183 184 UntypedExpr * createAssgn( ObjectDecl *left, ObjectDecl *right ) { 185 assert( left && right ); 186 std::list< Expression * > args; 187 args.push_back( new AddressExpr( new UntypedExpr( new NameExpr("*?"), std::list< Expression * >{ new VariableExpr( left ) } ) ) ); 188 args.push_back( new VariableExpr( right ) ); 189 return new UntypedExpr( new NameExpr( "?=?" ), args ); 190 } 191 192 ObjectDecl * newObject( UniqueName & namer, Expression * expr ) { 193 Type * type; 194 assert( expr->get_results().size() >= 1 ); 195 if ( expr->get_results().size() > 1 ) { 196 TupleType * tt = new TupleType( Type::Qualifiers() ); 197 cloneAll( expr->get_results(), tt->get_types() ); 198 type = tt; 199 } else { 200 type = expr->get_results().front()->clone(); 201 } 202 return new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, type, new SingleInit( expr->clone() ) ); 203 } 204 205 void TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) { 206 static UniqueName lhsNamer( "__massassign_L" ); 207 static UniqueName rhsNamer( "__massassign_R" ); 208 assert ( ! lhs.empty() && rhs.size() == 1); 209 210 ObjectDecl * rtmp = newObject( rhsNamer, rhs.front() ); 211 for ( Expression * l : lhs ) { 212 ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( l ) ); 213 out.push_back( createAssgn( ltmp, rtmp ) ); 214 tmpDecls.push_back( ltmp ); 215 } 216 tmpDecls.push_back( rtmp ); 217 } 218 219 void TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) { 220 static UniqueName lhsNamer( "__multassign_L" ); 221 static UniqueName rhsNamer( "__multassign_R" ); 222 // xxx - need more complicated matching? 263 223 if ( lhs.size() == rhs.size() ) { 264 zipWith( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), back_inserter(out), TupleAssignSpotter::Matcher::createAssgn ); 265 return true; 266 } //else 267 //std::cerr << "The length of (left, right) is: (" << lhs.size() << "," << rhs.size() << ")" << std::endl;*/ 268 return false; 269 } 270 271 bool TupleAssignSpotter::MultipleAssignMatcher::solve( std::list< Expression * > &assigns ) { 272 /* 273 std::list< Expression * > solved_assigns; 274 ResolvExpr::AltList solved_alts; 275 assert( currentFinder != 0 ); 276 277 ResolvExpr::AltList current; 278 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 279 //try { 280 ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() ); 281 finder.findWithAdjustment(*i); 282 // prune expressions that don't coincide with 283 ResolvExpr::AltList alts = finder.get_alternatives(); 284 assert( alts.size() == 1 ); 285 assert(alts.front().expr != 0 ); 286 current.push_back( finder.get_alternatives().front() ); 287 solved_assigns.push_back( alts.front().expr->clone() ); 288 //solved_assigns.back()->print(std::cerr); 289 //} catch( ... ) { 290 //continue; // no reasonable alternative found 291 //} 292 } 293 options.add_option( current ); 294 */ 295 296 return true; 297 } 298 299 void TupleAssignSpotter::Options::add_option( ResolvExpr::AltList &opt ) { 300 using namespace std; 301 302 options.push_back( opt ); 303 /* 304 vector< Cost > costs; 305 costs.reserve( opt.size() ); 306 transform( opt.begin(), opt.end(), back_inserter(costs), ptr_fun(extract_cost) ); 307 */ 308 // transpose matrix 309 if ( costMatrix.empty() ) 310 for ( unsigned int i = 0; i< opt.size(); ++i) 311 costMatrix.push_back( vector<ResolvExpr::Cost>() ); 312 313 int cnt = 0; 314 for ( ResolvExpr::AltList::iterator i = opt.begin(); i != opt.end(); ++i, cnt++ ) 315 costMatrix[cnt].push_back( i->cost ); 316 317 return; 318 } 319 320 std::list< ResolvExpr::AltList > TupleAssignSpotter::Options::get_best() { 321 using namespace std; 322 using namespace ResolvExpr; 323 list< ResolvExpr::AltList > ret; 324 list< multiset<int> > solns; 325 for ( vector< vector<Cost> >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) { 326 list<int> current; 327 findMinCost( i->begin(), i->end(), back_inserter(current) ); 328 solns.push_back( multiset<int>(current.begin(), current.end()) ); 329 } 330 // need to combine 331 multiset<int> result; 332 lift_intersection( solns.begin(), solns.end(), inserter( result, result.begin() ) ); 333 if ( result.size() != 1 ) 334 throw SemanticError("Ambiguous tuple expression"); 335 ret.push_back(get_option( *(result.begin() ))); 336 return ret; 224 std::list< ObjectDecl * > ltmp; 225 std::list< ObjectDecl * > rtmp; 226 std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( Expression * expr ){ 227 return newObject( lhsNamer, new AddressExpr( expr ) ); 228 }); 229 std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( Expression * expr ){ 230 return newObject( rhsNamer, expr ); 231 }); 232 zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), createAssgn ); 233 tmpDecls.splice( tmpDecls.end(), ltmp ); 234 tmpDecls.splice( tmpDecls.end(), rtmp ); 235 } 337 236 } 338 237 339 238 void TupleAssignSpotter::Options::print( std::ostream &ostr ) { 340 using namespace std;341 342 for ( vector< vector < ResolvExpr::Cost > >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {343 for ( vector < ResolvExpr::Cost >::iterator j = i->begin(); j != i->end(); ++j )344 ostr << *j << " " ;239 for ( ResolvExpr::AltList & l : options ) { 240 for ( ResolvExpr::Alternative & alt : l ) { 241 alt.print( ostr ); 242 ostr << " "; 243 } 345 244 ostr << std::endl; 346 245 } // for 347 return;348 }349 350 ResolvExpr::Cost extract_cost( ResolvExpr::Alternative &alt ) {351 return alt.cost;352 }353 354 template< typename InputIterator, typename OutputIterator >355 void TupleAssignSpotter::Options::findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {356 using namespace ResolvExpr;357 std::list<int> alternatives;358 359 // select the alternatives that have the minimum parameter cost360 Cost minCost = Cost::infinity;361 unsigned int index = 0;362 for ( InputIterator i = begin; i != end; ++i, index++ ) {363 if ( *i < minCost ) {364 minCost = *i;365 alternatives.clear();366 alternatives.push_back( index );367 } else if ( *i == minCost ) {368 alternatives.push_back( index );369 }370 }371 std::copy( alternatives.begin(), alternatives.end(), out );372 }373 374 template< class InputIterator, class OutputIterator >375 void TupleAssignSpotter::Options::lift_intersection( InputIterator begin, InputIterator end, OutputIterator out ) {376 if ( begin == end ) return;377 InputIterator test = begin;378 379 if (++test == end)380 { copy(begin->begin(), begin->end(), out); return; }381 382 383 std::multiset<int> cur; // InputIterator::value_type::value_type384 copy( begin->begin(), begin->end(), inserter( cur, cur.begin() ) );385 386 while ( test != end ) {387 std::multiset<int> temp;388 set_intersection( cur.begin(), cur.end(), test->begin(), test->end(), inserter(temp,temp.begin()) );389 cur.clear();390 copy( temp.begin(), temp.end(), inserter(cur,cur.begin()));391 ++test;392 }393 394 copy( cur.begin(), cur.end(), out );395 return;396 }397 398 ResolvExpr::AltList TupleAssignSpotter::Options::get_option( std::list< ResolvExpr::AltList >::size_type index ) {399 if ( index >= options.size() )400 throw 0; // XXX401 std::list< ResolvExpr::AltList >::iterator it = options.begin();402 for ( std::list< ResolvExpr::AltList >::size_type i = 0; i < index; ++i, ++it );403 return *it;404 246 } 405 247 } // namespace Tuples
Note:
See TracChangeset
for help on using the changeset viewer.