Generated on Fri Mar 20 15:55:57 2015 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: 2014-11-05 00:53:26 +0100 (Wed, 05 Nov 2014) $ by $Author: tack $
00017  *     $Revision: 14294 $
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, bool process=true);
00372     void cancel(Space& home, Propagator& p, PropCond pc);
00374     void subscribe(Space& home, Advisor& a);
00376     void cancel(Space& home, Advisor& a);
00378 
00380 
00381 
00388     void update(Space&, bool share, ViewArray<View>& a);
00390 
00391 
00393 
00394 
00395     void move_fst(int i);
00397     void move_lst(int i);
00403     void move_fst(int i, Space& home, Propagator& p, PropCond pc);
00409     void move_lst(int i, Space& home, Propagator& p, PropCond pc);
00415     void move_fst(int i, Space& home, Advisor& a);
00421     void move_lst(int i, Space& home, Advisor& a);
00423 
00425 
00426 
00427     void drop_fst(int i);
00429     void drop_lst(int i);
00435     void drop_fst(int i, Space& home, Propagator& p, PropCond pc);
00442     void drop_lst(int i, Space& home, Propagator& p, PropCond pc);
00448     void drop_fst(int i, Space& home, Advisor& a);
00454     void drop_lst(int i, Space& home, Advisor& a);
00456 
00458     bool assigned(void) const;
00459 
00461 
00462 
00467     bool same(const Space& home) const;
00473     bool same(const Space& home, const View& y) const;
00475     void unique(const Space& home);
00477 
00479 
00480 
00485     bool shared(const Space& home) const;
00491     template<class ViewY>
00492     bool shared(const Space& home, const ViewY& y) const;
00498     template<class ViewY>
00499     bool shared(const Space& home, const ViewArray<ViewY>& y) const;
00501 
00502   private:
00503     static void* operator new(size_t) throw();
00504     static void  operator delete(void*,size_t);
00505   };
00506 
00520   template<class T>
00521   class ArgArrayBase {
00522   protected:
00524     int n;
00526     int capacity;
00528     T*  a;
00530     static const int onstack_size = 16;
00532     T onstack[onstack_size];
00534     T* allocate(int n);
00536     void resize(int i);
00538     template<class A>
00539     A concat(const ArgArrayBase<T>& x) const;
00541     template<class A>
00542     A concat(const T& x) const;
00544     template<class A>
00545     A& append(const T& x);
00547     template<class A>
00548     A& append(const ArgArrayBase<T>& x);
00554     template<class A>
00555     A slice(int start, int inc=1, int n=-1);
00556   public:
00558 
00559 
00560     typedef T value_type;
00562     typedef T& reference;
00564     typedef const T& const_reference;
00566     typedef T* pointer;
00568     typedef const T* const_pointer;
00570     typedef T* iterator;
00572     typedef const T* const_iterator;
00574     typedef std::reverse_iterator<T*> reverse_iterator;
00576     typedef std::reverse_iterator<const T*> const_reverse_iterator;
00578 
00580 
00581 
00582     ArgArrayBase(void);
00584     explicit ArgArrayBase(int n);
00586     ArgArrayBase(const ArgArrayBase<T>& a);
00588     const ArgArrayBase<T>& operator =(const ArgArrayBase<T>& a);
00590     ArgArrayBase(const std::vector<T>& a);
00592     template<class InputIterator>
00593     ArgArrayBase(InputIterator first, InputIterator last);
00595 
00597 
00598 
00599     int size(void) const;
00601 
00603 
00604 
00605     T& operator [](int i);
00607     const T& operator [](int i) const;
00609 
00611 
00612 
00613     iterator begin(void);
00615     const_iterator begin(void) const;
00617     iterator end(void);
00619     const_iterator end(void) const;
00621     reverse_iterator rbegin(void);
00623     const_reverse_iterator rbegin(void) const;
00625     reverse_iterator rend(void);
00627     const_reverse_iterator rend(void) const;
00629 
00631 
00632 
00633     ~ArgArrayBase(void);
00635   private:
00636     static void* operator new(size_t) throw();
00637     static void  operator delete(void*,size_t);
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 process) {
01402     for (int i = n; i--; )
01403       x[i].subscribe(home,p,pc,process);
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   forceinline bool
01429   ViewArray<View>::assigned(void) const {
01430     for (int i = n; i--;)
01431       if (!x[i].assigned())
01432         return false;
01433     return true;
01434   }
01435 
01436   template<class View>
01437   forceinline bool
01438   __before(const View& x, const View& y) {
01439     return before(x,y);
01440   }
01441 
01442   template<class View> template<class X>
01443   forceinline bool
01444   ViewArray<View>::ViewLess<X>::operator ()(const X& a, const X& b) {
01445     return __before(a,b);
01446   }
01447 
01448   template<class View>
01449   void
01450   ViewArray<View>::sort(View* y, int m) {
01451     ViewLess<View> vl;
01452     Support::quicksort<View,ViewLess<View> >(y,m,vl);
01453   }
01454 
01455   template<class X, class Y>
01456   forceinline bool
01457   __same(const X& x, const Y& y) {
01458     return same(x,y);
01459   }
01460   template<class X, class Y>
01461   forceinline bool
01462   __shared(const X& x, const Y& y) {
01463     return shared(x,y);
01464   }
01465 
01466   template<class View>
01467   bool
01468   ViewArray<View>::same(const Space& home) const {
01469     if (n < 2)
01470       return false;
01471     Region r(home);
01472     View* y = r.alloc<View>(n);
01473     for (int i = n; i--; )
01474       y[i] = x[i];
01475     sort(y,n);
01476     for (int i = n-1; i--; )
01477       if (!y[i].assigned() && __same(y[i+1],y[i])) {
01478         r.free<View>(y,n);
01479         return true;
01480       }
01481     r.free<View>(y,n);
01482     return false;
01483   }
01484 
01485   template<class View>
01486   bool
01487   ViewArray<View>::same(const Space&, const View& y) const {
01488     if (y.assigned())
01489       return false;
01490     for (int i = n; i--; )
01491       if (__same(x[i],y))
01492         return true;
01493     return false;
01494   }
01495 
01496   template<class View>
01497   void
01498   ViewArray<View>::unique(const Space&) {
01499     if (n < 2)
01500       return;
01501     sort(x,n);
01502     int j = 0;
01503     for (int i = 1; i<n; i++)
01504       if (!__same(x[j],x[i]))
01505         x[++j] = x[i];
01506     n = j+1;
01507   }
01508 
01509   template<class View>
01510   bool
01511   ViewArray<View>::shared(const Space& home) const {
01512     if (n < 2)
01513       return false;
01514     Region r(home);
01515     View* y = r.alloc<View>(n);
01516     for (int i = n; i--; )
01517       y[i] = x[i];
01518     sort(y,n);
01519     for (int i = n-1; i--; )
01520       if (!y[i].assigned() && __shared(y[i+1],y[i])) {
01521         r.free<View>(y,n);
01522         return true;
01523       }
01524     r.free<View>(y,n);
01525     return false;
01526   }
01527 
01528   template<class View> template<class ViewY>
01529   bool
01530   ViewArray<View>::shared(const Space&, const ViewY& y) const {
01531     if (y.assigned())
01532       return false;
01533     for (int i = n; i--; )
01534       if (!x[i].assigned() && __shared(x[i],y))
01535         return true;
01536     return false;
01537   }
01538 
01539   template<class View> template<class ViewY>
01540   bool
01541   ViewArray<View>::shared(const Space& home, const ViewArray<ViewY>& y) const {
01542     if ((size() < 1) || (y.size() < 1))
01543       return false;
01544     Region r(home);
01545     View* xs = r.alloc<View>(size());
01546     for (int i=size(); i--; )
01547       xs[i] = x[i];
01548     ViewLess<View> xvl;
01549     Support::quicksort<View,ViewLess<View> >(xs,size(),xvl);
01550     ViewY* ys = r.alloc<ViewY>(y.size());
01551     for (int j=y.size(); j--; )
01552       ys[j] = y[j];
01553     ViewLess<ViewY> yvl;
01554     Support::quicksort<ViewY,ViewLess<ViewY> >(ys,y.size(),yvl);
01555     {
01556       int i=0, j=0;
01557       while ((i < size()) && (j < y.size()))
01558         if (!x[i].assigned() && __shared(x[i],y[j])) {
01559           r.free<View>(xs,size());
01560           r.free<ViewY>(ys,y.size());
01561           return true;
01562         } else if (before(x[i],y[j])) {
01563           i++;
01564         } else {
01565           j++;
01566         }
01567     }
01568     r.free<View>(xs,size());
01569     r.free<ViewY>(ys,y.size());
01570     return false;
01571   }
01572 
01573   template<class View>
01574   forceinline void*
01575   ViewArray<View>::operator new(size_t) throw() {
01576     return NULL;
01577   }
01578 
01579   template<class View>
01580   forceinline void
01581   ViewArray<View>::operator delete(void*,size_t) {
01582   }
01583 
01584 
01585   /*
01586    * Argument arrays: base class
01587    *
01588    */
01589 
01590   template<class T>
01591   forceinline T*
01592   ArgArrayBase<T>::allocate(int n) {
01593     return (n > onstack_size) ?
01594       heap.alloc<T>(static_cast<unsigned int>(n)) : &onstack[0];
01595   }
01596 
01597   template<class T>
01598   forceinline void
01599   ArgArrayBase<T>::resize(int i) {
01600     if (n+i >= capacity) {
01601       assert(n+i >= onstack_size);
01602       int newCapacity = (3*capacity)/2;
01603       if (newCapacity <= n+i)
01604         newCapacity = n+i;
01605       T* newA = allocate(newCapacity);
01606       heap.copy<T>(newA,a,n);
01607       if (capacity > onstack_size)
01608         heap.free(a,capacity);
01609       capacity = newCapacity;
01610       a = newA;
01611     }
01612   }
01613 
01614   template<class T>
01615   forceinline
01616   ArgArrayBase<T>::ArgArrayBase(void)
01617     : n(0), capacity(onstack_size), a(allocate(0)) {}
01618 
01619   template<class T>
01620   forceinline
01621   ArgArrayBase<T>::ArgArrayBase(int n0)
01622     : n(n0), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {}
01623 
01624   template<class T>
01625   inline
01626   ArgArrayBase<T>::ArgArrayBase(const ArgArrayBase<T>& aa)
01627     : n(aa.n), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01628     heap.copy<T>(a,aa.a,n);
01629   }
01630 
01631   template<class T>
01632   inline
01633   ArgArrayBase<T>::ArgArrayBase(const std::vector<T>& aa)
01634     : n(static_cast<int>(aa.size())),
01635       capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01636     heap.copy<T>(a,&aa[0],n);
01637   }
01638 
01639   template<class T>
01640   forceinline
01641   ArgArrayBase<T>::~ArgArrayBase(void) {
01642     if (capacity > onstack_size)
01643       heap.free(a,capacity);
01644   }
01645 
01646   template<class T>
01647   forceinline const ArgArrayBase<T>&
01648   ArgArrayBase<T>::operator =(const ArgArrayBase<T>& aa) {
01649     if (&aa != this) {
01650       if (capacity > onstack_size)
01651         heap.free(a,capacity);
01652       n = aa.n;
01653       capacity = (n < onstack_size ? onstack_size : n);
01654       a = allocate(aa.n);
01655       heap.copy<T>(a,aa.a,n);
01656     }
01657     return *this;
01658   }
01659 
01660   template<class T>
01661   forceinline int
01662   ArgArrayBase<T>::size(void) const {
01663     return n;
01664   }
01665 
01666   template<class T>
01667   forceinline T&
01668   ArgArrayBase<T>::operator [](int i) {
01669     assert((i>=0) && (i < n));
01670     return a[i];
01671   }
01672 
01673   template<class T>
01674   forceinline const T&
01675   ArgArrayBase<T>::operator [](int i) const {
01676     assert((i>=0) && (i < n));
01677     return a[i];
01678   }
01679 
01680   template<class T>
01681   forceinline typename ArgArrayBase<T>::iterator
01682   ArgArrayBase<T>::begin(void) {
01683     return a;
01684   }
01685 
01686   template<class T>
01687   forceinline typename ArgArrayBase<T>::const_iterator
01688   ArgArrayBase<T>::begin(void) const {
01689     return a;
01690   }
01691 
01692   template<class T>
01693   forceinline typename ArgArrayBase<T>::iterator
01694   ArgArrayBase<T>::end(void) {
01695     return a+n;
01696   }
01697 
01698   template<class T>
01699   forceinline typename ArgArrayBase<T>::const_iterator
01700   ArgArrayBase<T>::end(void) const {
01701     return a+n;
01702   }
01703 
01704   template<class T>
01705   forceinline typename ArgArrayBase<T>::reverse_iterator
01706   ArgArrayBase<T>::rbegin(void) {
01707     return reverse_iterator(a+n);
01708   }
01709 
01710   template<class T>
01711   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01712   ArgArrayBase<T>::rbegin(void) const {
01713     return const_reverse_iterator(a+n);
01714   }
01715 
01716   template<class T>
01717   forceinline typename ArgArrayBase<T>::reverse_iterator
01718   ArgArrayBase<T>::rend(void) {
01719     return reverse_iterator(a);
01720   }
01721 
01722   template<class T>
01723   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01724   ArgArrayBase<T>::rend(void) const {
01725     return const_reverse_iterator(a);
01726   }
01727 
01728   template<class T> template<class A>
01729   A
01730   ArgArrayBase<T>::slice(int start, int inc, int maxN) {
01731     assert(n==0 || start < n);
01732     if (n==0 || maxN<0)
01733       maxN = n;
01734     int s;
01735     if (inc == 0)
01736       s = n-start;
01737     else if (inc > 0)
01738       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
01739     else
01740       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
01741     A r(std::min(maxN,s));
01742     for (int i=0; i<r.size(); i++, start+=inc)
01743       new (&r[i]) T(a[start]);
01744     return r;
01745   }
01746 
01747   template<class T> template<class A>
01748   inline A&
01749   ArgArrayBase<T>::append(const T& x) {
01750     resize(1);
01751     new (&a[n++]) T(x);
01752     return static_cast<A&>(*this);
01753   }
01754 
01755   template<class T>
01756   template<class InputIterator>
01757   inline
01758   ArgArrayBase<T>::ArgArrayBase(InputIterator first, InputIterator last)
01759   : n(0), capacity(onstack_size), a(allocate(0)) {
01760     while (first != last) {
01761       (void) append<ArgArrayBase<T> >(*first);
01762       ++first;
01763     }
01764   }
01765 
01766 
01767   template<class T> template<class A>
01768   inline A&
01769   ArgArrayBase<T>::append(const ArgArrayBase<T>& x) {
01770     resize(x.size());
01771     for (int i=0; i<x.size(); i++)
01772       new (&a[n++]) T(x[i]);
01773     return static_cast<A&>(*this);
01774   }
01775 
01776   template<class T> template<class A>
01777   inline A
01778   ArgArrayBase<T>::concat(const ArgArrayBase<T>& x) const {
01779     A r(n+x.n);
01780     for (int i=n; i--;)
01781       new (&r[i]) T(a[i]);
01782     for (int i=x.n; i--;)
01783       new (&r[n+i]) T(x.a[i]);
01784     return r;
01785   }
01786 
01787   template<class T> template<class A>
01788   inline A
01789   ArgArrayBase<T>::concat(const T& x) const {
01790     A r(n+1);
01791     for (int i=n; i--;)
01792       new (&r[i]) T(a[i]);
01793     new (&r[n]) T(x);
01794     return r;
01795   }
01796 
01797   template<class T>
01798   forceinline void*
01799   ArgArrayBase<T>::operator new(size_t) throw () {
01800     return NULL;
01801   }
01802 
01803   template<class T>
01804   forceinline void
01805   ArgArrayBase<T>::operator delete(void*,size_t) {
01806   }
01807 
01808   /*
01809    * Argument arrays for primitive types
01810    *
01811    */
01812 
01813   template<class T>
01814   forceinline
01815   PrimArgArray<T>::PrimArgArray(void) {}
01816 
01817   template<class T>
01818   forceinline
01819   PrimArgArray<T>::PrimArgArray(int n) : ArgArrayBase<T>(n) {}
01820 
01821   template<class T>
01822   PrimArgArray<T>::PrimArgArray(int n, T a0, ...)
01823     : ArgArrayBase<T>(n) {
01824     va_list args;
01825     va_start(args, a0);
01826     a[0] = a0;
01827     for (int i = 1; i < n; i++)
01828       a[i] = va_arg(args,T);
01829     va_end(args);
01830   }
01831 
01832   template<class T>
01833   PrimArgArray<T>::PrimArgArray(int n, const T* a0)
01834     : ArgArrayBase<T>(n) {
01835     for (int i=n; i--; )
01836       a[i] = a0[i];
01837   }
01838 
01839   template<class T>
01840   forceinline
01841   PrimArgArray<T>::PrimArgArray(const PrimArgArray<T>& aa)
01842     : ArgArrayBase<T>(aa) {}
01843 
01844   template<class T>
01845   forceinline
01846   PrimArgArray<T>::PrimArgArray(const std::vector<T>& aa)
01847     : ArgArrayBase<T>(aa) {}
01848 
01849   template<class T>
01850   template<class InputIterator>
01851   forceinline
01852   PrimArgArray<T>::PrimArgArray(InputIterator first, InputIterator last)
01853     : ArgArrayBase<T>(first,last) {}
01854 
01855   template<class T>
01856   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType
01857   PrimArgArray<T>::slice(int start, int inc, int maxN) {
01858     return ArgArrayBase<T>::template slice
01859       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>
01860         (start,inc,maxN);
01861   }
01862 
01863   template<class T>
01864   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType&
01865   PrimArgArray<T>::operator <<(const T& x) {
01866     return
01867       ArgArrayBase<T>::template append
01868         <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(x);
01869   }
01870 
01871   template<class T>
01872   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType&
01873   PrimArgArray<T>::operator <<(const PrimArgArray<T>& x) {
01874     return
01875       ArgArrayBase<T>::template append
01876         <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(x);
01877   }
01878 
01879   template<class T>
01880   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01881   operator +(const PrimArgArray<T>& x, const PrimArgArray<T>& y) {
01882     return x.template concat
01883       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);
01884   }
01885 
01886   template<class T>
01887   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01888   operator +(const PrimArgArray<T>& x, const T& y) {
01889     return x.template concat
01890       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);    
01891   }
01892 
01893   template<class T>
01894   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01895   operator +(const T& x, const PrimArgArray<T>& y) {
01896     return PrimArgArray<T>(1,x).template concat
01897       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);    
01898   }
01899 
01900 
01901   /*
01902    * Argument arrays for non-primitive types
01903    *
01904    */
01905 
01906   template<class T>
01907   forceinline
01908   ArgArray<T>::ArgArray(void) {}
01909 
01910   template<class T>
01911   forceinline
01912   ArgArray<T>::ArgArray(int n) : ArgArrayBase<T>(n) {}
01913 
01914   template<class T>
01915   ArgArray<T>::ArgArray(int n, const T* a0)
01916     : ArgArrayBase<T>(n) {
01917     for (int i=n; i--; )
01918       a[i] = a0[i];
01919   }
01920 
01921   template<class T>
01922   forceinline
01923   ArgArray<T>::ArgArray(const ArgArray<T>& aa)
01924     : ArgArrayBase<T>(aa) {}
01925 
01926   template<class T>
01927   forceinline
01928   ArgArray<T>::ArgArray(const std::vector<T>& aa)
01929     : ArgArrayBase<T>(aa) {}
01930 
01931   template<class T>
01932   template<class InputIterator>
01933   forceinline
01934   ArgArray<T>::ArgArray(InputIterator first, InputIterator last)
01935     : ArgArrayBase<T>(first,last) {}
01936 
01937   template<class T>
01938   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType
01939   ArgArray<T>::slice(int start, int inc, int maxN) {
01940     return ArgArrayBase<T>::template slice
01941       <typename ArrayTraits<ArgArray<T> >::ArgsType>
01942       (start,inc,maxN);
01943   }
01944 
01945   template<class T>
01946   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType&
01947   ArgArray<T>::operator <<(const T& x) {
01948     return
01949       ArgArrayBase<T>::template append
01950         <typename ArrayTraits<ArgArray<T> >::ArgsType>(x);
01951   }
01952 
01953   template<class T>
01954   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType&
01955   ArgArray<T>::operator <<(const ArgArray<T>& x) {
01956     return
01957       ArgArrayBase<T>::template append
01958         <typename ArrayTraits<ArgArray<T> >::ArgsType>(x);
01959   }
01960 
01961   template<class T>
01962   typename ArrayTraits<ArgArray<T> >::ArgsType
01963   operator +(const ArgArray<T>& x, const ArgArray<T>& y) {
01964     return x.template concat
01965       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);
01966   }
01967 
01968   template<class T>
01969   typename ArrayTraits<ArgArray<T> >::ArgsType
01970   operator +(const ArgArray<T>& x, const T& y) {
01971     return x.template concat
01972       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);    
01973   }
01974 
01975   template<class T>
01976   typename ArrayTraits<ArgArray<T> >::ArgsType
01977   operator +(const T& x, const ArgArray<T>& y) {
01978     ArgArray<T> xa(1);
01979     xa[0] = x;
01980     return xa.template concat
01981       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);    
01982   }
01983 
01984   /*
01985    * Argument arrays for variables
01986    *
01987    */
01988 
01989   template<class Var>
01990   forceinline
01991   VarArgArray<Var>::VarArgArray(void) {}
01992 
01993   template<class Var>
01994   forceinline
01995   VarArgArray<Var>::VarArgArray(int n) : ArgArrayBase<Var>(n) {}
01996 
01997   template<class Var>
01998   forceinline
01999   VarArgArray<Var>::VarArgArray(const VarArgArray<Var>& aa)
02000     : ArgArrayBase<Var>(aa) {}
02001 
02002   template<class Var>
02003   forceinline
02004   VarArgArray<Var>::VarArgArray(const std::vector<Var>& aa)
02005     : ArgArrayBase<Var>(aa) {}
02006 
02007   template<class Var>
02008   template<class InputIterator>
02009   forceinline
02010   VarArgArray<Var>::VarArgArray(InputIterator first, InputIterator last)
02011     : ArgArrayBase<Var>(first,last) {}
02012 
02013   template<class Var>
02014   inline
02015   VarArgArray<Var>::VarArgArray(const VarArray<Var>& x)
02016     : ArgArrayBase<Var>(x.size()) {
02017     for (int i=x.size(); i--; )
02018       a[i]=x[i];
02019   }
02020 
02021   template<class Var>
02022   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType
02023   VarArgArray<Var>::slice(int start, int inc, int maxN) {
02024     return ArgArrayBase<Var>::template slice
02025       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>
02026         (start,inc,maxN);
02027   }
02028 
02029   template<class Var>
02030   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType&
02031   VarArgArray<Var>::operator <<(const Var& x) {
02032     return
02033       ArgArrayBase<Var>::template append
02034         <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(x);
02035   }
02036 
02037   template<class Var>
02038   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType&
02039   VarArgArray<Var>::operator <<(const VarArgArray<Var>& x) {
02040     return
02041       ArgArrayBase<Var>::template append
02042         <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(x);
02043   }
02044 
02045   template<class Var>
02046   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02047   operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y) {
02048     return x.template concat
02049       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);
02050   }
02051 
02052   template<class Var>
02053   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02054   operator +(const VarArgArray<Var>& x, const Var& y) {
02055     return x.template concat
02056       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);    
02057   }
02058 
02059   template<class Var>
02060   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02061   operator +(const Var& x, const VarArgArray<Var>& y) {
02062     VarArgArray<Var> xa(1);
02063     xa[0] = x;
02064     return xa.template concat
02065       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);    
02066   }
02067 
02068   template<class Var>
02069   forceinline bool
02070   VarArgArray<Var>::VarLess::operator ()(const Var& a, const Var& b) {
02071     return a.varimp() < b.varimp();
02072   }
02073 
02074   template<class Var>
02075   forceinline bool
02076   VarArgArray<Var>::assigned(void) const {
02077     for (int i = n; i--;)
02078       if (!a[i].assigned())
02079         return false;
02080     return true;
02081   }
02082 
02083   template<class Var>
02084   bool
02085   VarArgArray<Var>::same(const Space& home) const {
02086     if (n < 2)
02087       return false;
02088     Region r(home);
02089     Var* y = r.alloc<Var>(n);
02090     for (int i = n; i--; )
02091       y[i] = a[i];
02092     VarLess vl;
02093     Support::quicksort<Var,VarLess>(y,n,vl);
02094     for (int i = n-1; i--; )
02095       if (!y[i].assigned() && (y[i+1].varimp() == y[i].varimp())) {
02096         r.free<Var>(y,n);
02097         return true;
02098       }
02099     r.free<Var>(y,n);
02100     return false;
02101   }
02102 
02103   template<class Var>
02104   bool
02105   VarArgArray<Var>::same(const Space& home, const VarArgArray<Var>& y) const {
02106     int m = n + y.n;
02107     if (m < 2)
02108       return false;
02109     Region r(home);
02110     Var* z = r.alloc<Var>(m);
02111     for (int i = n; i--; )
02112       z[i] = a[i];
02113     for (int i = y.n; i--; )
02114       z[i+n] = y.a[i];
02115     VarLess vl;
02116     Support::quicksort<Var,VarLess>(z,m,vl);
02117     for (int i = m-1; i--; )
02118       if (!z[i].assigned() && (z[i+1].varimp() == z[i].varimp())) {
02119         r.free<Var>(z,m);
02120         return true;
02121       }
02122     r.free<Var>(z,m);
02123     return false;
02124   }
02125 
02126   template<class Var>
02127   bool
02128   VarArgArray<Var>::same(const Space&, const Var& y) const {
02129     if (y.assigned())
02130       return false;
02131     for (int i = n; i--; )
02132       if (a[i].varimp() == y.varimp())
02133         return true;
02134     return false;
02135   }
02136 
02137 
02138 
02139 
02140 
02141 
02142   /*
02143    * Interdependent code
02144    *
02145    */
02146 
02147   template<class Var>
02148   inline
02149   VarArray<Var>::VarArray(Space& home, const VarArgArray<Var>& a)
02150     : n(a.size()) {
02151     if (n>0) {
02152       x = home.alloc<Var>(n);
02153       for (int i=n; i--;)
02154         x[i] = a[i];
02155     } else {
02156       x = NULL;
02157     }
02158   }
02159 
02160 
02161   /*
02162    * Printing of arrays
02163    *
02164    */
02165   template<class Char, class Traits, class Var>
02166   std::basic_ostream<Char,Traits>&
02167   operator <<(std::basic_ostream<Char,Traits>& os,
02168               const VarArray<Var>& x) {
02169     std::basic_ostringstream<Char,Traits> s;
02170     s.copyfmt(os); s.width(0);
02171     s << '{';
02172     if (x.size() > 0) {
02173       s << x[0];
02174       for (int i=1; i<x.size(); i++)
02175         s << ", " << x[i];
02176     }
02177     s << '}';
02178     return os << s.str();
02179   }
02180 
02181   template<class Char, class Traits, class View>
02182   std::basic_ostream<Char,Traits>&
02183   operator <<(std::basic_ostream<Char,Traits>& os,
02184              const ViewArray<View>& x) {
02185     std::basic_ostringstream<Char,Traits> s;
02186     s.copyfmt(os); s.width(0);
02187     s << '{';
02188     if (x.size() > 0) {
02189       s << x[0];
02190       for (int i=1; i<x.size(); i++)
02191         s << ", " << x[i];
02192     }
02193     s << '}';
02194     return os << s.str();
02195   }
02196 
02197   template<class Char, class Traits, class T>
02198   std::basic_ostream<Char,Traits>&
02199   operator <<(std::basic_ostream<Char,Traits>& os,
02200              const ArgArrayBase<T>& x) {
02201     std::basic_ostringstream<Char,Traits> s;
02202     s.copyfmt(os); s.width(0);
02203     s << '{';
02204     if (x.size() > 0) {
02205       s << x[0];
02206       for (int i=1; i<x.size(); i++)
02207         s << ", " << x[i];
02208     }
02209     s << '}';
02210     return os << s.str();
02211   }
02212 
02213 }
02214 
02215 // STATISTICS: kernel-other