Generated on Tue May 22 09:39:43 2018 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  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 #include <cstdarg>
00041 #include <iostream>
00042 #include <iterator>
00043 #include <vector>
00044 #include <sstream>
00045 
00046 namespace Gecode {
00047 
00048   template<class Var> class VarArray;
00049   template<class Var> class VarArgArray;
00050 
00063   template<class A>
00064   class ArrayTraits {};
00065 
00081   template<class Var>
00082   class VarArray {
00083   protected:
00085     int n;
00087     Var* x;
00088   public:
00090 
00091 
00092     typedef Var value_type;
00094     typedef Var& reference;
00096     typedef const Var& const_reference;
00098     typedef Var* pointer;
00100     typedef const Var* const_pointer;
00102     typedef Var* iterator;
00104     typedef const Var* const_iterator;
00106     typedef std::reverse_iterator<Var*> reverse_iterator;
00108     typedef std::reverse_iterator<const Var*> const_reverse_iterator;
00110 
00112 
00113 
00114 
00115     VarArray(void);
00117     VarArray(Space& home, int m);
00119     VarArray(Space& home, const VarArgArray<Var>&);
00121     VarArray(const VarArray<Var>& a);
00123     const VarArray<Var>& operator =(const VarArray<Var>& a);
00125 
00127 
00128 
00129     int size(void) const;
00131 
00133 
00134 
00135     Var& operator [](int i);
00137     const Var& operator [](int i) const;
00143     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00144     slice(int start, int inc=1, int n=-1);
00146 
00148 
00149 
00150     iterator begin(void);
00152     const_iterator begin(void) const;
00154     iterator end(void);
00156     const_iterator end(void) const;
00158     reverse_iterator rbegin(void);
00160     const_reverse_iterator rbegin(void) const;
00162     reverse_iterator rend(void);
00164     const_reverse_iterator rend(void) const;
00166 
00168     bool assigned(void) const;
00169 
00171 
00172 
00173     void update(Space& home, VarArray<Var>& a);
00175   private:
00176     static void* operator new(size_t) throw();
00177     static void  operator delete(void*,size_t);
00178   };
00179 
00183   template<class T>
00184   typename ArrayTraits<VarArray<T> >::ArgsType
00185   operator +(const VarArray<T>& x, const VarArgArray<T>& y);
00186 
00190   template<class T>
00191   typename ArrayTraits<VarArray<T> >::ArgsType
00192   operator +(const VarArray<T>& x, const VarArray<T>& y);
00193 
00197   template<class T>
00198   typename ArrayTraits<VarArray<T> >::ArgsType
00199   operator +(const VarArgArray<T>& x, const VarArray<T>& y);
00200 
00204   template<class T>
00205   typename ArrayTraits<VarArray<T> >::ArgsType
00206   operator +(const VarArray<T>& x, const T& y);
00207 
00211   template<class T>
00212   typename ArrayTraits<VarArray<T> >::ArgsType
00213   operator +(const T& x, const VarArray<T>& y);
00214 
00223   template<class View>
00224   class ViewArray {
00225   private:
00227     int  n;
00229     View* x;
00231     template<class X>
00232     class ViewLess {
00233     public:
00234       bool operator ()(const X&, const X&);
00235     };
00237     static void sort(View* x, int n);
00238   public:
00240 
00241 
00242     typedef View value_type;
00244     typedef View& reference;
00246     typedef const View& const_reference;
00248     typedef View* pointer;
00250     typedef const View* const_pointer;
00252     typedef View* iterator;
00254     typedef const View* const_iterator;
00256     typedef std::reverse_iterator<View*> reverse_iterator;
00258     typedef std::reverse_iterator<const View*> const_reverse_iterator;
00260 
00262 
00263 
00264     ViewArray(void);
00266     ViewArray(Space& home, int m);
00268     ViewArray(Region& r, int m);
00270     ViewArray(const ViewArray<View>& a);
00272     ViewArray(Space& home, const ViewArray<View>& a);
00274     ViewArray(Region& r, const ViewArray<View>& a);
00276     const ViewArray<View>& operator =(const ViewArray<View>& a);
00283     template<class Var>
00284     ViewArray(Space& home, const VarArgArray<Var>& a)
00285       : n(a.size()) {
00286       // This may not be in the hpp file (to satisfy the MS compiler)
00287       if (n>0) {
00288         x = home.alloc<View>(n);
00289         for (int i=n; i--; )
00290           x[i]=a[i];
00291       } else {
00292         x = NULL;
00293       }
00294     }
00301     template<class Var>
00302     ViewArray(Region& r, const VarArgArray<Var>& a)
00303       : n(a.size()) {
00304       // This may not be in the hpp file (to satisfy the MS compiler)
00305       if (n>0) {
00306         x = r.alloc<View>(n);
00307         for (int i=n; i--; )
00308           x[i]=a[i];
00309       } else {
00310         x = NULL;
00311       }
00312     }
00314 
00316 
00317 
00318     int size(void) const;
00320     void size(int n);
00322 
00324 
00325 
00326     View& operator [](int i);
00328     const View& operator [](int i) const;
00330 
00332 
00333 
00334     iterator begin(void);
00336     const_iterator begin(void) const;
00338     iterator end(void);
00340     const_iterator end(void) const;
00342     reverse_iterator rbegin(void);
00344     const_reverse_iterator rbegin(void) const;
00346     reverse_iterator rend(void);
00348     const_reverse_iterator rend(void) const;
00350 
00352 
00353 
00360     void subscribe(Space& home, Propagator& p, PropCond pc,
00361                    bool schedule=true);
00363     void cancel(Space& home, Propagator& p, PropCond pc);
00365     void subscribe(Space& home, Advisor& a);
00367     void cancel(Space& home, Advisor& a);
00369     void reschedule(Space& home, Propagator& p, PropCond pc);
00371 
00373 
00374 
00375     void update(Space& home, ViewArray<View>& a);
00377 
00378 
00380 
00381 
00382     void move_fst(int i);
00384     void move_lst(int i);
00390     void move_fst(int i, Space& home, Propagator& p, PropCond pc);
00396     void move_lst(int i, Space& home, Propagator& p, PropCond pc);
00402     void move_fst(int i, Space& home, Advisor& a);
00408     void move_lst(int i, Space& home, Advisor& a);
00410 
00412 
00413 
00414     void drop_fst(int i);
00416     void drop_lst(int i);
00422     void drop_fst(int i, Space& home, Propagator& p, PropCond pc);
00429     void drop_lst(int i, Space& home, Propagator& p, PropCond pc);
00435     void drop_fst(int i, Space& home, Advisor& a);
00441     void drop_lst(int i, Space& home, Advisor& a);
00443 
00445     bool assigned(void) const;
00446 
00448 
00449 
00454     bool same(void) const;
00460     bool same(const View& y) const;
00462     void unique(void);
00464 
00466 
00467 
00472     bool shared(void) const;
00478     template<class ViewY>
00479     bool shared(const ViewY& y) const;
00485     template<class ViewY>
00486     bool shared(const ViewArray<ViewY>& y) const;
00488 
00489   private:
00490     static void* operator new(size_t) throw();
00491     static void  operator delete(void*,size_t);
00492   };
00493 
00507   template<class T>
00508   class ArgArrayBase {
00509   protected:
00511     int n;
00513     int capacity;
00515     T*  a;
00517     static const int onstack_size = 16;
00519     T onstack[onstack_size];
00521     T* allocate(int n);
00523     void resize(int i);
00525     template<class A>
00526     A concat(const ArgArrayBase<T>& x) const;
00528     template<class A>
00529     A concat(const T& x) const;
00531     template<class A>
00532     A& append(const T& x);
00534     template<class A>
00535     A& append(const ArgArrayBase<T>& x);
00541     template<class A>
00542     A slice(int start, int inc=1, int n=-1);
00543   public:
00545 
00546 
00547     typedef T value_type;
00549     typedef T& reference;
00551     typedef const T& const_reference;
00553     typedef T* pointer;
00555     typedef const T* const_pointer;
00557     typedef T* iterator;
00559     typedef const T* const_iterator;
00561     typedef std::reverse_iterator<T*> reverse_iterator;
00563     typedef std::reverse_iterator<const T*> const_reverse_iterator;
00565 
00567 
00568 
00569     ArgArrayBase(void);
00571     explicit ArgArrayBase(int n);
00573     ArgArrayBase(const ArgArrayBase<T>& a);
00575     const ArgArrayBase<T>& operator =(const ArgArrayBase<T>& a);
00577     ArgArrayBase(const std::vector<T>& a);
00579     template<class InputIterator>
00580     ArgArrayBase(InputIterator first, InputIterator last);
00582 
00584 
00585 
00586     int size(void) const;
00588 
00590 
00591 
00592     T& operator [](int i);
00594     const T& operator [](int i) const;
00596 
00598 
00599 
00600     iterator begin(void);
00602     const_iterator begin(void) const;
00604     iterator end(void);
00606     const_iterator end(void) const;
00608     reverse_iterator rbegin(void);
00610     const_reverse_iterator rbegin(void) const;
00612     reverse_iterator rend(void);
00614     const_reverse_iterator rend(void) const;
00616 
00618 
00619 
00620     ~ArgArrayBase(void);
00622   };
00623 
00624   template<class> class PrimArgArray;
00625 
00629   template<class T>
00630   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00631   operator +(const PrimArgArray<T>& x, const PrimArgArray<T>& y);
00632 
00636   template<class T>
00637   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00638   operator +(const PrimArgArray<T>& x, const T& y);
00639 
00643   template<class T>
00644   typename ArrayTraits<PrimArgArray<T> >::ArgsType
00645   operator +(const T& x, const PrimArgArray<T>& y);
00646 
00658   template<class T>
00659   class PrimArgArray : public ArgArrayBase<T> {
00660   protected:
00661     using ArgArrayBase<T>::a;
00662   public:
00663     using ArgArrayBase<T>::size;
00665 
00666 
00667     PrimArgArray(void);
00669     explicit PrimArgArray(int n);
00671     PrimArgArray(int n, T e0, ...);
00673     PrimArgArray(int n, const T* e);
00675     PrimArgArray(const PrimArgArray<T>& a);
00677     PrimArgArray(const std::vector<T>& a);
00679     template<class InputIterator>
00680     PrimArgArray(InputIterator first, InputIterator last);
00682 
00683 
00684 
00689     typename ArrayTraits<PrimArgArray<T> >::ArgsType
00690     slice(int start, int inc=1, int n=-1);
00692 
00693 
00694 
00695     typename ArrayTraits<PrimArgArray<T> >::ArgsType&
00696     operator <<(const T& x);
00698     typename ArrayTraits<PrimArgArray<T> >::ArgsType&
00699     operator <<(const PrimArgArray<T>& x);
00701 
00702     friend typename ArrayTraits<PrimArgArray<T> >::ArgsType
00703     operator + <>(const PrimArgArray<T>& x, const PrimArgArray<T>& y);
00704     friend typename ArrayTraits<PrimArgArray<T> >::ArgsType
00705     operator + <>(const PrimArgArray<T>& x, const T& y);
00706     friend
00707     typename ArrayTraits<PrimArgArray<T> >::ArgsType
00708     operator + <>(const T& x, const PrimArgArray<T>& y);
00709   };
00710 
00711   template<class> class ArgArray;
00712 
00716   template<class T>
00717   typename ArrayTraits<ArgArray<T> >::ArgsType
00718   operator +(const ArgArray<T>& x, const ArgArray<T>& y);
00719 
00723   template<class T>
00724   typename ArrayTraits<ArgArray<T> >::ArgsType
00725   operator +(const ArgArray<T>& x, const T& y);
00726 
00730   template<class T>
00731   typename ArrayTraits<ArgArray<T> >::ArgsType
00732   operator +(const T& x, const ArgArray<T>& y);
00733 
00745   template<class T>
00746   class ArgArray : public ArgArrayBase<T> {
00747   protected:
00748     using ArgArrayBase<T>::a;
00749   public:
00750     using ArgArrayBase<T>::size;
00752 
00753 
00754     ArgArray(void);
00756     explicit ArgArray(int n);
00758     ArgArray(int n, const T* e);
00760     ArgArray(const ArgArray<T>& a);
00762     ArgArray(const std::vector<T>& a);
00764     template<class InputIterator>
00765     ArgArray(InputIterator first, InputIterator last);
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     VarArgArray(const std::vector<Var>& a);
00851     template<class InputIterator>
00852     VarArgArray(InputIterator first, InputIterator last);
00854 
00855 
00856 
00857     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00858     slice(int start, int inc=1, int n=-1);
00860 
00861 
00862 
00863     typename ArrayTraits<VarArgArray<Var> >::ArgsType&
00864     operator <<(const Var& x);
00866     typename ArrayTraits<VarArgArray<Var> >::ArgsType&
00867     operator <<(const VarArgArray<Var>& x);
00869 
00871     bool assigned(void) const;
00872 
00873     friend typename ArrayTraits<VarArgArray<Var> >::ArgsType
00874     operator + <>(const VarArgArray<Var>& x, const VarArgArray<Var>& y);
00875     friend typename ArrayTraits<VarArgArray<Var> >::ArgsType
00876     operator + <>(const VarArgArray<Var>& x, const Var& y);
00877     friend
00878     typename ArrayTraits<VarArgArray<Var> >::ArgsType
00879     operator + <>(const Var& x, const VarArgArray<Var>& y);
00880 
00882 
00883 
00888     bool same(void) const;
00894     bool same(const Var& y) const;
00900     bool same(const VarArgArray<Var>& y) const;
00902   };
00903 
00908   template<class Char, class Traits, class Var>
00909   std::basic_ostream<Char,Traits>&
00910   operator <<(std::basic_ostream<Char,Traits>& os,
00911              const VarArray<Var>& x);
00912 
00917   template<class Char, class Traits, class View>
00918   std::basic_ostream<Char,Traits>&
00919   operator <<(std::basic_ostream<Char,Traits>& os, const ViewArray<View>& x);
00920 
00925   template<class Char, class Traits, class T>
00926   std::basic_ostream<Char,Traits>&
00927   operator <<(std::basic_ostream<Char,Traits>& os, const ArgArrayBase<T>& x);
00928 
00929 
00930   /*
00931    * Implementation
00932    *
00933    */
00934 
00935   /*
00936    * Variable arrays
00937    *
00938    * These arrays are allocated in the space.
00939    *
00940    */
00941 
00942   template<class Var>
00943   forceinline
00944   VarArray<Var>::VarArray(void) : n(0), x(NULL) {}
00945 
00946   template<class Var>
00947   forceinline
00948   VarArray<Var>::VarArray(Space& home, int n0)
00949     : n(n0) {
00950     // Allocate from space
00951     x = (n>0) ? home.alloc<Var>(n) : NULL;
00952   }
00953 
00954   template<class Var>
00955   forceinline
00956   VarArray<Var>::VarArray(const VarArray<Var>& a) {
00957     n = a.n; x = a.x;
00958   }
00959 
00960   template<class Var>
00961   inline const VarArray<Var>&
00962   VarArray<Var>::operator =(const VarArray<Var>& a) {
00963     n = a.n; x = a.x;
00964     return *this;
00965   }
00966 
00967   template<class Var>
00968   forceinline int
00969   VarArray<Var>::size(void) const {
00970     return n;
00971   }
00972 
00973   template<class Var>
00974   forceinline Var&
00975   VarArray<Var>::operator [](int i) {
00976     assert((i >= 0) && (i < size()));
00977     return x[i];
00978   }
00979 
00980   template<class Var>
00981   forceinline const Var&
00982   VarArray<Var>::operator [](int i) const {
00983     assert((i >= 0) && (i < size()));
00984     return x[i];
00985   }
00986 
00987   template<class Var>
00988   typename ArrayTraits<VarArgArray<Var> >::ArgsType
00989   VarArray<Var>::slice(int start, int inc, int maxN) {
00990     assert(n==0 || start < n);
00991     if (n==0 || maxN<0)
00992       maxN = n;
00993     int s;
00994     if (inc == 0)
00995       s = n-start;
00996     else if (inc > 0)
00997       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
00998     else
00999       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
01000     typename ArrayTraits<VarArgArray<Var> >::ArgsType r(std::min(maxN,s));
01001     for (int i=0; i<r.size(); i++, start+=inc)
01002       r[i] = x[start];
01003     return r;
01004   }
01005 
01006   template<class Var>
01007   forceinline typename VarArray<Var>::iterator
01008   VarArray<Var>::begin(void) {
01009     return x;
01010   }
01011 
01012   template<class Var>
01013   forceinline typename VarArray<Var>::const_iterator
01014   VarArray<Var>::begin(void) const {
01015     return x;
01016   }
01017 
01018   template<class Var>
01019   forceinline typename VarArray<Var>::iterator
01020   VarArray<Var>::end(void) {
01021     return x+n;
01022   }
01023 
01024   template<class Var>
01025   forceinline typename VarArray<Var>::const_iterator
01026   VarArray<Var>::end(void) const {
01027     return x+n;
01028   }
01029 
01030   template<class Var>
01031   forceinline typename VarArray<Var>::reverse_iterator
01032   VarArray<Var>::rbegin(void) {
01033     return reverse_iterator(x+n);
01034   }
01035 
01036   template<class Var>
01037   forceinline typename VarArray<Var>::const_reverse_iterator
01038   VarArray<Var>::rbegin(void) const {
01039     return const_reverse_iterator(x+n);
01040   }
01041 
01042   template<class Var>
01043   forceinline typename VarArray<Var>::reverse_iterator
01044   VarArray<Var>::rend(void) {
01045     return reverse_iterator(x);
01046   }
01047 
01048   template<class Var>
01049   forceinline typename VarArray<Var>::const_reverse_iterator
01050   VarArray<Var>::rend(void) const {
01051     return const_reverse_iterator(x);
01052   }
01053 
01054   template<class Var>
01055   forceinline void
01056   VarArray<Var>::update(Space& home, VarArray<Var>& a) {
01057     n = a.n;
01058     if (n > 0) {
01059       x = home.alloc<Var>(n);
01060       for (int i = n; i--;)
01061         x[i].update(home, a.x[i]);
01062     } else {
01063       x = NULL;
01064     }
01065   }
01066 
01067   template<class Var>
01068   forceinline bool
01069   VarArray<Var>::assigned(void) const {
01070     for (int i = n; i--;)
01071       if (!x[i].assigned())
01072         return false;
01073     return true;
01074   }
01075 
01076   template<class Var>
01077   forceinline void*
01078   VarArray<Var>::operator new(size_t) throw() {
01079     return NULL;
01080   }
01081 
01082   template<class Var>
01083   forceinline void
01084   VarArray<Var>::operator delete(void*,size_t) {
01085   }
01086 
01087   template<class Var>
01088   typename ArrayTraits<VarArray<Var> >::ArgsType
01089   operator +(const VarArray<Var>& x, const VarArray<Var>& y) {
01090     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01091     for (int i=x.size(); i--;)
01092       r[i] = x[i];
01093     for (int i=y.size(); i--;)
01094       r[x.size()+i] = y[i];
01095     return r;
01096   }
01097 
01098   template<class Var>
01099   typename ArrayTraits<VarArray<Var> >::ArgsType
01100   operator +(const VarArray<Var>& x, const VarArgArray<Var>& y) {
01101     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01102     for (int i=x.size(); i--;)
01103       r[i] = x[i];
01104     for (int i=y.size(); i--;)
01105       r[x.size()+i] = y[i];
01106     return r;
01107   }
01108 
01109   template<class Var>
01110   typename ArrayTraits<VarArray<Var> >::ArgsType
01111   operator +(const VarArgArray<Var>& x, const VarArray<Var>& y) {
01112     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+y.size());
01113     for (int i=x.size(); i--;)
01114       r[i] = x[i];
01115     for (int i=y.size(); i--;)
01116       r[x.size()+i] = y[i];
01117     return r;
01118   }
01119 
01120   template<class Var>
01121   typename ArrayTraits<VarArray<Var> >::ArgsType
01122   operator +(const VarArray<Var>& x, const Var& y) {
01123     typename ArrayTraits<VarArray<Var> >::ArgsType r(x.size()+1);
01124     for (int i=x.size(); i--;)
01125       r[i] = x[i];
01126     r[x.size()] = y;
01127     return r;
01128   }
01129 
01130   template<class Var>
01131   typename ArrayTraits<VarArray<Var> >::ArgsType
01132   operator +(const Var& x, const VarArray<Var>& y) {
01133     typename ArrayTraits<VarArray<Var> >::ArgsType r(y.size()+1);
01134     r[0] = x;
01135     for (int i=y.size(); i--;)
01136       r[1+i] = y[i];
01137     return r;
01138   }
01139 
01140   /*
01141    * View arrays
01142    *
01143    */
01144 
01145   template<class View>
01146   forceinline
01147   ViewArray<View>::ViewArray(void) : n(0), x(NULL) {}
01148 
01149   template<class View>
01150   forceinline
01151   ViewArray<View>::ViewArray(Space& home, int n0)
01152     : n(n0) {
01153     x = (n>0) ? home.alloc<View>(n) : NULL;
01154   }
01155   template<class View>
01156   forceinline
01157   ViewArray<View>::ViewArray(Region& r, int n0)
01158     : n(n0) {
01159     x = (n>0) ? r.alloc<View>(n) : NULL;
01160   }
01161 
01162   template<class View>
01163   ViewArray<View>::ViewArray(Space& home, const ViewArray<View>& a)
01164     : n(a.size()) {
01165     if (n>0) {
01166       x = home.alloc<View>(n);
01167       for (int i = n; i--; )
01168         x[i] = a[i];
01169     } else {
01170       x = NULL;
01171     }
01172   }
01173   template<class View>
01174   ViewArray<View>::ViewArray(Region& r, const ViewArray<View>& a)
01175     : n(a.size()) {
01176     if (n>0) {
01177       x = r.alloc<View>(n);
01178       for (int i = n; i--; )
01179         x[i] = a[i];
01180     } else {
01181       x = NULL;
01182     }
01183   }
01184 
01185   template<class View>
01186   forceinline
01187   ViewArray<View>::ViewArray(const ViewArray<View>& a)
01188     : n(a.n), x(a.x) {}
01189 
01190   template<class View>
01191   forceinline const ViewArray<View>&
01192   ViewArray<View>::operator =(const ViewArray<View>& a) {
01193     n = a.n; x = a.x;
01194     return *this;
01195   }
01196 
01197   template<class View>
01198   forceinline int
01199   ViewArray<View>::size(void) const {
01200     return n;
01201   }
01202 
01203   template<class View>
01204   forceinline void
01205   ViewArray<View>::size(int n0) {
01206     n = n0;
01207   }
01208 
01209   template<class View>
01210   forceinline View&
01211   ViewArray<View>::operator [](int i) {
01212     assert((i >= 0) && (i < size()));
01213     return x[i];
01214   }
01215 
01216   template<class View>
01217   forceinline const View&
01218   ViewArray<View>::operator [](int i) const {
01219     assert((i >= 0) && (i < size()));
01220     return x[i];
01221   }
01222 
01223   template<class View>
01224   forceinline typename ViewArray<View>::iterator
01225   ViewArray<View>::begin(void) {
01226     return x;
01227   }
01228 
01229   template<class View>
01230   forceinline typename ViewArray<View>::const_iterator
01231   ViewArray<View>::begin(void) const {
01232     return x;
01233   }
01234 
01235   template<class View>
01236   forceinline typename ViewArray<View>::iterator
01237   ViewArray<View>::end(void) {
01238     return x+n;
01239   }
01240 
01241   template<class View>
01242   forceinline typename ViewArray<View>::const_iterator
01243   ViewArray<View>::end(void) const {
01244     return x+n;
01245   }
01246 
01247   template<class View>
01248   forceinline typename ViewArray<View>::reverse_iterator
01249   ViewArray<View>::rbegin(void) {
01250     return reverse_iterator(x+n);
01251   }
01252 
01253   template<class View>
01254   forceinline typename ViewArray<View>::const_reverse_iterator
01255   ViewArray<View>::rbegin(void) const {
01256     return const_reverse_iterator(x+n);
01257   }
01258 
01259   template<class View>
01260   forceinline typename ViewArray<View>::reverse_iterator
01261   ViewArray<View>::rend(void) {
01262     return reverse_iterator(x);
01263   }
01264 
01265   template<class View>
01266   forceinline typename ViewArray<View>::const_reverse_iterator
01267   ViewArray<View>::rend(void) const {
01268     return const_reverse_iterator(x);
01269   }
01270 
01271   template<class View>
01272   forceinline void
01273   ViewArray<View>::move_fst(int i) {
01274     x[i]=x[0]; x++; n--;
01275   }
01276 
01277   template<class View>
01278   forceinline void
01279   ViewArray<View>::move_lst(int i) {
01280     n--; x[i]=x[n];
01281   }
01282 
01283   template<class View>
01284   forceinline void
01285   ViewArray<View>::drop_fst(int i) {
01286     assert(i>=0);
01287     x += i; n -= i;
01288   }
01289 
01290   template<class View>
01291   forceinline void
01292   ViewArray<View>::drop_lst(int i) {
01293     assert(i<n);
01294     n = i+1;
01295   }
01296 
01297   template<class View>
01298   forceinline void
01299   ViewArray<View>::move_fst(int i, Space& home, Propagator& p, PropCond pc) {
01300     // Move x[0] to x[i]
01301     x[i].cancel(home,p,pc);
01302     x[i]=x[0]; x++; n--;
01303   }
01304 
01305   template<class View>
01306   forceinline void
01307   ViewArray<View>::move_lst(int i, Space& home, Propagator& p, PropCond pc) {
01308     // Move x[n-1] to x[i]
01309     x[i].cancel(home,p,pc);
01310     n--; x[i]=x[n];
01311   }
01312 
01313   template<class View>
01314   void
01315   ViewArray<View>::drop_fst(int i, Space& home, Propagator& p, PropCond pc) {
01316     // Drop elements from 0..i-1
01317     assert(i>=0);
01318     for (int j=i; j--; )
01319       x[j].cancel(home,p,pc);
01320     x += i; n -= i;
01321   }
01322 
01323   template<class View>
01324   void
01325   ViewArray<View>::drop_lst(int i, Space& home, Propagator& p, PropCond pc) {
01326     // Drop elements from i+1..n-1
01327     assert(i<n);
01328     for (int j=i+1; j<n; j++)
01329       x[j].cancel(home,p,pc);
01330     n = i+1;
01331   }
01332 
01333   template<class View>
01334   forceinline void
01335   ViewArray<View>::move_fst(int i, Space& home, Advisor& a) {
01336     // Move x[0] to x[i]
01337     x[i].cancel(home,a);
01338     x[i]=x[0]; x++; n--;
01339   }
01340 
01341   template<class View>
01342   forceinline void
01343   ViewArray<View>::move_lst(int i, Space& home, Advisor& a) {
01344     // Move x[n-1] to x[i]
01345     x[i].cancel(home,a);
01346     n--; x[i]=x[n];
01347   }
01348 
01349   template<class View>
01350   void
01351   ViewArray<View>::drop_fst(int i, Space& home, Advisor& a) {
01352     // Drop elements from 0..i-1
01353     assert(i>=0);
01354     for (int j=i; j--; )
01355       x[j].cancel(home,a);
01356     x += i; n -= i;
01357   }
01358 
01359   template<class View>
01360   void
01361   ViewArray<View>::drop_lst(int i, Space& home, Advisor& a) {
01362     // Drop elements from i+1..n-1
01363     assert(i<n);
01364     for (int j=i+1; j<n; j++)
01365       x[j].cancel(home,a);
01366     n = i+1;
01367   }
01368 
01369   template<class View>
01370   void
01371   ViewArray<View>::update(Space& home, ViewArray<View>& y) {
01372     n = y.n;
01373     if (n > 0) {
01374       x = home.alloc<View>(n);
01375       for (int i = n; i--; )
01376         x[i].update(home, y.x[i]);
01377     } else {
01378       x = NULL;
01379     }
01380   }
01381 
01382   template<class View>
01383   void
01384   ViewArray<View>::subscribe(Space& home, Propagator& p, PropCond pc,
01385                              bool schedule) {
01386     for (int i = n; i--; )
01387       x[i].subscribe(home,p,pc,schedule);
01388   }
01389 
01390   template<class View>
01391   void
01392   ViewArray<View>::cancel(Space& home, Propagator& p, PropCond pc) {
01393     for (int i = n; i--; )
01394       x[i].cancel(home,p,pc);
01395   }
01396 
01397   template<class View>
01398   void
01399   ViewArray<View>::subscribe(Space& home, Advisor& a) {
01400     for (int i = n; i--; )
01401       x[i].subscribe(home,a);
01402   }
01403 
01404   template<class View>
01405   void
01406   ViewArray<View>::cancel(Space& home, Advisor& a) {
01407     for (int i = n; i--; )
01408       x[i].cancel(home,a);
01409   }
01410 
01411   template<class View>
01412   void
01413   ViewArray<View>::reschedule(Space& home, Propagator& p, PropCond pc) {
01414     for (int i = n; i--; )
01415       x[i].reschedule(home,p,pc);
01416   }
01417 
01418   template<class View>
01419   forceinline bool
01420   ViewArray<View>::assigned(void) const {
01421     for (int i = n; i--;)
01422       if (!x[i].assigned())
01423         return false;
01424     return true;
01425   }
01426 
01427   template<class View>
01428   forceinline bool
01429   __before(const View& x, const View& y) {
01430     return before(x,y);
01431   }
01432 
01433   template<class View> template<class X>
01434   forceinline bool
01435   ViewArray<View>::ViewLess<X>::operator ()(const X& a, const X& b) {
01436     return __before(a,b);
01437   }
01438 
01439   template<class View>
01440   void
01441   ViewArray<View>::sort(View* y, int m) {
01442     ViewLess<View> vl;
01443     Support::quicksort<View,ViewLess<View> >(y,m,vl);
01444   }
01445 
01446   template<class X, class Y>
01447   forceinline bool
01448   __same(const X& x, const Y& y) {
01449     return same(x,y);
01450   }
01451   template<class X, class Y>
01452   forceinline bool
01453   __shared(const X& x, const Y& y) {
01454     return shared(x,y);
01455   }
01456 
01457   template<class View>
01458   bool
01459   ViewArray<View>::same(void) const {
01460     if (n < 2)
01461       return false;
01462     Region r;
01463     View* y = r.alloc<View>(n);
01464     for (int i = n; i--; )
01465       y[i] = x[i];
01466     sort(y,n);
01467     for (int i = n-1; i--; )
01468       if (!y[i].assigned() && __same(y[i+1],y[i])) {
01469         r.free<View>(y,n);
01470         return true;
01471       }
01472     r.free<View>(y,n);
01473     return false;
01474   }
01475 
01476   template<class View>
01477   bool
01478   ViewArray<View>::same(const View& y) const {
01479     if (y.assigned())
01480       return false;
01481     for (int i = n; i--; )
01482       if (__same(x[i],y))
01483         return true;
01484     return false;
01485   }
01486 
01487   template<class View>
01488   void
01489   ViewArray<View>::unique(void) {
01490     if (n < 2)
01491       return;
01492     sort(x,n);
01493     int j = 0;
01494     for (int i = 1; i<n; i++)
01495       if (!__same(x[j],x[i]))
01496         x[++j] = x[i];
01497     n = j+1;
01498   }
01499 
01500   template<class View>
01501   bool
01502   ViewArray<View>::shared(void) const {
01503     if (n < 2)
01504       return false;
01505     Region r;
01506     View* y = r.alloc<View>(n);
01507     for (int i = n; i--; )
01508       y[i] = x[i];
01509     sort(y,n);
01510     for (int i = n-1; i--; )
01511       if (!y[i].assigned() && __shared(y[i+1],y[i])) {
01512         r.free<View>(y,n);
01513         return true;
01514       }
01515     r.free<View>(y,n);
01516     return false;
01517   }
01518 
01519   template<class View> template<class ViewY>
01520   bool
01521   ViewArray<View>::shared(const ViewY& y) const {
01522     if (y.assigned())
01523       return false;
01524     for (int i = n; i--; )
01525       if (!x[i].assigned() && __shared(x[i],y))
01526         return true;
01527     return false;
01528   }
01529 
01530   template<class View> template<class ViewY>
01531   bool
01532   ViewArray<View>::shared(const ViewArray<ViewY>& y) const {
01533     if ((size() < 1) || (y.size() < 1))
01534       return false;
01535     Region r;
01536     View* xs = r.alloc<View>(size());
01537     for (int i=size(); i--; )
01538       xs[i] = x[i];
01539     ViewLess<View> xvl;
01540     Support::quicksort<View,ViewLess<View> >(xs,size(),xvl);
01541     ViewY* ys = r.alloc<ViewY>(y.size());
01542     for (int j=y.size(); j--; )
01543       ys[j] = y[j];
01544     ViewLess<ViewY> yvl;
01545     Support::quicksort<ViewY,ViewLess<ViewY> >(ys,y.size(),yvl);
01546     {
01547       int i=0, j=0;
01548       while ((i < size()) && (j < y.size()))
01549         if (!x[i].assigned() && __shared(x[i],y[j])) {
01550           r.free<View>(xs,size());
01551           r.free<ViewY>(ys,y.size());
01552           return true;
01553         } else if (before(x[i],y[j])) {
01554           i++;
01555         } else {
01556           j++;
01557         }
01558     }
01559     r.free<View>(xs,size());
01560     r.free<ViewY>(ys,y.size());
01561     return false;
01562   }
01563 
01564   template<class View>
01565   forceinline void*
01566   ViewArray<View>::operator new(size_t) throw() {
01567     return NULL;
01568   }
01569 
01570   template<class View>
01571   forceinline void
01572   ViewArray<View>::operator delete(void*,size_t) {
01573   }
01574 
01575 
01576   /*
01577    * Argument arrays: base class
01578    *
01579    */
01580 
01581   template<class T>
01582   forceinline T*
01583   ArgArrayBase<T>::allocate(int n) {
01584     return (n > onstack_size) ?
01585       heap.alloc<T>(static_cast<unsigned int>(n)) : &onstack[0];
01586   }
01587 
01588   template<class T>
01589   forceinline void
01590   ArgArrayBase<T>::resize(int i) {
01591     if (n+i >= capacity) {
01592       assert(n+i >= onstack_size);
01593       int newCapacity = (3*capacity)/2;
01594       if (newCapacity <= n+i)
01595         newCapacity = n+i;
01596       T* newA = allocate(newCapacity);
01597       heap.copy<T>(newA,a,n);
01598       if (capacity > onstack_size)
01599         heap.free(a,capacity);
01600       capacity = newCapacity;
01601       a = newA;
01602     }
01603   }
01604 
01605   template<class T>
01606   forceinline
01607   ArgArrayBase<T>::ArgArrayBase(void)
01608     : n(0), capacity(onstack_size), a(allocate(0)) {}
01609 
01610   template<class T>
01611   forceinline
01612   ArgArrayBase<T>::ArgArrayBase(int n0)
01613     : n(n0), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {}
01614 
01615   template<class T>
01616   inline
01617   ArgArrayBase<T>::ArgArrayBase(const ArgArrayBase<T>& aa)
01618     : n(aa.n), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01619     heap.copy<T>(a,aa.a,n);
01620   }
01621 
01622   template<class T>
01623   inline
01624   ArgArrayBase<T>::ArgArrayBase(const std::vector<T>& aa)
01625     : n(static_cast<int>(aa.size())),
01626       capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01627     heap.copy<T>(a,&aa[0],n);
01628   }
01629 
01630   template<class T>
01631   forceinline
01632   ArgArrayBase<T>::~ArgArrayBase(void) {
01633     if (capacity > onstack_size)
01634       heap.free(a,capacity);
01635   }
01636 
01637   template<class T>
01638   forceinline const ArgArrayBase<T>&
01639   ArgArrayBase<T>::operator =(const ArgArrayBase<T>& aa) {
01640     if (&aa != this) {
01641       if (capacity > onstack_size)
01642         heap.free(a,capacity);
01643       n = aa.n;
01644       capacity = (n < onstack_size ? onstack_size : n);
01645       a = allocate(aa.n);
01646       heap.copy<T>(a,aa.a,n);
01647     }
01648     return *this;
01649   }
01650 
01651   template<class T>
01652   forceinline int
01653   ArgArrayBase<T>::size(void) const {
01654     return n;
01655   }
01656 
01657   template<class T>
01658   forceinline T&
01659   ArgArrayBase<T>::operator [](int i) {
01660     assert((i>=0) && (i < n));
01661     return a[i];
01662   }
01663 
01664   template<class T>
01665   forceinline const T&
01666   ArgArrayBase<T>::operator [](int i) const {
01667     assert((i>=0) && (i < n));
01668     return a[i];
01669   }
01670 
01671   template<class T>
01672   forceinline typename ArgArrayBase<T>::iterator
01673   ArgArrayBase<T>::begin(void) {
01674     return a;
01675   }
01676 
01677   template<class T>
01678   forceinline typename ArgArrayBase<T>::const_iterator
01679   ArgArrayBase<T>::begin(void) const {
01680     return a;
01681   }
01682 
01683   template<class T>
01684   forceinline typename ArgArrayBase<T>::iterator
01685   ArgArrayBase<T>::end(void) {
01686     return a+n;
01687   }
01688 
01689   template<class T>
01690   forceinline typename ArgArrayBase<T>::const_iterator
01691   ArgArrayBase<T>::end(void) const {
01692     return a+n;
01693   }
01694 
01695   template<class T>
01696   forceinline typename ArgArrayBase<T>::reverse_iterator
01697   ArgArrayBase<T>::rbegin(void) {
01698     return reverse_iterator(a+n);
01699   }
01700 
01701   template<class T>
01702   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01703   ArgArrayBase<T>::rbegin(void) const {
01704     return const_reverse_iterator(a+n);
01705   }
01706 
01707   template<class T>
01708   forceinline typename ArgArrayBase<T>::reverse_iterator
01709   ArgArrayBase<T>::rend(void) {
01710     return reverse_iterator(a);
01711   }
01712 
01713   template<class T>
01714   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01715   ArgArrayBase<T>::rend(void) const {
01716     return const_reverse_iterator(a);
01717   }
01718 
01719   template<class T> template<class A>
01720   A
01721   ArgArrayBase<T>::slice(int start, int inc, int maxN) {
01722     assert(n==0 || start < n);
01723     if (n==0 || maxN<0)
01724       maxN = n;
01725     int s;
01726     if (inc == 0)
01727       s = n-start;
01728     else if (inc > 0)
01729       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
01730     else
01731       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
01732     A r(std::min(maxN,s));
01733     for (int i=0; i<r.size(); i++, start+=inc)
01734       new (&r[i]) T(a[start]);
01735     return r;
01736   }
01737 
01738   template<class T> template<class A>
01739   inline A&
01740   ArgArrayBase<T>::append(const T& x) {
01741     resize(1);
01742     new (&a[n++]) T(x);
01743     return static_cast<A&>(*this);
01744   }
01745 
01746   template<class T>
01747   template<class InputIterator>
01748   inline
01749   ArgArrayBase<T>::ArgArrayBase(InputIterator first, InputIterator last)
01750   : n(0), capacity(onstack_size), a(allocate(0)) {
01751     while (first != last) {
01752       (void) append<ArgArrayBase<T> >(*first);
01753       ++first;
01754     }
01755   }
01756 
01757 
01758   template<class T> template<class A>
01759   inline A&
01760   ArgArrayBase<T>::append(const ArgArrayBase<T>& x) {
01761     resize(x.size());
01762     for (int i=0; i<x.size(); i++)
01763       new (&a[n++]) T(x[i]);
01764     return static_cast<A&>(*this);
01765   }
01766 
01767   template<class T> template<class A>
01768   inline A
01769   ArgArrayBase<T>::concat(const ArgArrayBase<T>& x) const {
01770     A r(n+x.n);
01771     for (int i=n; i--;)
01772       new (&r[i]) T(a[i]);
01773     for (int i=x.n; i--;)
01774       new (&r[n+i]) T(x.a[i]);
01775     return r;
01776   }
01777 
01778   template<class T> template<class A>
01779   inline A
01780   ArgArrayBase<T>::concat(const T& x) const {
01781     A r(n+1);
01782     for (int i=n; i--;)
01783       new (&r[i]) T(a[i]);
01784     new (&r[n]) T(x);
01785     return r;
01786   }
01787 
01788   /*
01789    * Argument arrays for primitive types
01790    *
01791    */
01792 
01793   template<class T>
01794   forceinline
01795   PrimArgArray<T>::PrimArgArray(void) {}
01796 
01797   template<class T>
01798   forceinline
01799   PrimArgArray<T>::PrimArgArray(int n) : ArgArrayBase<T>(n) {}
01800 
01801   template<class T>
01802   PrimArgArray<T>::PrimArgArray(int n, T a0, ...)
01803     : ArgArrayBase<T>(n) {
01804     va_list args;
01805     va_start(args, a0);
01806     a[0] = a0;
01807     for (int i = 1; i < n; i++)
01808       a[i] = va_arg(args,T);
01809     va_end(args);
01810   }
01811 
01812   template<class T>
01813   PrimArgArray<T>::PrimArgArray(int n, const T* a0)
01814     : ArgArrayBase<T>(n) {
01815     for (int i=n; i--; )
01816       a[i] = a0[i];
01817   }
01818 
01819   template<class T>
01820   forceinline
01821   PrimArgArray<T>::PrimArgArray(const PrimArgArray<T>& aa)
01822     : ArgArrayBase<T>(aa) {}
01823 
01824   template<class T>
01825   forceinline
01826   PrimArgArray<T>::PrimArgArray(const std::vector<T>& aa)
01827     : ArgArrayBase<T>(aa) {}
01828 
01829   template<class T>
01830   template<class InputIterator>
01831   forceinline
01832   PrimArgArray<T>::PrimArgArray(InputIterator first, InputIterator last)
01833     : ArgArrayBase<T>(first,last) {}
01834 
01835   template<class T>
01836   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType
01837   PrimArgArray<T>::slice(int start, int inc, int maxN) {
01838     return ArgArrayBase<T>::template slice
01839       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>
01840         (start,inc,maxN);
01841   }
01842 
01843   template<class T>
01844   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType&
01845   PrimArgArray<T>::operator <<(const T& x) {
01846     return
01847       ArgArrayBase<T>::template append
01848         <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(x);
01849   }
01850 
01851   template<class T>
01852   forceinline typename ArrayTraits<PrimArgArray<T> >::ArgsType&
01853   PrimArgArray<T>::operator <<(const PrimArgArray<T>& x) {
01854     return
01855       ArgArrayBase<T>::template append
01856         <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(x);
01857   }
01858 
01859   template<class T>
01860   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01861   operator +(const PrimArgArray<T>& x, const PrimArgArray<T>& y) {
01862     return x.template concat
01863       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);
01864   }
01865 
01866   template<class T>
01867   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01868   operator +(const PrimArgArray<T>& x, const T& y) {
01869     return x.template concat
01870       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);
01871   }
01872 
01873   template<class T>
01874   typename ArrayTraits<PrimArgArray<T> >::ArgsType
01875   operator +(const T& x, const PrimArgArray<T>& y) {
01876     return PrimArgArray<T>(1,x).template concat
01877       <typename ArrayTraits<PrimArgArray<T> >::ArgsType>(y);
01878   }
01879 
01880 
01881   /*
01882    * Argument arrays for non-primitive types
01883    *
01884    */
01885 
01886   template<class T>
01887   forceinline
01888   ArgArray<T>::ArgArray(void) {}
01889 
01890   template<class T>
01891   forceinline
01892   ArgArray<T>::ArgArray(int n) : ArgArrayBase<T>(n) {}
01893 
01894   template<class T>
01895   ArgArray<T>::ArgArray(int n, const T* a0)
01896     : ArgArrayBase<T>(n) {
01897     for (int i=n; i--; )
01898       a[i] = a0[i];
01899   }
01900 
01901   template<class T>
01902   forceinline
01903   ArgArray<T>::ArgArray(const ArgArray<T>& aa)
01904     : ArgArrayBase<T>(aa) {}
01905 
01906   template<class T>
01907   forceinline
01908   ArgArray<T>::ArgArray(const std::vector<T>& aa)
01909     : ArgArrayBase<T>(aa) {}
01910 
01911   template<class T>
01912   template<class InputIterator>
01913   forceinline
01914   ArgArray<T>::ArgArray(InputIterator first, InputIterator last)
01915     : ArgArrayBase<T>(first,last) {}
01916 
01917   template<class T>
01918   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType
01919   ArgArray<T>::slice(int start, int inc, int maxN) {
01920     return ArgArrayBase<T>::template slice
01921       <typename ArrayTraits<ArgArray<T> >::ArgsType>
01922       (start,inc,maxN);
01923   }
01924 
01925   template<class T>
01926   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType&
01927   ArgArray<T>::operator <<(const T& x) {
01928     return
01929       ArgArrayBase<T>::template append
01930         <typename ArrayTraits<ArgArray<T> >::ArgsType>(x);
01931   }
01932 
01933   template<class T>
01934   forceinline typename ArrayTraits<ArgArray<T> >::ArgsType&
01935   ArgArray<T>::operator <<(const ArgArray<T>& x) {
01936     return
01937       ArgArrayBase<T>::template append
01938         <typename ArrayTraits<ArgArray<T> >::ArgsType>(x);
01939   }
01940 
01941   template<class T>
01942   typename ArrayTraits<ArgArray<T> >::ArgsType
01943   operator +(const ArgArray<T>& x, const ArgArray<T>& y) {
01944     return x.template concat
01945       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);
01946   }
01947 
01948   template<class T>
01949   typename ArrayTraits<ArgArray<T> >::ArgsType
01950   operator +(const ArgArray<T>& x, const T& y) {
01951     return x.template concat
01952       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);
01953   }
01954 
01955   template<class T>
01956   typename ArrayTraits<ArgArray<T> >::ArgsType
01957   operator +(const T& x, const ArgArray<T>& y) {
01958     ArgArray<T> xa(1);
01959     xa[0] = x;
01960     return xa.template concat
01961       <typename ArrayTraits<ArgArray<T> >::ArgsType>(y);
01962   }
01963 
01964   /*
01965    * Argument arrays for variables
01966    *
01967    */
01968 
01969   template<class Var>
01970   forceinline
01971   VarArgArray<Var>::VarArgArray(void) {}
01972 
01973   template<class Var>
01974   forceinline
01975   VarArgArray<Var>::VarArgArray(int n) : ArgArrayBase<Var>(n) {}
01976 
01977   template<class Var>
01978   forceinline
01979   VarArgArray<Var>::VarArgArray(const VarArgArray<Var>& aa)
01980     : ArgArrayBase<Var>(aa) {}
01981 
01982   template<class Var>
01983   forceinline
01984   VarArgArray<Var>::VarArgArray(const std::vector<Var>& aa)
01985     : ArgArrayBase<Var>(aa) {}
01986 
01987   template<class Var>
01988   template<class InputIterator>
01989   forceinline
01990   VarArgArray<Var>::VarArgArray(InputIterator first, InputIterator last)
01991     : ArgArrayBase<Var>(first,last) {}
01992 
01993   template<class Var>
01994   inline
01995   VarArgArray<Var>::VarArgArray(const VarArray<Var>& x)
01996     : ArgArrayBase<Var>(x.size()) {
01997     for (int i=x.size(); i--; )
01998       a[i]=x[i];
01999   }
02000 
02001   template<class Var>
02002   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType
02003   VarArgArray<Var>::slice(int start, int inc, int maxN) {
02004     return ArgArrayBase<Var>::template slice
02005       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>
02006         (start,inc,maxN);
02007   }
02008 
02009   template<class Var>
02010   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType&
02011   VarArgArray<Var>::operator <<(const Var& x) {
02012     return
02013       ArgArrayBase<Var>::template append
02014         <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(x);
02015   }
02016 
02017   template<class Var>
02018   forceinline typename ArrayTraits<VarArgArray<Var> >::ArgsType&
02019   VarArgArray<Var>::operator <<(const VarArgArray<Var>& x) {
02020     return
02021       ArgArrayBase<Var>::template append
02022         <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(x);
02023   }
02024 
02025   template<class Var>
02026   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02027   operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y) {
02028     return x.template concat
02029       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);
02030   }
02031 
02032   template<class Var>
02033   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02034   operator +(const VarArgArray<Var>& x, const Var& y) {
02035     return x.template concat
02036       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);
02037   }
02038 
02039   template<class Var>
02040   typename ArrayTraits<VarArgArray<Var> >::ArgsType
02041   operator +(const Var& x, const VarArgArray<Var>& y) {
02042     VarArgArray<Var> xa(1);
02043     xa[0] = x;
02044     return xa.template concat
02045       <typename ArrayTraits<VarArgArray<Var> >::ArgsType>(y);
02046   }
02047 
02048   template<class Var>
02049   forceinline bool
02050   VarArgArray<Var>::VarLess::operator ()(const Var& a, const Var& b) {
02051     return a.varimp() < b.varimp();
02052   }
02053 
02054   template<class Var>
02055   forceinline bool
02056   VarArgArray<Var>::assigned(void) const {
02057     for (int i = n; i--;)
02058       if (!a[i].assigned())
02059         return false;
02060     return true;
02061   }
02062 
02063   template<class Var>
02064   bool
02065   VarArgArray<Var>::same(void) const {
02066     if (n < 2)
02067       return false;
02068     Region r;
02069     Var* y = r.alloc<Var>(n);
02070     for (int i = n; i--; )
02071       y[i] = a[i];
02072     VarLess vl;
02073     Support::quicksort<Var,VarLess>(y,n,vl);
02074     for (int i = n-1; i--; )
02075       if (!y[i].assigned() && (y[i+1].varimp() == y[i].varimp())) {
02076         r.free<Var>(y,n);
02077         return true;
02078       }
02079     r.free<Var>(y,n);
02080     return false;
02081   }
02082 
02083   template<class Var>
02084   bool
02085   VarArgArray<Var>::same(const VarArgArray<Var>& y) const {
02086     int m = n + y.n;
02087     if (m < 2)
02088       return false;
02089     Region r;
02090     Var* z = r.alloc<Var>(m);
02091     for (int i = n; i--; )
02092       z[i] = a[i];
02093     for (int i = y.n; i--; )
02094       z[i+n] = y.a[i];
02095     VarLess vl;
02096     Support::quicksort<Var,VarLess>(z,m,vl);
02097     for (int i = m-1; i--; )
02098       if (!z[i].assigned() && (z[i+1].varimp() == z[i].varimp())) {
02099         r.free<Var>(z,m);
02100         return true;
02101       }
02102     r.free<Var>(z,m);
02103     return false;
02104   }
02105 
02106   template<class Var>
02107   bool
02108   VarArgArray<Var>::same(const Var& y) const {
02109     if (y.assigned())
02110       return false;
02111     for (int i = n; i--; )
02112       if (a[i].varimp() == y.varimp())
02113         return true;
02114     return false;
02115   }
02116 
02117 
02118 
02119 
02120 
02121 
02122   /*
02123    * Interdependent code
02124    *
02125    */
02126 
02127   template<class Var>
02128   inline
02129   VarArray<Var>::VarArray(Space& home, const VarArgArray<Var>& a)
02130     : n(a.size()) {
02131     if (n>0) {
02132       x = home.alloc<Var>(n);
02133       for (int i=n; i--;)
02134         x[i] = a[i];
02135     } else {
02136       x = NULL;
02137     }
02138   }
02139 
02140 
02141   /*
02142    * Printing of arrays
02143    *
02144    */
02145   template<class Char, class Traits, class Var>
02146   std::basic_ostream<Char,Traits>&
02147   operator <<(std::basic_ostream<Char,Traits>& os,
02148               const VarArray<Var>& x) {
02149     std::basic_ostringstream<Char,Traits> s;
02150     s.copyfmt(os); s.width(0);
02151     s << '{';
02152     if (x.size() > 0) {
02153       s << x[0];
02154       for (int i=1; i<x.size(); i++)
02155         s << ", " << x[i];
02156     }
02157     s << '}';
02158     return os << s.str();
02159   }
02160 
02161   template<class Char, class Traits, class View>
02162   std::basic_ostream<Char,Traits>&
02163   operator <<(std::basic_ostream<Char,Traits>& os,
02164              const ViewArray<View>& x) {
02165     std::basic_ostringstream<Char,Traits> s;
02166     s.copyfmt(os); s.width(0);
02167     s << '{';
02168     if (x.size() > 0) {
02169       s << x[0];
02170       for (int i=1; i<x.size(); i++)
02171         s << ", " << x[i];
02172     }
02173     s << '}';
02174     return os << s.str();
02175   }
02176 
02177   template<class Char, class Traits, class T>
02178   std::basic_ostream<Char,Traits>&
02179   operator <<(std::basic_ostream<Char,Traits>& os,
02180              const ArgArrayBase<T>& x) {
02181     std::basic_ostringstream<Char,Traits> s;
02182     s.copyfmt(os); s.width(0);
02183     s << '{';
02184     if (x.size() > 0) {
02185       s << x[0];
02186       for (int i=1; i<x.size(); i++)
02187         s << ", " << x[i];
02188     }
02189     s << '}';
02190     return os << s.str();
02191   }
02192 
02193 }
02194 
02195 // STATISTICS: kernel-other