this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * Guido Tack <tack@gecode.org> 6 * 7 * Contributing authors: 8 * Gregory Crosswhite <gcross@phys.washington.edu> 9 * 10 * Copyright: 11 * Gregory Crosswhite, 2011 12 * Christian Schulte, 2003 13 * Guido Tack, 2004 14 * 15 * This file is part of Gecode, the generic constraint 16 * development environment: 17 * http://www.gecode.org 18 * 19 * Permission is hereby granted, free of charge, to any person obtaining 20 * a copy of this software and associated documentation files (the 21 * "Software"), to deal in the Software without restriction, including 22 * without limitation the rights to use, copy, modify, merge, publish, 23 * distribute, sublicense, and/or sell copies of the Software, and to 24 * permit persons to whom the Software is furnished to do so, subject to 25 * the following conditions: 26 * 27 * The above copyright notice and this permission notice shall be 28 * included in all copies or substantial portions of the Software. 29 * 30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 * 38 */ 39 40#include <iostream> 41#include <iterator> 42#include <vector> 43#include <sstream> 44#include <initializer_list> 45 46namespace Gecode { namespace Kernel { 47 48 /// Occurence information for a view 49 template<class View> 50 class ViewOcc { 51 public: 52 /// The view 53 View x; 54 /// The original index in the array 55 int i; 56 /// Sorting order 57 bool operator <(const ViewOcc& y) const; 58 }; 59 60 template<class View> 61 forceinline bool 62 ViewOcc<View>::operator <(const ViewOcc& y) const { 63 return x < y.x; 64 } 65 66 /// Check whether \a p has duplicates among its \a n elements (changes \a p) 67 GECODE_KERNEL_EXPORT 68 bool duplicates(void** p, int n); 69 70 /// Check whether \a p has common elements with \a q 71 GECODE_KERNEL_EXPORT 72 bool duplicates(void** p, int n, void** q, int m); 73 74}} 75 76namespace Gecode { 77 78 template<class Var> class VarArray; 79 template<class Var> class VarArgArray; 80 81 /** \brief Traits of arrays in %Gecode 82 * 83 * This class collects the traits of an array in Gecode. 84 * The traits used are the following. 85 * - <code>typedef Type StorageType</code> where \c Type is the type 86 * of an appropriate storage type for this array. 87 * - <code>typedef Type ValueType</code> where \c Type is the type 88 * of the elements of this array. 89 * - <code>typedef Type ArgsType</code> where \c Type is the type 90 * of the appropriate Args-array type (e.g., \c BoolVarArgs if \c A is 91 * \c BoolVarArray). 92 */ 93 template<class A> 94 class ArrayTraits {}; 95 96 /** 97 * \brief %Variable arrays 98 * 99 * %Variable arrays store variables. They are typically used 100 * for storing the variables being part of a solution. 101 * 102 * Never use them for temporary purposes, use argument arrays 103 * instead. 104 * 105 * %Variable arrays can be enlarged dynamically. For memory efficiency, the 106 * initial array is allocated in the space. When adding variables, it is 107 * automatically resized and allocated on the heap. 108 * 109 * \ingroup TaskVar 110 */ 111 template<class Var> 112 class VarArray { 113 protected: 114 /// Number of variables (size) 115 int n; 116 /// Array of variables 117 Var* x; 118 public: 119 /// \name Associated types 120 //@{ 121 /// Type of the variable stored in this array 122 typedef Var value_type; 123 /// Type of a reference to the value type 124 typedef Var& reference; 125 /// Type of a constant reference to the value type 126 typedef const Var& const_reference; 127 /// Type of a pointer to the value type 128 typedef Var* pointer; 129 /// Type of a read-only pointer to the value type 130 typedef const Var* const_pointer; 131 /// Type of the iterator used to iterate through this array's elements 132 typedef Var* iterator; 133 /// Type of the iterator used to iterate read-only through this array's elements 134 typedef const Var* const_iterator; 135 /// Type of the iterator used to iterate backwards through this array's elements 136 typedef std::reverse_iterator<Var*> reverse_iterator; 137 /// Type of the iterator used to iterate backwards and read-only through this array's elements 138 typedef std::reverse_iterator<const Var*> const_reverse_iterator; 139 //@} 140 141 //@{ 142 /// \name Constructors and initialization 143 //@{ 144 /// Default constructor (array of size 0) 145 VarArray(void); 146 /// Allocate array with \a m variables 147 VarArray(Space& home, int m); 148 /// Initialize from variable argument array \a a (copy elements) 149 VarArray(Space& home, const VarArgArray<Var>&); 150 /// Initialize from variable array \a a (share elements) 151 VarArray(const VarArray<Var>& a); 152 /// Initialize from variable array \a a (share elements) 153 const VarArray<Var>& operator =(const VarArray<Var>& a); 154 //@} 155 156 /// \name Array size 157 //@{ 158 /// Return size of array (number of elements) 159 int size(void) const; 160 //@} 161 162 /// \name Array elements 163 //@{ 164 /// Return variable at position \a i 165 Var& operator [](int i); 166 /// Return variable at position \a i 167 const Var& operator [](int i) const; 168 /** Return slice \f$y\f$ of length at most \a n such that forall \f$0\leq i<n\f$, \f$y_i=x_{\text{start}+i\cdot\text{inc}}\f$ 169 * 170 * If \a n is -1, then all possible elements starting from \a start 171 * with increment \a inc are returned. 172 */ 173 typename ArrayTraits<VarArgArray<Var>>::ArgsType 174 slice(int start, int inc=1, int n=-1); 175 //@} 176 177 /// \name Array iteration 178 //@{ 179 /// Return an iterator at the beginning of the array 180 iterator begin(void); 181 /// Return a read-only iterator at the beginning of the array 182 const_iterator begin(void) const; 183 /// Return an iterator past the end of the array 184 iterator end(void); 185 /// Return a read-only iterator past the end of the array 186 const_iterator end(void) const; 187 /// Return a reverse iterator at the end of the array 188 reverse_iterator rbegin(void); 189 /// Return a reverse and read-only iterator at the end of the array 190 const_reverse_iterator rbegin(void) const; 191 /// Return a reverse iterator past the beginning of the array 192 reverse_iterator rend(void); 193 /// Return a reverse and read-only iterator past the beginning of the array 194 const_reverse_iterator rend(void) const; 195 //@} 196 197 /// Test if all variables are assigned 198 bool assigned(void) const; 199 200 /// \name Cloning 201 //@{ 202 /// Update array to be a clone of array \a a 203 void update(Space& home, VarArray<Var>& a); 204 //@} 205 206 /// Allocate memory from heap (disabled) 207 static void* operator new(size_t s) = delete; 208 /// Free memory allocated from heap (disabled) 209 static void operator delete(void* p) = delete; 210 }; 211 212 /** Concatenate \a x and \a y and return result 213 * \relates VarArray 214 */ 215 template<class T> 216 typename ArrayTraits<VarArray<T>>::ArgsType 217 operator +(const VarArray<T>& x, const VarArgArray<T>& y); 218 219 /** Concatenate \a x and \a y and return result 220 * \relates VarArray 221 */ 222 template<class T> 223 typename ArrayTraits<VarArray<T>>::ArgsType 224 operator +(const VarArray<T>& x, const VarArray<T>& y); 225 226 /** Concatenate \a x and \a y and return result 227 * \relates VarArray 228 */ 229 template<class T> 230 typename ArrayTraits<VarArray<T>>::ArgsType 231 operator +(const VarArgArray<T>& x, const VarArray<T>& y); 232 233 /** Concatenate \a x and \a y and return result 234 * \relates VarArray 235 */ 236 template<class T> 237 typename ArrayTraits<VarArray<T>>::ArgsType 238 operator +(const VarArray<T>& x, const T& y); 239 240 /** Concatenate \a x and \a y and return result 241 * \relates VarArray 242 */ 243 template<class T> 244 typename ArrayTraits<VarArray<T>>::ArgsType 245 operator +(const T& x, const VarArray<T>& y); 246 247 /** 248 * \brief View arrays 249 * 250 * View arrays store views. They are typically used for storing the 251 * views with which propagators and branchers compute. 252 * \ingroup TaskActor 253 */ 254 template<class View> 255 class ViewArray { 256 private: 257 /// Number of views (size) 258 int n; 259 /// Views 260 View* x; 261 public: 262 /// \name Associated types 263 //@{ 264 /// Type of the view stored in this array 265 typedef View value_type; 266 /// Type of a reference to the value type 267 typedef View& reference; 268 /// Type of a constant reference to the value type 269 typedef const View& const_reference; 270 /// Type of a pointer to the value type 271 typedef View* pointer; 272 /// Type of a read-only pointer to the value type 273 typedef const View* const_pointer; 274 /// Type of the iterator used to iterate through this array's elements 275 typedef View* iterator; 276 /// Type of the iterator used to iterate read-only through this array's elements 277 typedef const View* const_iterator; 278 /// Type of the iterator used to iterate backwards through this array's elements 279 typedef std::reverse_iterator<View*> reverse_iterator; 280 /// Type of the iterator used to iterate backwards and read-only through this array's elements 281 typedef std::reverse_iterator<const View*> const_reverse_iterator; 282 //@} 283 284 /// \name Constructors and initialization 285 //@{ 286 /// Default constructor (array of size 0) 287 ViewArray(void); 288 /// Allocate array with \a m views 289 ViewArray(Space& home, int m); 290 /// Allocate array with \a m views 291 ViewArray(Region& r, int m); 292 /// Initialize from view array \a a (share elements) 293 ViewArray(const ViewArray<View>& a); 294 /// Initialize from view array \a a (copy elements) 295 ViewArray(Space& home, const ViewArray<View>& a); 296 /// Initialize from view array \a a (copy elements) 297 ViewArray(Region& r, const ViewArray<View>& a); 298 /// Initialize from view array \a a (share elements) 299 const ViewArray<View>& operator =(const ViewArray<View>& a); 300 /** 301 * \brief Initialize from variable argument array \a a (copy elements) 302 * 303 * Note that the view type \a View must provide a constructor 304 * for the associated \a Var type. 305 */ 306 template<class Var> 307 ViewArray(Space& home, const VarArgArray<Var>& a) 308 : n(a.size()) { 309 // This may not be in the hpp file (to satisfy the MS compiler) 310 if (n>0) { 311 x = home.alloc<View>(n); 312 for (int i=0; i<n; i++) 313 x[i]=a[i]; 314 } else { 315 x = nullptr; 316 } 317 } 318 /** 319 * \brief Initialize from variable argument array \a a (copy elements) 320 * 321 * Note that the view type \a View must provide a constructor 322 * for the associated \a Var type. 323 */ 324 template<class Var> 325 ViewArray(Region& r, const VarArgArray<Var>& a) 326 : n(a.size()) { 327 // This may not be in the hpp file (to satisfy the MS compiler) 328 if (n>0) { 329 x = r.alloc<View>(n); 330 for (int i=0; i<n; i++) 331 x[i]=a[i]; 332 } else { 333 x = nullptr; 334 } 335 } 336 //@} 337 338 /// \name Array size 339 //@{ 340 /// Return size of array (number of elements) 341 int size(void) const; 342 /// Decrease size of array (number of elements) 343 void size(int n); 344 //@} 345 346 /// \name Array elements 347 //@{ 348 /// Return view at position \a i 349 View& operator [](int i); 350 /// Return view at position \a i 351 const View& operator [](int i) const; 352 //@} 353 354 /// \name Array iteration 355 //@{ 356 /// Return an iterator at the beginning of the array 357 iterator begin(void); 358 /// Return a read-only iterator at the beginning of the array 359 const_iterator begin(void) const; 360 /// Return an iterator past the end of the array 361 iterator end(void); 362 /// Return a read-only iterator past the end of the array 363 const_iterator end(void) const; 364 /// Return a reverse iterator at the end of the array 365 reverse_iterator rbegin(void); 366 /// Return a reverse and read-only iterator at the end of the array 367 const_reverse_iterator rbegin(void) const; 368 /// Return a reverse iterator past the beginning of the array 369 reverse_iterator rend(void); 370 /// Return a reverse and read-only iterator past the beginning of the array 371 const_reverse_iterator rend(void) const; 372 //@} 373 374 /// \name Dependencies 375 //@{ 376 /** 377 * \brief Subscribe propagator \a p with propagation condition \a pc to variable 378 * 379 * In case \a process is false, the propagator is just subscribed but 380 * not scheduled for execution (this must be used when creating 381 * subscriptions during propagation). 382 */ 383 void subscribe(Space& home, Propagator& p, PropCond pc, 384 bool schedule=true); 385 /// Cancel subscription of propagator \a p with propagation condition \a pc to all views 386 void cancel(Space& home, Propagator& p, PropCond pc); 387 /// Subscribe advisor \a a to variable 388 void subscribe(Space& home, Advisor& a); 389 /// Cancel subscription of advisor \a a 390 void cancel(Space& home, Advisor& a); 391 /// Re-schedule propagator \a p with propagation condition \a pc 392 void reschedule(Space& home, Propagator& p, PropCond pc); 393 //@} 394 395 /// \name Cloning 396 //@{ 397 /// Update array to be a clone of array \a a 398 void update(Space& home, ViewArray<View>& a); 399 //@} 400 401 402 /// \name Moving elements 403 //@{ 404 /// Move view from position 0 to position \a i (shift elements to the left) 405 void move_fst(int i); 406 /// Move view from position \c size()-1 to position \a i (truncate array by one) 407 void move_lst(int i); 408 /** \brief Move view from position 0 to position \a i (shift elements to the left) 409 * 410 * Before moving, cancel subscription of propagator \a p with 411 * propagation condition \a pc to view at position \a i. 412 */ 413 void move_fst(int i, Space& home, Propagator& p, PropCond pc); 414 /** \brief Move view from position \c size()-1 to position \a i (truncate array by one) 415 * 416 * Before moving, cancel subscription of propagator \a p with 417 * propagation condition \a pc to view at position \a i. 418 */ 419 void move_lst(int i, Space& home, Propagator& p, PropCond pc); 420 /** \brief Move view from position 0 to position \a i (shift elements to the left) 421 * 422 * Before moving, cancel subscription of advisor \a a 423 * to view at position \a i. 424 */ 425 void move_fst(int i, Space& home, Advisor& a); 426 /** \brief Move view from position \c size()-1 to position \a i (truncate array by one) 427 * 428 * Before moving, cancel subscription of advisor \a a to view 429 * at position \a i. 430 */ 431 void move_lst(int i, Space& home, Advisor& a); 432 //@} 433 434 /// \name Dropping elements 435 //@{ 436 /// Drop views from positions 0 to \a i-1 from array 437 void drop_fst(int i); 438 /// Drop views from positions \a i+1 to \c size()-1 from array 439 void drop_lst(int i); 440 /** \brief Drop views from positions 0 to \a i-1 from array 441 * 442 * Before moving, cancel subscription of propagator \a p with 443 * propagation condition \a pc to views at positions 0 to \a i-1. 444 */ 445 void drop_fst(int i, Space& home, Propagator& p, PropCond pc); 446 /** \brief Drop assigned views from positions \a i+1 to \c size()-1 from array 447 * 448 * Before moving, cancel subscription of propagator \a p with 449 * propagation condition \a pc to views at positions \a i+1 to 450 * \c size()-1. 451 */ 452 void drop_lst(int i, Space& home, Propagator& p, PropCond pc); 453 /** \brief Drop views from positions 0 to \a i-1 from array 454 * 455 * Before moving, cancel subscription of advisor \a a to views at 456 * positions 0 to \a i-1. 457 */ 458 void drop_fst(int i, Space& home, Advisor& a); 459 /** \brief Drop assigned views from positions \a i+1 to \c size()-1 from array 460 * 461 * Before moving, cancel subscription of advisor \a a to views at 462 * positions \a i+1 to \c size()-1. 463 */ 464 void drop_lst(int i, Space& home, Advisor& a); 465 //@} 466 467 /// Test if all variables are assigned 468 bool assigned(void) const; 469 470 /// \name View equality 471 //@{ 472 /** 473 * \brief Test whether array has multiple occurence of the same view 474 * 475 * Note that assigned views are ignored. 476 */ 477 bool same(void) const; 478 /** 479 * \brief Test whether array contains a view being the same as \a y 480 * 481 * Note that assigned views are ignored. 482 */ 483 bool same(const View& y) const; 484 /// Remove all duplicate views from array (changes element order) 485 void unique(void); 486 //@} 487 488 /// Allocate memory from heap (disabled) 489 static void* operator new(size_t s) = delete; 490 /// Free memory allocated from heap (disabled) 491 static void operator delete(void* p) = delete; 492 }; 493 494 495 /** 496 * \brief Test whether array \a x together with array \a y contains shared views 497 * 498 * Note that assigned views are ignored. 499 * \relates ViewArray 500 */ 501 template<class ViewX, class ViewY> 502 bool shared(ViewArray<ViewX> x, ViewArray<ViewY> y); 503 /** 504 * \brief Test whether array \a x contains a view shared with \a y 505 * 506 * Note that assigned views are ignored. 507 * \relates ViewArray 508 */ 509 template<class ViewX, class ViewY> 510 bool shared(ViewArray<ViewX> x, ViewY y); 511 /** 512 * \brief Test whether array \a y contains a view shared with \a x 513 * 514 * Note that assigned views are ignored. 515 * \relates ViewArray 516 */ 517 template<class ViewX, class ViewY> 518 bool shared(ViewX x, ViewArray<ViewY> y); 519 /** 520 * \brief Test whether array \a x contains shared views 521 * 522 * Note that assigned views are ignored. 523 * \relates ViewArray 524 */ 525 template<class View> 526 bool shared(ViewArray<View> x); 527 528 529 /** 530 * \brief Base-class for argument arrays 531 * 532 * Argument arrays are used as convenient mechanism of passing arguments 533 * when calling functions as they combine both the size and the elements 534 * of an array. For a small number of elements, memory is allocated by 535 * creating an argument array object. Otherwise the memory is allocated 536 * from the heap. 537 * 538 * \ingroup TaskVar 539 */ 540 template<class T> 541 class ArgArrayBase { 542 protected: 543 /// Number of elements 544 int n; 545 /// Allocated size of the array 546 int capacity; 547 /// Element array 548 T* a; 549 /// How many elements are possible inside array 550 static const int onstack_size = 16; 551 /// In-array storage for elements 552 T onstack[onstack_size]; 553 /// Allocate memory for \a n elements 554 T* allocate(int n); 555 /// Resize to hold at least \a i additional elements 556 void resize(int i); 557 /// Return this array concatenated with \a x 558 template<class A> 559 A concat(const ArgArrayBase<T>& x) const; 560 /// Return this array concatenated with \a x 561 template<class A> 562 A concat(const T& x) const; 563 /// Insert a new element \a x at the end of the array (increase size by 1) 564 template<class A> 565 A& append(const T& x); 566 /// Append \a x to the end of the array 567 template<class A> 568 A& append(const ArgArrayBase<T>& x); 569 /** Return slice \f$y\f$ of length at most \a n such that forall \f$0\leq i<n\f$, \f$y_i=x_{\text{start}+i\cdot\text{inc}}\f$ 570 * 571 * If \a n is -1, then all possible elements starting from \a start 572 * with increment \a inc are returned. 573 */ 574 template<class A> 575 A slice(int start, int inc=1, int n=-1); 576 public: 577 /// \name Associated types 578 //@{ 579 /// Type of the view stored in this array 580 typedef T value_type; 581 /// Type of a reference to the value type 582 typedef T& reference; 583 /// Type of a constant reference to the value type 584 typedef const T& const_reference; 585 /// Type of a pointer to the value type 586 typedef T* pointer; 587 /// Type of a read-only pointer to the value type 588 typedef const T* const_pointer; 589 /// Type of the iterator used to iterate through this array's elements 590 typedef T* iterator; 591 /// Type of the iterator used to iterate read-only through this array's elements 592 typedef const T* const_iterator; 593 /// Type of the iterator used to iterate backwards through this array's elements 594 typedef std::reverse_iterator<T*> reverse_iterator; 595 /// Type of the iterator used to iterate backwards and read-only through this array's elements 596 typedef std::reverse_iterator<const T*> const_reverse_iterator; 597 //@} 598 599 /// \name Constructors and initialization 600 //@{ 601 /// Allocate empty array 602 ArgArrayBase(void); 603 /// Allocate array with \a n elements 604 explicit ArgArrayBase(int n); 605 /// Initialize from argument array \a a (copy elements) 606 ArgArrayBase(const ArgArrayBase<T>& a); 607 /// Initialize from view array \a a (copy elements) 608 const ArgArrayBase<T>& operator =(const ArgArrayBase<T>& a); 609 /// Initialize from vector \a a 610 ArgArrayBase(const std::vector<T>& a); 611 /// Initialize from initializer list \a a 612 ArgArrayBase(std::initializer_list<T> a); 613 /// Initialize from InputIterator \a begin and \a end 614 template<class InputIterator> 615 ArgArrayBase(InputIterator first, InputIterator last); 616 //@} 617 618 /// \name Array size 619 //@{ 620 /// Return size of array (number of elements) 621 int size(void) const; 622 //@} 623 624 /// \name Array elements 625 //@{ 626 /// Return element at position \a i 627 T& operator [](int i); 628 /// Return element at position \a i 629 const T& operator [](int i) const; 630 //@} 631 632 /// \name Array iteration 633 //@{ 634 /// Return an iterator at the beginning of the array 635 iterator begin(void); 636 /// Return a read-only iterator at the beginning of the array 637 const_iterator begin(void) const; 638 /// Return an iterator past the end of the array 639 iterator end(void); 640 /// Return a read-only iterator past the end of the array 641 const_iterator end(void) const; 642 /// Return a reverse iterator at the end of the array 643 reverse_iterator rbegin(void); 644 /// Return a reverse and read-only iterator at the end of the array 645 const_reverse_iterator rbegin(void) const; 646 /// Return a reverse iterator past the beginning of the array 647 reverse_iterator rend(void); 648 /// Return a reverse and read-only iterator past the beginning of the array 649 const_reverse_iterator rend(void) const; 650 //@} 651 652 /// \name Destructor 653 //@{ 654 /// Destructor 655 ~ArgArrayBase(void); 656 //@} 657 }; 658 659 660 template<class> class ArgArray; 661 662 /** Concatenate \a x and \a y and return result 663 * \relates ArgArray 664 */ 665 template<class T> 666 typename ArrayTraits<ArgArray<T>>::ArgsType 667 operator +(const ArgArray<T>& x, const ArgArray<T>& y); 668 669 /** Concatenate \a x and \a y and return result 670 * \relates ArgArray 671 */ 672 template<class T> 673 typename ArrayTraits<ArgArray<T>>::ArgsType 674 operator +(const ArgArray<T>& x, const T& y); 675 676 /** Concatenate \a x and \a y and return result 677 * \relates ArgArray 678 */ 679 template<class T> 680 typename ArrayTraits<ArgArray<T>>::ArgsType 681 operator +(const T& x, const ArgArray<T>& y); 682 683 /** 684 * \brief Argument array for non-primitive types 685 * 686 * Argument arrays are used as convenient mechanism of passing arguments 687 * when calling functions as they combine both the size and the elements 688 * of an array. For a small number of elements, memory is allocated by 689 * creating an argument array object. Otherwise the memory is allocated 690 * from the heap. 691 * 692 * \ingroup TaskVar 693 */ 694 template<class T> 695 class ArgArray : public ArgArrayBase<T> { 696 protected: 697 using ArgArrayBase<T>::a; 698 public: 699 using ArgArrayBase<T>::size; 700 /// \name Constructors and initialization 701 //@{ 702 /// Allocate empty array 703 ArgArray(void); 704 /// Allocate array with \a n elements 705 explicit ArgArray(int n); 706 /// Allocate array with \a n elements and initialize with elements from array \a e 707 ArgArray(int n, const T* e); 708 /// Initialize from argument array \a a (copy elements) 709 ArgArray(const ArgArray<T>& a); 710 /// Initialize from vector \a a 711 ArgArray(const std::vector<T>& a); 712 /// Initialize from initializer list \a a 713 ArgArray(std::initializer_list<T> a); 714 /// Initialize from InputIterator \a first and \a last 715 template<class InputIterator> 716 ArgArray(InputIterator first, InputIterator last); 717 //@} 718 /// \name Array elements 719 //@{ 720 /// Return slice \f$y\f$ of length \a n such that forall \f$0\leq i<n\f$, \f$y_i=x_{\text{start}+i\cdot\text{inc}}\f$ 721 typename ArrayTraits<ArgArray<T>>::ArgsType 722 slice(int start, int inc=1, int n=-1); 723 //@} 724 /// \name Appending elements 725 //@{ 726 /// Insert a new element \a x at the end of the array (increase size by 1) 727 typename ArrayTraits<ArgArray<T>>::ArgsType& 728 operator <<(const T& x); 729 /// Append \a x to the end of the array 730 typename ArrayTraits<ArgArray<T>>::ArgsType& 731 operator <<(const ArgArray<T>& x); 732 //@} 733 734 friend typename ArrayTraits<ArgArray<T>>::ArgsType 735 operator + <>(const ArgArray<T>& x, const ArgArray<T>& y); 736 friend typename ArrayTraits<ArgArray<T>>::ArgsType 737 operator + <>(const ArgArray<T>& x, const T& y); 738 friend 739 typename ArrayTraits<ArgArray<T>>::ArgsType 740 operator + <>(const T& x, const ArgArray<T>& y); 741 }; 742 743 template<class> class VarArgArray; 744 745 /** Concatenate \a x and \a y and return result 746 * \relates ArgArray 747 */ 748 template<class Var> 749 typename ArrayTraits<VarArgArray<Var>>::ArgsType 750 operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y); 751 752 /** Concatenate \a x and \a y and return result 753 * \relates ArgArray 754 */ 755 template<class Var> 756 typename ArrayTraits<VarArgArray<Var>>::ArgsType 757 operator +(const VarArgArray<Var>& x, const Var& y); 758 759 /** Concatenate \a x and \a y and return result 760 * \relates ArgArray 761 */ 762 template<class Var> 763 typename ArrayTraits<VarArgArray<Var>>::ArgsType 764 operator +(const Var& x, const VarArgArray<Var>& y); 765 766 /** 767 * \brief Argument array for variables 768 * 769 * Argument arrays are used as convenient mechanism of passing arguments 770 * when calling functions as they combine both the size and the elements 771 * of an array. For a small number of elements, memory is allocated by 772 * creating an argument array object. Otherwise the memory is allocated 773 * from the heap. 774 * 775 * \ingroup TaskVar 776 */ 777 template<class Var> 778 class VarArgArray : public ArgArrayBase<Var> { 779 protected: 780 using ArgArrayBase<Var>::a; 781 using ArgArrayBase<Var>::n; 782 public: 783 using ArgArrayBase<Var>::size; 784 /// \name Constructors and initialization 785 //@{ 786 /// Allocate empty array 787 VarArgArray(void); 788 /// Allocate array with \a n elements 789 explicit VarArgArray(int n); 790 /// Initialize from variable argument array \a a (copy elements) 791 VarArgArray(const VarArgArray<Var>& a); 792 /// Initialize from variable array \a a (copy elements) 793 VarArgArray(const VarArray<Var>& a); 794 /// Initialize from vector \a a 795 VarArgArray(const std::vector<Var>& a); 796 /// Initialize from initializer list \a a 797 VarArgArray(std::initializer_list<Var> a); 798 /// Initialize from InputIterator \a first and \a last 799 template<class InputIterator> 800 VarArgArray(InputIterator first, InputIterator last); 801 //@} 802 /// \name Array elements 803 //@{ 804 /// Return slice \f$y\f$ of length \a n such that forall \f$0\leq i<n\f$, \f$y_i=x_{\text{start}+i\cdot\text{inc}}\f$ 805 typename ArrayTraits<VarArgArray<Var>>::ArgsType 806 slice(int start, int inc=1, int n=-1); 807 //@} 808 /// \name Appending elements 809 //@{ 810 /// Insert a new element \a x at the end of the array (increase size by 1) 811 typename ArrayTraits<VarArgArray<Var>>::ArgsType& 812 operator <<(const Var& x); 813 /// Append \a x to the end of the array 814 typename ArrayTraits<VarArgArray<Var>>::ArgsType& 815 operator <<(const VarArgArray<Var>& x); 816 //@} 817 818 /// Test if all variables are assigned 819 bool assigned(void) const; 820 821 friend typename ArrayTraits<VarArgArray<Var>>::ArgsType 822 operator + <>(const VarArgArray<Var>& x, const VarArgArray<Var>& y); 823 friend typename ArrayTraits<VarArgArray<Var>>::ArgsType 824 operator + <>(const VarArgArray<Var>& x, const Var& y); 825 friend 826 typename ArrayTraits<VarArgArray<Var>>::ArgsType 827 operator + <>(const Var& x, const VarArgArray<Var>& y); 828 }; 829 830 831 /** 832 * \brief Test whether array \a x together with array \a y contains at least one variable being the same 833 * 834 * Note that assigned variables are ignored. 835 * \relates VarArgArray 836 */ 837 template<class Var> 838 bool same(VarArgArray<Var> x, VarArgArray<Var> y); 839 /** 840 * \brief Test whether array \a x contains variable \a y 841 * 842 * Note that assigned variables are ignored. 843 * \relates VarArgArray 844 */ 845 template<class Var> 846 bool same(VarArgArray<Var> x, Var y); 847 /** 848 * \brief Test whether array \a y contains variable \a x 849 * 850 * Note that assigned variables are ignored. 851 * \relates VarArgArray 852 */ 853 template<class Var> 854 bool same(Var x, VarArgArray<Var> y); 855 /** 856 * \brief Test whether array \a x contains a variable multiply 857 * 858 * Note that assigned variables are ignored. 859 * \relates VarArgArray 860 */ 861 template<class Var> 862 bool same(VarArgArray<Var> x); 863 864 865 /** 866 * \brief Print array elements enclosed in curly brackets 867 * \relates VarArray 868 */ 869 template<class Char, class Traits, class Var> 870 std::basic_ostream<Char,Traits>& 871 operator <<(std::basic_ostream<Char,Traits>& os, 872 const VarArray<Var>& x); 873 874 /** 875 * \brief Print array elements enclosed in curly brackets 876 * \relates ViewArray 877 */ 878 template<class Char, class Traits, class View> 879 std::basic_ostream<Char,Traits>& 880 operator <<(std::basic_ostream<Char,Traits>& os, const ViewArray<View>& x); 881 882 /** 883 * \brief Print array elements enclosed in curly brackets 884 * \relates ArgArrayBase 885 */ 886 template<class Char, class Traits, class T> 887 std::basic_ostream<Char,Traits>& 888 operator <<(std::basic_ostream<Char,Traits>& os, const ArgArrayBase<T>& x); 889 890 891 /* 892 * Implementation 893 * 894 */ 895 896 /* 897 * Variable arrays 898 * 899 * These arrays are allocated in the space. 900 * 901 */ 902 903 template<class Var> 904 forceinline 905 VarArray<Var>::VarArray(void) : n(0), x(nullptr) {} 906 907 template<class Var> 908 forceinline 909 VarArray<Var>::VarArray(Space& home, int n0) 910 : n(n0) { 911 // Allocate from space 912 x = (n>0) ? home.alloc<Var>(n) : nullptr; 913 } 914 915 template<class Var> 916 forceinline 917 VarArray<Var>::VarArray(const VarArray<Var>& a) { 918 n = a.n; x = a.x; 919 } 920 921 template<class Var> 922 inline const VarArray<Var>& 923 VarArray<Var>::operator =(const VarArray<Var>& a) { 924 n = a.n; x = a.x; 925 return *this; 926 } 927 928 template<class Var> 929 forceinline int 930 VarArray<Var>::size(void) const { 931 return n; 932 } 933 934 template<class Var> 935 forceinline Var& 936 VarArray<Var>::operator [](int i) { 937 assert((i >= 0) && (i < size())); 938 return x[i]; 939 } 940 941 template<class Var> 942 forceinline const Var& 943 VarArray<Var>::operator [](int i) const { 944 assert((i >= 0) && (i < size())); 945 return x[i]; 946 } 947 948 template<class Var> 949 typename ArrayTraits<VarArgArray<Var>>::ArgsType 950 VarArray<Var>::slice(int start, int inc, int maxN) { 951 assert(n==0 || start < n); 952 if (n==0 || maxN<0) 953 maxN = n; 954 int s; 955 if (inc == 0) 956 s = n-start; 957 else if (inc > 0) 958 s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1); 959 else 960 s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1); 961 typename ArrayTraits<VarArgArray<Var>>::ArgsType r(std::min(maxN,s)); 962 for (int i=0; i<r.size(); i++, start+=inc) 963 r[i] = x[start]; 964 return r; 965 } 966 967 template<class Var> 968 forceinline typename VarArray<Var>::iterator 969 VarArray<Var>::begin(void) { 970 return x; 971 } 972 973 template<class Var> 974 forceinline typename VarArray<Var>::const_iterator 975 VarArray<Var>::begin(void) const { 976 return x; 977 } 978 979 template<class Var> 980 forceinline typename VarArray<Var>::iterator 981 VarArray<Var>::end(void) { 982 return x+n; 983 } 984 985 template<class Var> 986 forceinline typename VarArray<Var>::const_iterator 987 VarArray<Var>::end(void) const { 988 return x+n; 989 } 990 991 template<class Var> 992 forceinline typename VarArray<Var>::reverse_iterator 993 VarArray<Var>::rbegin(void) { 994 return reverse_iterator(x+n); 995 } 996 997 template<class Var> 998 forceinline typename VarArray<Var>::const_reverse_iterator 999 VarArray<Var>::rbegin(void) const { 1000 return const_reverse_iterator(x+n); 1001 } 1002 1003 template<class Var> 1004 forceinline typename VarArray<Var>::reverse_iterator 1005 VarArray<Var>::rend(void) { 1006 return reverse_iterator(x); 1007 } 1008 1009 template<class Var> 1010 forceinline typename VarArray<Var>::const_reverse_iterator 1011 VarArray<Var>::rend(void) const { 1012 return const_reverse_iterator(x); 1013 } 1014 1015 template<class Var> 1016 forceinline void 1017 VarArray<Var>::update(Space& home, VarArray<Var>& a) { 1018 n = a.n; 1019 if (n > 0) { 1020 x = home.alloc<Var>(n); 1021 for (int i=0; i<n; i++) 1022 x[i].update(home, a.x[i]); 1023 } else { 1024 x = nullptr; 1025 } 1026 } 1027 1028 template<class Var> 1029 forceinline bool 1030 VarArray<Var>::assigned(void) const { 1031 for (int i=0; i<n; i++) 1032 if (!x[i].assigned()) 1033 return false; 1034 return true; 1035 } 1036 1037 1038 template<class Var> 1039 typename ArrayTraits<VarArray<Var>>::ArgsType 1040 operator +(const VarArray<Var>& x, const VarArray<Var>& y) { 1041 typename ArrayTraits<VarArray<Var>>::ArgsType r(x.size()+y.size()); 1042 for (int i=0; i<x.size(); i++) 1043 r[i] = x[i]; 1044 for (int i=0; i<y.size(); i++) 1045 r[x.size()+i] = y[i]; 1046 return r; 1047 } 1048 1049 template<class Var> 1050 typename ArrayTraits<VarArray<Var>>::ArgsType 1051 operator +(const VarArray<Var>& x, const VarArgArray<Var>& y) { 1052 typename ArrayTraits<VarArray<Var>>::ArgsType r(x.size()+y.size()); 1053 for (int i=0; i<x.size(); i++) 1054 r[i] = x[i]; 1055 for (int i=0; i<y.size(); i++) 1056 r[x.size()+i] = y[i]; 1057 return r; 1058 } 1059 1060 template<class Var> 1061 typename ArrayTraits<VarArray<Var>>::ArgsType 1062 operator +(const VarArgArray<Var>& x, const VarArray<Var>& y) { 1063 typename ArrayTraits<VarArray<Var>>::ArgsType r(x.size()+y.size()); 1064 for (int i=0; i<x.size(); i++) 1065 r[i] = x[i]; 1066 for (int i=0; i<y.size(); i++) 1067 r[x.size()+i] = y[i]; 1068 return r; 1069 } 1070 1071 template<class Var> 1072 typename ArrayTraits<VarArray<Var>>::ArgsType 1073 operator +(const VarArray<Var>& x, const Var& y) { 1074 typename ArrayTraits<VarArray<Var>>::ArgsType r(x.size()+1); 1075 for (int i=0; i<x.size(); i++) 1076 r[i] = x[i]; 1077 r[x.size()] = y; 1078 return r; 1079 } 1080 1081 template<class Var> 1082 typename ArrayTraits<VarArray<Var>>::ArgsType 1083 operator +(const Var& x, const VarArray<Var>& y) { 1084 typename ArrayTraits<VarArray<Var>>::ArgsType r(y.size()+1); 1085 r[0] = x; 1086 for (int i=0; i<y.size(); i++) 1087 r[1+i] = y[i]; 1088 return r; 1089 } 1090 1091 /* 1092 * View arrays 1093 * 1094 */ 1095 1096 template<class View> 1097 forceinline 1098 ViewArray<View>::ViewArray(void) : n(0), x(nullptr) {} 1099 1100 template<class View> 1101 forceinline 1102 ViewArray<View>::ViewArray(Space& home, int n0) 1103 : n(n0) { 1104 x = (n>0) ? home.alloc<View>(n) : nullptr; 1105 } 1106 template<class View> 1107 forceinline 1108 ViewArray<View>::ViewArray(Region& r, int n0) 1109 : n(n0) { 1110 x = (n>0) ? r.alloc<View>(n) : nullptr; 1111 } 1112 1113 template<class View> 1114 ViewArray<View>::ViewArray(Space& home, const ViewArray<View>& a) 1115 : n(a.size()) { 1116 if (n>0) { 1117 x = home.alloc<View>(n); 1118 for (int i=0; i<n; i++) 1119 x[i] = a[i]; 1120 } else { 1121 x = nullptr; 1122 } 1123 } 1124 template<class View> 1125 ViewArray<View>::ViewArray(Region& r, const ViewArray<View>& a) 1126 : n(a.size()) { 1127 if (n>0) { 1128 x = r.alloc<View>(n); 1129 for (int i=0; i<n; i++) 1130 x[i] = a[i]; 1131 } else { 1132 x = nullptr; 1133 } 1134 } 1135 1136 template<class View> 1137 forceinline 1138 ViewArray<View>::ViewArray(const ViewArray<View>& a) 1139 : n(a.n), x(a.x) {} 1140 1141 template<class View> 1142 forceinline const ViewArray<View>& 1143 ViewArray<View>::operator =(const ViewArray<View>& a) { 1144 n = a.n; x = a.x; 1145 return *this; 1146 } 1147 1148 template<class View> 1149 forceinline int 1150 ViewArray<View>::size(void) const { 1151 return n; 1152 } 1153 1154 template<class View> 1155 forceinline void 1156 ViewArray<View>::size(int n0) { 1157 n = n0; 1158 } 1159 1160 template<class View> 1161 forceinline View& 1162 ViewArray<View>::operator [](int i) { 1163 assert((i >= 0) && (i < size())); 1164 return x[i]; 1165 } 1166 1167 template<class View> 1168 forceinline const View& 1169 ViewArray<View>::operator [](int i) const { 1170 assert((i >= 0) && (i < size())); 1171 return x[i]; 1172 } 1173 1174 template<class View> 1175 forceinline typename ViewArray<View>::iterator 1176 ViewArray<View>::begin(void) { 1177 return x; 1178 } 1179 1180 template<class View> 1181 forceinline typename ViewArray<View>::const_iterator 1182 ViewArray<View>::begin(void) const { 1183 return x; 1184 } 1185 1186 template<class View> 1187 forceinline typename ViewArray<View>::iterator 1188 ViewArray<View>::end(void) { 1189 return x+n; 1190 } 1191 1192 template<class View> 1193 forceinline typename ViewArray<View>::const_iterator 1194 ViewArray<View>::end(void) const { 1195 return x+n; 1196 } 1197 1198 template<class View> 1199 forceinline typename ViewArray<View>::reverse_iterator 1200 ViewArray<View>::rbegin(void) { 1201 return reverse_iterator(x+n); 1202 } 1203 1204 template<class View> 1205 forceinline typename ViewArray<View>::const_reverse_iterator 1206 ViewArray<View>::rbegin(void) const { 1207 return const_reverse_iterator(x+n); 1208 } 1209 1210 template<class View> 1211 forceinline typename ViewArray<View>::reverse_iterator 1212 ViewArray<View>::rend(void) { 1213 return reverse_iterator(x); 1214 } 1215 1216 template<class View> 1217 forceinline typename ViewArray<View>::const_reverse_iterator 1218 ViewArray<View>::rend(void) const { 1219 return const_reverse_iterator(x); 1220 } 1221 1222 template<class View> 1223 forceinline void 1224 ViewArray<View>::move_fst(int i) { 1225 x[i]=x[0]; x++; n--; 1226 } 1227 1228 template<class View> 1229 forceinline void 1230 ViewArray<View>::move_lst(int i) { 1231 n--; x[i]=x[n]; 1232 } 1233 1234 template<class View> 1235 forceinline void 1236 ViewArray<View>::drop_fst(int i) { 1237 assert(i>=0); 1238 x += i; n -= i; 1239 } 1240 1241 template<class View> 1242 forceinline void 1243 ViewArray<View>::drop_lst(int i) { 1244 assert(i<n); 1245 n = i+1; 1246 } 1247 1248 template<class View> 1249 forceinline void 1250 ViewArray<View>::move_fst(int i, Space& home, Propagator& p, PropCond pc) { 1251 // Move x[0] to x[i] 1252 x[i].cancel(home,p,pc); 1253 x[i]=x[0]; x++; n--; 1254 } 1255 1256 template<class View> 1257 forceinline void 1258 ViewArray<View>::move_lst(int i, Space& home, Propagator& p, PropCond pc) { 1259 // Move x[n-1] to x[i] 1260 x[i].cancel(home,p,pc); 1261 n--; x[i]=x[n]; 1262 } 1263 1264 template<class View> 1265 void 1266 ViewArray<View>::drop_fst(int i, Space& home, Propagator& p, PropCond pc) { 1267 // Drop elements from 0..i-1 1268 assert(i>=0); 1269 for (int j=0; j<i; j++) 1270 x[j].cancel(home,p,pc); 1271 x += i; n -= i; 1272 } 1273 1274 template<class View> 1275 void 1276 ViewArray<View>::drop_lst(int i, Space& home, Propagator& p, PropCond pc) { 1277 // Drop elements from i+1..n-1 1278 assert(i<n); 1279 for (int j=i+1; j<n; j++) 1280 x[j].cancel(home,p,pc); 1281 n = i+1; 1282 } 1283 1284 template<class View> 1285 forceinline void 1286 ViewArray<View>::move_fst(int i, Space& home, Advisor& a) { 1287 // Move x[0] to x[i] 1288 x[i].cancel(home,a); 1289 x[i]=x[0]; x++; n--; 1290 } 1291 1292 template<class View> 1293 forceinline void 1294 ViewArray<View>::move_lst(int i, Space& home, Advisor& a) { 1295 // Move x[n-1] to x[i] 1296 x[i].cancel(home,a); 1297 n--; x[i]=x[n]; 1298 } 1299 1300 template<class View> 1301 void 1302 ViewArray<View>::drop_fst(int i, Space& home, Advisor& a) { 1303 // Drop elements from 0..i-1 1304 assert(i>=0); 1305 for (int j=0; j<i; j++) 1306 x[j].cancel(home,a); 1307 x += i; n -= i; 1308 } 1309 1310 template<class View> 1311 void 1312 ViewArray<View>::drop_lst(int i, Space& home, Advisor& a) { 1313 // Drop elements from i+1..n-1 1314 assert(i<n); 1315 for (int j=i+1; j<n; j++) 1316 x[j].cancel(home,a); 1317 n = i+1; 1318 } 1319 1320 template<class View> 1321 void 1322 ViewArray<View>::update(Space& home, ViewArray<View>& y) { 1323 n = y.n; 1324 if (n > 0) { 1325 x = home.alloc<View>(n); 1326 for (int i=0; i<n; i++) 1327 x[i].update(home, y.x[i]); 1328 } else { 1329 x = nullptr; 1330 } 1331 } 1332 1333 template<class View> 1334 void 1335 ViewArray<View>::subscribe(Space& home, Propagator& p, PropCond pc, 1336 bool schedule) { 1337 for (int i=0; i<n; i++) 1338 x[i].subscribe(home,p,pc,schedule); 1339 } 1340 1341 template<class View> 1342 void 1343 ViewArray<View>::cancel(Space& home, Propagator& p, PropCond pc) { 1344 for (int i=0; i<n; i++) 1345 x[i].cancel(home,p,pc); 1346 } 1347 1348 template<class View> 1349 void 1350 ViewArray<View>::subscribe(Space& home, Advisor& a) { 1351 for (int i=0; i<n; i++) 1352 x[i].subscribe(home,a); 1353 } 1354 1355 template<class View> 1356 void 1357 ViewArray<View>::cancel(Space& home, Advisor& a) { 1358 for (int i=0; i<n; i++) 1359 x[i].cancel(home,a); 1360 } 1361 1362 template<class View> 1363 void 1364 ViewArray<View>::reschedule(Space& home, Propagator& p, PropCond pc) { 1365 for (int i=0; i<n; i++) 1366 x[i].reschedule(home,p,pc); 1367 } 1368 1369 template<class View> 1370 forceinline bool 1371 ViewArray<View>::assigned(void) const { 1372 for (int i=0; i<n; i++) 1373 if (!x[i].assigned()) 1374 return false; 1375 return true; 1376 } 1377 1378 template<class View> 1379 bool 1380 ViewArray<View>::same(void) const { 1381 if (n < 2) 1382 return false; 1383 Region r; 1384 View* y = r.alloc<View>(n); 1385 int j=0; 1386 for (int i=0; i<n; i++) 1387 if (!x[i].assigned()) 1388 y[j++] = x[i]; 1389 if (j < 2) 1390 return false; 1391 Support::quicksort<View>(y,j); 1392 for (int i=1; i<j; i++) 1393 if (y[i-1] == y[i]) 1394 return true; 1395 return false; 1396 } 1397 1398 template<class View> 1399 bool 1400 ViewArray<View>::same(const View& y) const { 1401 if (y.assigned()) 1402 return false; 1403 for (int i=0; i<n; i++) 1404 if (x[i] == y) 1405 return true; 1406 return false; 1407 } 1408 1409 template<class View> 1410 void 1411 ViewArray<View>::unique(void) { 1412 if (n < 2) 1413 return; 1414 Region r; 1415 Kernel::ViewOcc<View>* o = r.alloc<Kernel::ViewOcc<View>>(n); 1416 for (int i=0; i<n; i++) { 1417 o[i].x = x[i]; o[i].i = i; 1418 } 1419 Support::quicksort<Kernel::ViewOcc<View>>(o,n); 1420 // Assign bucket numbers 1421 int* bkt = r.alloc<int>(n); 1422 int b = 0; 1423 bkt[o[0].i] = b; 1424 for (int i=1; i<n; i++) { 1425 if (o[i-1].x != o[i].x) 1426 b++; 1427 bkt[o[i].i] = b; 1428 } 1429 // Eliminate duplicate elements 1430 Support::BitSet<Region> seen(r,static_cast<unsigned int>(b+1)); 1431 int j=0; 1432 for (int i=0; i<n; i++) 1433 if (!seen.get(static_cast<unsigned int>(bkt[i]))) { 1434 x[j++]=x[i]; seen.set(static_cast<unsigned int>(bkt[i])); 1435 } else { 1436 x[j]=x[i]; 1437 } 1438 assert(j == b+1); 1439 n = j; 1440 } 1441 1442 1443 /* 1444 * Sharing for view arrays 1445 * 1446 */ 1447 template<class ViewX, class ViewY> 1448 bool 1449 shared(ViewArray<ViewX> x, ViewArray<ViewY> y) { 1450 if ((x.size() == 0) || (y.size() == 0)) 1451 return false; 1452 Region r; 1453 void** px = r.alloc<void*>(x.size()); 1454 int j=0; 1455 for (int i=0; i<x.size(); i++) 1456 if (!x[i].assigned() && x[i].varimp()) 1457 px[j++] = x[i].varimp(); 1458 if (j == 0) 1459 return false; 1460 void** py = r.alloc<void*>(y.size()); 1461 int k=0; 1462 for (int i=0; i<y.size(); i++) 1463 if (!y[i].assigned() && y[i].varimp()) 1464 py[k++] = y[i].varimp(); 1465 if (k == 0) 1466 return false; 1467 return Kernel::duplicates(px,j,py,k); 1468 } 1469 1470 template<class ViewX, class ViewY> 1471 bool 1472 shared(ViewArray<ViewX> x, ViewY y) { 1473 if (y.assigned() || !y.varimp()) 1474 return false; 1475 for (int i=0; i<x.size(); i++) 1476 if (!x[i].assigned() && x[i].varimp() && (x[i].varimp() == y.varimp())) 1477 return true; 1478 return false; 1479 } 1480 1481 template<class ViewX, class ViewY> 1482 forceinline bool 1483 shared(ViewX x, ViewArray<ViewY> y) { 1484 return shared(y,x); 1485 } 1486 1487 template<class View> 1488 bool 1489 shared(ViewArray<View> x) { 1490 if (x.size() < 2) 1491 return false; 1492 Region r; 1493 void** px = r.alloc<void*>(x.size()); 1494 int j=0; 1495 for (int i=0; i<x.size(); i++) 1496 if (!x[i].assigned() && x[i].varimp()) 1497 px[j++] = x[i].varimp(); 1498 return (j > 2) && Kernel::duplicates(px,j); 1499 } 1500 1501 1502 1503 /* 1504 * Argument arrays: base class 1505 * 1506 */ 1507 1508 template<class T> 1509 forceinline T* 1510 ArgArrayBase<T>::allocate(int n) { 1511 return (n > onstack_size) ? 1512 heap.alloc<T>(static_cast<unsigned int>(n)) : &onstack[0]; 1513 } 1514 1515 template<class T> 1516 forceinline void 1517 ArgArrayBase<T>::resize(int i) { 1518 if (n+i >= capacity) { 1519 assert(n+i >= onstack_size); 1520 int newCapacity = (3*capacity)/2; 1521 if (newCapacity <= n+i) 1522 newCapacity = n+i; 1523 T* newA = allocate(newCapacity); 1524 heap.copy<T>(newA,a,n); 1525 if (capacity > onstack_size) 1526 heap.free(a,capacity); 1527 capacity = newCapacity; 1528 a = newA; 1529 } 1530 } 1531 1532 template<class T> 1533 forceinline 1534 ArgArrayBase<T>::ArgArrayBase(void) 1535 : n(0), capacity(onstack_size), a(allocate(0)) {} 1536 1537 template<class T> 1538 forceinline 1539 ArgArrayBase<T>::ArgArrayBase(int n0) 1540 : n(n0), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {} 1541 1542 template<class T> 1543 inline 1544 ArgArrayBase<T>::ArgArrayBase(const ArgArrayBase<T>& aa) 1545 : n(aa.n), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) { 1546 heap.copy<T>(a,aa.a,n); 1547 } 1548 1549 template<class T> 1550 inline 1551 ArgArrayBase<T>::ArgArrayBase(const std::vector<T>& aa) 1552 : n(static_cast<int>(aa.size())), 1553 capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) { 1554 heap.copy<T>(a,&aa[0],n); 1555 } 1556 1557 template<class T> 1558 inline 1559 ArgArrayBase<T>::ArgArrayBase(std::initializer_list<T> aa) 1560 : n(static_cast<int>(aa.size())), 1561 capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) { 1562 int i=0; 1563 for (const T& x : aa) 1564 a[i++]=x; 1565 } 1566 1567 template<class T> 1568 forceinline 1569 ArgArrayBase<T>::~ArgArrayBase(void) { 1570 if (capacity > onstack_size) 1571 heap.free(a,capacity); 1572 } 1573 1574 template<class T> 1575 forceinline const ArgArrayBase<T>& 1576 ArgArrayBase<T>::operator =(const ArgArrayBase<T>& aa) { 1577 if (&aa != this) { 1578 if (capacity > onstack_size) 1579 heap.free(a,capacity); 1580 n = aa.n; 1581 capacity = (n < onstack_size ? onstack_size : n); 1582 a = allocate(aa.n); 1583 heap.copy<T>(a,aa.a,n); 1584 } 1585 return *this; 1586 } 1587 1588 template<class T> 1589 forceinline int 1590 ArgArrayBase<T>::size(void) const { 1591 return n; 1592 } 1593 1594 template<class T> 1595 forceinline T& 1596 ArgArrayBase<T>::operator [](int i) { 1597 assert((i>=0) && (i < n)); 1598 return a[i]; 1599 } 1600 1601 template<class T> 1602 forceinline const T& 1603 ArgArrayBase<T>::operator [](int i) const { 1604 assert((i>=0) && (i < n)); 1605 return a[i]; 1606 } 1607 1608 template<class T> 1609 forceinline typename ArgArrayBase<T>::iterator 1610 ArgArrayBase<T>::begin(void) { 1611 return a; 1612 } 1613 1614 template<class T> 1615 forceinline typename ArgArrayBase<T>::const_iterator 1616 ArgArrayBase<T>::begin(void) const { 1617 return a; 1618 } 1619 1620 template<class T> 1621 forceinline typename ArgArrayBase<T>::iterator 1622 ArgArrayBase<T>::end(void) { 1623 return a+n; 1624 } 1625 1626 template<class T> 1627 forceinline typename ArgArrayBase<T>::const_iterator 1628 ArgArrayBase<T>::end(void) const { 1629 return a+n; 1630 } 1631 1632 template<class T> 1633 forceinline typename ArgArrayBase<T>::reverse_iterator 1634 ArgArrayBase<T>::rbegin(void) { 1635 return reverse_iterator(a+n); 1636 } 1637 1638 template<class T> 1639 forceinline typename ArgArrayBase<T>::const_reverse_iterator 1640 ArgArrayBase<T>::rbegin(void) const { 1641 return const_reverse_iterator(a+n); 1642 } 1643 1644 template<class T> 1645 forceinline typename ArgArrayBase<T>::reverse_iterator 1646 ArgArrayBase<T>::rend(void) { 1647 return reverse_iterator(a); 1648 } 1649 1650 template<class T> 1651 forceinline typename ArgArrayBase<T>::const_reverse_iterator 1652 ArgArrayBase<T>::rend(void) const { 1653 return const_reverse_iterator(a); 1654 } 1655 1656 template<class T> template<class A> 1657 A 1658 ArgArrayBase<T>::slice(int start, int inc, int maxN) { 1659 assert(n==0 || start < n); 1660 if (n==0 || maxN<0) 1661 maxN = n; 1662 int s; 1663 if (inc == 0) 1664 s = n-start; 1665 else if (inc > 0) 1666 s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1); 1667 else 1668 s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1); 1669 A r(std::min(maxN,s)); 1670 for (int i=0; i<r.size(); i++, start+=inc) 1671 new (&r[i]) T(a[start]); 1672 return r; 1673 } 1674 1675 template<class T> template<class A> 1676 inline A& 1677 ArgArrayBase<T>::append(const T& x) { 1678 resize(1); 1679 new (&a[n++]) T(x); 1680 return static_cast<A&>(*this); 1681 } 1682 1683 template<class T> 1684 template<class InputIterator> 1685 inline 1686 ArgArrayBase<T>::ArgArrayBase(InputIterator first, InputIterator last) 1687 : n(0), capacity(onstack_size), a(allocate(0)) { 1688 while (first != last) { 1689 (void) append<ArgArrayBase<T>>(*first); 1690 ++first; 1691 } 1692 } 1693 1694 1695 template<class T> template<class A> 1696 inline A& 1697 ArgArrayBase<T>::append(const ArgArrayBase<T>& x) { 1698 resize(x.size()); 1699 for (int i=0; i<x.size(); i++) 1700 new (&a[n++]) T(x[i]); 1701 return static_cast<A&>(*this); 1702 } 1703 1704 template<class T> template<class A> 1705 inline A 1706 ArgArrayBase<T>::concat(const ArgArrayBase<T>& x) const { 1707 A r(n+x.n); 1708 for (int i=0; i<n; i++) 1709 new (&r[i]) T(a[i]); 1710 for (int i=0; i<x.n; i++) 1711 new (&r[n+i]) T(x.a[i]); 1712 return r; 1713 } 1714 1715 template<class T> template<class A> 1716 inline A 1717 ArgArrayBase<T>::concat(const T& x) const { 1718 A r(n+1); 1719 for (int i=0; i<n; i++) 1720 new (&r[i]) T(a[i]); 1721 new (&r[n]) T(x); 1722 return r; 1723 } 1724 1725 1726 /* 1727 * Argument arrays 1728 * 1729 */ 1730 1731 template<class T> 1732 forceinline 1733 ArgArray<T>::ArgArray(void) {} 1734 1735 template<class T> 1736 forceinline 1737 ArgArray<T>::ArgArray(int n) 1738 : ArgArrayBase<T>(n) {} 1739 1740 template<class T> 1741 ArgArray<T>::ArgArray(int n, const T* a0) 1742 : ArgArrayBase<T>(n) { 1743 for (int i=0; i<n; i++) 1744 a[i] = a0[i]; 1745 } 1746 1747 template<class T> 1748 forceinline 1749 ArgArray<T>::ArgArray(const ArgArray<T>& aa) 1750 : ArgArrayBase<T>(aa) {} 1751 1752 template<class T> 1753 forceinline 1754 ArgArray<T>::ArgArray(const std::vector<T>& aa) 1755 : ArgArrayBase<T>(aa) {} 1756 1757 template<class T> 1758 forceinline 1759 ArgArray<T>::ArgArray(std::initializer_list<T> aa) 1760 : ArgArrayBase<T>(aa) {} 1761 1762 template<class T> 1763 template<class InputIterator> 1764 forceinline 1765 ArgArray<T>::ArgArray(InputIterator first, InputIterator last) 1766 : ArgArrayBase<T>(first,last) {} 1767 1768 template<class T> 1769 forceinline typename ArrayTraits<ArgArray<T>>::ArgsType 1770 ArgArray<T>::slice(int start, int inc, int maxN) { 1771 return ArgArrayBase<T>::template slice 1772 <typename ArrayTraits<ArgArray<T>>::ArgsType> 1773 (start,inc,maxN); 1774 } 1775 1776 template<class T> 1777 forceinline typename ArrayTraits<ArgArray<T>>::ArgsType& 1778 ArgArray<T>::operator <<(const T& x) { 1779 return 1780 ArgArrayBase<T>::template append 1781 <typename ArrayTraits<ArgArray<T>>::ArgsType>(x); 1782 } 1783 1784 template<class T> 1785 forceinline typename ArrayTraits<ArgArray<T>>::ArgsType& 1786 ArgArray<T>::operator <<(const ArgArray<T>& x) { 1787 return 1788 ArgArrayBase<T>::template append 1789 <typename ArrayTraits<ArgArray<T>>::ArgsType>(x); 1790 } 1791 1792 template<class T> 1793 typename ArrayTraits<ArgArray<T>>::ArgsType 1794 operator +(const ArgArray<T>& x, const ArgArray<T>& y) { 1795 return x.template concat 1796 <typename ArrayTraits<ArgArray<T>>::ArgsType>(y); 1797 } 1798 1799 template<class T> 1800 typename ArrayTraits<ArgArray<T>>::ArgsType 1801 operator +(const ArgArray<T>& x, const T& y) { 1802 return x.template concat 1803 <typename ArrayTraits<ArgArray<T>>::ArgsType>(y); 1804 } 1805 1806 template<class T> 1807 typename ArrayTraits<ArgArray<T>>::ArgsType 1808 operator +(const T& x, const ArgArray<T>& y) { 1809 ArgArray<T> xa(1); 1810 xa[0] = x; 1811 return xa.template concat 1812 <typename ArrayTraits<ArgArray<T>>::ArgsType>(y); 1813 } 1814 1815 /* 1816 * Argument arrays for variables 1817 * 1818 */ 1819 1820 template<class Var> 1821 forceinline 1822 VarArgArray<Var>::VarArgArray(void) {} 1823 1824 template<class Var> 1825 forceinline 1826 VarArgArray<Var>::VarArgArray(int n) : ArgArrayBase<Var>(n) {} 1827 1828 template<class Var> 1829 forceinline 1830 VarArgArray<Var>::VarArgArray(const VarArgArray<Var>& aa) 1831 : ArgArrayBase<Var>(aa) {} 1832 1833 template<class Var> 1834 forceinline 1835 VarArgArray<Var>::VarArgArray(const std::vector<Var>& aa) 1836 : ArgArrayBase<Var>(aa) {} 1837 1838 template<class Var> 1839 forceinline 1840 VarArgArray<Var>::VarArgArray(std::initializer_list<Var> aa) 1841 : ArgArrayBase<Var>(aa) {} 1842 1843 template<class Var> 1844 template<class InputIterator> 1845 forceinline 1846 VarArgArray<Var>::VarArgArray(InputIterator first, InputIterator last) 1847 : ArgArrayBase<Var>(first,last) {} 1848 1849 template<class Var> 1850 inline 1851 VarArgArray<Var>::VarArgArray(const VarArray<Var>& x) 1852 : ArgArrayBase<Var>(x.size()) { 1853 for (int i=0; i<x.size(); i++) 1854 a[i]=x[i]; 1855 } 1856 1857 template<class Var> 1858 forceinline typename ArrayTraits<VarArgArray<Var>>::ArgsType 1859 VarArgArray<Var>::slice(int start, int inc, int maxN) { 1860 return ArgArrayBase<Var>::template slice 1861 <typename ArrayTraits<VarArgArray<Var>>::ArgsType> 1862 (start,inc,maxN); 1863 } 1864 1865 template<class Var> 1866 forceinline typename ArrayTraits<VarArgArray<Var>>::ArgsType& 1867 VarArgArray<Var>::operator <<(const Var& x) { 1868 return 1869 ArgArrayBase<Var>::template append 1870 <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(x); 1871 } 1872 1873 template<class Var> 1874 forceinline typename ArrayTraits<VarArgArray<Var>>::ArgsType& 1875 VarArgArray<Var>::operator <<(const VarArgArray<Var>& x) { 1876 return 1877 ArgArrayBase<Var>::template append 1878 <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(x); 1879 } 1880 1881 template<class Var> 1882 typename ArrayTraits<VarArgArray<Var>>::ArgsType 1883 operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y) { 1884 return x.template concat 1885 <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(y); 1886 } 1887 1888 template<class Var> 1889 typename ArrayTraits<VarArgArray<Var>>::ArgsType 1890 operator +(const VarArgArray<Var>& x, const Var& y) { 1891 return x.template concat 1892 <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(y); 1893 } 1894 1895 template<class Var> 1896 typename ArrayTraits<VarArgArray<Var>>::ArgsType 1897 operator +(const Var& x, const VarArgArray<Var>& y) { 1898 VarArgArray<Var> xa(1); 1899 xa[0] = x; 1900 return xa.template concat 1901 <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(y); 1902 } 1903 1904 template<class Var> 1905 forceinline bool 1906 VarArgArray<Var>::assigned(void) const { 1907 for (int i=0; i<n; i++) 1908 if (!a[i].assigned()) 1909 return false; 1910 return true; 1911 } 1912 1913 1914 /* 1915 * Checking for multiple occurences of the same variable 1916 * 1917 */ 1918 template<class Var> 1919 bool 1920 same(VarArgArray<Var> x, VarArgArray<Var> y) { 1921 if ((x.size() == 0) || (y.size() == 0)) 1922 return false; 1923 Region r; 1924 void** px = r.alloc<void*>(x.size()); 1925 int j=0; 1926 for (int i=0; i<x.size(); i++) 1927 if (!x[i].assigned()) 1928 px[j++] = x[i].varimp(); 1929 if (j == 0) 1930 return false; 1931 void** py = r.alloc<void*>(y.size()); 1932 int k=0; 1933 for (int i=0; i<y.size(); i++) 1934 if (!y[i].assigned()) 1935 py[k++] = y[i].varimp(); 1936 if (k == 0) 1937 return false; 1938 return Kernel::duplicates(px,j,py,k); 1939 } 1940 1941 template<class Var> 1942 bool 1943 same(VarArgArray<Var> x, Var y) { 1944 if (y.assigned()) 1945 return false; 1946 for (int i=0; i<x.size(); i++) 1947 if (x[i].varimp() == y.varimp()) 1948 return true; 1949 return false; 1950 } 1951 1952 template<class Var> 1953 forceinline bool 1954 same(Var x, VarArgArray<Var> y) { 1955 return same(y,x); 1956 } 1957 1958 template<class Var> 1959 bool 1960 same(VarArgArray<Var> x) { 1961 if (x.size() < 2) 1962 return false; 1963 Region r; 1964 void** px = r.alloc<void*>(x.size()); 1965 int j=0; 1966 for (int i=0; i<x.size(); i++) 1967 if (!x[i].assigned()) 1968 px[j++] = x[i].varimp(); 1969 return (j > 1) && Kernel::duplicates(px,j); 1970 } 1971 1972 1973 1974 /* 1975 * Interdependent code 1976 * 1977 */ 1978 1979 template<class Var> 1980 inline 1981 VarArray<Var>::VarArray(Space& home, const VarArgArray<Var>& a) 1982 : n(a.size()) { 1983 if (n>0) { 1984 x = home.alloc<Var>(n); 1985 for (int i=0; i<n; i++) 1986 x[i] = a[i]; 1987 } else { 1988 x = nullptr; 1989 } 1990 } 1991 1992 1993 /* 1994 * Printing of arrays 1995 * 1996 */ 1997 template<class Char, class Traits, class Var> 1998 std::basic_ostream<Char,Traits>& 1999 operator <<(std::basic_ostream<Char,Traits>& os, 2000 const VarArray<Var>& x) { 2001 std::basic_ostringstream<Char,Traits> s; 2002 s.copyfmt(os); s.width(0); 2003 s << '{'; 2004 if (x.size() > 0) { 2005 s << x[0]; 2006 for (int i=1; i<x.size(); i++) 2007 s << ", " << x[i]; 2008 } 2009 s << '}'; 2010 return os << s.str(); 2011 } 2012 2013 template<class Char, class Traits, class View> 2014 std::basic_ostream<Char,Traits>& 2015 operator <<(std::basic_ostream<Char,Traits>& os, 2016 const ViewArray<View>& x) { 2017 std::basic_ostringstream<Char,Traits> s; 2018 s.copyfmt(os); s.width(0); 2019 s << '{'; 2020 if (x.size() > 0) { 2021 s << x[0]; 2022 for (int i=1; i<x.size(); i++) 2023 s << ", " << x[i]; 2024 } 2025 s << '}'; 2026 return os << s.str(); 2027 } 2028 2029 template<class Char, class Traits, class T> 2030 std::basic_ostream<Char,Traits>& 2031 operator <<(std::basic_ostream<Char,Traits>& os, 2032 const ArgArrayBase<T>& x) { 2033 std::basic_ostringstream<Char,Traits> s; 2034 s.copyfmt(os); s.width(0); 2035 s << '{'; 2036 if (x.size() > 0) { 2037 s << x[0]; 2038 for (int i=1; i<x.size(); i++) 2039 s << ", " << x[i]; 2040 } 2041 s << '}'; 2042 return os << s.str(); 2043 } 2044 2045} 2046 2047// STATISTICS: kernel-other