Generated on Sun Feb 17 15:24:05 2019 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 <iostream>
00041 #include <iterator>
00042 #include <vector>
00043 #include <sstream>
00044 #include <initializer_list>
00045 
00046 namespace Gecode { namespace Kernel {
00047 
00049   GECODE_KERNEL_EXPORT
00050   bool duplicates(void** p, int n);
00051 
00053   GECODE_KERNEL_EXPORT
00054   bool duplicates(void** p, int n, void** q, int m);
00055 
00056 }}
00057 
00058 namespace Gecode {
00059 
00060   template<class Var> class VarArray;
00061   template<class Var> class VarArgArray;
00062 
00075   template<class A>
00076   class ArrayTraits {};
00077 
00093   template<class Var>
00094   class VarArray {
00095   protected:
00097     int n;
00099     Var* x;
00100   public:
00102 
00103 
00104     typedef Var value_type;
00106     typedef Var& reference;
00108     typedef const Var& const_reference;
00110     typedef Var* pointer;
00112     typedef const Var* const_pointer;
00114     typedef Var* iterator;
00116     typedef const Var* const_iterator;
00118     typedef std::reverse_iterator<Var*> reverse_iterator;
00120     typedef std::reverse_iterator<const Var*> const_reverse_iterator;
00122 
00124 
00125 
00126 
00127     VarArray(void);
00129     VarArray(Space& home, int m);
00131     VarArray(Space& home, const VarArgArray<Var>&);
00133     VarArray(const VarArray<Var>& a);
00135     const VarArray<Var>& operator =(const VarArray<Var>& a);
00137 
00139 
00140 
00141     int size(void) const;
00143 
00145 
00146 
00147     Var& operator [](int i);
00149     const Var& operator [](int i) const;
00155     typename ArrayTraits<VarArgArray<Var>>::ArgsType
00156     slice(int start, int inc=1, int n=-1);
00158 
00160 
00161 
00162     iterator begin(void);
00164     const_iterator begin(void) const;
00166     iterator end(void);
00168     const_iterator end(void) const;
00170     reverse_iterator rbegin(void);
00172     const_reverse_iterator rbegin(void) const;
00174     reverse_iterator rend(void);
00176     const_reverse_iterator rend(void) const;
00178 
00180     bool assigned(void) const;
00181 
00183 
00184 
00185     void update(Space& home, VarArray<Var>& a);
00187   private:
00188     static void* operator new(size_t) throw();
00189     static void  operator delete(void*,size_t);
00190   };
00191 
00195   template<class T>
00196   typename ArrayTraits<VarArray<T>>::ArgsType
00197   operator +(const VarArray<T>& x, const VarArgArray<T>& y);
00198 
00202   template<class T>
00203   typename ArrayTraits<VarArray<T>>::ArgsType
00204   operator +(const VarArray<T>& x, const VarArray<T>& y);
00205 
00209   template<class T>
00210   typename ArrayTraits<VarArray<T>>::ArgsType
00211   operator +(const VarArgArray<T>& x, const VarArray<T>& y);
00212 
00216   template<class T>
00217   typename ArrayTraits<VarArray<T>>::ArgsType
00218   operator +(const VarArray<T>& x, const T& y);
00219 
00223   template<class T>
00224   typename ArrayTraits<VarArray<T>>::ArgsType
00225   operator +(const T& x, const VarArray<T>& y);
00226 
00234   template<class View>
00235   class ViewArray {
00236   private:
00238     int  n;
00240     View* x;
00241   public:
00243 
00244 
00245     typedef View value_type;
00247     typedef View& reference;
00249     typedef const View& const_reference;
00251     typedef View* pointer;
00253     typedef const View* const_pointer;
00255     typedef View* iterator;
00257     typedef const View* const_iterator;
00259     typedef std::reverse_iterator<View*> reverse_iterator;
00261     typedef std::reverse_iterator<const View*> const_reverse_iterator;
00263 
00265 
00266 
00267     ViewArray(void);
00269     ViewArray(Space& home, int m);
00271     ViewArray(Region& r, int m);
00273     ViewArray(const ViewArray<View>& a);
00275     ViewArray(Space& home, const ViewArray<View>& a);
00277     ViewArray(Region& r, const ViewArray<View>& a);
00279     const ViewArray<View>& operator =(const ViewArray<View>& a);
00286     template<class Var>
00287     ViewArray(Space& home, const VarArgArray<Var>& a)
00288       : n(a.size()) {
00289       // This may not be in the hpp file (to satisfy the MS compiler)
00290       if (n>0) {
00291         x = home.alloc<View>(n);
00292         for (int i=0; i<n; i++)
00293           x[i]=a[i];
00294       } else {
00295         x = nullptr;
00296       }
00297     }
00304     template<class Var>
00305     ViewArray(Region& r, const VarArgArray<Var>& a)
00306       : n(a.size()) {
00307       // This may not be in the hpp file (to satisfy the MS compiler)
00308       if (n>0) {
00309         x = r.alloc<View>(n);
00310         for (int i=0; i<n; i++)
00311           x[i]=a[i];
00312       } else {
00313         x = nullptr;
00314       }
00315     }
00317 
00319 
00320 
00321     int size(void) const;
00323     void size(int n);
00325 
00327 
00328 
00329     View& operator [](int i);
00331     const View& operator [](int i) const;
00333 
00335 
00336 
00337     iterator begin(void);
00339     const_iterator begin(void) const;
00341     iterator end(void);
00343     const_iterator end(void) const;
00345     reverse_iterator rbegin(void);
00347     const_reverse_iterator rbegin(void) const;
00349     reverse_iterator rend(void);
00351     const_reverse_iterator rend(void) const;
00353 
00355 
00356 
00363     void subscribe(Space& home, Propagator& p, PropCond pc,
00364                    bool schedule=true);
00366     void cancel(Space& home, Propagator& p, PropCond pc);
00368     void subscribe(Space& home, Advisor& a);
00370     void cancel(Space& home, Advisor& a);
00372     void reschedule(Space& home, Propagator& p, PropCond pc);
00374 
00376 
00377 
00378     void update(Space& home, ViewArray<View>& a);
00380 
00381 
00383 
00384 
00385     void move_fst(int i);
00387     void move_lst(int i);
00393     void move_fst(int i, Space& home, Propagator& p, PropCond pc);
00399     void move_lst(int i, Space& home, Propagator& p, PropCond pc);
00405     void move_fst(int i, Space& home, Advisor& a);
00411     void move_lst(int i, Space& home, Advisor& a);
00413 
00415 
00416 
00417     void drop_fst(int i);
00419     void drop_lst(int i);
00425     void drop_fst(int i, Space& home, Propagator& p, PropCond pc);
00432     void drop_lst(int i, Space& home, Propagator& p, PropCond pc);
00438     void drop_fst(int i, Space& home, Advisor& a);
00444     void drop_lst(int i, Space& home, Advisor& a);
00446 
00448     bool assigned(void) const;
00449 
00451 
00452 
00457     bool same(void) const;
00463     bool same(const View& y) const;
00465     void unique(void);
00467   private:
00468     static void* operator new(size_t) throw();
00469     static void  operator delete(void*,size_t);
00470   };
00471 
00472 
00479   template<class ViewX, class ViewY>
00480   bool shared(ViewArray<ViewX> x, ViewArray<ViewY> y);
00487   template<class ViewX, class ViewY>
00488   bool shared(ViewArray<ViewX> x, ViewY y);
00495   template<class ViewX, class ViewY>
00496   bool shared(ViewX x, ViewArray<ViewY> y);
00503   template<class View>
00504   bool shared(ViewArray<View> x);
00505 
00506 
00518   template<class T>
00519   class ArgArrayBase {
00520   protected:
00522     int n;
00524     int capacity;
00526     T*  a;
00528     static const int onstack_size = 16;
00530     T onstack[onstack_size];
00532     T* allocate(int n);
00534     void resize(int i);
00536     template<class A>
00537     A concat(const ArgArrayBase<T>& x) const;
00539     template<class A>
00540     A concat(const T& x) const;
00542     template<class A>
00543     A& append(const T& x);
00545     template<class A>
00546     A& append(const ArgArrayBase<T>& x);
00552     template<class A>
00553     A slice(int start, int inc=1, int n=-1);
00554   public:
00556 
00557 
00558     typedef T value_type;
00560     typedef T& reference;
00562     typedef const T& const_reference;
00564     typedef T* pointer;
00566     typedef const T* const_pointer;
00568     typedef T* iterator;
00570     typedef const T* const_iterator;
00572     typedef std::reverse_iterator<T*> reverse_iterator;
00574     typedef std::reverse_iterator<const T*> const_reverse_iterator;
00576 
00578 
00579 
00580     ArgArrayBase(void);
00582     explicit ArgArrayBase(int n);
00584     ArgArrayBase(const ArgArrayBase<T>& a);
00586     const ArgArrayBase<T>& operator =(const ArgArrayBase<T>& a);
00588     ArgArrayBase(const std::vector<T>& a);
00590     ArgArrayBase(std::initializer_list<T> a);
00592     template<class InputIterator>
00593     ArgArrayBase(InputIterator first, InputIterator last);
00595 
00597 
00598 
00599     int size(void) const;
00601 
00603 
00604 
00605     T& operator [](int i);
00607     const T& operator [](int i) const;
00609 
00611 
00612 
00613     iterator begin(void);
00615     const_iterator begin(void) const;
00617     iterator end(void);
00619     const_iterator end(void) const;
00621     reverse_iterator rbegin(void);
00623     const_reverse_iterator rbegin(void) const;
00625     reverse_iterator rend(void);
00627     const_reverse_iterator rend(void) const;
00629 
00631 
00632 
00633     ~ArgArrayBase(void);
00635   };
00636 
00637 
00638   template<class> class ArgArray;
00639 
00643   template<class T>
00644   typename ArrayTraits<ArgArray<T>>::ArgsType
00645   operator +(const ArgArray<T>& x, const ArgArray<T>& y);
00646 
00650   template<class T>
00651   typename ArrayTraits<ArgArray<T>>::ArgsType
00652   operator +(const ArgArray<T>& x, const T& y);
00653 
00657   template<class T>
00658   typename ArrayTraits<ArgArray<T>>::ArgsType
00659   operator +(const T& x, const ArgArray<T>& y);
00660 
00672   template<class T>
00673   class ArgArray : public ArgArrayBase<T> {
00674   protected:
00675     using ArgArrayBase<T>::a;
00676   public:
00677     using ArgArrayBase<T>::size;
00679 
00680 
00681     ArgArray(void);
00683     explicit ArgArray(int n);
00685     ArgArray(int n, const T* e);
00687     ArgArray(const ArgArray<T>& a);
00689     ArgArray(const std::vector<T>& a);
00691     ArgArray(std::initializer_list<T> a);
00693     template<class InputIterator>
00694     ArgArray(InputIterator first, InputIterator last);
00696 
00697 
00698 
00699     typename ArrayTraits<ArgArray<T>>::ArgsType
00700     slice(int start, int inc=1, int n=-1);
00702 
00703 
00704 
00705     typename ArrayTraits<ArgArray<T>>::ArgsType&
00706     operator <<(const T& x);
00708     typename ArrayTraits<ArgArray<T>>::ArgsType&
00709     operator <<(const ArgArray<T>& x);
00711 
00712     friend typename ArrayTraits<ArgArray<T>>::ArgsType
00713     operator + <>(const ArgArray<T>& x, const ArgArray<T>& y);
00714     friend typename ArrayTraits<ArgArray<T>>::ArgsType
00715     operator + <>(const ArgArray<T>& x, const T& y);
00716     friend
00717     typename ArrayTraits<ArgArray<T>>::ArgsType
00718     operator + <>(const T& x, const ArgArray<T>& y);
00719   };
00720 
00721   template<class> class VarArgArray;
00722 
00726   template<class Var>
00727   typename ArrayTraits<VarArgArray<Var>>::ArgsType
00728   operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y);
00729 
00733   template<class Var>
00734   typename ArrayTraits<VarArgArray<Var>>::ArgsType
00735   operator +(const VarArgArray<Var>& x, const Var& y);
00736 
00740   template<class Var>
00741   typename ArrayTraits<VarArgArray<Var>>::ArgsType
00742   operator +(const Var& x, const VarArgArray<Var>& y);
00743 
00755   template<class Var>
00756   class VarArgArray : public ArgArrayBase<Var> {
00757   protected:
00758     using ArgArrayBase<Var>::a;
00759     using ArgArrayBase<Var>::n;
00760   public:
00761     using ArgArrayBase<Var>::size;
00763 
00764 
00765     VarArgArray(void);
00767     explicit VarArgArray(int n);
00769     VarArgArray(const VarArgArray<Var>& a);
00771     VarArgArray(const VarArray<Var>& a);
00773     VarArgArray(const std::vector<Var>& a);
00775     VarArgArray(std::initializer_list<Var> a);
00777     template<class InputIterator>
00778     VarArgArray(InputIterator first, InputIterator last);
00780 
00781 
00782 
00783     typename ArrayTraits<VarArgArray<Var>>::ArgsType
00784     slice(int start, int inc=1, int n=-1);
00786 
00787 
00788 
00789     typename ArrayTraits<VarArgArray<Var>>::ArgsType&
00790     operator <<(const Var& x);
00792     typename ArrayTraits<VarArgArray<Var>>::ArgsType&
00793     operator <<(const VarArgArray<Var>& x);
00795 
00797     bool assigned(void) const;
00798 
00799     friend typename ArrayTraits<VarArgArray<Var>>::ArgsType
00800     operator + <>(const VarArgArray<Var>& x, const VarArgArray<Var>& y);
00801     friend typename ArrayTraits<VarArgArray<Var>>::ArgsType
00802     operator + <>(const VarArgArray<Var>& x, const Var& y);
00803     friend
00804     typename ArrayTraits<VarArgArray<Var>>::ArgsType
00805     operator + <>(const Var& x, const VarArgArray<Var>& y);
00806   };
00807 
00808 
00815   template<class Var>
00816   bool same(VarArgArray<Var> x, VarArgArray<Var> y);
00823   template<class Var>
00824   bool same(VarArgArray<Var> x, Var y);
00831   template<class Var>
00832   bool same(Var x, VarArgArray<Var> y);
00839   template<class Var>
00840   bool same(VarArgArray<Var> x);
00841 
00842 
00847   template<class Char, class Traits, class Var>
00848   std::basic_ostream<Char,Traits>&
00849   operator <<(std::basic_ostream<Char,Traits>& os,
00850              const VarArray<Var>& x);
00851 
00856   template<class Char, class Traits, class View>
00857   std::basic_ostream<Char,Traits>&
00858   operator <<(std::basic_ostream<Char,Traits>& os, const ViewArray<View>& x);
00859 
00864   template<class Char, class Traits, class T>
00865   std::basic_ostream<Char,Traits>&
00866   operator <<(std::basic_ostream<Char,Traits>& os, const ArgArrayBase<T>& x);
00867 
00868 
00869   /*
00870    * Implementation
00871    *
00872    */
00873 
00874   /*
00875    * Variable arrays
00876    *
00877    * These arrays are allocated in the space.
00878    *
00879    */
00880 
00881   template<class Var>
00882   forceinline
00883   VarArray<Var>::VarArray(void) : n(0), x(nullptr) {}
00884 
00885   template<class Var>
00886   forceinline
00887   VarArray<Var>::VarArray(Space& home, int n0)
00888     : n(n0) {
00889     // Allocate from space
00890     x = (n>0) ? home.alloc<Var>(n) : nullptr;
00891   }
00892 
00893   template<class Var>
00894   forceinline
00895   VarArray<Var>::VarArray(const VarArray<Var>& a) {
00896     n = a.n; x = a.x;
00897   }
00898 
00899   template<class Var>
00900   inline const VarArray<Var>&
00901   VarArray<Var>::operator =(const VarArray<Var>& a) {
00902     n = a.n; x = a.x;
00903     return *this;
00904   }
00905 
00906   template<class Var>
00907   forceinline int
00908   VarArray<Var>::size(void) const {
00909     return n;
00910   }
00911 
00912   template<class Var>
00913   forceinline Var&
00914   VarArray<Var>::operator [](int i) {
00915     assert((i >= 0) && (i < size()));
00916     return x[i];
00917   }
00918 
00919   template<class Var>
00920   forceinline const Var&
00921   VarArray<Var>::operator [](int i) const {
00922     assert((i >= 0) && (i < size()));
00923     return x[i];
00924   }
00925 
00926   template<class Var>
00927   typename ArrayTraits<VarArgArray<Var>>::ArgsType
00928   VarArray<Var>::slice(int start, int inc, int maxN) {
00929     assert(n==0 || start < n);
00930     if (n==0 || maxN<0)
00931       maxN = n;
00932     int s;
00933     if (inc == 0)
00934       s = n-start;
00935     else if (inc > 0)
00936       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
00937     else
00938       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
00939     typename ArrayTraits<VarArgArray<Var>>::ArgsType r(std::min(maxN,s));
00940     for (int i=0; i<r.size(); i++, start+=inc)
00941       r[i] = x[start];
00942     return r;
00943   }
00944 
00945   template<class Var>
00946   forceinline typename VarArray<Var>::iterator
00947   VarArray<Var>::begin(void) {
00948     return x;
00949   }
00950 
00951   template<class Var>
00952   forceinline typename VarArray<Var>::const_iterator
00953   VarArray<Var>::begin(void) const {
00954     return x;
00955   }
00956 
00957   template<class Var>
00958   forceinline typename VarArray<Var>::iterator
00959   VarArray<Var>::end(void) {
00960     return x+n;
00961   }
00962 
00963   template<class Var>
00964   forceinline typename VarArray<Var>::const_iterator
00965   VarArray<Var>::end(void) const {
00966     return x+n;
00967   }
00968 
00969   template<class Var>
00970   forceinline typename VarArray<Var>::reverse_iterator
00971   VarArray<Var>::rbegin(void) {
00972     return reverse_iterator(x+n);
00973   }
00974 
00975   template<class Var>
00976   forceinline typename VarArray<Var>::const_reverse_iterator
00977   VarArray<Var>::rbegin(void) const {
00978     return const_reverse_iterator(x+n);
00979   }
00980 
00981   template<class Var>
00982   forceinline typename VarArray<Var>::reverse_iterator
00983   VarArray<Var>::rend(void) {
00984     return reverse_iterator(x);
00985   }
00986 
00987   template<class Var>
00988   forceinline typename VarArray<Var>::const_reverse_iterator
00989   VarArray<Var>::rend(void) const {
00990     return const_reverse_iterator(x);
00991   }
00992 
00993   template<class Var>
00994   forceinline void
00995   VarArray<Var>::update(Space& home, VarArray<Var>& a) {
00996     n = a.n;
00997     if (n > 0) {
00998       x = home.alloc<Var>(n);
00999       for (int i=0; i<n; i++)
01000         x[i].update(home, a.x[i]);
01001     } else {
01002       x = nullptr;
01003     }
01004   }
01005 
01006   template<class Var>
01007   forceinline bool
01008   VarArray<Var>::assigned(void) const {
01009     for (int i=0; i<n; i++)
01010       if (!x[i].assigned())
01011         return false;
01012     return true;
01013   }
01014 
01015   template<class Var>
01016   forceinline void*
01017   VarArray<Var>::operator new(size_t) throw() {
01018     return nullptr;
01019   }
01020 
01021   template<class Var>
01022   forceinline void
01023   VarArray<Var>::operator delete(void*,size_t) {
01024   }
01025 
01026   template<class Var>
01027   typename ArrayTraits<VarArray<Var>>::ArgsType
01028   operator +(const VarArray<Var>& x, const VarArray<Var>& y) {
01029     typename ArrayTraits<VarArray<Var>>::ArgsType r(x.size()+y.size());
01030     for (int i=0; i<x.size(); i++)
01031       r[i] = x[i];
01032     for (int i=0; i<y.size(); i++)
01033       r[x.size()+i] = y[i];
01034     return r;
01035   }
01036 
01037   template<class Var>
01038   typename ArrayTraits<VarArray<Var>>::ArgsType
01039   operator +(const VarArray<Var>& x, const VarArgArray<Var>& y) {
01040     typename ArrayTraits<VarArray<Var>>::ArgsType r(x.size()+y.size());
01041     for (int i=0; i<x.size(); i++)
01042       r[i] = x[i];
01043     for (int i=0; i<y.size(); i++)
01044       r[x.size()+i] = y[i];
01045     return r;
01046   }
01047 
01048   template<class Var>
01049   typename ArrayTraits<VarArray<Var>>::ArgsType
01050   operator +(const VarArgArray<Var>& x, const VarArray<Var>& y) {
01051     typename ArrayTraits<VarArray<Var>>::ArgsType r(x.size()+y.size());
01052     for (int i=0; i<x.size(); i++)
01053       r[i] = x[i];
01054     for (int i=0; i<y.size(); i++)
01055       r[x.size()+i] = y[i];
01056     return r;
01057   }
01058 
01059   template<class Var>
01060   typename ArrayTraits<VarArray<Var>>::ArgsType
01061   operator +(const VarArray<Var>& x, const Var& y) {
01062     typename ArrayTraits<VarArray<Var>>::ArgsType r(x.size()+1);
01063     for (int i=0; i<x.size(); i++)
01064       r[i] = x[i];
01065     r[x.size()] = y;
01066     return r;
01067   }
01068 
01069   template<class Var>
01070   typename ArrayTraits<VarArray<Var>>::ArgsType
01071   operator +(const Var& x, const VarArray<Var>& y) {
01072     typename ArrayTraits<VarArray<Var>>::ArgsType r(y.size()+1);
01073     r[0] = x;
01074     for (int i=0; i<y.size(); i++)
01075       r[1+i] = y[i];
01076     return r;
01077   }
01078 
01079   /*
01080    * View arrays
01081    *
01082    */
01083 
01084   template<class View>
01085   forceinline
01086   ViewArray<View>::ViewArray(void) : n(0), x(nullptr) {}
01087 
01088   template<class View>
01089   forceinline
01090   ViewArray<View>::ViewArray(Space& home, int n0)
01091     : n(n0) {
01092     x = (n>0) ? home.alloc<View>(n) : nullptr;
01093   }
01094   template<class View>
01095   forceinline
01096   ViewArray<View>::ViewArray(Region& r, int n0)
01097     : n(n0) {
01098     x = (n>0) ? r.alloc<View>(n) : nullptr;
01099   }
01100 
01101   template<class View>
01102   ViewArray<View>::ViewArray(Space& home, const ViewArray<View>& a)
01103     : n(a.size()) {
01104     if (n>0) {
01105       x = home.alloc<View>(n);
01106       for (int i=0; i<n; i++)
01107         x[i] = a[i];
01108     } else {
01109       x = nullptr;
01110     }
01111   }
01112   template<class View>
01113   ViewArray<View>::ViewArray(Region& r, const ViewArray<View>& a)
01114     : n(a.size()) {
01115     if (n>0) {
01116       x = r.alloc<View>(n);
01117       for (int i=0; i<n; i++)
01118         x[i] = a[i];
01119     } else {
01120       x = nullptr;
01121     }
01122   }
01123 
01124   template<class View>
01125   forceinline
01126   ViewArray<View>::ViewArray(const ViewArray<View>& a)
01127     : n(a.n), x(a.x) {}
01128 
01129   template<class View>
01130   forceinline const ViewArray<View>&
01131   ViewArray<View>::operator =(const ViewArray<View>& a) {
01132     n = a.n; x = a.x;
01133     return *this;
01134   }
01135 
01136   template<class View>
01137   forceinline int
01138   ViewArray<View>::size(void) const {
01139     return n;
01140   }
01141 
01142   template<class View>
01143   forceinline void
01144   ViewArray<View>::size(int n0) {
01145     n = n0;
01146   }
01147 
01148   template<class View>
01149   forceinline View&
01150   ViewArray<View>::operator [](int i) {
01151     assert((i >= 0) && (i < size()));
01152     return x[i];
01153   }
01154 
01155   template<class View>
01156   forceinline const View&
01157   ViewArray<View>::operator [](int i) const {
01158     assert((i >= 0) && (i < size()));
01159     return x[i];
01160   }
01161 
01162   template<class View>
01163   forceinline typename ViewArray<View>::iterator
01164   ViewArray<View>::begin(void) {
01165     return x;
01166   }
01167 
01168   template<class View>
01169   forceinline typename ViewArray<View>::const_iterator
01170   ViewArray<View>::begin(void) const {
01171     return x;
01172   }
01173 
01174   template<class View>
01175   forceinline typename ViewArray<View>::iterator
01176   ViewArray<View>::end(void) {
01177     return x+n;
01178   }
01179 
01180   template<class View>
01181   forceinline typename ViewArray<View>::const_iterator
01182   ViewArray<View>::end(void) const {
01183     return x+n;
01184   }
01185 
01186   template<class View>
01187   forceinline typename ViewArray<View>::reverse_iterator
01188   ViewArray<View>::rbegin(void) {
01189     return reverse_iterator(x+n);
01190   }
01191 
01192   template<class View>
01193   forceinline typename ViewArray<View>::const_reverse_iterator
01194   ViewArray<View>::rbegin(void) const {
01195     return const_reverse_iterator(x+n);
01196   }
01197 
01198   template<class View>
01199   forceinline typename ViewArray<View>::reverse_iterator
01200   ViewArray<View>::rend(void) {
01201     return reverse_iterator(x);
01202   }
01203 
01204   template<class View>
01205   forceinline typename ViewArray<View>::const_reverse_iterator
01206   ViewArray<View>::rend(void) const {
01207     return const_reverse_iterator(x);
01208   }
01209 
01210   template<class View>
01211   forceinline void
01212   ViewArray<View>::move_fst(int i) {
01213     x[i]=x[0]; x++; n--;
01214   }
01215 
01216   template<class View>
01217   forceinline void
01218   ViewArray<View>::move_lst(int i) {
01219     n--; x[i]=x[n];
01220   }
01221 
01222   template<class View>
01223   forceinline void
01224   ViewArray<View>::drop_fst(int i) {
01225     assert(i>=0);
01226     x += i; n -= i;
01227   }
01228 
01229   template<class View>
01230   forceinline void
01231   ViewArray<View>::drop_lst(int i) {
01232     assert(i<n);
01233     n = i+1;
01234   }
01235 
01236   template<class View>
01237   forceinline void
01238   ViewArray<View>::move_fst(int i, Space& home, Propagator& p, PropCond pc) {
01239     // Move x[0] to x[i]
01240     x[i].cancel(home,p,pc);
01241     x[i]=x[0]; x++; n--;
01242   }
01243 
01244   template<class View>
01245   forceinline void
01246   ViewArray<View>::move_lst(int i, Space& home, Propagator& p, PropCond pc) {
01247     // Move x[n-1] to x[i]
01248     x[i].cancel(home,p,pc);
01249     n--; x[i]=x[n];
01250   }
01251 
01252   template<class View>
01253   void
01254   ViewArray<View>::drop_fst(int i, Space& home, Propagator& p, PropCond pc) {
01255     // Drop elements from 0..i-1
01256     assert(i>=0);
01257     for (int j=0; j<i; j++)
01258       x[j].cancel(home,p,pc);
01259     x += i; n -= i;
01260   }
01261 
01262   template<class View>
01263   void
01264   ViewArray<View>::drop_lst(int i, Space& home, Propagator& p, PropCond pc) {
01265     // Drop elements from i+1..n-1
01266     assert(i<n);
01267     for (int j=i+1; j<n; j++)
01268       x[j].cancel(home,p,pc);
01269     n = i+1;
01270   }
01271 
01272   template<class View>
01273   forceinline void
01274   ViewArray<View>::move_fst(int i, Space& home, Advisor& a) {
01275     // Move x[0] to x[i]
01276     x[i].cancel(home,a);
01277     x[i]=x[0]; x++; n--;
01278   }
01279 
01280   template<class View>
01281   forceinline void
01282   ViewArray<View>::move_lst(int i, Space& home, Advisor& a) {
01283     // Move x[n-1] to x[i]
01284     x[i].cancel(home,a);
01285     n--; x[i]=x[n];
01286   }
01287 
01288   template<class View>
01289   void
01290   ViewArray<View>::drop_fst(int i, Space& home, Advisor& a) {
01291     // Drop elements from 0..i-1
01292     assert(i>=0);
01293     for (int j=0; j<i; j++)
01294       x[j].cancel(home,a);
01295     x += i; n -= i;
01296   }
01297 
01298   template<class View>
01299   void
01300   ViewArray<View>::drop_lst(int i, Space& home, Advisor& a) {
01301     // Drop elements from i+1..n-1
01302     assert(i<n);
01303     for (int j=i+1; j<n; j++)
01304       x[j].cancel(home,a);
01305     n = i+1;
01306   }
01307 
01308   template<class View>
01309   void
01310   ViewArray<View>::update(Space& home, ViewArray<View>& y) {
01311     n = y.n;
01312     if (n > 0) {
01313       x = home.alloc<View>(n);
01314       for (int i=0; i<n; i++)
01315         x[i].update(home, y.x[i]);
01316     } else {
01317       x = nullptr;
01318     }
01319   }
01320 
01321   template<class View>
01322   void
01323   ViewArray<View>::subscribe(Space& home, Propagator& p, PropCond pc,
01324                              bool schedule) {
01325     for (int i=0; i<n; i++)
01326       x[i].subscribe(home,p,pc,schedule);
01327   }
01328 
01329   template<class View>
01330   void
01331   ViewArray<View>::cancel(Space& home, Propagator& p, PropCond pc) {
01332     for (int i=0; i<n; i++)
01333       x[i].cancel(home,p,pc);
01334   }
01335 
01336   template<class View>
01337   void
01338   ViewArray<View>::subscribe(Space& home, Advisor& a) {
01339     for (int i=0; i<n; i++)
01340       x[i].subscribe(home,a);
01341   }
01342 
01343   template<class View>
01344   void
01345   ViewArray<View>::cancel(Space& home, Advisor& a) {
01346     for (int i=0; i<n; i++)
01347       x[i].cancel(home,a);
01348   }
01349 
01350   template<class View>
01351   void
01352   ViewArray<View>::reschedule(Space& home, Propagator& p, PropCond pc) {
01353     for (int i=0; i<n; i++)
01354       x[i].reschedule(home,p,pc);
01355   }
01356 
01357   template<class View>
01358   forceinline bool
01359   ViewArray<View>::assigned(void) const {
01360     for (int i=0; i<n; i++)
01361       if (!x[i].assigned())
01362         return false;
01363     return true;
01364   }
01365 
01366   template<class View>
01367   bool
01368   ViewArray<View>::same(void) const {
01369     if (n < 2)
01370       return false;
01371     Region r;
01372     View* y = r.alloc<View>(n);
01373     int j=0;
01374     for (int i=0; i<n; i++)
01375       if (!x[i].assigned())
01376         y[j++] = x[i];
01377     if (j < 2)
01378       return false;
01379     Support::quicksort<View>(y,j);
01380     for (int i=1; i<j; i++)
01381       if (y[i-1] == y[i])
01382         return true;
01383     return false;
01384   }
01385 
01386   template<class View>
01387   bool
01388   ViewArray<View>::same(const View& y) const {
01389     if (y.assigned())
01390       return false;
01391     for (int i=0; i<n; i++)
01392       if (x[i] == y)
01393         return true;
01394     return false;
01395   }
01396 
01397   template<class View>
01398   void
01399   ViewArray<View>::unique(void) {
01400     if (n < 2)
01401       return;
01402     Support::quicksort<View>(x,n);
01403     int j = 0;
01404     for (int i=1; i<n; i++)
01405       if (x[j] != x[i])
01406         x[++j] = x[i];
01407     n = j+1;
01408   }
01409 
01410   template<class View>
01411   forceinline void*
01412   ViewArray<View>::operator new(size_t) throw() {
01413     return nullptr;
01414   }
01415 
01416   template<class View>
01417   forceinline void
01418   ViewArray<View>::operator delete(void*,size_t) {
01419   }
01420 
01421 
01422   /*
01423    * Sharing for view arrays
01424    *
01425    */
01426   template<class ViewX, class ViewY>
01427   bool
01428   shared(ViewArray<ViewX> x, ViewArray<ViewY> y) {
01429     if ((x.size() == 0) || (y.size() == 0))
01430       return false;
01431     Region r;
01432     void** px = r.alloc<void*>(x.size());
01433     int j=0;
01434     for (int i=0; i<x.size(); i++)
01435       if (!x[i].assigned() && x[i].varimp())
01436         px[j++] = x[i].varimp();
01437     if (j == 0)
01438       return false;
01439     void** py = r.alloc<void*>(y.size());
01440     int k=0;
01441     for (int i=0; i<y.size(); i++)
01442       if (!y[i].assigned() && y[i].varimp())
01443         py[k++] = y[i].varimp();
01444     if (k == 0)
01445       return false;
01446     return Kernel::duplicates(px,j,py,k);
01447   }
01448 
01449   template<class ViewX, class ViewY>
01450   bool
01451   shared(ViewArray<ViewX> x, ViewY y) {
01452     if (y.assigned() || !y.varimp())
01453       return false;
01454     for (int i=0; i<x.size(); i++)
01455       if (!x[i].assigned() && x[i].varimp() && (x[i].varimp() == y.varimp()))
01456         return true;
01457     return false;
01458   }
01459 
01460   template<class ViewX, class ViewY>
01461   forceinline bool
01462   shared(ViewX x, ViewArray<ViewY> y) {
01463     return shared(y,x);
01464   }
01465 
01466   template<class View>
01467   bool
01468   shared(ViewArray<View> x) {
01469     if (x.size() < 2)
01470       return false;
01471     Region r;
01472     void** px = r.alloc<void*>(x.size());
01473     int j=0;
01474     for (int i=0; i<x.size(); i++)
01475       if (!x[i].assigned() && x[i].varimp())
01476         px[j++] = x[i].varimp();
01477     return (j > 2) && Kernel::duplicates(px,j);
01478   }
01479 
01480 
01481 
01482   /*
01483    * Argument arrays: base class
01484    *
01485    */
01486 
01487   template<class T>
01488   forceinline T*
01489   ArgArrayBase<T>::allocate(int n) {
01490     return (n > onstack_size) ?
01491       heap.alloc<T>(static_cast<unsigned int>(n)) : &onstack[0];
01492   }
01493 
01494   template<class T>
01495   forceinline void
01496   ArgArrayBase<T>::resize(int i) {
01497     if (n+i >= capacity) {
01498       assert(n+i >= onstack_size);
01499       int newCapacity = (3*capacity)/2;
01500       if (newCapacity <= n+i)
01501         newCapacity = n+i;
01502       T* newA = allocate(newCapacity);
01503       heap.copy<T>(newA,a,n);
01504       if (capacity > onstack_size)
01505         heap.free(a,capacity);
01506       capacity = newCapacity;
01507       a = newA;
01508     }
01509   }
01510 
01511   template<class T>
01512   forceinline
01513   ArgArrayBase<T>::ArgArrayBase(void)
01514     : n(0), capacity(onstack_size), a(allocate(0)) {}
01515 
01516   template<class T>
01517   forceinline
01518   ArgArrayBase<T>::ArgArrayBase(int n0)
01519     : n(n0), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {}
01520 
01521   template<class T>
01522   inline
01523   ArgArrayBase<T>::ArgArrayBase(const ArgArrayBase<T>& aa)
01524     : n(aa.n), capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01525     heap.copy<T>(a,aa.a,n);
01526   }
01527 
01528   template<class T>
01529   inline
01530   ArgArrayBase<T>::ArgArrayBase(const std::vector<T>& aa)
01531     : n(static_cast<int>(aa.size())),
01532       capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01533     heap.copy<T>(a,&aa[0],n);
01534   }
01535 
01536   template<class T>
01537   inline
01538   ArgArrayBase<T>::ArgArrayBase(std::initializer_list<T> aa)
01539     : n(static_cast<int>(aa.size())),
01540       capacity(n < onstack_size ? onstack_size : n), a(allocate(n)) {
01541     int i=0;
01542     for (const T& x : aa)
01543       a[i++]=x;
01544   }
01545 
01546   template<class T>
01547   forceinline
01548   ArgArrayBase<T>::~ArgArrayBase(void) {
01549     if (capacity > onstack_size)
01550       heap.free(a,capacity);
01551   }
01552 
01553   template<class T>
01554   forceinline const ArgArrayBase<T>&
01555   ArgArrayBase<T>::operator =(const ArgArrayBase<T>& aa) {
01556     if (&aa != this) {
01557       if (capacity > onstack_size)
01558         heap.free(a,capacity);
01559       n = aa.n;
01560       capacity = (n < onstack_size ? onstack_size : n);
01561       a = allocate(aa.n);
01562       heap.copy<T>(a,aa.a,n);
01563     }
01564     return *this;
01565   }
01566 
01567   template<class T>
01568   forceinline int
01569   ArgArrayBase<T>::size(void) const {
01570     return n;
01571   }
01572 
01573   template<class T>
01574   forceinline T&
01575   ArgArrayBase<T>::operator [](int i) {
01576     assert((i>=0) && (i < n));
01577     return a[i];
01578   }
01579 
01580   template<class T>
01581   forceinline const T&
01582   ArgArrayBase<T>::operator [](int i) const {
01583     assert((i>=0) && (i < n));
01584     return a[i];
01585   }
01586 
01587   template<class T>
01588   forceinline typename ArgArrayBase<T>::iterator
01589   ArgArrayBase<T>::begin(void) {
01590     return a;
01591   }
01592 
01593   template<class T>
01594   forceinline typename ArgArrayBase<T>::const_iterator
01595   ArgArrayBase<T>::begin(void) const {
01596     return a;
01597   }
01598 
01599   template<class T>
01600   forceinline typename ArgArrayBase<T>::iterator
01601   ArgArrayBase<T>::end(void) {
01602     return a+n;
01603   }
01604 
01605   template<class T>
01606   forceinline typename ArgArrayBase<T>::const_iterator
01607   ArgArrayBase<T>::end(void) const {
01608     return a+n;
01609   }
01610 
01611   template<class T>
01612   forceinline typename ArgArrayBase<T>::reverse_iterator
01613   ArgArrayBase<T>::rbegin(void) {
01614     return reverse_iterator(a+n);
01615   }
01616 
01617   template<class T>
01618   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01619   ArgArrayBase<T>::rbegin(void) const {
01620     return const_reverse_iterator(a+n);
01621   }
01622 
01623   template<class T>
01624   forceinline typename ArgArrayBase<T>::reverse_iterator
01625   ArgArrayBase<T>::rend(void) {
01626     return reverse_iterator(a);
01627   }
01628 
01629   template<class T>
01630   forceinline typename ArgArrayBase<T>::const_reverse_iterator
01631   ArgArrayBase<T>::rend(void) const {
01632     return const_reverse_iterator(a);
01633   }
01634 
01635   template<class T> template<class A>
01636   A
01637   ArgArrayBase<T>::slice(int start, int inc, int maxN) {
01638     assert(n==0 || start < n);
01639     if (n==0 || maxN<0)
01640       maxN = n;
01641     int s;
01642     if (inc == 0)
01643       s = n-start;
01644     else if (inc > 0)
01645       s = (n-start)/inc + ((n-start) % inc == 0 ? 0 : 1);
01646     else
01647       s = (start+1)/-inc + ((start+1) % -inc == 0 ? 0 : 1);
01648     A r(std::min(maxN,s));
01649     for (int i=0; i<r.size(); i++, start+=inc)
01650       new (&r[i]) T(a[start]);
01651     return r;
01652   }
01653 
01654   template<class T> template<class A>
01655   inline A&
01656   ArgArrayBase<T>::append(const T& x) {
01657     resize(1);
01658     new (&a[n++]) T(x);
01659     return static_cast<A&>(*this);
01660   }
01661 
01662   template<class T>
01663   template<class InputIterator>
01664   inline
01665   ArgArrayBase<T>::ArgArrayBase(InputIterator first, InputIterator last)
01666   : n(0), capacity(onstack_size), a(allocate(0)) {
01667     while (first != last) {
01668       (void) append<ArgArrayBase<T>>(*first);
01669       ++first;
01670     }
01671   }
01672 
01673 
01674   template<class T> template<class A>
01675   inline A&
01676   ArgArrayBase<T>::append(const ArgArrayBase<T>& x) {
01677     resize(x.size());
01678     for (int i=0; i<x.size(); i++)
01679       new (&a[n++]) T(x[i]);
01680     return static_cast<A&>(*this);
01681   }
01682 
01683   template<class T> template<class A>
01684   inline A
01685   ArgArrayBase<T>::concat(const ArgArrayBase<T>& x) const {
01686     A r(n+x.n);
01687     for (int i=0; i<n; i++)
01688       new (&r[i]) T(a[i]);
01689     for (int i=0; i<x.n; i++)
01690       new (&r[n+i]) T(x.a[i]);
01691     return r;
01692   }
01693 
01694   template<class T> template<class A>
01695   inline A
01696   ArgArrayBase<T>::concat(const T& x) const {
01697     A r(n+1);
01698     for (int i=0; i<n; i++)
01699       new (&r[i]) T(a[i]);
01700     new (&r[n]) T(x);
01701     return r;
01702   }
01703 
01704 
01705   /*
01706    * Argument arrays
01707    *
01708    */
01709 
01710   template<class T>
01711   forceinline
01712   ArgArray<T>::ArgArray(void) {}
01713 
01714   template<class T>
01715   forceinline
01716   ArgArray<T>::ArgArray(int n)
01717     : ArgArrayBase<T>(n) {}
01718 
01719   template<class T>
01720   ArgArray<T>::ArgArray(int n, const T* a0)
01721     : ArgArrayBase<T>(n) {
01722     for (int i=0; i<n; i++)
01723       a[i] = a0[i];
01724   }
01725 
01726   template<class T>
01727   forceinline
01728   ArgArray<T>::ArgArray(const ArgArray<T>& aa)
01729     : ArgArrayBase<T>(aa) {}
01730 
01731   template<class T>
01732   forceinline
01733   ArgArray<T>::ArgArray(const std::vector<T>& aa)
01734     : ArgArrayBase<T>(aa) {}
01735 
01736   template<class T>
01737   forceinline
01738   ArgArray<T>::ArgArray(std::initializer_list<T> aa)
01739     : ArgArrayBase<T>(aa) {}
01740 
01741   template<class T>
01742   template<class InputIterator>
01743   forceinline
01744   ArgArray<T>::ArgArray(InputIterator first, InputIterator last)
01745     : ArgArrayBase<T>(first,last) {}
01746 
01747   template<class T>
01748   forceinline typename ArrayTraits<ArgArray<T>>::ArgsType
01749   ArgArray<T>::slice(int start, int inc, int maxN) {
01750     return ArgArrayBase<T>::template slice
01751       <typename ArrayTraits<ArgArray<T>>::ArgsType>
01752       (start,inc,maxN);
01753   }
01754 
01755   template<class T>
01756   forceinline typename ArrayTraits<ArgArray<T>>::ArgsType&
01757   ArgArray<T>::operator <<(const T& x) {
01758     return
01759       ArgArrayBase<T>::template append
01760         <typename ArrayTraits<ArgArray<T>>::ArgsType>(x);
01761   }
01762 
01763   template<class T>
01764   forceinline typename ArrayTraits<ArgArray<T>>::ArgsType&
01765   ArgArray<T>::operator <<(const ArgArray<T>& x) {
01766     return
01767       ArgArrayBase<T>::template append
01768         <typename ArrayTraits<ArgArray<T>>::ArgsType>(x);
01769   }
01770 
01771   template<class T>
01772   typename ArrayTraits<ArgArray<T>>::ArgsType
01773   operator +(const ArgArray<T>& x, const ArgArray<T>& y) {
01774     return x.template concat
01775       <typename ArrayTraits<ArgArray<T>>::ArgsType>(y);
01776   }
01777 
01778   template<class T>
01779   typename ArrayTraits<ArgArray<T>>::ArgsType
01780   operator +(const ArgArray<T>& x, const T& y) {
01781     return x.template concat
01782       <typename ArrayTraits<ArgArray<T>>::ArgsType>(y);
01783   }
01784 
01785   template<class T>
01786   typename ArrayTraits<ArgArray<T>>::ArgsType
01787   operator +(const T& x, const ArgArray<T>& y) {
01788     ArgArray<T> xa(1);
01789     xa[0] = x;
01790     return xa.template concat
01791       <typename ArrayTraits<ArgArray<T>>::ArgsType>(y);
01792   }
01793 
01794   /*
01795    * Argument arrays for variables
01796    *
01797    */
01798 
01799   template<class Var>
01800   forceinline
01801   VarArgArray<Var>::VarArgArray(void) {}
01802 
01803   template<class Var>
01804   forceinline
01805   VarArgArray<Var>::VarArgArray(int n) : ArgArrayBase<Var>(n) {}
01806 
01807   template<class Var>
01808   forceinline
01809   VarArgArray<Var>::VarArgArray(const VarArgArray<Var>& aa)
01810     : ArgArrayBase<Var>(aa) {}
01811 
01812   template<class Var>
01813   forceinline
01814   VarArgArray<Var>::VarArgArray(const std::vector<Var>& aa)
01815     : ArgArrayBase<Var>(aa) {}
01816 
01817   template<class Var>
01818   forceinline
01819   VarArgArray<Var>::VarArgArray(std::initializer_list<Var> aa)
01820     : ArgArrayBase<Var>(aa) {}
01821 
01822   template<class Var>
01823   template<class InputIterator>
01824   forceinline
01825   VarArgArray<Var>::VarArgArray(InputIterator first, InputIterator last)
01826     : ArgArrayBase<Var>(first,last) {}
01827 
01828   template<class Var>
01829   inline
01830   VarArgArray<Var>::VarArgArray(const VarArray<Var>& x)
01831     : ArgArrayBase<Var>(x.size()) {
01832     for (int i=0; i<x.size(); i++)
01833       a[i]=x[i];
01834   }
01835 
01836   template<class Var>
01837   forceinline typename ArrayTraits<VarArgArray<Var>>::ArgsType
01838   VarArgArray<Var>::slice(int start, int inc, int maxN) {
01839     return ArgArrayBase<Var>::template slice
01840       <typename ArrayTraits<VarArgArray<Var>>::ArgsType>
01841         (start,inc,maxN);
01842   }
01843 
01844   template<class Var>
01845   forceinline typename ArrayTraits<VarArgArray<Var>>::ArgsType&
01846   VarArgArray<Var>::operator <<(const Var& x) {
01847     return
01848       ArgArrayBase<Var>::template append
01849         <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(x);
01850   }
01851 
01852   template<class Var>
01853   forceinline typename ArrayTraits<VarArgArray<Var>>::ArgsType&
01854   VarArgArray<Var>::operator <<(const VarArgArray<Var>& x) {
01855     return
01856       ArgArrayBase<Var>::template append
01857         <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(x);
01858   }
01859 
01860   template<class Var>
01861   typename ArrayTraits<VarArgArray<Var>>::ArgsType
01862   operator +(const VarArgArray<Var>& x, const VarArgArray<Var>& y) {
01863     return x.template concat
01864       <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(y);
01865   }
01866 
01867   template<class Var>
01868   typename ArrayTraits<VarArgArray<Var>>::ArgsType
01869   operator +(const VarArgArray<Var>& x, const Var& y) {
01870     return x.template concat
01871       <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(y);
01872   }
01873 
01874   template<class Var>
01875   typename ArrayTraits<VarArgArray<Var>>::ArgsType
01876   operator +(const Var& x, const VarArgArray<Var>& y) {
01877     VarArgArray<Var> xa(1);
01878     xa[0] = x;
01879     return xa.template concat
01880       <typename ArrayTraits<VarArgArray<Var>>::ArgsType>(y);
01881   }
01882 
01883   template<class Var>
01884   forceinline bool
01885   VarArgArray<Var>::assigned(void) const {
01886     for (int i=0; i<n; i++)
01887       if (!a[i].assigned())
01888         return false;
01889     return true;
01890   }
01891 
01892 
01893   /*
01894    * Checking for multiple occurences of the same variable
01895    *
01896    */
01897   template<class Var>
01898   bool
01899   same(VarArgArray<Var> x, VarArgArray<Var> y) {
01900     if ((x.size() == 0) || (y.size() == 0))
01901       return false;
01902     Region r;
01903     void** px = r.alloc<void*>(x.size());
01904     int j=0;
01905     for (int i=0; i<x.size(); i++)
01906       if (!x[i].assigned())
01907         px[j++] = x[i].varimp();
01908     if (j == 0)
01909       return false;
01910     void** py = r.alloc<void*>(y.size());
01911     int k=0;
01912     for (int i=0; i<y.size(); i++)
01913       if (!y[i].assigned())
01914         py[k++] = y[i].varimp();
01915     if (k == 0)
01916       return false;
01917     return Kernel::duplicates(px,j,py,k);
01918   }
01919 
01920   template<class Var>
01921   bool
01922   same(VarArgArray<Var> x, Var y) {
01923     if (y.assigned())
01924       return false;
01925     for (int i=0; i<x.size(); i++)
01926       if (x[i].varimp() == y.varimp())
01927         return true;
01928     return false;
01929   }
01930 
01931   template<class Var>
01932   forceinline bool
01933   same(Var x, VarArgArray<Var> y) {
01934     return same(y,x);
01935   }
01936 
01937   template<class Var>
01938   bool
01939   same(VarArgArray<Var> x) {
01940     if (x.size() < 2)
01941       return false;
01942     Region r;
01943     void** px = r.alloc<void*>(x.size());
01944     int j=0;
01945     for (int i=0; i<x.size(); i++)
01946       if (!x[i].assigned())
01947         px[j++] = x[i].varimp();
01948     return (j > 1) && Kernel::duplicates(px,j);
01949   }
01950 
01951 
01952 
01953   /*
01954    * Interdependent code
01955    *
01956    */
01957 
01958   template<class Var>
01959   inline
01960   VarArray<Var>::VarArray(Space& home, const VarArgArray<Var>& a)
01961     : n(a.size()) {
01962     if (n>0) {
01963       x = home.alloc<Var>(n);
01964       for (int i=0; i<n; i++)
01965         x[i] = a[i];
01966     } else {
01967       x = nullptr;
01968     }
01969   }
01970 
01971 
01972   /*
01973    * Printing of arrays
01974    *
01975    */
01976   template<class Char, class Traits, class Var>
01977   std::basic_ostream<Char,Traits>&
01978   operator <<(std::basic_ostream<Char,Traits>& os,
01979               const VarArray<Var>& x) {
01980     std::basic_ostringstream<Char,Traits> s;
01981     s.copyfmt(os); s.width(0);
01982     s << '{';
01983     if (x.size() > 0) {
01984       s << x[0];
01985       for (int i=1; i<x.size(); i++)
01986         s << ", " << x[i];
01987     }
01988     s << '}';
01989     return os << s.str();
01990   }
01991 
01992   template<class Char, class Traits, class View>
01993   std::basic_ostream<Char,Traits>&
01994   operator <<(std::basic_ostream<Char,Traits>& os,
01995              const ViewArray<View>& x) {
01996     std::basic_ostringstream<Char,Traits> s;
01997     s.copyfmt(os); s.width(0);
01998     s << '{';
01999     if (x.size() > 0) {
02000       s << x[0];
02001       for (int i=1; i<x.size(); i++)
02002         s << ", " << x[i];
02003     }
02004     s << '}';
02005     return os << s.str();
02006   }
02007 
02008   template<class Char, class Traits, class T>
02009   std::basic_ostream<Char,Traits>&
02010   operator <<(std::basic_ostream<Char,Traits>& os,
02011              const ArgArrayBase<T>& x) {
02012     std::basic_ostringstream<Char,Traits> s;
02013     s.copyfmt(os); s.width(0);
02014     s << '{';
02015     if (x.size() > 0) {
02016       s << x[0];
02017       for (int i=1; i<x.size(); i++)
02018         s << ", " << x[i];
02019     }
02020     s << '}';
02021     return os << s.str();
02022   }
02023 
02024 }
02025 
02026 // STATISTICS: kernel-other