Generated on Thu Mar 22 10:39:33 2012 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: 2011-08-18 12:10:04 +0200 (Thu, 18 Aug 2011) $ by $Author: tack $
00017  *     $Revision: 12313 $
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 <sstream>
00048 
00049 namespace Gecode {
00050 
00051   template<class Var> class VarArray;
00052   template<class Var> class VarArgArray;
00053 
00066   template<class A>
00067   class ArrayTraits {};
00068 
00084   template<class Var>
00085   class VarArray {
00086   protected:
00088     int n;
00090     Var* x;
00091   public:
00093 
00094 
00095     typedef Var value_type;
00097     typedef Var& reference;
00099     typedef const Var& const_reference;
00101     typedef Var* pointer;
00103     typedef const Var* const_pointer;
00105     typedef Var* iterator;
00107     typedef const Var* const_iterator;
00109     typedef std::reverse_iterator<Var*> reverse_iterator;
00111     typedef std::reverse_iterator<const Var*> const_reverse_iterator;
00113 
00115 
00116 
00117 
00118     VarArray(void);
00120     VarArray(Space& home, int m);
00122     VarArray(Space& home, const VarArgArray<Var>&);
00124     VarArray(const VarArray<Var>& a);
00126     const VarArray<Var>& operator =(const VarArray<Var>& a);
00128 
00130 
00131 
00132     int size(void) const;
00134 
00136 
00137 
00138     Var& operator [](int i);
00140     const Var& operator [](int i) const;
00146     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00147     slice(int start, int inc=1, int n=-1);
00149 
00151 
00152 
00153     iterator begin(void);
00155     const_iterator begin(void) const;
00157     iterator end(void);
00159     const_iterator end(void) const;
00161     reverse_iterator rbegin(void);
00163     const_reverse_iterator rbegin(void) const;
00165     reverse_iterator rend(void);
00167     const_reverse_iterator rend(void) const;
00169 
00171     bool assigned(void) const;
00172 
00174 
00175 
00182     void update(Space&, bool share, VarArray<Var>& a);
00184   private:
00185     static void* operator new(size_t);
00186     static void  operator delete(void*,size_t);
00187   };
00188 
00192   template<class T>
00193   typename ArrayTraits<VarArray<T> >::ArgsType
00194   operator +(const VarArray<T>& x, const VarArgArray<T>& y);
00195 
00199   template<class T>
00200   typename ArrayTraits<VarArray<T> >::ArgsType
00201   operator +(const VarArray<T>& x, const VarArray<T>& y);
00202 
00206   template<class T>
00207   typename ArrayTraits<VarArray<T> >::ArgsType
00208   operator +(const VarArgArray<T>& x, const VarArray<T>& y);
00209 
00213   template<class T>
00214   typename ArrayTraits<VarArray<T> >::ArgsType
00215   operator +(const VarArray<T>& x, const T& y);
00216 
00220   template<class T>
00221   typename ArrayTraits<VarArray<T> >::ArgsType
00222   operator +(const T& x, const VarArray<T>& y);
00223 
00232   template<class View>
00233   class ViewArray {
00234   private:
00236     int  n;
00238     View* x;
00240     template<class X>
00241     class ViewLess {
00242     public:
00243       bool operator ()(const X&, const X&);
00244     };
00246     static void sort(View* x, int n);
00247   public:
00249 
00250 
00251     typedef View value_type;
00253     typedef View& reference;
00255     typedef const View& const_reference;
00257     typedef View* pointer;
00259     typedef const View* const_pointer;
00261     typedef View* iterator;
00263     typedef const View* const_iterator;
00265     typedef std::reverse_iterator<View*> reverse_iterator;
00267     typedef std::reverse_iterator<const View*> const_reverse_iterator;
00269 
00271 
00272 
00273     ViewArray(void);
00275     ViewArray(Space& home, int m);
00277     ViewArray(Region& r, int m);
00279     ViewArray(const ViewArray<View>& a);
00281     ViewArray(Space& home, const ViewArray<View>& a);
00283     ViewArray(Region& r, const ViewArray<View>& a);
00285     const ViewArray<View>& operator =(const ViewArray<View>& a);
00292     template<class Var>
00293     ViewArray(Space& home, const VarArgArray<Var>& a)
00294       : n(a.size()) {
00295       // This may not be in the hpp file (to satisfy the MS compiler)
00296       if (n>0) {
00297         x = home.alloc<View>(n);
00298         for (int i=n; i--; )
00299           x[i]=a[i];
00300       } else {
00301         x = NULL;
00302       }
00303     }
00310     template<class Var>
00311     ViewArray(Region& r, const VarArgArray<Var>& a)
00312       : n(a.size()) {
00313       // This may not be in the hpp file (to satisfy the MS compiler)
00314       if (n>0) {
00315         x = r.alloc<View>(n);
00316         for (int i=n; i--; )
00317           x[i]=a[i];
00318       } else {
00319         x = NULL;
00320       }
00321     }
00323 
00325 
00326 
00327     int size(void) const;
00329     void size(int n);
00331 
00333 
00334 
00335     View& operator [](int i);
00337     const View& operator [](int i) const;
00339 
00341 
00342 
00343     iterator begin(void);
00345     const_iterator begin(void) const;
00347     iterator end(void);
00349     const_iterator end(void) const;
00351     reverse_iterator rbegin(void);
00353     const_reverse_iterator rbegin(void) const;
00355     reverse_iterator rend(void);
00357     const_reverse_iterator rend(void) const;
00359 
00361 
00362 
00369     void subscribe(Space& home, Propagator& p, PropCond pc, bool process=true);
00371     void cancel(Space& home, Propagator& p, PropCond pc);
00373     void subscribe(Space& home, Advisor& a);
00375     void cancel(Space& home, Advisor& a);
00377 
00379 
00380 
00387     void update(Space&, bool share, ViewArray<View>& a);
00389 
00390 
00392 
00393 
00394     void move_fst(int i);
00396     void move_lst(int i);
00402     void move_fst(int i, Space& home, Propagator& p, PropCond pc);
00408     void move_lst(int i, Space& home, Propagator& p, PropCond pc);
00414     void move_fst(int i, Space& home, Advisor& a);
00420     void move_lst(int i, Space& home, Advisor& a);
00422 
00424 
00425 
00426     void drop_fst(int i);
00428     void drop_lst(int i);
00434     void drop_fst(int i, Space& home, Propagator& p, PropCond pc);
00441     void drop_lst(int i, Space& home, Propagator& p, PropCond pc);
00447     void drop_fst(int i, Space& home, Advisor& a);
00453     void drop_lst(int i, Space& home, Advisor& a);
00455 
00457     bool assigned(void) const;
00458 
00460 
00461 
00466     bool same(const Space& home) const;
00472     bool same(const Space& home, const View& y) const;
00474     void unique(const Space& home);
00476 
00478 
00479 
00484     bool shared(const Space& home) const;
00490     template<class ViewY>
00491     bool shared(const Space& home, const ViewY& y) const;
00497     template<class ViewY>
00498     bool shared(const Space& home, const ViewArray<ViewY>& y) const;
00500 
00501   private:
00502     static void* operator new(size_t);
00503     static void  operator delete(void*,size_t);
00504   };
00505 
00519   template<class T>
00520   class ArgArrayBase {
00521   protected:
00523     int n;
00525     int capacity;
00527     T*  a;
00529     static const int onstack_size = 16;
00531     T onstack[onstack_size];
00533     T* allocate(int n);
00535     void resize(int i);
00537     template<class A>
00538     A concat(const ArgArrayBase<T>& x) const;
00540     template<class A>
00541     A concat(const T& x) const;
00543     template<class A>
00544     A& append(const T& x);
00546     template<class A>
00547     A& append(const ArgArrayBase<T>& x);
00553     template<class A>
00554     A slice(int start, int inc=1, int n=-1);
00555   public:
00557 
00558 
00559     typedef T value_type;
00561     typedef T& reference;
00563     typedef const T& const_reference;
00565     typedef T* pointer;
00567     typedef const T* const_pointer;
00569     typedef T* iterator;
00571     typedef const T* const_iterator;
00573     typedef std::reverse_iterator<T*> reverse_iterator;
00575     typedef std::reverse_iterator<const T*> const_reverse_iterator;
00577 
00579 
00580 
00581     ArgArrayBase(void);
00583     explicit ArgArrayBase(int n);
00585     ArgArrayBase(const ArgArrayBase<T>& a);
00587     const ArgArrayBase<T>& operator =(const ArgArrayBase<T>& a);
00589 
00591 
00592 
00593     int size(void) const;
00595 
00597 
00598 
00599     T& operator [](int i);
00601     const T& operator [](int i) const;
00603 
00605 
00606 
00607     iterator begin(void);
00609     const_iterator begin(void) const;
00611     iterator end(void);
00613     const_iterator end(void) const;
00615     reverse_iterator rbegin(void);
00617     const_reverse_iterator rbegin(void) const;
00619     reverse_iterator rend(void);
00621     const_reverse_iterator rend(void) const;
00623 
00625 
00626 
00627     ~ArgArrayBase(void);
00629   private:
00630     static void* operator new(size_t);
00631     static void  operator delete(void*,size_t);
00632   };
00633 
00634   template<class> class PrimArgArray;
00635 
00639   template<class T>
00640   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00641   operator +(const PrimArgArray<T>& x, const PrimArgArray<T>& y);
00642 
00646   template<class T>
00647   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00648   operator +(const PrimArgArray<T>& x, const T& y);
00649 
00653   template<class T>
00654   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00655   operator +(const T& x, const PrimArgArray<T>& y);
00656 
00668   template<class T>
00669   class PrimArgArray : public ArgArrayBase<T> {
00670   protected:
00671     using ArgArrayBase<T>::a;
00672   public:
00673     using ArgArrayBase<T>::size;
00675 
00676 
00677     PrimArgArray(void);
00679     explicit PrimArgArray(int n);
00681     PrimArgArray(int n, T e0, ...);
00683     PrimArgArray(int n, const T* e);
00685     PrimArgArray(const PrimArgArray<T>& a);
00687 
00688 
00689 
00694     typename ArrayTraits<PrimArgArray<T> >::ArgsType
00695     slice(int start, int inc=1, int n=-1);
00697 
00698 
00699 
00700     typename ArrayTraits<PrimArgArray<T> >::ArgsType&
00701     operator <<(const T& x);
00703     typename ArrayTraits<PrimArgArray<T> >::ArgsType&
00704     operator <<(const PrimArgArray<T>& x);
00706 
00707     friend typename ArrayTraits<PrimArgArray<T> >::ArgsType
00708     operator + <>(const PrimArgArray<T>& x, const PrimArgArray<T>& y);
00709     friend typename ArrayTraits<PrimArgArray<T> >::ArgsType
00710     operator + <>(const PrimArgArray<T>& x, const T& y);
00711     friend
00712     typename ArrayTraits<PrimArgArray<T> >::ArgsType
00713     operator + <>(const T& x, const PrimArgArray<T>& y);
00714   };
00715 
00716   template<class> class ArgArray;
00717 
00721   template<class T>
00722   typename ArrayTraits<ArgArray<T> >::ArgsType
00723   operator +(const ArgArray<T>& x, const ArgArray<T>& y);
00724 
00728   template<class T>
00729   typename ArrayTraits<ArgArray<T> >::ArgsType
00730   operator +(const ArgArray<T>& x, const T& y);
00731 
00735   template<class T>
00736   typename ArrayTraits<ArgArray<T> >::ArgsType
00737   operator +(const T& x, const ArgArray<T>& y);
00738 
00750   template<class T>
00751   class ArgArray : public ArgArrayBase<T> {
00752   protected:
00753     using ArgArrayBase<T>::a;
00754   public:
00755     using ArgArrayBase<T>::size;
00757 
00758 
00759     ArgArray(void);
00761     explicit ArgArray(int n);
00763     ArgArray(int n, const T* e);
00765     ArgArray(const ArgArray<T>& a);
00767 
00768 
00769 
00770     typename ArrayTraits<ArgArray<T> >::ArgsType
00771     slice(int start, int inc=1, int n=-1);
00773 
00774 
00775 
00776     typename ArrayTraits<ArgArray<T> >::ArgsType&
00777     operator <<(const T& x);
00779     typename ArrayTraits<ArgArray<T> >::ArgsType&
00780     operator <<(const ArgArray<T>& x);
00782 
00783     friend typename ArrayTraits<ArgArray<T> >::ArgsType
00784     operator + <>(const ArgArray<T>& x, const ArgArray<T>& y);
00785     friend typename ArrayTraits<ArgArray<T> >::ArgsType
00786     operator + <>(const ArgArray<T>& x, const T& y);
00787     friend
00788     typename ArrayTraits<ArgArray<T> >::ArgsType
00789     operator + <>(const T& x, const ArgArray<T>& y);
00790   };
00791 
00792   template<class> class VarArgArray;
00793 
00797   template<class Var>
00798   typename ArrayTraits<VarArgArray<Var> >::ArgsType
00799   operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y);
00800 
00804   template<class Var>
00805   typename ArrayTraits<VarArgArray<Var> >::ArgsType
00806   operator +(const VarArgArray<Var>& x, const Var& y);
00807 
00811   template<class Var>
00812   typename ArrayTraits<VarArgArray<Var> >::ArgsType
00813   operator +(const Var& x, const VarArgArray<Var>& y);
00814 
00826   template<class Var>
00827   class VarArgArray : public ArgArrayBase<Var> {
00828   protected:
00829     using ArgArrayBase<Var>::a;
00830     using ArgArrayBase<Var>::n;
00832     class VarLess {
00833     public:
00834       bool operator ()(const Var&, const Var&);
00835     };
00836   public:
00837     using ArgArrayBase<Var>::size;
00839 
00840 
00841     VarArgArray(void);
00843     explicit VarArgArray(int n);
00845     VarArgArray(const VarArgArray<Var>& a);
00847     VarArgArray(const VarArray<Var>& a);
00849 
00850 
00851 
00852     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00853     slice(int start, int inc=1, int n=-1);
00855 
00856 
00857 
00858     typename ArrayTraits<VarArgArray<Var> >::ArgsType&
00859     operator <<(const Var& x);
00861     typename ArrayTraits<VarArgArray<Var> >::ArgsType&
00862     operator <<(const VarArgArray<Var>& x);
00864 
00866     bool assigned(void) const;
00867 
00868     friend typename ArrayTraits<VarArgArray<Var> >::ArgsType
00869     operator + <>(const VarArgArray<Var>& x, const VarArgArray<Var>& y);
00870     friend typename ArrayTraits<VarArgArray<Var> >::ArgsType
00871     operator + <>(const VarArgArray<Var>& x, const Var& y);
00872     friend
00873     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00874     operator + <>(const Var& x, const VarArgArray<Var>& y);
00875 
00877 
00878 
00883     bool same(const Space& home) const;
00889     bool same(const Space& home, const Var& y) const;
00895     bool same(const Space& home, const VarArgArray<Var>& y) const;
00897   };
00898 
00903   template<class Char, class Traits, class Var>
00904   std::basic_ostream<Char,Traits>&
00905   operator <<(std::basic_ostream<Char,Traits>& os,
00906              const VarArray<Var>& x);
00907 
00912   template<class Char, class Traits, class View>
00913   std::basic_ostream<Char,Traits>&
00914   operator <<(std::basic_ostream<Char,Traits>& os, const ViewArray<View>& x);
00915 
00920   template<class Char, class Traits, class T>
00921   std::basic_ostream<Char,Traits>&
00922   operator <<(std::basic_ostream<Char,Traits>& os, const ArgArrayBase<T>& x);
00923 
00924 
00925   /*
00926    * Implementation
00927    *
00928    */
00929 
00930   /*
00931    * Variable arrays
00932    *
00933    * These arrays are usually allocated in the space, but if they are resized,
00934    * the new array is allocated on the heap. The size (n) and capacity show
00935    * where the array is allocated: it is in the space if and only if
00936    * n==capacity.
00937    *
00938    */
00939 
00940   template<class Var>
00941   forceinline
00942   VarArray<Var>::VarArray(void) : n(0), x(NULL) {}
00943 
00944   template<class Var>
00945   forceinline
00946   VarArray<Var>::VarArray(Space& home, int n0)
00947     : n(n0) {
00948     // Allocate from space
00949     x = (n>0) ? home.alloc<Var>(n) : NULL;
00950   }
00951 
00952   template<class Var>
00953   forceinline
00954   VarArray<Var>::VarArray(const VarArray<Var>& a) {
00955     n = a.n; x = a.x;
00956   }
00957 
00958   template<class Var>
00959   inline const VarArray<Var>&
00960   VarArray<Var>::operator =(const VarArray<Var>& a) {
00961     n = a.n; x = a.x;
00962     return *this;
00963   }
00964 
00965   template<class Var>
00966   forceinline int
00967   VarArray<Var>::size(void) const {
00968     return n;
00969   }
00970 
00971   template<class Var>
00972   forceinline Var&
00973   VarArray<Var>::operator [](int i) {
00974     assert((i >= 0) && (i < size()));
00975     return x[i];
00976   }
00977 
00978   template<class Var>
00979   forceinline const Var&
00980   VarArray<Var>::operator [](int i) const {
00981     assert((i >= 0) && (i < size()));
00982     return x[i];
00983   }
00984 
00985   template<class Var>
00986   typename ArrayTraits<VarArgArray<Var> >::ArgsType
00987   VarArray<Var>::slice(int start, int inc, int maxN) {
00988     assert(n==0 || start < n);
00989     if (n==0 || maxN<0)
00990       maxN = n;
00991     int s;
00992     if (inc == 0)
00993       s = n-start;
00994     else if (inc > 0)
00995       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
00996     else
00997       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
00998     typename ArrayTraits<VarArgArray<Var> >::ArgsType r(std::min(maxN,s));
00999     for (int i=0; i<r.size(); i++, start+=inc)
01000       r[i] = x[start];
01001     return r;
01002   }
01003 
01004   template<class Var>
01005   forceinline typename VarArray<Var>::iterator
01006   VarArray<Var>::begin(void) {
01007     return x;
01008   }
01009 
01010   template<class Var>
01011   forceinline typename VarArray<Var>::const_iterator
01012   VarArray<Var>::begin(void) const {
01013     return x;
01014   }
01015 
01016   template<class Var>
01017   forceinline typename VarArray<Var>::iterator
01018   VarArray<Var>::end(void) {
01019     return x+n;
01020   }
01021 
01022   template<class Var>
01023   forceinline typename VarArray<Var>::const_iterator
01024   VarArray<Var>::end(void) const {
01025     return x+n;
01026   }
01027 
01028   template<class Var>
01029   forceinline typename VarArray<Var>::reverse_iterator
01030   VarArray<Var>::rbegin(void) {
01031     return reverse_iterator(x+n);
01032   }
01033 
01034   template<class Var>
01035   forceinline typename VarArray<Var>::const_reverse_iterator
01036   VarArray<Var>::rbegin(void) const {
01037     return const_reverse_iterator(x+n);
01038   }
01039 
01040   template<class Var>
01041   forceinline typename VarArray<Var>::reverse_iterator
01042   VarArray<Var>::rend(void) {
01043     return reverse_iterator(x);
01044   }
01045 
01046   template<class Var>
01047   forceinline typename VarArray<Var>::const_reverse_iterator
01048   VarArray<Var>::rend(void) const {
01049     return const_reverse_iterator(x);
01050   }
01051 
01052   template<class Var>
01053   forceinline void
01054   VarArray<Var>::update(Space& home, bool share, VarArray<Var>& a) {
01055     n = a.n;
01056     if (n > 0) {
01057       x = home.alloc<Var>(n);
01058       for (int i = n; i--;)
01059         x[i].update(home, share, a.x[i]);
01060     } else {
01061       x = NULL;
01062     }
01063   }
01064 
01065   template<class Var>
01066   forceinline bool
01067   VarArray<Var>::assigned(void) const {
01068     for (int i = n; i--;)
01069       if (!x[i].assigned())
01070         return false;
01071     return true;
01072   }
01073   
01074   template<class Var>
01075   void*
01076   VarArray<Var>::operator new(size_t) {
01077     return NULL;
01078   }
01079 
01080   template<class Var>
01081   void
01082   VarArray<Var>::operator delete(void*,size_t) {
01083   }
01084 
01085   template<class Var>
01086   typename ArrayTraits<VarArray<Var> >::ArgsType
01087   operator +(const VarArray<Var>& x, const VarArray<Var>& y) {
01088     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01089     for (int i=x.size(); i--;)
01090       r[i] = x[i];
01091     for (int i=y.size(); i--;)
01092       r[x.size()+i] = y[i];
01093     return r;
01094   }
01095 
01096   template<class Var>
01097   typename ArrayTraits<VarArray<Var> >::ArgsType
01098   operator +(const VarArray<Var>& x, const VarArgArray<Var>& y) {
01099     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01100     for (int i=x.size(); i--;)
01101       r[i] = x[i];
01102     for (int i=y.size(); i--;)
01103       r[x.size()+i] = y[i];
01104     return r;
01105   }
01106 
01107   template<class Var>
01108   typename ArrayTraits<VarArray<Var> >::ArgsType
01109   operator +(const VarArgArray<Var>& x, const VarArray<Var>& y) {
01110     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01111     for (int i=x.size(); i--;)
01112       r[i] = x[i];
01113     for (int i=y.size(); i--;)
01114       r[x.size()+i] = y[i];
01115     return r;
01116   }
01117 
01118   template<class Var>
01119   typename ArrayTraits<VarArray<Var> >::ArgsType
01120   operator +(const VarArray<Var>& x, const Var& y) {
01121     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+1);
01122     for (int i=x.size(); i--;)
01123       r[i] = x[i];
01124     r[x.size()] = y;
01125     return r;    
01126   }
01127 
01128   template<class Var>
01129   typename ArrayTraits<VarArray<Var> >::ArgsType
01130   operator +(const Var& x, const VarArray<Var>& y) {
01131     typename ArrayTraits<VarArray<Var> >::ArgsType r(y.size()+1);
01132     r[0] = x;
01133     for (int i=y.size(); i--;)
01134       r[1+i] = y[i];
01135     return r;
01136   }
01137 
01138   /*
01139    * View arrays
01140    *
01141    */
01142 
01143   template<class View>
01144   forceinline
01145   ViewArray<View>::ViewArray(void) : n(0), x(NULL) {}
01146 
01147   template<class View>
01148   forceinline
01149   ViewArray<View>::ViewArray(Space& home, int n0)
01150     : n(n0) {
01151     x = (n>0) ? home.alloc<View>(n) : NULL;
01152   }
01153   template<class View>
01154   forceinline
01155   ViewArray<View>::ViewArray(Region& r, int n0)
01156     : n(n0) {
01157     x = (n>0) ? r.alloc<View>(n) : NULL;
01158   }
01159 
01160   template<class View>
01161   ViewArray<View>::ViewArray(Space& home, const ViewArray<View>& a)
01162     : n(a.size()) {
01163     if (n>0) {
01164       x = home.alloc<View>(n);
01165       for (int i = n; i--; )
01166         x[i] = a[i];
01167     } else {
01168       x = NULL;
01169     }
01170   }
01171   template<class View>
01172   ViewArray<View>::ViewArray(Region& r, const ViewArray<View>& a)
01173     : n(a.size()) {
01174     if (n>0) {
01175       x = r.alloc<View>(n);
01176       for (int i = n; i--; )
01177         x[i] = a[i];
01178     } else {
01179       x = NULL;
01180     }
01181   }
01182 
01183   template<class View>
01184   forceinline
01185   ViewArray<View>::ViewArray(const ViewArray<View>& a)
01186     : n(a.n), x(a.x) {}
01187 
01188   template<class View>
01189   forceinline const ViewArray<View>&
01190   ViewArray<View>::operator =(const ViewArray<View>& a) {
01191     n = a.n; x = a.x;
01192     return *this;
01193   }
01194 
01195   template<class View>
01196   forceinline int
01197   ViewArray<View>::size(void) const {
01198     return n;
01199   }
01200 
01201   template<class View>
01202   forceinline void
01203   ViewArray<View>::size(int n0) {
01204     n = n0;
01205   }
01206 
01207   template<class View>
01208   forceinline View&
01209   ViewArray<View>::operator [](int i) {
01210     assert((i >= 0) && (i < size()));
01211     return x[i];
01212   }
01213 
01214   template<class View>
01215   forceinline const View&
01216   ViewArray<View>::operator [](int i) const {
01217     assert((i >= 0) && (i < size()));
01218     return x[i];
01219   }
01220 
01221   template<class View>
01222   forceinline typename ViewArray<View>::iterator
01223   ViewArray<View>::begin(void) {
01224     return x;
01225   }
01226 
01227   template<class View>
01228   forceinline typename ViewArray<View>::const_iterator
01229   ViewArray<View>::begin(void) const {
01230     return x;
01231   }
01232 
01233   template<class View>
01234   forceinline typename ViewArray<View>::iterator
01235   ViewArray<View>::end(void) {
01236     return x+n;
01237   }
01238 
01239   template<class View>
01240   forceinline typename ViewArray<View>::const_iterator
01241   ViewArray<View>::end(void) const {
01242     return x+n;
01243   }
01244 
01245   template<class View>
01246   forceinline typename ViewArray<View>::reverse_iterator
01247   ViewArray<View>::rbegin(void) {
01248     return reverse_iterator(x+n);
01249   }
01250 
01251   template<class View>
01252   forceinline typename ViewArray<View>::const_reverse_iterator
01253   ViewArray<View>::rbegin(void) const {
01254     return const_reverse_iterator(x+n);
01255   }
01256 
01257   template<class View>
01258   forceinline typename ViewArray<View>::reverse_iterator
01259   ViewArray<View>::rend(void) {
01260     return reverse_iterator(x);
01261   }
01262 
01263   template<class View>
01264   forceinline typename ViewArray<View>::const_reverse_iterator
01265   ViewArray<View>::rend(void) const {
01266     return const_reverse_iterator(x);
01267   }
01268 
01269   template<class View>
01270   forceinline void
01271   ViewArray<View>::move_fst(int i) {
01272     x[i]=x[0]; x++; n--;
01273   }
01274 
01275   template<class View>
01276   forceinline void
01277   ViewArray<View>::move_lst(int i) {
01278     n--; x[i]=x[n];
01279   }
01280 
01281   template<class View>
01282   forceinline void
01283   ViewArray<View>::drop_fst(int i) {
01284     assert(i>=0);
01285     x += i; n -= i;
01286   }
01287 
01288   template<class View>
01289   forceinline void
01290   ViewArray<View>::drop_lst(int i) {
01291     assert(i<n);
01292     n = i+1;
01293   }
01294 
01295   template<class View>
01296   forceinline void
01297   ViewArray<View>::move_fst(int i, Space& home, Propagator& p, PropCond pc) {
01298     // Move x[0] to x[i]
01299     x[i].cancel(home,p,pc);
01300     x[i]=x[0]; x++; n--;
01301   }
01302 
01303   template<class View>
01304   forceinline void
01305   ViewArray<View>::move_lst(int i, Space& home, Propagator& p, PropCond pc) {
01306     // Move x[n-1] to x[i]
01307     x[i].cancel(home,p,pc);
01308     n--; x[i]=x[n];
01309   }
01310 
01311   template<class View>
01312   void
01313   ViewArray<View>::drop_fst(int i, Space& home, Propagator& p, PropCond pc) {
01314     // Drop elements from 0..i-1
01315     assert(i>=0);
01316     for (int j=i; j--; )
01317       x[j].cancel(home,p,pc);
01318     x += i; n -= i;
01319   }
01320 
01321   template<class View>
01322   void
01323   ViewArray<View>::drop_lst(int i, Space& home, Propagator& p, PropCond pc) {
01324     // Drop elements from i+1..n-1
01325     assert(i<n);
01326     for (int j=i+1; j<n; j++)
01327       x[j].cancel(home,p,pc);
01328     n = i+1;
01329   }
01330 
01331   template<class View>
01332   forceinline void
01333   ViewArray<View>::move_fst(int i, Space& home, Advisor& a) {
01334     // Move x[0] to x[i]
01335     x[i].cancel(home,a);
01336     x[i]=x[0]; x++; n--;
01337   }
01338 
01339   template<class View>
01340   forceinline void
01341   ViewArray<View>::move_lst(int i, Space& home, Advisor& a) {
01342     // Move x[n-1] to x[i]
01343     x[i].cancel(home,a);
01344     n--; x[i]=x[n];
01345   }
01346 
01347   template<class View>
01348   void
01349   ViewArray<View>::drop_fst(int i, Space& home, Advisor& a) {
01350     // Drop elements from 0..i-1
01351     assert(i>=0);
01352     for (int j=i; j--; )
01353       x[j].cancel(home,a);
01354     x += i; n -= i;
01355   }
01356 
01357   template<class View>
01358   void
01359   ViewArray<View>::drop_lst(int i, Space& home, Advisor& a) {
01360     // Drop elements from i+1..n-1
01361     assert(i<n);
01362     for (int j=i+1; j<n; j++)
01363       x[j].cancel(home,a);
01364     n = i+1;
01365   }
01366 
01367   template<class View>
01368   void
01369   ViewArray<View>::update(Space& home, bool share, ViewArray<View>& y) {
01370     n = y.n;
01371     if (n > 0) {
01372       x = home.alloc<View>(n);
01373       for (int i = n; i--; )
01374         x[i].update(home, share, y.x[i]);
01375     } else {
01376       x = NULL;
01377     }
01378   }
01379 
01380   template<class View>
01381   void
01382   ViewArray<View>::subscribe(Space& home, Propagator& p, PropCond pc,
01383                              bool process) {
01384     for (int i = n; i--; )
01385       x[i].subscribe(home,p,pc,process);
01386   }
01387 
01388   template<class View>
01389   void
01390   ViewArray<View>::cancel(Space& home, Propagator& p, PropCond pc) {
01391     for (int i = n; i--; )
01392       x[i].cancel(home,p,pc);
01393   }
01394 
01395   template<class View>
01396   void
01397   ViewArray<View>::subscribe(Space& home, Advisor& a) {
01398     for (int i = n; i--; )
01399       x[i].subscribe(home,a);
01400   }
01401 
01402   template<class View>
01403   void
01404   ViewArray<View>::cancel(Space& home, Advisor& a) {
01405     for (int i = n; i--; )
01406       x[i].cancel(home,a);
01407   }
01408 
01409   template<class View>
01410   forceinline bool
01411   ViewArray<View>::assigned(void) const {
01412     for (int i = n; i--;)
01413       if (!x[i].assigned())
01414         return false;
01415     return true;
01416   }
01417 
01418   template<class View>
01419   forceinline bool
01420   __before(const View& x, const View& y) {
01421     return before(x,y);
01422   }
01423 
01424   template<class View> template<class X>
01425   forceinline bool
01426   ViewArray<View>::ViewLess<X>::operator ()(const X& a, const X& b) {
01427     return __before(a,b);
01428   }
01429 
01430   template<class View>
01431   void
01432   ViewArray<View>::sort(View* y, int m) {
01433     ViewLess<View> vl;
01434     Support::quicksort<View,ViewLess<View> >(y,m,vl);
01435   }
01436 
01437   template<class X, class Y>
01438   forceinline bool
01439   __same(const X& x, const Y& y) {
01440     return same(x,y);
01441   }
01442   template<class X, class Y>
01443   forceinline bool
01444   __shared(const X& x, const Y& y) {
01445     return shared(x,y);
01446   }
01447 
01448   template<class View>
01449   bool
01450   ViewArray<View>::same(const Space& home) const {
01451     if (n < 2)
01452       return false;
01453     Region r(home);
01454     View* y = r.alloc<View>(n);
01455     for (int i = n; i--; )
01456       y[i] = x[i];
01457     sort(y,n);
01458     for (int i = n-1; i--; )
01459       if (!y[i].assigned() && __same(y[i+1],y[i])) {
01460         r.free<View>(y,n);
01461         return true;
01462       }
01463     r.free<View>(y,n);
01464     return false;
01465   }
01466 
01467   template<class View>
01468   bool
01469   ViewArray<View>::same(const Space&, const View& y) const {
01470     if (y.assigned())
01471       return false;
01472     for (int i = n; i--; )
01473       if (__same(x[i],y))
01474         return true;
01475     return false;
01476   }
01477 
01478   template<class View>
01479   void
01480   ViewArray<View>::unique(const Space&) {
01481     if (n < 2)
01482       return;
01483     sort(x,n);
01484     int j = 0;
01485     for (int i = 1; i<n; i++)
01486       if (!__same(x[j],x[i]))
01487         x[++j] = x[i];
01488     n = j+1;
01489   }
01490 
01491   template<class View>
01492   bool
01493   ViewArray<View>::shared(const Space& home) const {
01494     if (n < 2)
01495       return false;
01496     Region r(home);
01497     View* y = r.alloc<View>(n);
01498     for (int i = n; i--; )
01499       y[i] = x[i];
01500     sort(y,n);
01501     for (int i = n-1; i--; )
01502       if (!y[i].assigned() && __shared(y[i+1],y[i])) {
01503         r.free<View>(y,n);
01504         return true;
01505       }
01506     r.free<View>(y,n);
01507     return false;
01508   }
01509 
01510   template<class View> template<class ViewY>
01511   bool
01512   ViewArray<View>::shared(const Space&, const ViewY& y) const {
01513     if (y.assigned())
01514       return false;
01515     for (int i = n; i--; )
01516       if (!x[i].assigned() && __shared(x[i],y))
01517         return true;
01518     return false;
01519   }
01520 
01521   template<class View> template<class ViewY>
01522   bool
01523   ViewArray<View>::shared(const Space& home, const ViewArray<ViewY>& y) const {
01524     if ((size() < 1) || (y.size() < 1))
01525       return false;
01526     Region r(home);
01527     View* xs = r.alloc<View>(size());
01528     for (int i=size(); i--; )
01529       xs[i] = x[i];
01530     ViewLess<View> xvl;
01531     Support::quicksort<View,ViewLess<View> >(xs,size(),xvl);
01532     ViewY* ys = r.alloc<ViewY>(y.size());
01533     for (int j=y.size(); j--; )
01534       ys[j] = y[j];
01535     ViewLess<ViewY> yvl;
01536     Support::quicksort<ViewY,ViewLess<ViewY> >(ys,y.size(),yvl);
01537     {
01538       int i=0, j=0;
01539       while ((i < size()) && (j < y.size()))
01540         if (!x[i].assigned() && __shared(x[i],y[j])) {
01541           r.free<View>(xs,size());
01542           r.free<ViewY>(ys,y.size());
01543           return true;
01544         } else if (before(x[i],y[j])) {
01545           i++;
01546         } else {
01547           j++;
01548         }
01549     }
01550     r.free<View>(xs,size());
01551     r.free<ViewY>(ys,y.size());
01552     return false;
01553   }
01554 
01555   template<class View>
01556   void*
01557   ViewArray<View>::operator new(size_t) {
01558     return NULL;
01559   }
01560 
01561   template<class View>
01562   void
01563   ViewArray<View>::operator delete(void*,size_t) {
01564   }
01565 
01566 
01567   /*
01568    * Argument arrays: base class
01569    *
01570    */
01571 
01572   template<class T>
01573   forceinline T*
01574   ArgArrayBase<T>::allocate(int n) {
01575     return (n > onstack_size) ?
01576       heap.alloc<T>(static_cast<unsigned int>(n)) : &onstack[0];
01577   }
01578 
01579   template<class T>
01580   forceinline void
01581   ArgArrayBase<T>::resize(int i) {
01582     if (n+i >= capacity) {
01583       assert(n+i >= onstack_size);
01584       int newCapacity = (3*capacity)/2;
01585       if (newCapacity <= n+i)
01586         newCapacity = n+i;
01587       T* newA = allocate(newCapacity);
01588       heap.copy<T>(newA,a,n);
01589       if (capacity > onstack_size)
01590         heap.free(a,capacity);
01591       capacity = newCapacity;
01592       a = newA;
01593     }
01594   }
01595 
01596   template<class T>
01597   forceinline
01598   ArgArrayBase<T>::ArgArrayBase(void)
01599     : n(0), capacity(onstack_size), a(allocate(0)) {}
01600 
01601   template<class T>
01602   forceinline
01603   ArgArrayBase<T>::ArgArrayBase(int n0)
01604     : n(n0), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {}
01605 
01606   template<class T>
01607   inline
01608   ArgArrayBase<T>::ArgArrayBase(const ArgArrayBase<T>& aa)
01609     : n(aa.n), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01610     heap.copy<T>(a,aa.a,n);
01611   }
01612 
01613   template<class T>
01614   forceinline
01615   ArgArrayBase<T>::~ArgArrayBase(void) {
01616     if (capacity > onstack_size)
01617       heap.free(a,capacity);
01618   }
01619 
01620   template<class T>
01621   forceinline const ArgArrayBase<T>&
01622   ArgArrayBase<T>::operator =(const ArgArrayBase<T>& aa) {
01623     if (&aa != this) {
01624       if (capacity > onstack_size)
01625         heap.free(a,capacity);
01626       n = aa.n;
01627       capacity = (n < onstack_size ? onstack_size : n);
01628       a = allocate(aa.n);
01629       heap.copy<T>(a,aa.a,n);
01630     }
01631     return *this;
01632   }
01633 
01634   template<class T>
01635   forceinline int
01636   ArgArrayBase<T>::size(void) const {
01637     return n;
01638   }
01639 
01640   template<class T>
01641   forceinline T&
01642   ArgArrayBase<T>::operator [](int i) {
01643     assert((i>=0) && (i < n));
01644     return a[i];
01645   }
01646 
01647   template<class T>
01648   forceinline const T&
01649   ArgArrayBase<T>::operator [](int i) const {
01650     assert((i>=0) && (i < n));
01651     return a[i];
01652   }
01653 
01654   template<class T>
01655   forceinline typename ArgArrayBase<T>::iterator
01656   ArgArrayBase<T>::begin(void) {
01657     return a;
01658   }
01659 
01660   template<class T>
01661   forceinline typename ArgArrayBase<T>::const_iterator
01662   ArgArrayBase<T>::begin(void) const {
01663     return a;
01664   }
01665 
01666   template<class T>
01667   forceinline typename ArgArrayBase<T>::iterator
01668   ArgArrayBase<T>::end(void) {
01669     return a+n;
01670   }
01671 
01672   template<class T>
01673   forceinline typename ArgArrayBase<T>::const_iterator
01674   ArgArrayBase<T>::end(void) const {
01675     return a+n;
01676   }
01677 
01678   template<class T>
01679   forceinline typename ArgArrayBase<T>::reverse_iterator
01680   ArgArrayBase<T>::rbegin(void) {
01681     return reverse_iterator(a+n);
01682   }
01683 
01684   template<class T>
01685   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01686   ArgArrayBase<T>::rbegin(void) const {
01687     return const_reverse_iterator(a+n);
01688   }
01689 
01690   template<class T>
01691   forceinline typename ArgArrayBase<T>::reverse_iterator
01692   ArgArrayBase<T>::rend(void) {
01693     return reverse_iterator(a);
01694   }
01695 
01696   template<class T>
01697   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01698   ArgArrayBase<T>::rend(void) const {
01699     return const_reverse_iterator(a);
01700   }
01701 
01702   template<class T> template<class A>
01703   A
01704   ArgArrayBase<T>::slice(int start, int inc, int maxN) {
01705     assert(n==0 || start < n);
01706     if (n==0 || maxN<0)
01707       maxN = n;
01708     int s;
01709     if (inc == 0)
01710       s = n-start;
01711     else if (inc > 0)
01712       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
01713     else
01714       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
01715     A r(std::min(maxN,s));
01716     for (int i=0; i<r.size(); i++, start+=inc)
01717       new (&r[i]) T(a[start]);
01718     return r;
01719   }
01720 
01721   template<class T> template<class A>
01722   inline A&
01723   ArgArrayBase<T>::append(const T& x) {
01724     resize(1);
01725     new (&a[n++]) T(x);
01726     return static_cast<A&>(*this);
01727   }
01728 
01729   template<class T> template<class A>
01730   inline A&
01731   ArgArrayBase<T>::append(const ArgArrayBase<T>& x) {
01732     resize(x.size());
01733     for (int i=0; i<x.size(); i++)
01734       new (&a[n++]) T(x[i]);
01735     return static_cast<A&>(*this);
01736   }
01737 
01738   template<class T> template<class A>
01739   inline A
01740   ArgArrayBase<T>::concat(const ArgArrayBase<T>& x) const {
01741     A r(n+x.n);
01742     for (int i=n; i--;)
01743       new (&r[i]) T(a[i]);
01744     for (int i=x.n; i--;)
01745       new (&r[n+i]) T(x.a[i]);
01746     return r;
01747   }
01748 
01749   template<class T> template<class A>
01750   inline A
01751   ArgArrayBase<T>::concat(const T& x) const {
01752     A r(n+1);
01753     for (int i=n; i--;)
01754       new (&r[i]) T(a[i]);
01755     new (&r[n]) T(x);
01756     return r;
01757   }
01758 
01759   /*
01760    * Argument arrays for primitive types
01761    *
01762    */
01763 
01764   template<class T>
01765   forceinline
01766   PrimArgArray<T>::PrimArgArray(void) {}
01767 
01768   template<class T>
01769   forceinline
01770   PrimArgArray<T>::PrimArgArray(int n) : ArgArrayBase<T>(n) {}
01771 
01772   template<class T>
01773   PrimArgArray<T>::PrimArgArray(int n, T a0, ...)
01774     : ArgArrayBase<T>(n) {
01775     va_list args;
01776     va_start(args, a0);
01777     a[0] = a0;
01778     for (int i = 1; i < n; i++)
01779       a[i] = va_arg(args,T);
01780     va_end(args);
01781   }
01782 
01783   template<class T>
01784   PrimArgArray<T>::PrimArgArray(int n, const T* a0)
01785     : ArgArrayBase<T>(n) {
01786     for (int i=n; i--; )
01787       a[i] = a0[i];
01788   }
01789 
01790   template<class T>
01791   forceinline
01792   PrimArgArray<T>::PrimArgArray(const PrimArgArray<T>& aa)
01793     : ArgArrayBase<T>(aa) {}
01794 
01795   template<class T>
01796   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType
01797   PrimArgArray<T>::slice(int start, int inc, int maxN) {
01798     return ArgArrayBase<T>::template slice
01799       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>
01800         (start,inc,maxN);
01801   }
01802 
01803   template<class T>
01804   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType&
01805   PrimArgArray<T>::operator <<(const T& x) {
01806     return
01807       ArgArrayBase<T>::template append
01808         <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(x);
01809   }
01810 
01811   template<class T>
01812   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType&
01813   PrimArgArray<T>::operator <<(const PrimArgArray<T>& x) {
01814     return
01815       ArgArrayBase<T>::template append
01816         <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(x);
01817   }
01818 
01819   template<class T>
01820   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01821   operator +(const PrimArgArray<T>& x, const PrimArgArray<T>& y) {
01822     return x.template concat
01823       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);
01824   }
01825 
01826   template<class T>
01827   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01828   operator +(const PrimArgArray<T>& x, const T& y) {
01829     return x.template concat
01830       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);    
01831   }
01832 
01833   template<class T>
01834   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01835   operator +(const T& x, const PrimArgArray<T>& y) {
01836     return PrimArgArray<T>(1,x).template concat
01837       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);    
01838   }
01839 
01840 
01841   /*
01842    * Argument arrays for non-primitive types
01843    *
01844    */
01845 
01846   template<class T>
01847   forceinline
01848   ArgArray<T>::ArgArray(void) {}
01849 
01850   template<class T>
01851   forceinline
01852   ArgArray<T>::ArgArray(int n) : ArgArrayBase<T>(n) {}
01853 
01854   template<class T>
01855   ArgArray<T>::ArgArray(int n, const T* a0)
01856     : ArgArrayBase<T>(n) {
01857     for (int i=n; i--; )
01858       a[i] = a0[i];
01859   }
01860 
01861   template<class T>
01862   forceinline
01863   ArgArray<T>::ArgArray(const ArgArray<T>& aa)
01864     : ArgArrayBase<T>(aa) {}
01865 
01866   template<class T>
01867   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType
01868   ArgArray<T>::slice(int start, int inc, int maxN) {
01869     return ArgArrayBase<T>::template slice
01870       <typename ArrayTraits<ArgArray<T> >::ArgsType>
01871       (start,inc,maxN);
01872   }
01873 
01874   template<class T>
01875   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType&
01876   ArgArray<T>::operator <<(const T& x) {
01877     return
01878       ArgArrayBase<T>::template append
01879         <typename ArrayTraits<ArgArray<T> >::ArgsType>(x);
01880   }
01881 
01882   template<class T>
01883   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType&
01884   ArgArray<T>::operator <<(const ArgArray<T>& x) {
01885     return
01886       ArgArrayBase<T>::template append
01887         <typename ArrayTraits<ArgArray<T> >::ArgsType>(x);
01888   }
01889 
01890   template<class T>
01891   typename ArrayTraits<ArgArray<T> >::ArgsType
01892   operator +(const ArgArray<T>& x, const ArgArray<T>& y) {
01893     return x.template concat
01894       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);
01895   }
01896 
01897   template<class T>
01898   typename ArrayTraits<ArgArray<T> >::ArgsType
01899   operator +(const ArgArray<T>& x, const T& y) {
01900     return x.template concat
01901       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);    
01902   }
01903 
01904   template<class T>
01905   typename ArrayTraits<ArgArray<T> >::ArgsType
01906   operator +(const T& x, const ArgArray<T>& y) {
01907     ArgArray<T> xa(1);
01908     xa[0] = x;
01909     return xa.template concat
01910       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);    
01911   }
01912 
01913   /*
01914    * Argument arrays for variables
01915    *
01916    */
01917 
01918   template<class Var>
01919   forceinline
01920   VarArgArray<Var>::VarArgArray(void) {}
01921 
01922   template<class Var>
01923   forceinline
01924   VarArgArray<Var>::VarArgArray(int n) : ArgArrayBase<Var>(n) {}
01925 
01926   template<class Var>
01927   forceinline
01928   VarArgArray<Var>::VarArgArray(const VarArgArray<Var>& aa)
01929     : ArgArrayBase<Var>(aa) {}
01930 
01931   template<class Var>
01932   inline
01933   VarArgArray<Var>::VarArgArray(const VarArray<Var>& x)
01934     : ArgArrayBase<Var>(x.size()) {
01935     for (int i=x.size(); i--; )
01936       a[i]=x[i];
01937   }
01938 
01939   template<class Var>
01940   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType
01941   VarArgArray<Var>::slice(int start, int inc, int maxN) {
01942     return ArgArrayBase<Var>::template slice
01943       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>
01944         (start,inc,maxN);
01945   }
01946 
01947   template<class Var>
01948   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType&
01949   VarArgArray<Var>::operator <<(const Var& x) {
01950     return
01951       ArgArrayBase<Var>::template append
01952         <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(x);
01953   }
01954 
01955   template<class Var>
01956   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType&
01957   VarArgArray<Var>::operator <<(const VarArgArray<Var>& x) {
01958     return
01959       ArgArrayBase<Var>::template append
01960         <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(x);
01961   }
01962 
01963   template<class Var>
01964   typename ArrayTraits<VarArgArray<Var> >::ArgsType
01965   operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y) {
01966     return x.template concat
01967       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);
01968   }
01969 
01970   template<class Var>
01971   typename ArrayTraits<VarArgArray<Var> >::ArgsType
01972   operator +(const VarArgArray<Var>& x, const Var& y) {
01973     return x.template concat
01974       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);    
01975   }
01976 
01977   template<class Var>
01978   typename ArrayTraits<VarArgArray<Var> >::ArgsType
01979   operator +(const Var& x, const VarArgArray<Var>& y) {
01980     VarArgArray<Var> xa(1);
01981     xa[0] = x;
01982     return xa.template concat
01983       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);    
01984   }
01985 
01986   template<class Var>
01987   forceinline bool
01988   VarArgArray<Var>::VarLess::operator ()(const Var& a, const Var& b) {
01989     return a.varimp() < b.varimp();
01990   }
01991 
01992   template<class Var>
01993   forceinline bool
01994   VarArgArray<Var>::assigned(void) const {
01995     for (int i = n; i--;)
01996       if (!a[i].assigned())
01997         return false;
01998     return true;
01999   }
02000 
02001   template<class Var>
02002   bool
02003   VarArgArray<Var>::same(const Space& home) const {
02004     if (n < 2)
02005       return false;
02006     Region r(home);
02007     Var* y = r.alloc<Var>(n);
02008     for (int i = n; i--; )
02009       y[i] = a[i];
02010     VarLess vl;
02011     Support::quicksort<Var,VarLess>(y,n,vl);
02012     for (int i = n-1; i--; )
02013       if (!y[i].assigned() && (y[i+1].varimp() == y[i].varimp())) {
02014         r.free<Var>(y,n);
02015         return true;
02016       }
02017     r.free<Var>(y,n);
02018     return false;
02019   }
02020 
02021   template<class Var>
02022   bool
02023   VarArgArray<Var>::same(const Space& home, const VarArgArray<Var>& y) const {
02024     int m = n + y.n;
02025     if (m < 2)
02026       return false;
02027     Region r(home);
02028     Var* z = r.alloc<Var>(m);
02029     for (int i = n; i--; )
02030       z[i] = a[i];
02031     for (int i = y.n; i--; )
02032       z[i+n] = y.a[i];
02033     VarLess vl;
02034     Support::quicksort<Var,VarLess>(z,m,vl);
02035     for (int i = m-1; i--; )
02036       if (!z[i].assigned() && (z[i+1].varimp() == z[i].varimp())) {
02037         r.free<Var>(z,m);
02038         return true;
02039       }
02040     r.free<Var>(z,m);
02041     return false;
02042   }
02043 
02044   template<class Var>
02045   bool
02046   VarArgArray<Var>::same(const Space&, const Var& y) const {
02047     if (y.assigned())
02048       return false;
02049     for (int i = n; i--; )
02050       if (a[i].varimp() == y.varimp())
02051         return true;
02052     return false;
02053   }
02054 
02055 
02056 
02057 
02058 
02059 
02060   /*
02061    * Interdependent code
02062    *
02063    */
02064 
02065   template<class Var>
02066   inline
02067   VarArray<Var>::VarArray(Space& home, const VarArgArray<Var>& a)
02068     : n(a.size()) {
02069     if (n>0) {
02070       x = home.alloc<Var>(n);
02071       for (int i=n; i--;)
02072         x[i] = a[i];
02073     } else {
02074       x = NULL;
02075     }
02076   }
02077 
02078 
02079   /*
02080    * Printing of arrays
02081    *
02082    */
02083   template<class Char, class Traits, class Var>
02084   std::basic_ostream<Char,Traits>&
02085   operator <<(std::basic_ostream<Char,Traits>& os,
02086              const VarArray<Var>& x) {
02087     std::basic_ostringstream<Char,Traits> s;
02088     s.copyfmt(os); s.width(0);
02089     s << '{';
02090     if (x.size() > 0) {
02091       s << x[0];
02092       for (int i=1; i<x.size(); i++)
02093         s << ", " << x[i];
02094     }
02095     s << '}';
02096     return os << s.str();
02097   }
02098 
02099   template<class Char, class Traits, class View>
02100   std::basic_ostream<Char,Traits>&
02101   operator <<(std::basic_ostream<Char,Traits>& os,
02102              const ViewArray<View>& x) {
02103     std::basic_ostringstream<Char,Traits> s;
02104     s.copyfmt(os); s.width(0);
02105     s << '{';
02106     if (x.size() > 0) {
02107       s << x[0];
02108       for (int i=1; i<x.size(); i++)
02109         s << ", " << x[i];
02110     }
02111     s << '}';
02112     return os << s.str();
02113   }
02114 
02115   template<class Char, class Traits, class T>
02116   std::basic_ostream<Char,Traits>&
02117   operator <<(std::basic_ostream<Char,Traits>& os,
02118              const ArgArrayBase<T>& x) {
02119     std::basic_ostringstream<Char,Traits> s;
02120     s.copyfmt(os); s.width(0);
02121     s << '{';
02122     if (x.size() > 0) {
02123       s << x[0];
02124       for (int i=1; i<x.size(); i++)
02125         s << ", " << x[i];
02126     }
02127     s << '}';
02128     return os << s.str();
02129   }
02130 
02131 }
02132 
02133 // STATISTICS: kernel-other