annotate DEPENDENCIES/generic/include/boost/polygon/detail/boolean_op.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*
Chris@16 2 Copyright 2008 Intel Corporation
Chris@16 3
Chris@16 4 Use, modification and distribution are subject to the Boost Software License,
Chris@16 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 http://www.boost.org/LICENSE_1_0.txt).
Chris@16 7 */
Chris@16 8 #ifndef BOOST_POLYGON_BOOLEAN_OP_HPP
Chris@16 9 #define BOOST_POLYGON_BOOLEAN_OP_HPP
Chris@16 10 namespace boost { namespace polygon{
Chris@16 11 namespace boolean_op {
Chris@16 12
Chris@16 13 //BooleanOp is the generic boolean operation scanline algorithm that provides
Chris@16 14 //all the simple boolean set operations on manhattan data. By templatizing
Chris@16 15 //the intersection count of the input and algorithm internals it is extensible
Chris@16 16 //to multi-layer scans, properties and other advanced scanline operations above
Chris@16 17 //and beyond simple booleans.
Chris@16 18 //T must cast to int
Chris@16 19 template <class T, typename Unit>
Chris@16 20 class BooleanOp {
Chris@16 21 public:
Chris@16 22 typedef std::map<Unit, T> ScanData;
Chris@16 23 typedef std::pair<Unit, T> ElementType;
Chris@16 24 protected:
Chris@16 25 ScanData scanData_;
Chris@16 26 typename ScanData::iterator nextItr_;
Chris@16 27 T nullT_;
Chris@16 28 public:
Chris@16 29 inline BooleanOp () : scanData_(), nextItr_(), nullT_() { nextItr_ = scanData_.end(); nullT_ = 0; }
Chris@16 30 inline BooleanOp (T nullT) : scanData_(), nextItr_(), nullT_(nullT) { nextItr_ = scanData_.end(); }
Chris@16 31 inline BooleanOp (const BooleanOp& that) : scanData_(that.scanData_), nextItr_(),
Chris@16 32 nullT_(that.nullT_) { nextItr_ = scanData_.begin(); }
Chris@16 33 inline BooleanOp& operator=(const BooleanOp& that);
Chris@16 34
Chris@16 35 //moves scanline forward
Chris@16 36 inline void advanceScan() { nextItr_ = scanData_.begin(); }
Chris@16 37
Chris@16 38 //proceses the given interval and T data
Chris@16 39 //appends output edges to cT
Chris@16 40 template <class cT>
Chris@16 41 inline void processInterval(cT& outputContainer, interval_data<Unit> ivl, T deltaCount);
Chris@16 42
Chris@16 43 private:
Chris@16 44 inline typename ScanData::iterator lookup_(Unit pos){
Chris@16 45 if(nextItr_ != scanData_.end() && nextItr_->first >= pos) {
Chris@16 46 return nextItr_;
Chris@16 47 }
Chris@16 48 return nextItr_ = scanData_.lower_bound(pos);
Chris@16 49 }
Chris@16 50 inline typename ScanData::iterator insert_(Unit pos, T count){
Chris@16 51 return nextItr_ = scanData_.insert(nextItr_, ElementType(pos, count));
Chris@16 52 }
Chris@16 53 template <class cT>
Chris@16 54 inline void evaluateInterval_(cT& outputContainer, interval_data<Unit> ivl, T beforeCount, T afterCount);
Chris@16 55 };
Chris@16 56
Chris@16 57 class BinaryAnd {
Chris@16 58 public:
Chris@16 59 inline BinaryAnd() {}
Chris@16 60 inline bool operator()(int a, int b) { return (a > 0) & (b > 0); }
Chris@16 61 };
Chris@16 62 class BinaryOr {
Chris@16 63 public:
Chris@16 64 inline BinaryOr() {}
Chris@16 65 inline bool operator()(int a, int b) { return (a > 0) | (b > 0); }
Chris@16 66 };
Chris@16 67 class BinaryNot {
Chris@16 68 public:
Chris@16 69 inline BinaryNot() {}
Chris@16 70 inline bool operator()(int a, int b) { return (a > 0) & !(b > 0); }
Chris@16 71 };
Chris@16 72 class BinaryXor {
Chris@16 73 public:
Chris@16 74 inline BinaryXor() {}
Chris@16 75 inline bool operator()(int a, int b) { return (a > 0) ^ (b > 0); }
Chris@16 76 };
Chris@16 77
Chris@16 78 //BinaryCount is an array of two deltaCounts coming from two different layers
Chris@16 79 //of scan event data. It is the merged count of the two suitable for consumption
Chris@16 80 //as the template argument of the BooleanOp algorithm because BinaryCount casts to int.
Chris@16 81 //T is a binary functor object that evaluates the array of counts and returns a logical
Chris@16 82 //result of some operation on those values.
Chris@16 83 //BinaryCount supports many of the operators that work with int, particularly the
Chris@16 84 //binary operators, but cannot support less than or increment.
Chris@16 85 template <class T>
Chris@16 86 class BinaryCount {
Chris@16 87 public:
Chris@16 88 inline BinaryCount()
Chris@16 89 #ifndef BOOST_POLYGON_MSVC
Chris@16 90 : counts_()
Chris@16 91 #endif
Chris@16 92 { counts_[0] = counts_[1] = 0; }
Chris@16 93 // constructs from two integers
Chris@16 94 inline BinaryCount(int countL, int countR)
Chris@16 95 #ifndef BOOST_POLYGON_MSVC
Chris@16 96 : counts_()
Chris@16 97 #endif
Chris@16 98 { counts_[0] = countL, counts_[1] = countR; }
Chris@16 99 inline BinaryCount& operator=(int count) { counts_[0] = count, counts_[1] = count; return *this; }
Chris@16 100 inline BinaryCount& operator=(const BinaryCount& that);
Chris@16 101 inline BinaryCount(const BinaryCount& that)
Chris@16 102 #ifndef BOOST_POLYGON_MSVC
Chris@16 103 : counts_()
Chris@16 104 #endif
Chris@16 105 { *this = that; }
Chris@16 106 inline bool operator==(const BinaryCount& that) const;
Chris@16 107 inline bool operator!=(const BinaryCount& that) const { return !((*this) == that);}
Chris@16 108 inline BinaryCount& operator+=(const BinaryCount& that);
Chris@16 109 inline BinaryCount& operator-=(const BinaryCount& that);
Chris@16 110 inline BinaryCount operator+(const BinaryCount& that) const;
Chris@16 111 inline BinaryCount operator-(const BinaryCount& that) const;
Chris@16 112 inline BinaryCount operator-() const;
Chris@16 113 inline int& operator[](bool index) { return counts_[index]; }
Chris@16 114
Chris@16 115 //cast to int operator evaluates data using T binary functor
Chris@16 116 inline operator int() const { return T()(counts_[0], counts_[1]); }
Chris@16 117 private:
Chris@16 118 int counts_[2];
Chris@16 119 };
Chris@16 120
Chris@16 121 class UnaryCount {
Chris@16 122 public:
Chris@16 123 inline UnaryCount() : count_(0) {}
Chris@16 124 // constructs from two integers
Chris@16 125 inline explicit UnaryCount(int count) : count_(count) {}
Chris@16 126 inline UnaryCount& operator=(int count) { count_ = count; return *this; }
Chris@16 127 inline UnaryCount& operator=(const UnaryCount& that) { count_ = that.count_; return *this; }
Chris@16 128 inline UnaryCount(const UnaryCount& that) : count_(that.count_) {}
Chris@16 129 inline bool operator==(const UnaryCount& that) const { return count_ == that.count_; }
Chris@16 130 inline bool operator!=(const UnaryCount& that) const { return !((*this) == that);}
Chris@16 131 inline UnaryCount& operator+=(const UnaryCount& that) { count_ += that.count_; return *this; }
Chris@16 132 inline UnaryCount& operator-=(const UnaryCount& that) { count_ -= that.count_; return *this; }
Chris@16 133 inline UnaryCount operator+(const UnaryCount& that) const { UnaryCount tmp(*this); tmp += that; return tmp; }
Chris@16 134 inline UnaryCount operator-(const UnaryCount& that) const { UnaryCount tmp(*this); tmp -= that; return tmp; }
Chris@16 135 inline UnaryCount operator-() const { UnaryCount tmp; return tmp - *this; }
Chris@16 136
Chris@16 137 //cast to int operator evaluates data using T binary functor
Chris@16 138 inline operator int() const { return count_ % 2; }
Chris@16 139 private:
Chris@16 140 int count_;
Chris@16 141 };
Chris@16 142
Chris@16 143 template <class T, typename Unit>
Chris@16 144 inline BooleanOp<T, Unit>& BooleanOp<T, Unit>::operator=(const BooleanOp& that) {
Chris@16 145 scanData_ = that.scanData_;
Chris@16 146 nextItr_ = scanData_.begin();
Chris@16 147 nullT_ = that.nullT_;
Chris@16 148 return *this;
Chris@16 149 }
Chris@16 150
Chris@16 151 //appends output edges to cT
Chris@16 152 template <class T, typename Unit>
Chris@16 153 template <class cT>
Chris@16 154 inline void BooleanOp<T, Unit>::processInterval(cT& outputContainer, interval_data<Unit> ivl, T deltaCount) {
Chris@16 155 typename ScanData::iterator lowItr = lookup_(ivl.low());
Chris@16 156 typename ScanData::iterator highItr = lookup_(ivl.high());
Chris@16 157 //add interval to scan data if it is past the end
Chris@16 158 if(lowItr == scanData_.end()) {
Chris@16 159 lowItr = insert_(ivl.low(), deltaCount);
Chris@16 160 highItr = insert_(ivl.high(), nullT_);
Chris@16 161 evaluateInterval_(outputContainer, ivl, nullT_, deltaCount);
Chris@16 162 return;
Chris@16 163 }
Chris@16 164 //ensure that highItr points to the end of the ivl
Chris@16 165 if(highItr == scanData_.end() || (*highItr).first > ivl.high()) {
Chris@16 166 T value = nullT_;
Chris@16 167 if(highItr != scanData_.begin()) {
Chris@16 168 --highItr;
Chris@16 169 value = highItr->second;
Chris@16 170 }
Chris@16 171 nextItr_ = highItr;
Chris@16 172 highItr = insert_(ivl.high(), value);
Chris@16 173 }
Chris@16 174 //split the low interval if needed
Chris@16 175 if(lowItr->first > ivl.low()) {
Chris@16 176 if(lowItr != scanData_.begin()) {
Chris@16 177 --lowItr;
Chris@16 178 nextItr_ = lowItr;
Chris@16 179 lowItr = insert_(ivl.low(), lowItr->second);
Chris@16 180 } else {
Chris@16 181 nextItr_ = lowItr;
Chris@16 182 lowItr = insert_(ivl.low(), nullT_);
Chris@16 183 }
Chris@16 184 }
Chris@16 185 //process scan data intersecting interval
Chris@16 186 for(typename ScanData::iterator itr = lowItr; itr != highItr; ){
Chris@16 187 T beforeCount = itr->second;
Chris@16 188 T afterCount = itr->second += deltaCount;
Chris@16 189 Unit low = itr->first;
Chris@16 190 ++itr;
Chris@16 191 Unit high = itr->first;
Chris@16 192 evaluateInterval_(outputContainer, interval_data<Unit>(low, high), beforeCount, afterCount);
Chris@16 193 }
Chris@16 194 //merge the bottom interval with the one below if they have the same count
Chris@16 195 if(lowItr != scanData_.begin()){
Chris@16 196 typename ScanData::iterator belowLowItr = lowItr;
Chris@16 197 --belowLowItr;
Chris@16 198 if(belowLowItr->second == lowItr->second) {
Chris@16 199 scanData_.erase(lowItr);
Chris@16 200 }
Chris@16 201 }
Chris@16 202 //merge the top interval with the one above if they have the same count
Chris@16 203 if(highItr != scanData_.begin()) {
Chris@16 204 typename ScanData::iterator beforeHighItr = highItr;
Chris@16 205 --beforeHighItr;
Chris@16 206 if(beforeHighItr->second == highItr->second) {
Chris@16 207 scanData_.erase(highItr);
Chris@16 208 highItr = beforeHighItr;
Chris@16 209 ++highItr;
Chris@16 210 }
Chris@16 211 }
Chris@16 212 nextItr_ = highItr;
Chris@16 213 }
Chris@16 214
Chris@16 215 template <class T, typename Unit>
Chris@16 216 template <class cT>
Chris@16 217 inline void BooleanOp<T, Unit>::evaluateInterval_(cT& outputContainer, interval_data<Unit> ivl,
Chris@16 218 T beforeCount, T afterCount) {
Chris@16 219 bool before = (int)beforeCount > 0;
Chris@16 220 bool after = (int)afterCount > 0;
Chris@16 221 int value = (!before & after) - (before & !after);
Chris@16 222 if(value) {
Chris@16 223 outputContainer.insert(outputContainer.end(), std::pair<interval_data<Unit>, int>(ivl, value));
Chris@16 224 }
Chris@16 225 }
Chris@16 226
Chris@16 227 template <class T>
Chris@16 228 inline BinaryCount<T>& BinaryCount<T>::operator=(const BinaryCount<T>& that) {
Chris@16 229 counts_[0] = that.counts_[0];
Chris@16 230 counts_[1] = that.counts_[1];
Chris@16 231 return *this;
Chris@16 232 }
Chris@16 233 template <class T>
Chris@16 234 inline bool BinaryCount<T>::operator==(const BinaryCount<T>& that) const {
Chris@16 235 return counts_[0] == that.counts_[0] &&
Chris@16 236 counts_[1] == that.counts_[1];
Chris@16 237 }
Chris@16 238 template <class T>
Chris@16 239 inline BinaryCount<T>& BinaryCount<T>::operator+=(const BinaryCount<T>& that) {
Chris@16 240 counts_[0] += that.counts_[0];
Chris@16 241 counts_[1] += that.counts_[1];
Chris@16 242 return *this;
Chris@16 243 }
Chris@16 244 template <class T>
Chris@16 245 inline BinaryCount<T>& BinaryCount<T>::operator-=(const BinaryCount<T>& that) {
Chris@16 246 counts_[0] += that.counts_[0];
Chris@16 247 counts_[1] += that.counts_[1];
Chris@16 248 return *this;
Chris@16 249 }
Chris@16 250 template <class T>
Chris@16 251 inline BinaryCount<T> BinaryCount<T>::operator+(const BinaryCount<T>& that) const {
Chris@16 252 BinaryCount retVal(*this);
Chris@16 253 retVal += that;
Chris@16 254 return retVal;
Chris@16 255 }
Chris@16 256 template <class T>
Chris@16 257 inline BinaryCount<T> BinaryCount<T>::operator-(const BinaryCount<T>& that) const {
Chris@16 258 BinaryCount retVal(*this);
Chris@16 259 retVal -= that;
Chris@16 260 return retVal;
Chris@16 261 }
Chris@16 262 template <class T>
Chris@16 263 inline BinaryCount<T> BinaryCount<T>::operator-() const {
Chris@16 264 return BinaryCount<T>() - *this;
Chris@16 265 }
Chris@16 266
Chris@16 267
Chris@16 268 template <class T, typename Unit, typename iterator_type_1, typename iterator_type_2>
Chris@16 269 inline void applyBooleanBinaryOp(std::vector<std::pair<Unit, std::pair<Unit, int> > >& output,
Chris@16 270 //const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input1,
Chris@16 271 //const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input2,
Chris@16 272 iterator_type_1 itr1, iterator_type_1 itr1_end,
Chris@16 273 iterator_type_2 itr2, iterator_type_2 itr2_end,
Chris@16 274 T defaultCount) {
Chris@16 275 BooleanOp<T, Unit> boolean(defaultCount);
Chris@16 276 //typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::const_iterator itr1 = input1.begin();
Chris@16 277 //typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::const_iterator itr2 = input2.begin();
Chris@16 278 std::vector<std::pair<interval_data<Unit>, int> > container;
Chris@16 279 //output.reserve((std::max)(input1.size(), input2.size()));
Chris@16 280
Chris@16 281 //consider eliminating dependecy on limits with bool flag for initial state
Chris@16 282 Unit UnitMax = (std::numeric_limits<Unit>::max)();
Chris@16 283 Unit prevCoord = UnitMax;
Chris@16 284 Unit prevPosition = UnitMax;
Chris@16 285 T count(defaultCount);
Chris@16 286 //define the starting point
Chris@16 287 if(itr1 != itr1_end) {
Chris@16 288 prevCoord = (*itr1).first;
Chris@16 289 prevPosition = (*itr1).second.first;
Chris@16 290 count[0] += (*itr1).second.second;
Chris@16 291 }
Chris@16 292 if(itr2 != itr2_end) {
Chris@16 293 if((*itr2).first < prevCoord ||
Chris@16 294 ((*itr2).first == prevCoord && (*itr2).second.first < prevPosition)) {
Chris@16 295 prevCoord = (*itr2).first;
Chris@16 296 prevPosition = (*itr2).second.first;
Chris@16 297 count = defaultCount;
Chris@16 298 count[1] += (*itr2).second.second;
Chris@16 299 ++itr2;
Chris@16 300 } else if((*itr2).first == prevCoord && (*itr2).second.first == prevPosition) {
Chris@16 301 count[1] += (*itr2).second.second;
Chris@16 302 ++itr2;
Chris@16 303 if(itr1 != itr1_end) ++itr1;
Chris@16 304 } else {
Chris@16 305 if(itr1 != itr1_end) ++itr1;
Chris@16 306 }
Chris@16 307 } else {
Chris@16 308 if(itr1 != itr1_end) ++itr1;
Chris@16 309 }
Chris@16 310
Chris@16 311 while(itr1 != itr1_end || itr2 != itr2_end) {
Chris@16 312 Unit curCoord = UnitMax;
Chris@16 313 Unit curPosition = UnitMax;
Chris@16 314 T curCount(defaultCount);
Chris@16 315 if(itr1 != itr1_end) {
Chris@16 316 curCoord = (*itr1).first;
Chris@16 317 curPosition = (*itr1).second.first;
Chris@16 318 curCount[0] += (*itr1).second.second;
Chris@16 319 }
Chris@16 320 if(itr2 != itr2_end) {
Chris@16 321 if((*itr2).first < curCoord ||
Chris@16 322 ((*itr2).first == curCoord && (*itr2).second.first < curPosition)) {
Chris@16 323 curCoord = (*itr2).first;
Chris@16 324 curPosition = (*itr2).second.first;
Chris@16 325 curCount = defaultCount;
Chris@16 326 curCount[1] += (*itr2).second.second;
Chris@16 327 ++itr2;
Chris@16 328 } else if((*itr2).first == curCoord && (*itr2).second.first == curPosition) {
Chris@16 329 curCount[1] += (*itr2).second.second;
Chris@16 330 ++itr2;
Chris@16 331 if(itr1 != itr1_end) ++itr1;
Chris@16 332 } else {
Chris@16 333 if(itr1 != itr1_end) ++itr1;
Chris@16 334 }
Chris@16 335 } else {
Chris@16 336 ++itr1;
Chris@16 337 }
Chris@16 338
Chris@16 339 if(prevCoord != curCoord) {
Chris@16 340 boolean.advanceScan();
Chris@16 341 prevCoord = curCoord;
Chris@16 342 prevPosition = curPosition;
Chris@16 343 count = curCount;
Chris@16 344 continue;
Chris@16 345 }
Chris@16 346 if(curPosition != prevPosition && count != defaultCount) {
Chris@16 347 interval_data<Unit> ivl(prevPosition, curPosition);
Chris@16 348 container.clear();
Chris@16 349 boolean.processInterval(container, ivl, count);
Chris@16 350 for(std::size_t i = 0; i < container.size(); ++i) {
Chris@16 351 std::pair<interval_data<Unit>, int>& element = container[i];
Chris@16 352 if(!output.empty() && output.back().first == prevCoord &&
Chris@16 353 output.back().second.first == element.first.low() &&
Chris@16 354 output.back().second.second == element.second * -1) {
Chris@16 355 output.pop_back();
Chris@16 356 } else {
Chris@16 357 output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevCoord, std::pair<Unit, int>(element.first.low(),
Chris@16 358 element.second)));
Chris@16 359 }
Chris@16 360 output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevCoord, std::pair<Unit, int>(element.first.high(),
Chris@16 361 element.second * -1)));
Chris@16 362 }
Chris@16 363 }
Chris@16 364 prevPosition = curPosition;
Chris@16 365 count += curCount;
Chris@16 366 }
Chris@16 367 }
Chris@16 368
Chris@16 369 template <class T, typename Unit>
Chris@16 370 inline void applyBooleanBinaryOp(std::vector<std::pair<Unit, std::pair<Unit, int> > >& inputOutput,
Chris@16 371 const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input2,
Chris@16 372 T defaultCount) {
Chris@16 373 std::vector<std::pair<Unit, std::pair<Unit, int> > > output;
Chris@16 374 applyBooleanBinaryOp(output, inputOutput, input2, defaultCount);
Chris@16 375 if(output.size() < inputOutput.size() / 2) {
Chris@16 376 inputOutput = std::vector<std::pair<Unit, std::pair<Unit, int> > >();
Chris@16 377 } else {
Chris@16 378 inputOutput.clear();
Chris@16 379 }
Chris@16 380 inputOutput.insert(inputOutput.end(), output.begin(), output.end());
Chris@16 381 }
Chris@16 382
Chris@16 383 template <typename Unit>
Chris@16 384 inline void applyUnaryXOr(std::vector<std::pair<Unit, std::pair<Unit, int> > >& input) {
Chris@16 385 BooleanOp<UnaryCount, Unit> booleanXOr;
Chris@16 386
Chris@16 387 }
Chris@16 388
Chris@16 389 template <typename count_type = int>
Chris@16 390 struct default_arg_workaround {
Chris@16 391 template <typename Unit>
Chris@16 392 static inline void applyBooleanOr(std::vector<std::pair<Unit, std::pair<Unit, int> > >& input) {
Chris@16 393 BooleanOp<count_type, Unit> booleanOr;
Chris@16 394 std::vector<std::pair<interval_data<Unit>, int> > container;
Chris@16 395 std::vector<std::pair<Unit, std::pair<Unit, int> > > output;
Chris@16 396 output.reserve(input.size());
Chris@16 397 //consider eliminating dependecy on limits with bool flag for initial state
Chris@16 398 Unit UnitMax = (std::numeric_limits<Unit>::max)();
Chris@16 399 Unit prevPos = UnitMax;
Chris@16 400 Unit prevY = UnitMax;
Chris@16 401 int count = 0;
Chris@16 402 for(typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::iterator itr = input.begin();
Chris@16 403 itr != input.end(); ++itr) {
Chris@16 404 Unit pos = (*itr).first;
Chris@16 405 Unit y = (*itr).second.first;
Chris@16 406 if(pos != prevPos) {
Chris@16 407 booleanOr.advanceScan();
Chris@16 408 prevPos = pos;
Chris@16 409 prevY = y;
Chris@16 410 count = (*itr).second.second;
Chris@16 411 continue;
Chris@16 412 }
Chris@16 413 if(y != prevY && count != 0) {
Chris@16 414 interval_data<Unit> ivl(prevY, y);
Chris@16 415 container.clear();
Chris@16 416 booleanOr.processInterval(container, ivl, count_type(count));
Chris@16 417 for(std::size_t i = 0; i < container.size(); ++i) {
Chris@16 418 std::pair<interval_data<Unit>, int>& element = container[i];
Chris@16 419 if(!output.empty() && output.back().first == prevPos &&
Chris@16 420 output.back().second.first == element.first.low() &&
Chris@16 421 output.back().second.second == element.second * -1) {
Chris@16 422 output.pop_back();
Chris@16 423 } else {
Chris@16 424 output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevPos, std::pair<Unit, int>(element.first.low(),
Chris@16 425 element.second)));
Chris@16 426 }
Chris@16 427 output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevPos, std::pair<Unit, int>(element.first.high(),
Chris@16 428 element.second * -1)));
Chris@16 429 }
Chris@16 430 }
Chris@16 431 prevY = y;
Chris@16 432 count += (*itr).second.second;
Chris@16 433 }
Chris@16 434 if(output.size() < input.size() / 2) {
Chris@16 435 input = std::vector<std::pair<Unit, std::pair<Unit, int> > >();
Chris@16 436 } else {
Chris@16 437 input.clear();
Chris@16 438 }
Chris@16 439 input.insert(input.end(), output.begin(), output.end());
Chris@16 440 }
Chris@16 441 };
Chris@16 442
Chris@16 443 }
Chris@16 444
Chris@16 445 }
Chris@16 446
Chris@16 447 }
Chris@16 448 #endif