Generated on Tue Apr 18 10:21:34 2017 for Gecode by doxygen 1.6.3

array.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *     Guido Tack <tack@gecode.org>
00006  *
00007  *  Contributing authors:
00008  *     Gregory Crosswhite <gcross@phys.washington.edu>
00009  *
00010  *  Copyright:
00011  *     Gregory Crosswhite, 2011
00012  *     Christian Schulte, 2003
00013  *     Guido Tack, 2004
00014  *
00015  *  Last modified:
00016  *     $Date: 2016-09-25 21:42:04 +0200 (Sun, 25 Sep 2016) $ by $Author: schulte $
00017  *     $Revision: 15170 $
00018  *
00019  *  This file is part of Gecode, the generic constraint
00020  *  development environment:
00021  *     http://www.gecode.org
00022  *
00023  *  Permission is hereby granted, free of charge, to any person obtaining
00024  *  a copy of this software and associated documentation files (the
00025  *  "Software"), to deal in the Software without restriction, including
00026  *  without limitation the rights to use, copy, modify, merge, publish,
00027  *  distribute, sublicense, and/or sell copies of the Software, and to
00028  *  permit persons to whom the Software is furnished to do so, subject to
00029  *  the following conditions:
00030  *
00031  *  The above copyright notice and this permission notice shall be
00032  *  included in all copies or substantial portions of the Software.
00033  *
00034  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00035  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00036  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00037  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00038  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00039  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00040  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00041  *
00042  */
00043 
00044 #include <cstdarg>
00045 #include <iostream>
00046 #include <iterator>
00047 #include <vector>
00048 #include <sstream>
00049 
00050 namespace Gecode {
00051 
00052   template<class Var> class VarArray;
00053   template<class Var> class VarArgArray;
00054 
00067   template<class A>
00068   class ArrayTraits {};
00069 
00085   template<class Var>
00086   class VarArray {
00087   protected:
00089     int n;
00091     Var* x;
00092   public:
00094 
00095 
00096     typedef Var value_type;
00098     typedef Var& reference;
00100     typedef const Var& const_reference;
00102     typedef Var* pointer;
00104     typedef const Var* const_pointer;
00106     typedef Var* iterator;
00108     typedef const Var* const_iterator;
00110     typedef std::reverse_iterator<Var*> reverse_iterator;
00112     typedef std::reverse_iterator<const Var*> const_reverse_iterator;
00114 
00116 
00117 
00118 
00119     VarArray(void);
00121     VarArray(Space& home, int m);
00123     VarArray(Space& home, const VarArgArray<Var>&);
00125     VarArray(const VarArray<Var>& a);
00127     const VarArray<Var>& operator =(const VarArray<Var>& a);
00129 
00131 
00132 
00133     int size(void) const;
00135 
00137 
00138 
00139     Var& operator [](int i);
00141     const Var& operator [](int i) const;
00147     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00148     slice(int start, int inc=1, int n=-1);
00150 
00152 
00153 
00154     iterator begin(void);
00156     const_iterator begin(void) const;
00158     iterator end(void);
00160     const_iterator end(void) const;
00162     reverse_iterator rbegin(void);
00164     const_reverse_iterator rbegin(void) const;
00166     reverse_iterator rend(void);
00168     const_reverse_iterator rend(void) const;
00170 
00172     bool assigned(void) const;
00173 
00175 
00176 
00183     void update(Space&, bool share, VarArray<Var>& a);
00185   private:
00186     static void* operator new(size_t) throw();
00187     static void  operator delete(void*,size_t);
00188   };
00189 
00193   template<class T>
00194   typename ArrayTraits<VarArray<T> >::ArgsType
00195   operator +(const VarArray<T>& x, const VarArgArray<T>& y);
00196 
00200   template<class T>
00201   typename ArrayTraits<VarArray<T> >::ArgsType
00202   operator +(const VarArray<T>& x, const VarArray<T>& y);
00203 
00207   template<class T>
00208   typename ArrayTraits<VarArray<T> >::ArgsType
00209   operator +(const VarArgArray<T>& x, const VarArray<T>& y);
00210 
00214   template<class T>
00215   typename ArrayTraits<VarArray<T> >::ArgsType
00216   operator +(const VarArray<T>& x, const T& y);
00217 
00221   template<class T>
00222   typename ArrayTraits<VarArray<T> >::ArgsType
00223   operator +(const T& x, const VarArray<T>& y);
00224 
00233   template<class View>
00234   class ViewArray {
00235   private:
00237     int  n;
00239     View* x;
00241     template<class X>
00242     class ViewLess {
00243     public:
00244       bool operator ()(const X&, const X&);
00245     };
00247     static void sort(View* x, int n);
00248   public:
00250 
00251 
00252     typedef View value_type;
00254     typedef View& reference;
00256     typedef const View& const_reference;
00258     typedef View* pointer;
00260     typedef const View* const_pointer;
00262     typedef View* iterator;
00264     typedef const View* const_iterator;
00266     typedef std::reverse_iterator<View*> reverse_iterator;
00268     typedef std::reverse_iterator<const View*> const_reverse_iterator;
00270 
00272 
00273 
00274     ViewArray(void);
00276     ViewArray(Space& home, int m);
00278     ViewArray(Region& r, int m);
00280     ViewArray(const ViewArray<View>& a);
00282     ViewArray(Space& home, const ViewArray<View>& a);
00284     ViewArray(Region& r, const ViewArray<View>& a);
00286     const ViewArray<View>& operator =(const ViewArray<View>& a);
00293     template<class Var>
00294     ViewArray(Space& home, const VarArgArray<Var>& a)
00295       : n(a.size()) {
00296       // This may not be in the hpp file (to satisfy the MS compiler)
00297       if (n>0) {
00298         x = home.alloc<View>(n);
00299         for (int i=n; i--; )
00300           x[i]=a[i];
00301       } else {
00302         x = NULL;
00303       }
00304     }
00311     template<class Var>
00312     ViewArray(Region& r, const VarArgArray<Var>& a)
00313       : n(a.size()) {
00314       // This may not be in the hpp file (to satisfy the MS compiler)
00315       if (n>0) {
00316         x = r.alloc<View>(n);
00317         for (int i=n; i--; )
00318           x[i]=a[i];
00319       } else {
00320         x = NULL;
00321       }
00322     }
00324 
00326 
00327 
00328     int size(void) const;
00330     void size(int n);
00332 
00334 
00335 
00336     View& operator [](int i);
00338     const View& operator [](int i) const;
00340 
00342 
00343 
00344     iterator begin(void);
00346     const_iterator begin(void) const;
00348     iterator end(void);
00350     const_iterator end(void) const;
00352     reverse_iterator rbegin(void);
00354     const_reverse_iterator rbegin(void) const;
00356     reverse_iterator rend(void);
00358     const_reverse_iterator rend(void) const;
00360 
00362 
00363 
00370     void subscribe(Space& home, Propagator& p, PropCond pc,
00371                    bool schedule=true);
00373     void cancel(Space& home, Propagator& p, PropCond pc);
00375     void subscribe(Space& home, Advisor& a);
00377     void cancel(Space& home, Advisor& a);
00379     void reschedule(Space& home, Propagator& p, PropCond pc);
00381 
00383 
00384 
00391     void update(Space&, bool share, ViewArray<View>& a);
00393 
00394 
00396 
00397 
00398     void move_fst(int i);
00400     void move_lst(int i);
00406     void move_fst(int i, Space& home, Propagator& p, PropCond pc);
00412     void move_lst(int i, Space& home, Propagator& p, PropCond pc);
00418     void move_fst(int i, Space& home, Advisor& a);
00424     void move_lst(int i, Space& home, Advisor& a);
00426 
00428 
00429 
00430     void drop_fst(int i);
00432     void drop_lst(int i);
00438     void drop_fst(int i, Space& home, Propagator& p, PropCond pc);
00445     void drop_lst(int i, Space& home, Propagator& p, PropCond pc);
00451     void drop_fst(int i, Space& home, Advisor& a);
00457     void drop_lst(int i, Space& home, Advisor& a);
00459 
00461     bool assigned(void) const;
00462 
00464 
00465 
00470     bool same(const Space& home) const;
00476     bool same(const Space& home, const View& y) const;
00478     void unique(const Space& home);
00480 
00482 
00483 
00488     bool shared(const Space& home) const;
00494     template<class ViewY>
00495     bool shared(const Space& home, const ViewY& y) const;
00501     template<class ViewY>
00502     bool shared(const Space& home, const ViewArray<ViewY>& y) const;
00504 
00505   private:
00506     static void* operator new(size_t) throw();
00507     static void  operator delete(void*,size_t);
00508   };
00509 
00523   template<class T>
00524   class ArgArrayBase {
00525   protected:
00527     int n;
00529     int capacity;
00531     T*  a;
00533     static const int onstack_size = 16;
00535     T onstack[onstack_size];
00537     T* allocate(int n);
00539     void resize(int i);
00541     template<class A>
00542     A concat(const ArgArrayBase<T>& x) const;
00544     template<class A>
00545     A concat(const T& x) const;
00547     template<class A>
00548     A& append(const T& x);
00550     template<class A>
00551     A& append(const ArgArrayBase<T>& x);
00557     template<class A>
00558     A slice(int start, int inc=1, int n=-1);
00559   public:
00561 
00562 
00563     typedef T value_type;
00565     typedef T& reference;
00567     typedef const T& const_reference;
00569     typedef T* pointer;
00571     typedef const T* const_pointer;
00573     typedef T* iterator;
00575     typedef const T* const_iterator;
00577     typedef std::reverse_iterator<T*> reverse_iterator;
00579     typedef std::reverse_iterator<const T*> const_reverse_iterator;
00581 
00583 
00584 
00585     ArgArrayBase(void);
00587     explicit ArgArrayBase(int n);
00589     ArgArrayBase(const ArgArrayBase<T>& a);
00591     const ArgArrayBase<T>& operator =(const ArgArrayBase<T>& a);
00593     ArgArrayBase(const std::vector<T>& a);
00595     template<class InputIterator>
00596     ArgArrayBase(InputIterator first, InputIterator last);
00598 
00600 
00601 
00602     int size(void) const;
00604 
00606 
00607 
00608     T& operator [](int i);
00610     const T& operator [](int i) const;
00612 
00614 
00615 
00616     iterator begin(void);
00618     const_iterator begin(void) const;
00620     iterator end(void);
00622     const_iterator end(void) const;
00624     reverse_iterator rbegin(void);
00626     const_reverse_iterator rbegin(void) const;
00628     reverse_iterator rend(void);
00630     const_reverse_iterator rend(void) const;
00632 
00634 
00635 
00636     ~ArgArrayBase(void);
00638   };
00639 
00640   template<class> class PrimArgArray;
00641 
00645   template<class T>
00646   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00647   operator +(const PrimArgArray<T>& x, const PrimArgArray<T>& y);
00648 
00652   template<class T>
00653   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00654   operator +(const PrimArgArray<T>& x, const T& y);
00655 
00659   template<class T>
00660   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00661   operator +(const T& x, const PrimArgArray<T>& y);
00662 
00674   template<class T>
00675   class PrimArgArray : public ArgArrayBase<T> {
00676   protected:
00677     using ArgArrayBase<T>::a;
00678   public:
00679     using ArgArrayBase<T>::size;
00681 
00682 
00683     PrimArgArray(void);
00685     explicit PrimArgArray(int n);
00687     PrimArgArray(int n, T e0, ...);
00689     PrimArgArray(int n, const T* e);
00691     PrimArgArray(const PrimArgArray<T>& a);
00693     PrimArgArray(const std::vector<T>& a);
00695     template<class InputIterator>
00696     PrimArgArray(InputIterator first, InputIterator last);
00698 
00699 
00700 
00705     typename ArrayTraits<PrimArgArray<T> >::ArgsType
00706     slice(int start, int inc=1, int n=-1);
00708 
00709 
00710 
00711     typename ArrayTraits<PrimArgArray<T> >::ArgsType&
00712     operator <<(const T& x);
00714     typename ArrayTraits<PrimArgArray<T> >::ArgsType&
00715     operator <<(const PrimArgArray<T>& x);
00717 
00718     friend typename ArrayTraits<PrimArgArray<T> >::ArgsType
00719     operator + <>(const PrimArgArray<T>& x, const PrimArgArray<T>& y);
00720     friend typename ArrayTraits<PrimArgArray<T> >::ArgsType
00721     operator + <>(const PrimArgArray<T>& x, const T& y);
00722     friend
00723     typename ArrayTraits<PrimArgArray<T> >::ArgsType
00724     operator + <>(const T& x, const PrimArgArray<T>& y);
00725   };
00726 
00727   template<class> class ArgArray;
00728 
00732   template<class T>
00733   typename ArrayTraits<ArgArray<T> >::ArgsType
00734   operator +(const ArgArray<T>& x, const ArgArray<T>& y);
00735 
00739   template<class T>
00740   typename ArrayTraits<ArgArray<T> >::ArgsType
00741   operator +(const ArgArray<T>& x, const T& y);
00742 
00746   template<class T>
00747   typename ArrayTraits<ArgArray<T> >::ArgsType
00748   operator +(const T& x, const ArgArray<T>& y);
00749 
00761   template<class T>
00762   class ArgArray : public ArgArrayBase<T> {
00763   protected:
00764     using ArgArrayBase<T>::a;
00765   public:
00766     using ArgArrayBase<T>::size;
00768 
00769 
00770     ArgArray(void);
00772     explicit ArgArray(int n);
00774     ArgArray(int n, const T* e);
00776     ArgArray(const ArgArray<T>& a);
00778     ArgArray(const std::vector<T>& a);
00780     template<class InputIterator>
00781     ArgArray(InputIterator first, InputIterator last);
00783 
00784 
00785 
00786     typename ArrayTraits<ArgArray<T> >::ArgsType
00787     slice(int start, int inc=1, int n=-1);
00789 
00790 
00791 
00792     typename ArrayTraits<ArgArray<T> >::ArgsType&
00793     operator <<(const T& x);
00795     typename ArrayTraits<ArgArray<T> >::ArgsType&
00796     operator <<(const ArgArray<T>& x);
00798 
00799     friend typename ArrayTraits<ArgArray<T> >::ArgsType
00800     operator + <>(const ArgArray<T>& x, const ArgArray<T>& y);
00801     friend typename ArrayTraits<ArgArray<T> >::ArgsType
00802     operator + <>(const ArgArray<T>& x, const T& y);
00803     friend
00804     typename ArrayTraits<ArgArray<T> >::ArgsType
00805     operator + <>(const T& x, const ArgArray<T>& y);
00806   };
00807 
00808   template<class> class VarArgArray;
00809 
00813   template<class Var>
00814   typename ArrayTraits<VarArgArray<Var> >::ArgsType
00815   operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y);
00816 
00820   template<class Var>
00821   typename ArrayTraits<VarArgArray<Var> >::ArgsType
00822   operator +(const VarArgArray<Var>& x, const Var& y);
00823 
00827   template<class Var>
00828   typename ArrayTraits<VarArgArray<Var> >::ArgsType
00829   operator +(const Var& x, const VarArgArray<Var>& y);
00830 
00842   template<class Var>
00843   class VarArgArray : public ArgArrayBase<Var> {
00844   protected:
00845     using ArgArrayBase<Var>::a;
00846     using ArgArrayBase<Var>::n;
00848     class VarLess {
00849     public:
00850       bool operator ()(const Var&, const Var&);
00851     };
00852   public:
00853     using ArgArrayBase<Var>::size;
00855 
00856 
00857     VarArgArray(void);
00859     explicit VarArgArray(int n);
00861     VarArgArray(const VarArgArray<Var>& a);
00863     VarArgArray(const VarArray<Var>& a);
00865     VarArgArray(const std::vector<Var>& a);
00867     template<class InputIterator>
00868     VarArgArray(InputIterator first, InputIterator last);
00870 
00871 
00872 
00873     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00874     slice(int start, int inc=1, int n=-1);
00876 
00877 
00878 
00879     typename ArrayTraits<VarArgArray<Var> >::ArgsType&
00880     operator <<(const Var& x);
00882     typename ArrayTraits<VarArgArray<Var> >::ArgsType&
00883     operator <<(const VarArgArray<Var>& x);
00885 
00887     bool assigned(void) const;
00888 
00889     friend typename ArrayTraits<VarArgArray<Var> >::ArgsType
00890     operator + <>(const VarArgArray<Var>& x, const VarArgArray<Var>& y);
00891     friend typename ArrayTraits<VarArgArray<Var> >::ArgsType
00892     operator + <>(const VarArgArray<Var>& x, const Var& y);
00893     friend
00894     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00895     operator + <>(const Var& x, const VarArgArray<Var>& y);
00896 
00898 
00899 
00904     bool same(const Space& home) const;
00910     bool same(const Space& home, const Var& y) const;
00916     bool same(const Space& home, const VarArgArray<Var>& y) const;
00918   };
00919 
00924   template<class Char, class Traits, class Var>
00925   std::basic_ostream<Char,Traits>&
00926   operator <<(std::basic_ostream<Char,Traits>& os,
00927              const VarArray<Var>& x);
00928 
00933   template<class Char, class Traits, class View>
00934   std::basic_ostream<Char,Traits>&
00935   operator <<(std::basic_ostream<Char,Traits>& os, const ViewArray<View>& x);
00936 
00941   template<class Char, class Traits, class T>
00942   std::basic_ostream<Char,Traits>&
00943   operator <<(std::basic_ostream<Char,Traits>& os, const ArgArrayBase<T>& x);
00944 
00945 
00946   /*
00947    * Implementation
00948    *
00949    */
00950 
00951   /*
00952    * Variable arrays
00953    *
00954    * These arrays are allocated in the space.
00955    *
00956    */
00957 
00958   template<class Var>
00959   forceinline
00960   VarArray<Var>::VarArray(void) : n(0), x(NULL) {}
00961 
00962   template<class Var>
00963   forceinline
00964   VarArray<Var>::VarArray(Space& home, int n0)
00965     : n(n0) {
00966     // Allocate from space
00967     x = (n>0) ? home.alloc<Var>(n) : NULL;
00968   }
00969 
00970   template<class Var>
00971   forceinline
00972   VarArray<Var>::VarArray(const VarArray<Var>& a) {
00973     n = a.n; x = a.x;
00974   }
00975 
00976   template<class Var>
00977   inline const VarArray<Var>&
00978   VarArray<Var>::operator =(const VarArray<Var>& a) {
00979     n = a.n; x = a.x;
00980     return *this;
00981   }
00982 
00983   template<class Var>
00984   forceinline int
00985   VarArray<Var>::size(void) const {
00986     return n;
00987   }
00988 
00989   template<class Var>
00990   forceinline Var&
00991   VarArray<Var>::operator [](int i) {
00992     assert((i >= 0) && (i < size()));
00993     return x[i];
00994   }
00995 
00996   template<class Var>
00997   forceinline const Var&
00998   VarArray<Var>::operator [](int i) const {
00999     assert((i >= 0) && (i < size()));
01000     return x[i];
01001   }
01002 
01003   template<class Var>
01004   typename ArrayTraits<VarArgArray<Var> >::ArgsType
01005   VarArray<Var>::slice(int start, int inc, int maxN) {
01006     assert(n==0 || start < n);
01007     if (n==0 || maxN<0)
01008       maxN = n;
01009     int s;
01010     if (inc == 0)
01011       s = n-start;
01012     else if (inc > 0)
01013       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
01014     else
01015       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
01016     typename ArrayTraits<VarArgArray<Var> >::ArgsType r(std::min(maxN,s));
01017     for (int i=0; i<r.size(); i++, start+=inc)
01018       r[i] = x[start];
01019     return r;
01020   }
01021 
01022   template<class Var>
01023   forceinline typename VarArray<Var>::iterator
01024   VarArray<Var>::begin(void) {
01025     return x;
01026   }
01027 
01028   template<class Var>
01029   forceinline typename VarArray<Var>::const_iterator
01030   VarArray<Var>::begin(void) const {
01031     return x;
01032   }
01033 
01034   template<class Var>
01035   forceinline typename VarArray<Var>::iterator
01036   VarArray<Var>::end(void) {
01037     return x+n;
01038   }
01039 
01040   template<class Var>
01041   forceinline typename VarArray<Var>::const_iterator
01042   VarArray<Var>::end(void) const {
01043     return x+n;
01044   }
01045 
01046   template<class Var>
01047   forceinline typename VarArray<Var>::reverse_iterator
01048   VarArray<Var>::rbegin(void) {
01049     return reverse_iterator(x+n);
01050   }
01051 
01052   template<class Var>
01053   forceinline typename VarArray<Var>::const_reverse_iterator
01054   VarArray<Var>::rbegin(void) const {
01055     return const_reverse_iterator(x+n);
01056   }
01057 
01058   template<class Var>
01059   forceinline typename VarArray<Var>::reverse_iterator
01060   VarArray<Var>::rend(void) {
01061     return reverse_iterator(x);
01062   }
01063 
01064   template<class Var>
01065   forceinline typename VarArray<Var>::const_reverse_iterator
01066   VarArray<Var>::rend(void) const {
01067     return const_reverse_iterator(x);
01068   }
01069 
01070   template<class Var>
01071   forceinline void
01072   VarArray<Var>::update(Space& home, bool share, VarArray<Var>& a) {
01073     n = a.n;
01074     if (n > 0) {
01075       x = home.alloc<Var>(n);
01076       for (int i = n; i--;)
01077         x[i].update(home, share, a.x[i]);
01078     } else {
01079       x = NULL;
01080     }
01081   }
01082 
01083   template<class Var>
01084   forceinline bool
01085   VarArray<Var>::assigned(void) const {
01086     for (int i = n; i--;)
01087       if (!x[i].assigned())
01088         return false;
01089     return true;
01090   }
01091 
01092   template<class Var>
01093   forceinline void*
01094   VarArray<Var>::operator new(size_t) throw() {
01095     return NULL;
01096   }
01097 
01098   template<class Var>
01099   forceinline void
01100   VarArray<Var>::operator delete(void*,size_t) {
01101   }
01102 
01103   template<class Var>
01104   typename ArrayTraits<VarArray<Var> >::ArgsType
01105   operator +(const VarArray<Var>& x, const VarArray<Var>& y) {
01106     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01107     for (int i=x.size(); i--;)
01108       r[i] = x[i];
01109     for (int i=y.size(); i--;)
01110       r[x.size()+i] = y[i];
01111     return r;
01112   }
01113 
01114   template<class Var>
01115   typename ArrayTraits<VarArray<Var> >::ArgsType
01116   operator +(const VarArray<Var>& x, const VarArgArray<Var>& y) {
01117     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01118     for (int i=x.size(); i--;)
01119       r[i] = x[i];
01120     for (int i=y.size(); i--;)
01121       r[x.size()+i] = y[i];
01122     return r;
01123   }
01124 
01125   template<class Var>
01126   typename ArrayTraits<VarArray<Var> >::ArgsType
01127   operator +(const VarArgArray<Var>& x, const VarArray<Var>& y) {
01128     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01129     for (int i=x.size(); i--;)
01130       r[i] = x[i];
01131     for (int i=y.size(); i--;)
01132       r[x.size()+i] = y[i];
01133     return r;
01134   }
01135 
01136   template<class Var>
01137   typename ArrayTraits<VarArray<Var> >::ArgsType
01138   operator +(const VarArray<Var>& x, const Var& y) {
01139     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+1);
01140     for (int i=x.size(); i--;)
01141       r[i] = x[i];
01142     r[x.size()] = y;
01143     return r;
01144   }
01145 
01146   template<class Var>
01147   typename ArrayTraits<VarArray<Var> >::ArgsType
01148   operator +(const Var& x, const VarArray<Var>& y) {
01149     typename ArrayTraits<VarArray<Var> >::ArgsType r(y.size()+1);
01150     r[0] = x;
01151     for (int i=y.size(); i--;)
01152       r[1+i] = y[i];
01153     return r;
01154   }
01155 
01156   /*
01157    * View arrays
01158    *
01159    */
01160 
01161   template<class View>
01162   forceinline
01163   ViewArray<View>::ViewArray(void) : n(0), x(NULL) {}
01164 
01165   template<class View>
01166   forceinline
01167   ViewArray<View>::ViewArray(Space& home, int n0)
01168     : n(n0) {
01169     x = (n>0) ? home.alloc<View>(n) : NULL;
01170   }
01171   template<class View>
01172   forceinline
01173   ViewArray<View>::ViewArray(Region& r, int n0)
01174     : n(n0) {
01175     x = (n>0) ? r.alloc<View>(n) : NULL;
01176   }
01177 
01178   template<class View>
01179   ViewArray<View>::ViewArray(Space& home, const ViewArray<View>& a)
01180     : n(a.size()) {
01181     if (n>0) {
01182       x = home.alloc<View>(n);
01183       for (int i = n; i--; )
01184         x[i] = a[i];
01185     } else {
01186       x = NULL;
01187     }
01188   }
01189   template<class View>
01190   ViewArray<View>::ViewArray(Region& r, const ViewArray<View>& a)
01191     : n(a.size()) {
01192     if (n>0) {
01193       x = r.alloc<View>(n);
01194       for (int i = n; i--; )
01195         x[i] = a[i];
01196     } else {
01197       x = NULL;
01198     }
01199   }
01200 
01201   template<class View>
01202   forceinline
01203   ViewArray<View>::ViewArray(const ViewArray<View>& a)
01204     : n(a.n), x(a.x) {}
01205 
01206   template<class View>
01207   forceinline const ViewArray<View>&
01208   ViewArray<View>::operator =(const ViewArray<View>& a) {
01209     n = a.n; x = a.x;
01210     return *this;
01211   }
01212 
01213   template<class View>
01214   forceinline int
01215   ViewArray<View>::size(void) const {
01216     return n;
01217   }
01218 
01219   template<class View>
01220   forceinline void
01221   ViewArray<View>::size(int n0) {
01222     n = n0;
01223   }
01224 
01225   template<class View>
01226   forceinline View&
01227   ViewArray<View>::operator [](int i) {
01228     assert((i >= 0) && (i < size()));
01229     return x[i];
01230   }
01231 
01232   template<class View>
01233   forceinline const View&
01234   ViewArray<View>::operator [](int i) const {
01235     assert((i >= 0) && (i < size()));
01236     return x[i];
01237   }
01238 
01239   template<class View>
01240   forceinline typename ViewArray<View>::iterator
01241   ViewArray<View>::begin(void) {
01242     return x;
01243   }
01244 
01245   template<class View>
01246   forceinline typename ViewArray<View>::const_iterator
01247   ViewArray<View>::begin(void) const {
01248     return x;
01249   }
01250 
01251   template<class View>
01252   forceinline typename ViewArray<View>::iterator
01253   ViewArray<View>::end(void) {
01254     return x+n;
01255   }
01256 
01257   template<class View>
01258   forceinline typename ViewArray<View>::const_iterator
01259   ViewArray<View>::end(void) const {
01260     return x+n;
01261   }
01262 
01263   template<class View>
01264   forceinline typename ViewArray<View>::reverse_iterator
01265   ViewArray<View>::rbegin(void) {
01266     return reverse_iterator(x+n);
01267   }
01268 
01269   template<class View>
01270   forceinline typename ViewArray<View>::const_reverse_iterator
01271   ViewArray<View>::rbegin(void) const {
01272     return const_reverse_iterator(x+n);
01273   }
01274 
01275   template<class View>
01276   forceinline typename ViewArray<View>::reverse_iterator
01277   ViewArray<View>::rend(void) {
01278     return reverse_iterator(x);
01279   }
01280 
01281   template<class View>
01282   forceinline typename ViewArray<View>::const_reverse_iterator
01283   ViewArray<View>::rend(void) const {
01284     return const_reverse_iterator(x);
01285   }
01286 
01287   template<class View>
01288   forceinline void
01289   ViewArray<View>::move_fst(int i) {
01290     x[i]=x[0]; x++; n--;
01291   }
01292 
01293   template<class View>
01294   forceinline void
01295   ViewArray<View>::move_lst(int i) {
01296     n--; x[i]=x[n];
01297   }
01298 
01299   template<class View>
01300   forceinline void
01301   ViewArray<View>::drop_fst(int i) {
01302     assert(i>=0);
01303     x += i; n -= i;
01304   }
01305 
01306   template<class View>
01307   forceinline void
01308   ViewArray<View>::drop_lst(int i) {
01309     assert(i<n);
01310     n = i+1;
01311   }
01312 
01313   template<class View>
01314   forceinline void
01315   ViewArray<View>::move_fst(int i, Space& home, Propagator& p, PropCond pc) {
01316     // Move x[0] to x[i]
01317     x[i].cancel(home,p,pc);
01318     x[i]=x[0]; x++; n--;
01319   }
01320 
01321   template<class View>
01322   forceinline void
01323   ViewArray<View>::move_lst(int i, Space& home, Propagator& p, PropCond pc) {
01324     // Move x[n-1] to x[i]
01325     x[i].cancel(home,p,pc);
01326     n--; x[i]=x[n];
01327   }
01328 
01329   template<class View>
01330   void
01331   ViewArray<View>::drop_fst(int i, Space& home, Propagator& p, PropCond pc) {
01332     // Drop elements from 0..i-1
01333     assert(i>=0);
01334     for (int j=i; j--; )
01335       x[j].cancel(home,p,pc);
01336     x += i; n -= i;
01337   }
01338 
01339   template<class View>
01340   void
01341   ViewArray<View>::drop_lst(int i, Space& home, Propagator& p, PropCond pc) {
01342     // Drop elements from i+1..n-1
01343     assert(i<n);
01344     for (int j=i+1; j<n; j++)
01345       x[j].cancel(home,p,pc);
01346     n = i+1;
01347   }
01348 
01349   template<class View>
01350   forceinline void
01351   ViewArray<View>::move_fst(int i, Space& home, Advisor& a) {
01352     // Move x[0] to x[i]
01353     x[i].cancel(home,a);
01354     x[i]=x[0]; x++; n--;
01355   }
01356 
01357   template<class View>
01358   forceinline void
01359   ViewArray<View>::move_lst(int i, Space& home, Advisor& a) {
01360     // Move x[n-1] to x[i]
01361     x[i].cancel(home,a);
01362     n--; x[i]=x[n];
01363   }
01364 
01365   template<class View>
01366   void
01367   ViewArray<View>::drop_fst(int i, Space& home, Advisor& a) {
01368     // Drop elements from 0..i-1
01369     assert(i>=0);
01370     for (int j=i; j--; )
01371       x[j].cancel(home,a);
01372     x += i; n -= i;
01373   }
01374 
01375   template<class View>
01376   void
01377   ViewArray<View>::drop_lst(int i, Space& home, Advisor& a) {
01378     // Drop elements from i+1..n-1
01379     assert(i<n);
01380     for (int j=i+1; j<n; j++)
01381       x[j].cancel(home,a);
01382     n = i+1;
01383   }
01384 
01385   template<class View>
01386   void
01387   ViewArray<View>::update(Space& home, bool share, ViewArray<View>& y) {
01388     n = y.n;
01389     if (n > 0) {
01390       x = home.alloc<View>(n);
01391       for (int i = n; i--; )
01392         x[i].update(home, share, y.x[i]);
01393     } else {
01394       x = NULL;
01395     }
01396   }
01397 
01398   template<class View>
01399   void
01400   ViewArray<View>::subscribe(Space& home, Propagator& p, PropCond pc,
01401                              bool schedule) {
01402     for (int i = n; i--; )
01403       x[i].subscribe(home,p,pc,schedule);
01404   }
01405 
01406   template<class View>
01407   void
01408   ViewArray<View>::cancel(Space& home, Propagator& p, PropCond pc) {
01409     for (int i = n; i--; )
01410       x[i].cancel(home,p,pc);
01411   }
01412 
01413   template<class View>
01414   void
01415   ViewArray<View>::subscribe(Space& home, Advisor& a) {
01416     for (int i = n; i--; )
01417       x[i].subscribe(home,a);
01418   }
01419 
01420   template<class View>
01421   void
01422   ViewArray<View>::cancel(Space& home, Advisor& a) {
01423     for (int i = n; i--; )
01424       x[i].cancel(home,a);
01425   }
01426 
01427   template<class View>
01428   void
01429   ViewArray<View>::reschedule(Space& home, Propagator& p, PropCond pc) {
01430     for (int i = n; i--; )
01431       x[i].reschedule(home,p,pc);
01432   }
01433 
01434   template<class View>
01435   forceinline bool
01436   ViewArray<View>::assigned(void) const {
01437     for (int i = n; i--;)
01438       if (!x[i].assigned())
01439         return false;
01440     return true;
01441   }
01442 
01443   template<class View>
01444   forceinline bool
01445   __before(const View& x, const View& y) {
01446     return before(x,y);
01447   }
01448 
01449   template<class View> template<class X>
01450   forceinline bool
01451   ViewArray<View>::ViewLess<X>::operator ()(const X& a, const X& b) {
01452     return __before(a,b);
01453   }
01454 
01455   template<class View>
01456   void
01457   ViewArray<View>::sort(View* y, int m) {
01458     ViewLess<View> vl;
01459     Support::quicksort<View,ViewLess<View> >(y,m,vl);
01460   }
01461 
01462   template<class X, class Y>
01463   forceinline bool
01464   __same(const X& x, const Y& y) {
01465     return same(x,y);
01466   }
01467   template<class X, class Y>
01468   forceinline bool
01469   __shared(const X& x, const Y& y) {
01470     return shared(x,y);
01471   }
01472 
01473   template<class View>
01474   bool
01475   ViewArray<View>::same(const Space& home) const {
01476     if (n < 2)
01477       return false;
01478     Region r(home);
01479     View* y = r.alloc<View>(n);
01480     for (int i = n; i--; )
01481       y[i] = x[i];
01482     sort(y,n);
01483     for (int i = n-1; i--; )
01484       if (!y[i].assigned() && __same(y[i+1],y[i])) {
01485         r.free<View>(y,n);
01486         return true;
01487       }
01488     r.free<View>(y,n);
01489     return false;
01490   }
01491 
01492   template<class View>
01493   bool
01494   ViewArray<View>::same(const Space&, const View& y) const {
01495     if (y.assigned())
01496       return false;
01497     for (int i = n; i--; )
01498       if (__same(x[i],y))
01499         return true;
01500     return false;
01501   }
01502 
01503   template<class View>
01504   void
01505   ViewArray<View>::unique(const Space&) {
01506     if (n < 2)
01507       return;
01508     sort(x,n);
01509     int j = 0;
01510     for (int i = 1; i<n; i++)
01511       if (!__same(x[j],x[i]))
01512         x[++j] = x[i];
01513     n = j+1;
01514   }
01515 
01516   template<class View>
01517   bool
01518   ViewArray<View>::shared(const Space& home) const {
01519     if (n < 2)
01520       return false;
01521     Region r(home);
01522     View* y = r.alloc<View>(n);
01523     for (int i = n; i--; )
01524       y[i] = x[i];
01525     sort(y,n);
01526     for (int i = n-1; i--; )
01527       if (!y[i].assigned() && __shared(y[i+1],y[i])) {
01528         r.free<View>(y,n);
01529         return true;
01530       }
01531     r.free<View>(y,n);
01532     return false;
01533   }
01534 
01535   template<class View> template<class ViewY>
01536   bool
01537   ViewArray<View>::shared(const Space&, const ViewY& y) const {
01538     if (y.assigned())
01539       return false;
01540     for (int i = n; i--; )
01541       if (!x[i].assigned() && __shared(x[i],y))
01542         return true;
01543     return false;
01544   }
01545 
01546   template<class View> template<class ViewY>
01547   bool
01548   ViewArray<View>::shared(const Space& home, const ViewArray<ViewY>& y) const {
01549     if ((size() < 1) || (y.size() < 1))
01550       return false;
01551     Region r(home);
01552     View* xs = r.alloc<View>(size());
01553     for (int i=size(); i--; )
01554       xs[i] = x[i];
01555     ViewLess<View> xvl;
01556     Support::quicksort<View,ViewLess<View> >(xs,size(),xvl);
01557     ViewY* ys = r.alloc<ViewY>(y.size());
01558     for (int j=y.size(); j--; )
01559       ys[j] = y[j];
01560     ViewLess<ViewY> yvl;
01561     Support::quicksort<ViewY,ViewLess<ViewY> >(ys,y.size(),yvl);
01562     {
01563       int i=0, j=0;
01564       while ((i < size()) && (j < y.size()))
01565         if (!x[i].assigned() && __shared(x[i],y[j])) {
01566           r.free<View>(xs,size());
01567           r.free<ViewY>(ys,y.size());
01568           return true;
01569         } else if (before(x[i],y[j])) {
01570           i++;
01571         } else {
01572           j++;
01573         }
01574     }
01575     r.free<View>(xs,size());
01576     r.free<ViewY>(ys,y.size());
01577     return false;
01578   }
01579 
01580   template<class View>
01581   forceinline void*
01582   ViewArray<View>::operator new(size_t) throw() {
01583     return NULL;
01584   }
01585 
01586   template<class View>
01587   forceinline void
01588   ViewArray<View>::operator delete(void*,size_t) {
01589   }
01590 
01591 
01592   /*
01593    * Argument arrays: base class
01594    *
01595    */
01596 
01597   template<class T>
01598   forceinline T*
01599   ArgArrayBase<T>::allocate(int n) {
01600     return (n > onstack_size) ?
01601       heap.alloc<T>(static_cast<unsigned int>(n)) : &onstack[0];
01602   }
01603 
01604   template<class T>
01605   forceinline void
01606   ArgArrayBase<T>::resize(int i) {
01607     if (n+i >= capacity) {
01608       assert(n+i >= onstack_size);
01609       int newCapacity = (3*capacity)/2;
01610       if (newCapacity <= n+i)
01611         newCapacity = n+i;
01612       T* newA = allocate(newCapacity);
01613       heap.copy<T>(newA,a,n);
01614       if (capacity > onstack_size)
01615         heap.free(a,capacity);
01616       capacity = newCapacity;
01617       a = newA;
01618     }
01619   }
01620 
01621   template<class T>
01622   forceinline
01623   ArgArrayBase<T>::ArgArrayBase(void)
01624     : n(0), capacity(onstack_size), a(allocate(0)) {}
01625 
01626   template<class T>
01627   forceinline
01628   ArgArrayBase<T>::ArgArrayBase(int n0)
01629     : n(n0), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {}
01630 
01631   template<class T>
01632   inline
01633   ArgArrayBase<T>::ArgArrayBase(const ArgArrayBase<T>& aa)
01634     : n(aa.n), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01635     heap.copy<T>(a,aa.a,n);
01636   }
01637 
01638   template<class T>
01639   inline
01640   ArgArrayBase<T>::ArgArrayBase(const std::vector<T>& aa)
01641     : n(static_cast<int>(aa.size())),
01642       capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01643     heap.copy<T>(a,&aa[0],n);
01644   }
01645 
01646   template<class T>
01647   forceinline
01648   ArgArrayBase<T>::~ArgArrayBase(void) {
01649     if (capacity > onstack_size)
01650       heap.free(a,capacity);
01651   }
01652 
01653   template<class T>
01654   forceinline const ArgArrayBase<T>&
01655   ArgArrayBase<T>::operator =(const ArgArrayBase<T>& aa) {
01656     if (&aa != this) {
01657       if (capacity > onstack_size)
01658         heap.free(a,capacity);
01659       n = aa.n;
01660       capacity = (n < onstack_size ? onstack_size : n);
01661       a = allocate(aa.n);
01662       heap.copy<T>(a,aa.a,n);
01663     }
01664     return *this;
01665   }
01666 
01667   template<class T>
01668   forceinline int
01669   ArgArrayBase<T>::size(void) const {
01670     return n;
01671   }
01672 
01673   template<class T>
01674   forceinline T&
01675   ArgArrayBase<T>::operator [](int i) {
01676     assert((i>=0) && (i < n));
01677     return a[i];
01678   }
01679 
01680   template<class T>
01681   forceinline const T&
01682   ArgArrayBase<T>::operator [](int i) const {
01683     assert((i>=0) && (i < n));
01684     return a[i];
01685   }
01686 
01687   template<class T>
01688   forceinline typename ArgArrayBase<T>::iterator
01689   ArgArrayBase<T>::begin(void) {
01690     return a;
01691   }
01692 
01693   template<class T>
01694   forceinline typename ArgArrayBase<T>::const_iterator
01695   ArgArrayBase<T>::begin(void) const {
01696     return a;
01697   }
01698 
01699   template<class T>
01700   forceinline typename ArgArrayBase<T>::iterator
01701   ArgArrayBase<T>::end(void) {
01702     return a+n;
01703   }
01704 
01705   template<class T>
01706   forceinline typename ArgArrayBase<T>::const_iterator
01707   ArgArrayBase<T>::end(void) const {
01708     return a+n;
01709   }
01710 
01711   template<class T>
01712   forceinline typename ArgArrayBase<T>::reverse_iterator
01713   ArgArrayBase<T>::rbegin(void) {
01714     return reverse_iterator(a+n);
01715   }
01716 
01717   template<class T>
01718   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01719   ArgArrayBase<T>::rbegin(void) const {
01720     return const_reverse_iterator(a+n);
01721   }
01722 
01723   template<class T>
01724   forceinline typename ArgArrayBase<T>::reverse_iterator
01725   ArgArrayBase<T>::rend(void) {
01726     return reverse_iterator(a);
01727   }
01728 
01729   template<class T>
01730   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01731   ArgArrayBase<T>::rend(void) const {
01732     return const_reverse_iterator(a);
01733   }
01734 
01735   template<class T> template<class A>
01736   A
01737   ArgArrayBase<T>::slice(int start, int inc, int maxN) {
01738     assert(n==0 || start < n);
01739     if (n==0 || maxN<0)
01740       maxN = n;
01741     int s;
01742     if (inc == 0)
01743       s = n-start;
01744     else if (inc > 0)
01745       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
01746     else
01747       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
01748     A r(std::min(maxN,s));
01749     for (int i=0; i<r.size(); i++, start+=inc)
01750       new (&r[i]) T(a[start]);
01751     return r;
01752   }
01753 
01754   template<class T> template<class A>
01755   inline A&
01756   ArgArrayBase<T>::append(const T& x) {
01757     resize(1);
01758     new (&a[n++]) T(x);
01759     return static_cast<A&>(*this);
01760   }
01761 
01762   template<class T>
01763   template<class InputIterator>
01764   inline
01765   ArgArrayBase<T>::ArgArrayBase(InputIterator first, InputIterator last)
01766   : n(0), capacity(onstack_size), a(allocate(0)) {
01767     while (first != last) {
01768       (void) append<ArgArrayBase<T> >(*first);
01769       ++first;
01770     }
01771   }
01772 
01773 
01774   template<class T> template<class A>
01775   inline A&
01776   ArgArrayBase<T>::append(const ArgArrayBase<T>& x) {
01777     resize(x.size());
01778     for (int i=0; i<x.size(); i++)
01779       new (&a[n++]) T(x[i]);
01780     return static_cast<A&>(*this);
01781   }
01782 
01783   template<class T> template<class A>
01784   inline A
01785   ArgArrayBase<T>::concat(const ArgArrayBase<T>& x) const {
01786     A r(n+x.n);
01787     for (int i=n; i--;)
01788       new (&r[i]) T(a[i]);
01789     for (int i=x.n; i--;)
01790       new (&r[n+i]) T(x.a[i]);
01791     return r;
01792   }
01793 
01794   template<class T> template<class A>
01795   inline A
01796   ArgArrayBase<T>::concat(const T& x) const {
01797     A r(n+1);
01798     for (int i=n; i--;)
01799       new (&r[i]) T(a[i]);
01800     new (&r[n]) T(x);
01801     return r;
01802   }
01803 
01804   /*
01805    * Argument arrays for primitive types
01806    *
01807    */
01808 
01809   template<class T>
01810   forceinline
01811   PrimArgArray<T>::PrimArgArray(void) {}
01812 
01813   template<class T>
01814   forceinline
01815   PrimArgArray<T>::PrimArgArray(int n) : ArgArrayBase<T>(n) {}
01816 
01817   template<class T>
01818   PrimArgArray<T>::PrimArgArray(int n, T a0, ...)
01819     : ArgArrayBase<T>(n) {
01820     va_list args;
01821     va_start(args, a0);
01822     a[0] = a0;
01823     for (int i = 1; i < n; i++)
01824       a[i] = va_arg(args,T);
01825     va_end(args);
01826   }
01827 
01828   template<class T>
01829   PrimArgArray<T>::PrimArgArray(int n, const T* a0)
01830     : ArgArrayBase<T>(n) {
01831     for (int i=n; i--; )
01832       a[i] = a0[i];
01833   }
01834 
01835   template<class T>
01836   forceinline
01837   PrimArgArray<T>::PrimArgArray(const PrimArgArray<T>& aa)
01838     : ArgArrayBase<T>(aa) {}
01839 
01840   template<class T>
01841   forceinline
01842   PrimArgArray<T>::PrimArgArray(const std::vector<T>& aa)
01843     : ArgArrayBase<T>(aa) {}
01844 
01845   template<class T>
01846   template<class InputIterator>
01847   forceinline
01848   PrimArgArray<T>::PrimArgArray(InputIterator first, InputIterator last)
01849     : ArgArrayBase<T>(first,last) {}
01850 
01851   template<class T>
01852   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType
01853   PrimArgArray<T>::slice(int start, int inc, int maxN) {
01854     return ArgArrayBase<T>::template slice
01855       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>
01856         (start,inc,maxN);
01857   }
01858 
01859   template<class T>
01860   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType&
01861   PrimArgArray<T>::operator <<(const T& x) {
01862     return
01863       ArgArrayBase<T>::template append
01864         <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(x);
01865   }
01866 
01867   template<class T>
01868   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType&
01869   PrimArgArray<T>::operator <<(const PrimArgArray<T>& x) {
01870     return
01871       ArgArrayBase<T>::template append
01872         <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(x);
01873   }
01874 
01875   template<class T>
01876   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01877   operator +(const PrimArgArray<T>& x, const PrimArgArray<T>& y) {
01878     return x.template concat
01879       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);
01880   }
01881 
01882   template<class T>
01883   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01884   operator +(const PrimArgArray<T>& x, const T& y) {
01885     return x.template concat
01886       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);
01887   }
01888 
01889   template<class T>
01890   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01891   operator +(const T& x, const PrimArgArray<T>& y) {
01892     return PrimArgArray<T>(1,x).template concat
01893       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);
01894   }
01895 
01896 
01897   /*
01898    * Argument arrays for non-primitive types
01899    *
01900    */
01901 
01902   template<class T>
01903   forceinline
01904   ArgArray<T>::ArgArray(void) {}
01905 
01906   template<class T>
01907   forceinline
01908   ArgArray<T>::ArgArray(int n) : ArgArrayBase<T>(n) {}
01909 
01910   template<class T>
01911   ArgArray<T>::ArgArray(int n, const T* a0)
01912     : ArgArrayBase<T>(n) {
01913     for (int i=n; i--; )
01914       a[i] = a0[i];
01915   }
01916 
01917   template<class T>
01918   forceinline
01919   ArgArray<T>::ArgArray(const ArgArray<T>& aa)
01920     : ArgArrayBase<T>(aa) {}
01921 
01922   template<class T>
01923   forceinline
01924   ArgArray<T>::ArgArray(const std::vector<T>& aa)
01925     : ArgArrayBase<T>(aa) {}
01926 
01927   template<class T>
01928   template<class InputIterator>
01929   forceinline
01930   ArgArray<T>::ArgArray(InputIterator first, InputIterator last)
01931     : ArgArrayBase<T>(first,last) {}
01932 
01933   template<class T>
01934   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType
01935   ArgArray<T>::slice(int start, int inc, int maxN) {
01936     return ArgArrayBase<T>::template slice
01937       <typename ArrayTraits<ArgArray<T> >::ArgsType>
01938       (start,inc,maxN);
01939   }
01940 
01941   template<class T>
01942   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType&
01943   ArgArray<T>::operator <<(const T& x) {
01944     return
01945       ArgArrayBase<T>::template append
01946         <typename ArrayTraits<ArgArray<T> >::ArgsType>(x);
01947   }
01948 
01949   template<class T>
01950   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType&
01951   ArgArray<T>::operator <<(const ArgArray<T>& x) {
01952     return
01953       ArgArrayBase<T>::template append
01954         <typename ArrayTraits<ArgArray<T> >::ArgsType>(x);
01955   }
01956 
01957   template<class T>
01958   typename ArrayTraits<ArgArray<T> >::ArgsType
01959   operator +(const ArgArray<T>& x, const ArgArray<T>& y) {
01960     return x.template concat
01961       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);
01962   }
01963 
01964   template<class T>
01965   typename ArrayTraits<ArgArray<T> >::ArgsType
01966   operator +(const ArgArray<T>& x, const T& y) {
01967     return x.template concat
01968       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);
01969   }
01970 
01971   template<class T>
01972   typename ArrayTraits<ArgArray<T> >::ArgsType
01973   operator +(const T& x, const ArgArray<T>& y) {
01974     ArgArray<T> xa(1);
01975     xa[0] = x;
01976     return xa.template concat
01977       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);
01978   }
01979 
01980   /*
01981    * Argument arrays for variables
01982    *
01983    */
01984 
01985   template<class Var>
01986   forceinline
01987   VarArgArray<Var>::VarArgArray(void) {}
01988 
01989   template<class Var>
01990   forceinline
01991   VarArgArray<Var>::VarArgArray(int n) : ArgArrayBase<Var>(n) {}
01992 
01993   template<class Var>
01994   forceinline
01995   VarArgArray<Var>::VarArgArray(const VarArgArray<Var>& aa)
01996     : ArgArrayBase<Var>(aa) {}
01997 
01998   template<class Var>
01999   forceinline
02000   VarArgArray<Var>::VarArgArray(const std::vector<Var>& aa)
02001     : ArgArrayBase<Var>(aa) {}
02002 
02003   template<class Var>
02004   template<class InputIterator>
02005   forceinline
02006   VarArgArray<Var>::VarArgArray(InputIterator first, InputIterator last)
02007     : ArgArrayBase<Var>(first,last) {}
02008 
02009   template<class Var>
02010   inline
02011   VarArgArray<Var>::VarArgArray(const VarArray<Var>& x)
02012     : ArgArrayBase<Var>(x.size()) {
02013     for (int i=x.size(); i--; )
02014       a[i]=x[i];
02015   }
02016 
02017   template<class Var>
02018   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType
02019   VarArgArray<Var>::slice(int start, int inc, int maxN) {
02020     return ArgArrayBase<Var>::template slice
02021       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>
02022         (start,inc,maxN);
02023   }
02024 
02025   template<class Var>
02026   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType&
02027   VarArgArray<Var>::operator <<(const Var& x) {
02028     return
02029       ArgArrayBase<Var>::template append
02030         <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(x);
02031   }
02032 
02033   template<class Var>
02034   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType&
02035   VarArgArray<Var>::operator <<(const VarArgArray<Var>& x) {
02036     return
02037       ArgArrayBase<Var>::template append
02038         <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(x);
02039   }
02040 
02041   template<class Var>
02042   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02043   operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y) {
02044     return x.template concat
02045       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);
02046   }
02047 
02048   template<class Var>
02049   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02050   operator +(const VarArgArray<Var>& x, const Var& y) {
02051     return x.template concat
02052       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);
02053   }
02054 
02055   template<class Var>
02056   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02057   operator +(const Var& x, const VarArgArray<Var>& y) {
02058     VarArgArray<Var> xa(1);
02059     xa[0] = x;
02060     return xa.template concat
02061       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);
02062   }
02063 
02064   template<class Var>
02065   forceinline bool
02066   VarArgArray<Var>::VarLess::operator ()(const Var& a, const Var& b) {
02067     return a.varimp() < b.varimp();
02068   }
02069 
02070   template<class Var>
02071   forceinline bool
02072   VarArgArray<Var>::assigned(void) const {
02073     for (int i = n; i--;)
02074       if (!a[i].assigned())
02075         return false;
02076     return true;
02077   }
02078 
02079   template<class Var>
02080   bool
02081   VarArgArray<Var>::same(const Space& home) const {
02082     if (n < 2)
02083       return false;
02084     Region r(home);
02085     Var* y = r.alloc<Var>(n);
02086     for (int i = n; i--; )
02087       y[i] = a[i];
02088     VarLess vl;
02089     Support::quicksort<Var,VarLess>(y,n,vl);
02090     for (int i = n-1; i--; )
02091       if (!y[i].assigned() && (y[i+1].varimp() == y[i].varimp())) {
02092         r.free<Var>(y,n);
02093         return true;
02094       }
02095     r.free<Var>(y,n);
02096     return false;
02097   }
02098 
02099   template<class Var>
02100   bool
02101   VarArgArray<Var>::same(const Space& home, const VarArgArray<Var>& y) const {
02102     int m = n + y.n;
02103     if (m < 2)
02104       return false;
02105     Region r(home);
02106     Var* z = r.alloc<Var>(m);
02107     for (int i = n; i--; )
02108       z[i] = a[i];
02109     for (int i = y.n; i--; )
02110       z[i+n] = y.a[i];
02111     VarLess vl;
02112     Support::quicksort<Var,VarLess>(z,m,vl);
02113     for (int i = m-1; i--; )
02114       if (!z[i].assigned() && (z[i+1].varimp() == z[i].varimp())) {
02115         r.free<Var>(z,m);
02116         return true;
02117       }
02118     r.free<Var>(z,m);
02119     return false;
02120   }
02121 
02122   template<class Var>
02123   bool
02124   VarArgArray<Var>::same(const Space&, const Var& y) const {
02125     if (y.assigned())
02126       return false;
02127     for (int i = n; i--; )
02128       if (a[i].varimp() == y.varimp())
02129         return true;
02130     return false;
02131   }
02132 
02133 
02134 
02135 
02136 
02137 
02138   /*
02139    * Interdependent code
02140    *
02141    */
02142 
02143   template<class Var>
02144   inline
02145   VarArray<Var>::VarArray(Space& home, const VarArgArray<Var>& a)
02146     : n(a.size()) {
02147     if (n>0) {
02148       x = home.alloc<Var>(n);
02149       for (int i=n; i--;)
02150         x[i] = a[i];
02151     } else {
02152       x = NULL;
02153     }
02154   }
02155 
02156 
02157   /*
02158    * Printing of arrays
02159    *
02160    */
02161   template<class Char, class Traits, class Var>
02162   std::basic_ostream<Char,Traits>&
02163   operator <<(std::basic_ostream<Char,Traits>& os,
02164               const VarArray<Var>& x) {
02165     std::basic_ostringstream<Char,Traits> s;
02166     s.copyfmt(os); s.width(0);
02167     s << '{';
02168     if (x.size() > 0) {
02169       s << x[0];
02170       for (int i=1; i<x.size(); i++)
02171         s << ", " << x[i];
02172     }
02173     s << '}';
02174     return os << s.str();
02175   }
02176 
02177   template<class Char, class Traits, class View>
02178   std::basic_ostream<Char,Traits>&
02179   operator <<(std::basic_ostream<Char,Traits>& os,
02180              const ViewArray<View>& x) {
02181     std::basic_ostringstream<Char,Traits> s;
02182     s.copyfmt(os); s.width(0);
02183     s << '{';
02184     if (x.size() > 0) {
02185       s << x[0];
02186       for (int i=1; i<x.size(); i++)
02187         s << ", " << x[i];
02188     }
02189     s << '}';
02190     return os << s.str();
02191   }
02192 
02193   template<class Char, class Traits, class T>
02194   std::basic_ostream<Char,Traits>&
02195   operator <<(std::basic_ostream<Char,Traits>& os,
02196              const ArgArrayBase<T>& x) {
02197     std::basic_ostringstream<Char,Traits> s;
02198     s.copyfmt(os); s.width(0);
02199     s << '{';
02200     if (x.size() > 0) {
02201       s << x[0];
02202       for (int i=1; i<x.size(); i++)
02203         s << ", " << x[i];
02204     }
02205     s << '}';
02206     return os << s.str();
02207   }
02208 
02209 }
02210 
02211 // STATISTICS: kernel-other