Generated on Mon Aug 25 11:35:33 2008 for Gecode by doxygen 1.5.6

array.icc

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  *  Copyright:
00008  *     Christian Schulte, 2003
00009  *     Guido Tack, 2004
00010  *
00011  *  Last modified:
00012  *     $Date: 2008-02-20 08:39:15 +0100 (Wed, 20 Feb 2008) $ by $Author: tack $
00013  *     $Revision: 6240 $
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 
00043 namespace Gecode {
00044 
00045   template <class Var> class VarArray;
00046   template <class Var> class VarArgArray;
00047 
00058   template <class Var>
00059   class VarArray {
00060   protected:
00062     int  used;
00064     int n;
00066     Var* x;
00067   public:
00069 
00070 
00071     VarArray(void);
00073     VarArray(Space*, int m);
00075     VarArray(Space*,const VarArgArray<Var>&);
00077     VarArray(const VarArray<Var>& a);
00079     const VarArray<Var>& operator=(const VarArray<Var>& a);
00081     ~VarArray(void);
00083 
00085 
00086 
00087     int size(void) const;
00092     void resize(Space* home, int m);
00094 
00096 
00097 
00098     Var& operator[](int i);
00100     const Var& operator[](int i) const;
00102     void add(Space* home, const Var& v);
00104 
00106 
00107 
00114     void update(Space*, bool share, VarArray<Var>& a);
00116   private:
00117     static void* operator new(size_t);
00118     static void  operator delete(void*,size_t);
00119   };
00120 
00121 
00130   template <class View>
00131   class ViewArray {
00132   private:
00134     int  n;
00136     View* x;
00138     class ViewLess {
00139     public:
00140       bool operator()(const View&, const View&);
00141     };
00143     static void sort(View* x, int n);
00144   public:
00146 
00147 
00148     ViewArray(void);
00150     ViewArray(Space* home, int m);
00152     ViewArray(const ViewArray<View>& a);
00154     ViewArray(Space* home, const Reflection::VarMap& vars,
00155               Reflection::Arg* spec);
00157     ViewArray(Space* home, const ViewArray<View>& a);
00159     const ViewArray<View>& operator=(const ViewArray<View>& a);
00166     template <class Var>
00167     ViewArray(Space* home, const VarArgArray<Var>& a)
00168       : n(a.size()) {
00169       // This may not be in the icc file (to satisfy the MS compiler)
00170       if (n>0) {
00171         x = static_cast<View*>(home->alloc(sizeof(View)*n));
00172         for (int i = n; i--; )
00173           x[i] = a[i];
00174       } else {
00175         x = NULL;
00176       }
00177     }
00179 
00181 
00182 
00183     int size(void) const;
00185     void size(int n);
00187 
00189 
00190 
00191     View& operator[](int i);
00193     const View& operator[](int i) const;
00195 
00197 
00198 
00205     void subscribe(Space* home, Propagator* p, PropCond pc, bool process=true);
00207     void cancel(Space* home, Propagator* p, PropCond pc);
00209     void subscribe(Space* home, Advisor* a);
00211     void cancel(Space* home, Advisor* a);
00213 
00215 
00216 
00223     void update(Space*, bool share, ViewArray<View>& a);
00225 
00226 
00228 
00229 
00230     void move_fst(int i);
00232     void move_lst(int i);
00238     void move_fst(int i, Space* home, Propagator* p, PropCond pc);
00244     void move_lst(int i, Space* home, Propagator* p, PropCond pc);
00250     void move_fst(int i, Space* home, Advisor* a);
00256     void move_lst(int i, Space* home, Advisor* a);
00258 
00260 
00261 
00262     void drop_fst(int i);
00264     void drop_lst(int i);
00270     void drop_fst(int i, Space* home, Propagator* p, PropCond pc);
00277     void drop_lst(int i, Space* home, Propagator* p, PropCond pc);
00283     void drop_fst(int i, Space* home, Advisor* a);
00289     void drop_lst(int i, Space* home, Advisor* a);
00291 
00293 
00294 
00299     bool same(void) const;
00305     bool same(const View& y) const;
00307     void unique(void);
00309 
00311 
00312 
00317     bool shared(void) const;
00323     bool shared(const View& y) const;
00325 
00327 
00328     Reflection::Arg* spec(const Space* home, Reflection::VarMap& m) const;
00330 
00331   private:
00332     static void* operator new(size_t);
00333     static void  operator delete(void*,size_t);
00334   };
00335 
00349   template <class T>
00350   class ArgArrayBase {
00351   protected:
00353     int n;
00355     T*  a;
00357     static const int onstack_size = 16;
00359     T onstack[onstack_size];
00361     T* allocate(int n);
00362   public:
00364 
00365 
00366     ArgArrayBase(int n);
00368     ArgArrayBase(const ArgArrayBase<T>& a);
00370     const ArgArrayBase<T>& operator=(const ArgArrayBase<T>& a);
00372 
00374 
00375 
00376     int size(void) const;
00378 
00380 
00381 
00382     T& operator[](int i);
00384     const T& operator[](int i) const;
00386 
00388 
00389 
00390     ~ArgArrayBase(void);
00392   private:
00393     static void* operator new(size_t);
00394     static void  operator delete(void*,size_t);
00395   };
00396 
00397 
00409   template <class T>
00410   class PrimArgArray : public ArgArrayBase<T> {
00411   protected:
00412     using ArgArrayBase<T>::a;
00413   public:
00414     using ArgArrayBase<T>::size;
00416 
00417 
00418     PrimArgArray(int n);
00420     PrimArgArray(int n, T e0, ...);
00422     PrimArgArray(int n, const T* e);
00424     PrimArgArray(const PrimArgArray<T>& a);
00426   };
00427 
00439   template <class Var>
00440   class VarArgArray : public ArgArrayBase<Var> {
00441   protected:
00442     using ArgArrayBase<Var>::a;
00443     using ArgArrayBase<Var>::n;
00445     class VarLess {
00446     public:
00447       bool operator()(const Var&, const Var&);
00448     };
00449   public:
00450     using ArgArrayBase<Var>::size;
00452 
00453 
00454     VarArgArray(int n);
00456     VarArgArray(const VarArgArray<Var>& a);
00458     VarArgArray(const VarArray<Var>& a);
00460 
00461 
00462 
00467     bool same(void) const;
00473     bool same(const Var& y) const;
00479     bool same(const VarArgArray<Var>& y) const;
00481   };
00482 
00483 }
00484 
00489 template<class Var>
00490 std::ostream& operator<<(std::ostream& os, const Gecode::VarArray<Var>& x);
00491 
00496 template<class View>
00497 std::ostream& operator<<(std::ostream& os, const Gecode::ViewArray<View>& x);
00498 
00503 template<class T>
00504 std::ostream& operator<<(std::ostream& os, const Gecode::ArgArrayBase<T>& x);
00505 
00506 
00507 namespace Gecode {
00520   template <class A>
00521   class ArrayTraits {};
00522 
00523   /*
00524    * Implementation
00525    *
00526    */
00527 
00528   /*
00529    * Variable arrays
00530    *
00531    */
00532 
00533   template <class Var>
00534   forceinline
00535   VarArray<Var>::VarArray(void) : used(0), n(0), x(NULL) {}
00536 
00537   template <class Var>
00538   forceinline
00539   VarArray<Var>::VarArray(Space* home, int n0)
00540     : used(n0), n(n0) {
00541     x = (n>0) ? static_cast<Var*>(home->alloc(sizeof(Var)*n)) : NULL;
00542   }
00543 
00544   template <class Var>
00545   forceinline
00546   VarArray<Var>::VarArray(const VarArray<Var>& a) {
00547     used = a.used; n = a.n; x = a.x;
00548   }
00549 
00550   template <class Var>
00551   forceinline
00552   VarArray<Var>::~VarArray(void) {
00553     if (used != n) {
00554       // Array was allocated on the heap instead of the space
00555       Memory::free(x);
00556     }
00557   }
00558 
00559   template <class Var>
00560   forceinline const VarArray<Var>&
00561   VarArray<Var>::operator=(const VarArray<Var>& a) {
00562     used = a.used; n = a.n; x = a.x;
00563     return *this;
00564   }
00565 
00566   template <class Var>
00567   forceinline int
00568   VarArray<Var>::size(void) const {
00569     return used;
00570   }
00571 
00572   template <class Var>
00573   forceinline void
00574   VarArray<Var>::resize(Space* home, int m) {
00575     int newsize;
00576     if (m<used) {
00577       newsize = m;
00578     } else if (m<n) {
00579       used = m; n = m;
00580       return;
00581     } else {
00582       newsize = std::max(m, (3*n)/2);
00583     }
00584     Var* oldx = x;
00585     x = static_cast<Var*>(Memory::malloc(sizeof(Var)*newsize));
00586     for (int i=used; i--;)
00587       new (&x[i]) Var(oldx[i]);
00588     if (used != n)
00589       Memory::free(oldx);
00590     else
00591       home->reuse(oldx, n);
00592     n = newsize; used = m;
00593   }
00594 
00595   template <class Var>
00596   forceinline Var&
00597   VarArray<Var>::operator[](int i) {
00598     assert((i >= 0) && (i < size()));
00599     return x[i];
00600   }
00601 
00602   template <class Var>
00603   forceinline const Var&
00604   VarArray<Var>::operator[](int i) const {
00605     assert((i >= 0) && (i < size()));
00606     return x[i];
00607   }
00608 
00609   template <class Var>
00610   forceinline void
00611   VarArray<Var>::add(Space* home, const Var& v) {
00612     resize(home, used+1);
00613     new (&(*this)[used-1]) Var(v);
00614   }
00615 
00616   template <class Var>
00617   forceinline void
00618   VarArray<Var>::update(Space* home, bool share, VarArray<Var>& a) {
00619     n = a.used;
00620     used = n;
00621     if (n > 0) {
00622       x = static_cast<Var*>(home->alloc(sizeof(Var)*n));
00623       for (int i = n; i--; )
00624         x[i].update(home, share, a.x[i]);
00625     } else {
00626       x = NULL;
00627     }
00628   }
00629 
00630   template <class Var>
00631   void*
00632   VarArray<Var>::operator new(size_t) {
00633     return NULL;
00634   }
00635 
00636   template <class Var>
00637   void
00638   VarArray<Var>::operator delete(void*,size_t) {
00639   }
00640 
00641   /*
00642    * View arrays
00643    *
00644    */
00645 
00646   template <class View>
00647   forceinline
00648   ViewArray<View>::ViewArray(void) : n(0), x(NULL) {}
00649 
00650   template <class View>
00651   forceinline
00652   ViewArray<View>::ViewArray(Space* home, int n0)
00653     : n(n0) {
00654     x = (n>0) ? static_cast<View*>(home->alloc(sizeof(View)*n)) : NULL;
00655   }
00656 
00657   template <class View>
00658   ViewArray<View>::ViewArray(Space* home, const ViewArray<View>& a)
00659     : n(a.size()) {
00660     if (n>0) {
00661       x = static_cast<View*>(home->alloc(sizeof(View)*n));
00662       for (int i = n; i--; )
00663         x[i] = a[i];
00664     } else {
00665       x = NULL;
00666     }
00667   }
00668 
00669   template <class View>
00670   ViewArray<View>::ViewArray(Space* home, const Reflection::VarMap& vars,
00671                              Reflection::Arg* spec) {
00672     if (spec == NULL) {
00673       x = NULL;
00674       n = 0;
00675       return;
00676     }
00677     Reflection::ArrayArg* a = spec->toArray();
00678     n = a->size();
00679     x = n>0 ? static_cast<View*>(home->alloc(sizeof(View)*n)) : NULL;
00680     for (int i=n; i--;)
00681       x[i] = View(home, vars, (*a)[i]);
00682   }
00683 
00684   template <class View>
00685   forceinline
00686   ViewArray<View>::ViewArray(const ViewArray<View>& a)
00687     : n(a.n), x(a.x) {}
00688 
00689   template <class View>
00690   forceinline const ViewArray<View>&
00691   ViewArray<View>::operator=(const ViewArray<View>& a) {
00692     n = a.n; x = a.x;
00693     return *this;
00694   }
00695 
00696   template <class View>
00697   forceinline int
00698   ViewArray<View>::size(void) const {
00699     return n;
00700   }
00701 
00702   template <class View>
00703   forceinline void
00704   ViewArray<View>::size(int n0) {
00705     n = n0;
00706   }
00707 
00708   template <class View>
00709   forceinline View&
00710   ViewArray<View>::operator[](int i) {
00711     assert((i >= 0) && (i < size()));
00712     return x[i];
00713   }
00714 
00715   template <class View>
00716   forceinline const View&
00717   ViewArray<View>::operator[](int i) const {
00718     assert((i >= 0) && (i < size()));
00719     return x[i];
00720   }
00721 
00722   template <class View>
00723   forceinline void
00724   ViewArray<View>::move_fst(int i) {
00725     // move x[0] to x[i]
00726     assert(x[i].assigned());
00727     x[i]=x[0]; x++; n--;
00728   }
00729 
00730   template <class View>
00731   forceinline void
00732   ViewArray<View>::move_lst(int i) {
00733     // move x[n-1] to x[i]
00734     assert(x[i].assigned());
00735     n--; x[i]=x[n];
00736   }
00737 
00738   template <class View>
00739   forceinline void
00740   ViewArray<View>::drop_fst(int i) {
00741     // Drop elements from 0..i-1
00742     assert(i>=0);
00743     x += i; n -= i;
00744   }
00745 
00746   template <class View>
00747   forceinline void
00748   ViewArray<View>::drop_lst(int i) {
00749     // Drop elements from i+1..n-1
00750     assert(i<n);
00751     n = i+1;
00752   }
00753 
00754   template <class View>
00755   forceinline void
00756   ViewArray<View>::move_fst(int i, Space* home, Propagator* p, PropCond pc) {
00757     // Move x[0] to x[i]
00758     x[i].cancel(home,p,pc);
00759     x[i]=x[0]; x++; n--;
00760   }
00761 
00762   template <class View>
00763   forceinline void
00764   ViewArray<View>::move_lst(int i, Space* home, Propagator* p, PropCond pc) {
00765     // Move x[n-1] to x[i]
00766     x[i].cancel(home,p,pc);
00767     n--; x[i]=x[n];
00768   }
00769 
00770   template <class View>
00771   void
00772   ViewArray<View>::drop_fst(int i, Space* home, Propagator* p, PropCond pc) {
00773     // Drop elements from 0..i-1
00774     assert(i>=0);
00775     for (int j=i; j--; )
00776       x[j].cancel(home,p,pc);
00777     x += i; n -= i;
00778   }
00779 
00780   template <class View>
00781   void
00782   ViewArray<View>::drop_lst(int i, Space* home, Propagator* p, PropCond pc) {
00783     // Drop elements from i+1..n-1
00784     assert(i<n);
00785     for (int j=i+1; j<n; j++)
00786       x[j].cancel(home,p,pc);
00787     n = i+1;
00788   }
00789 
00790   template <class View>
00791   forceinline void
00792   ViewArray<View>::move_fst(int i, Space* home, Advisor* a) {
00793     // Move x[0] to x[i]
00794     x[i].cancel(home,a);
00795     x[i]=x[0]; x++; n--;
00796   }
00797 
00798   template <class View>
00799   forceinline void
00800   ViewArray<View>::move_lst(int i, Space* home, Advisor* a) {
00801     // Move x[n-1] to x[i]
00802     x[i].cancel(home,a);
00803     n--; x[i]=x[n];
00804   }
00805 
00806   template <class View>
00807   void
00808   ViewArray<View>::drop_fst(int i, Space* home, Advisor* a) {
00809     // Drop elements from 0..i-1
00810     assert(i>=0);
00811     for (int j=i; j--; )
00812       x[j].cancel(home,a);
00813     x += i; n -= i;
00814   }
00815 
00816   template <class View>
00817   void
00818   ViewArray<View>::drop_lst(int i, Space* home, Advisor* a) {
00819     // Drop elements from i+1..n-1
00820     assert(i<n);
00821     for (int j=i+1; j<n; j++)
00822       x[j].cancel(home,a);
00823     n = i+1;
00824   }
00825 
00826   template <class View>
00827   void
00828   ViewArray<View>::update(Space* home, bool share, ViewArray<View>& y) {
00829     n = y.n;
00830     if (n > 0) {
00831       x = static_cast<View*>(home->alloc(sizeof(View)*n));
00832       for (int i = n; i--; )
00833         x[i].update(home, share, y.x[i]);
00834     } else {
00835       x = NULL;
00836     }
00837   }
00838 
00839   template <class View>
00840   void
00841   ViewArray<View>::subscribe(Space* home, Propagator* p, PropCond pc, 
00842                              bool process) {
00843     for (int i = n; i--; )
00844       x[i].subscribe(home,p,pc,process);
00845   }
00846 
00847   template <class View>
00848   void
00849   ViewArray<View>::cancel(Space* home, Propagator* p, PropCond pc) {
00850     for (int i = n; i--; )
00851       x[i].cancel(home,p,pc);
00852   }
00853 
00854   template <class View>
00855   void
00856   ViewArray<View>::subscribe(Space* home, Advisor* a) {
00857     for (int i = n; i--; )
00858       x[i].subscribe(home,a);
00859   }
00860 
00861   template <class View>
00862   void
00863   ViewArray<View>::cancel(Space* home, Advisor* a) {
00864     for (int i = n; i--; )
00865       x[i].cancel(home,a);
00866   }
00867 
00868   template <class View>
00869   forceinline bool
00870   __before(const View& x, const View& y) {
00871     return before(x,y);
00872   }
00873 
00874   template <class View>
00875   forceinline bool
00876   ViewArray<View>::ViewLess::operator()(const View& a, const View& b) {
00877     return __before(a,b);
00878   }
00879 
00880   template <class View>
00881   void
00882   ViewArray<View>::sort(View* y, int m) {
00883     ViewLess vl;
00884     Support::quicksort<View,ViewLess>(y,m,vl);
00885   }
00886 
00887   template <class View>
00888   forceinline bool
00889   __same(const View& x, const View& y) {
00890     return same(x,y);
00891   }
00892   template <class View>
00893   forceinline bool
00894   __shared(const View& x, const View& y) {
00895     return shared(x,y);
00896   }
00897 
00898   template <class View>
00899   bool
00900   ViewArray<View>::same(void) const {
00901     if (n < 2)
00902       return false;
00903     GECODE_AUTOARRAY(View,y,n);
00904     for (int i = n; i--; )
00905       y[i] = x[i];
00906     sort(y,n);
00907     for (int i = n-1; i--; )
00908       if (!y[i].assigned() && __same(y[i+1],y[i]))
00909         return true;
00910     return false;
00911   }
00912 
00913   template <class View>
00914   bool
00915   ViewArray<View>::same(const View& y) const {
00916     if (y.assigned())
00917       return false;
00918     for (int i = n; i--; )
00919       if (__same(x[i],y))
00920         return true;
00921     return false;
00922   }
00923 
00924   template <class View>
00925   void
00926   ViewArray<View>::unique(void) {
00927     if (n < 2)
00928       return;
00929     sort(x,n);
00930     int j = 0;
00931     for (int i = 1; i<n; i++)
00932       if (!__same(x[j],x[i]))
00933         x[++j] = x[i];
00934     n = j+1;
00935   }
00936 
00937   template <class View>
00938   bool
00939   ViewArray<View>::shared(void) const {
00940     if (n < 2)
00941       return false;
00942     GECODE_AUTOARRAY(View,y,n);
00943     for (int i = n; i--; )
00944       y[i] = x[i];
00945     sort(y,n);
00946     for (int i = n-1; i--; )
00947       if (!y[i].assigned() && __shared(y[i+1],y[i]))
00948         return true;
00949     return false;
00950   }
00951 
00952   template <class View>
00953   bool
00954   ViewArray<View>::shared(const View& y) const {
00955     if (y.assigned())
00956       return false;
00957     for (int i = n; i--; )
00958       if (__shared(x[i],y))
00959         return true;
00960     return false;
00961   }
00962 
00963   template <class View>
00964   Reflection::Arg*
00965   ViewArray<View>::spec(const Space* home, Reflection::VarMap& m) const {
00966     Reflection::ArrayArg* s = Reflection::Arg::newArray(n);
00967     for (int i = 0; i<n; i++)
00968       (*s)[i] = x[i].spec(home, m);
00969     return s;
00970   }
00971 
00972   template <class View>
00973   void*
00974   ViewArray<View>::operator new(size_t) {
00975     return NULL;
00976   }
00977 
00978   template <class View>
00979   void
00980   ViewArray<View>::operator delete(void*,size_t) {
00981   }
00982 
00983 
00984   /*
00985    * Argument arrays: base class
00986    *
00987    */
00988 
00989   template <class T>
00990   forceinline T*
00991   ArgArrayBase<T>::allocate(int n) {
00992     return (n > onstack_size) ?
00993       Memory::bmalloc<T>(static_cast<size_t>(n)) : &onstack[0];
00994   }
00995 
00996   template <class T>
00997   forceinline
00998   ArgArrayBase<T>::ArgArrayBase(int n0)
00999     : n(n0), a(allocate(n0)) {
01000     for (int i=n; i--;)
01001       new (&a[i]) T();
01002   }
01003 
01004   template <class T>
01005   inline
01006   ArgArrayBase<T>::ArgArrayBase(const ArgArrayBase<T>& aa)
01007     : n(aa.n), a(allocate(aa.n)) {
01008     for (int i = n; i--; )
01009       new (&a[i]) T(aa.a[i]);
01010   }
01011 
01012   template <class T>
01013   forceinline
01014   ArgArrayBase<T>::~ArgArrayBase(void) {
01015     for (int i=n; i--;)
01016       a[i].~T();
01017     if (n > onstack_size)
01018       Memory::free(a);
01019   }
01020 
01021   template <class T>
01022   forceinline const ArgArrayBase<T>&
01023   ArgArrayBase<T>::operator=(const ArgArrayBase<T>& aa) {
01024     if (&aa != this) {
01025       if (n > onstack_size)
01026         Memory::free(a);
01027       n = aa.n;
01028       a = allocate(aa.n);
01029       for (int i = n; i--; )
01030         a[i] = aa.a[i];
01031     }
01032     return *this;
01033   }
01034 
01035   template <class T>
01036   forceinline int
01037   ArgArrayBase<T>::size(void) const {
01038     return n;
01039   }
01040 
01041   template <class T>
01042   forceinline T&
01043   ArgArrayBase<T>::operator[](int i) {
01044     assert((i>=0) && (i < n));
01045     return a[i];
01046   }
01047 
01048   template <class T>
01049   forceinline const T&
01050   ArgArrayBase<T>::operator[](int i) const {
01051     assert((i>=0) && (i < n));
01052     return a[i];
01053   }
01054 
01055 
01056   /*
01057    * Argument arrays for primitive types
01058    *
01059    */
01060 
01061   template <class T>
01062   forceinline
01063   PrimArgArray<T>::PrimArgArray(int n)
01064     : ArgArrayBase<T>(n) {}
01065 
01066   template <class T>
01067   PrimArgArray<T>::PrimArgArray(int n, T a0, ...)
01068     : ArgArrayBase<T>(n) {
01069     va_list args;
01070     va_start(args, a0);
01071     a[0] = a0;
01072     for (int i = 1; i < n; i++)
01073       a[i] = va_arg(args,T);
01074     va_end(args);
01075   }
01076 
01077   template <class T>
01078   PrimArgArray<T>::PrimArgArray(int n, const T* a0)
01079     : ArgArrayBase<T>(n) {
01080     for (int i=n; i--; )
01081       a[i] = a0[i];
01082   }
01083 
01084   template <class T>
01085   forceinline
01086   PrimArgArray<T>::PrimArgArray(const PrimArgArray<T>& aa)
01087     : ArgArrayBase<T>(aa) {}
01088 
01089 
01090 
01091   /*
01092    * Argument arrays for variables
01093    *
01094    */
01095 
01096   template <class T>
01097   forceinline
01098   VarArgArray<T>::VarArgArray(int n)
01099     : ArgArrayBase<T>(n) {}
01100 
01101   template <class T>
01102   forceinline
01103   VarArgArray<T>::VarArgArray(const VarArgArray<T>& aa)
01104     : ArgArrayBase<T>(aa) {}
01105 
01106   template <class T>
01107   inline
01108   VarArgArray<T>::VarArgArray(const VarArray<T>& x)
01109     : ArgArrayBase<T>(x.size()) {
01110     for (int i = x.size(); i--; )
01111       a[i] = x[i];
01112   }
01113 
01114   template <class Var>
01115   forceinline bool
01116   VarArgArray<Var>::VarLess::operator()(const Var& a, const Var& b) {
01117     return a.var() < b.var();
01118   }
01119 
01120   template <class Var>
01121   bool
01122   VarArgArray<Var>::same(void) const {
01123     if (n < 2)
01124       return false;
01125     GECODE_AUTOARRAY(Var,y,n);
01126     for (int i = n; i--; )
01127       y[i] = a[i];
01128     VarLess vl;
01129     Support::quicksort<Var,VarLess>(y,n,vl);
01130     for (int i = n-1; i--; )
01131       if (!y[i].assigned() && (y[i+1].var() == y[i].var()))
01132         return true;
01133     return false;
01134   }
01135 
01136   template <class Var>
01137   bool
01138   VarArgArray<Var>::same(const VarArgArray<Var>& y) const {
01139     int m = n + y.n;
01140     if (m < 2)
01141       return false;
01142     GECODE_AUTOARRAY(Var,z,m);
01143     for (int i = n; i--; )
01144       z[i] = a[i];
01145     for (int i = y.n; i--; )
01146       z[i+n] = y.a[i];
01147     VarLess vl;
01148     Support::quicksort<Var,VarLess>(z,m,vl);
01149     for (int i = m-1; i--; )
01150       if (!z[i].assigned() && (z[i+1].var() == z[i].var()))
01151         return true;
01152     return false;
01153   }
01154 
01155   template <class Var>
01156   bool
01157   VarArgArray<Var>::same(const Var& y) const {
01158     if (y.assigned())
01159       return false;
01160     for (int i = n; i--; )
01161       if (a[i].var() == y.var())
01162         return true;
01163     return false;
01164   }
01165 
01166 
01167 
01168 
01169 
01170 
01171   /*
01172    * Interdependent code
01173    *
01174    */
01175 
01176   template <class Var>
01177   inline
01178   VarArray<Var>::VarArray(Space* home, const VarArgArray<Var>& a)
01179     : n(a.size()) {
01180     if (n>0) {
01181       x = static_cast<Var*>(home->alloc(sizeof(Var)*n));
01182       for (int i = n; i--; )
01183         x[i] = a[i];
01184     } else {
01185       x = NULL;
01186     }
01187   }
01188 
01189 }
01190 
01191 
01192 /*
01193  * Printing of arrays
01194  *
01195  */
01196 template<class Var>
01197 std::ostream& 
01198 operator<<(std::ostream& os, const Gecode::VarArray<Var>& x) {
01199   os << '{';
01200   if (x.size() > 0) {
01201     os << x[0];
01202     for (int i=1; i<x.size(); i++)
01203       os << ", " << x[i];
01204   }
01205   return os << '}';
01206 }
01207 
01208 template<class View>
01209 std::ostream& 
01210 operator<<(std::ostream& os, const Gecode::ViewArray<View>& x) {
01211   os << '{';
01212   if (x.size() > 0) {
01213     os << x[0];
01214     for (int i=1; i<x.size(); i++)
01215       os << ", " << x[i];
01216   }
01217   return os << '}';
01218 }
01219 
01220 template<class T>
01221 std::ostream& 
01222 operator<<(std::ostream& os, const Gecode::ArgArrayBase<T>& x) {
01223   os << '{';
01224   if (x.size() > 0) {
01225     os << x[0];
01226     for (int i=1; i<x.size(); i++)
01227       os << ", " << x[i];
01228   }
01229   return os << '}';
01230 }
01231 
01232 // STATISTICS: kernel-other