00001 # ifndef CPPAD_VECTOR_INCLUDED
00002 # define CPPAD_VECTOR_INCLUDED
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 # include <cstddef>
00216 # include <iostream>
00217 # include <limits>
00218 # include <cppad/local/cppad_assert.hpp>
00219 # include <cppad/track_new_del.hpp>
00220 
00221 # ifndef CPPAD_NULL
00222 # define CPPAD_NULL 0
00223 # endif
00224 
00225 namespace CppAD { 
00226 
00227 
00228 
00229 template <class Type>
00230 class vector {
00231 private:
00232         size_t capacity;
00233         size_t length;
00234         Type   * data;
00235 public:
00236         
00237         typedef Type value_type;
00238 
00239         
00240         inline vector(void) : capacity(0), length(0) , data(CPPAD_NULL)
00241         { }
00242         
00243         inline vector(size_t n) : capacity(n), length(n)
00244         {
00245                 data = CPPAD_NULL;
00246                 if( length > 0 )
00247                         data = CPPAD_TRACK_NEW_VEC(capacity, data);
00248         }
00249         
00250         inline vector(const vector &x) : capacity(x.length), length(x.length)
00251         {       size_t i;
00252                 data = CPPAD_NULL;
00253                 if( length > 0 )
00254                         data = CPPAD_TRACK_NEW_VEC(capacity, data);
00255 
00256                 for(i = 0; i < length; i++)
00257                         data[i] = x.data[i];
00258         }
00259         
00260         ~vector(void)
00261         {       if( data != CPPAD_NULL )
00262                         CPPAD_TRACK_DEL_VEC(data); 
00263         }
00264 
00265         
00266         inline size_t size(void) const
00267         {       return length; }
00268 
00269         
00270         inline void resize(size_t n)
00271         {       length = n;
00272                 if( (capacity >= n) & (n > 0)  )
00273                         return;
00274                 if( data != CPPAD_NULL  )
00275                         CPPAD_TRACK_DEL_VEC(data);
00276                 capacity = n;
00277                 if( capacity == 0 )
00278                         data = CPPAD_NULL;
00279                 else    data = CPPAD_TRACK_NEW_VEC(capacity, data);
00280         }
00281         
00282         inline vector & operator=(const vector &x)
00283         {       size_t i;
00284                 CPPAD_ASSERT_KNOWN(
00285                         length == x.length ,
00286                         "size miss match in assignment operation"
00287                 );
00288                 for(i = 0; i < length; i++)
00289                         data[i] = x.data[i];
00290                 return *this;
00291         }
00292         
00293         Type & operator[](size_t i)
00294         {       CPPAD_ASSERT_KNOWN(
00295                         i < length,
00296                         "vector index greater than or equal vector size"
00297                 );
00298                 return data[i]; 
00299         }
00300         
00301         const Type & operator[](size_t i) const
00302         {       CPPAD_ASSERT_KNOWN(
00303                         i < length,
00304                         "vector index greater than or equal vector size"
00305                 );
00306                 return data[i]; 
00307         }
00308         
00309         void push_back(const Type &x)
00310         {       CPPAD_ASSERT_UNKNOWN( length <= capacity );
00311                 if( length == capacity )
00312                 {       
00313                         if( capacity == 0 )
00314                                 capacity = 2;
00315                         else    capacity = 2 * length;
00316                         data = CPPAD_TRACK_EXTEND(capacity, length, data);
00317                 }
00318                 data[length++] = x;
00319         }
00320 };
00321 
00322 
00323 template <class Type>
00324 inline std::ostream& operator << (
00325         std::ostream              &os  , 
00326         const CppAD::vector<Type> &vec )
00327 {       size_t i = 0;
00328         size_t n = vec.size();
00329 
00330         os << "{ ";
00331         while(i < n)
00332         {       os << vec[i++]; 
00333                 if( i < n )
00334                         os << ", ";
00335         }
00336         os << " }";
00337         return os;
00338 }
00339 
00340 
00341 
00342 
00343 class vectorBoolElement {
00344         typedef size_t UnitType;
00345 private:
00346         UnitType *unit;
00347         UnitType mask;
00348 public:
00349         vectorBoolElement(UnitType *unit_, UnitType mask_)
00350         : unit(unit_) , mask(mask_)
00351         { }
00352         vectorBoolElement(const vectorBoolElement &e)
00353         : unit(e.unit) , mask(e.mask)
00354         { }
00355         operator bool() const
00356         {       return (*unit & mask) != 0; }
00357         vectorBoolElement& operator=(bool bit)
00358         {       if(bit)
00359                         *unit |= mask;
00360                 else    *unit &= ~mask;
00361                 return *this;
00362         } 
00363 };
00364 
00365 class vectorBool {
00366         typedef size_t UnitType;
00367 private:
00368         static const  size_t BitPerUnit 
00369                 = std::numeric_limits<UnitType>::digits;
00370         size_t    nunit;
00371         size_t    length;
00372         UnitType *data;
00373 public:
00374         
00375         typedef bool value_type;
00376 
00377         
00378         inline vectorBool(void) : nunit(0), length(0), data(CPPAD_NULL)
00379         { }
00380         
00381         inline vectorBool(size_t n) : nunit(0), length(0), data(CPPAD_NULL)
00382         {       if( n == 0 )
00383                         data = CPPAD_NULL;
00384                 else 
00385                 {       nunit    = (n - 1) / BitPerUnit + 1;
00386                         length   = n;
00387                         data     = CPPAD_TRACK_NEW_VEC(nunit, data);
00388                 }
00389         }
00390         
00391         inline vectorBool(const vectorBool &v) 
00392         : nunit(v.nunit), length(v.length)
00393         {       size_t i;
00394                 if( nunit == 0 )
00395                         data = CPPAD_NULL;
00396                 else    data = CPPAD_TRACK_NEW_VEC(nunit, data);
00397 
00398                 for(i = 0; i < nunit; i++)
00399                         data[i] = v.data[i];
00400         }
00401         
00402         ~vectorBool(void)
00403         {       if( data != CPPAD_NULL )
00404                         CPPAD_TRACK_DEL_VEC(data);
00405         }
00406 
00407         
00408         inline size_t size(void) const
00409         {       return length; }
00410 
00411         
00412         inline void resize(size_t n)
00413         {       length = n;
00414                 if( (nunit * BitPerUnit >= n) & (n > 0) )
00415                         return;
00416                 if( data != CPPAD_NULL )
00417                         CPPAD_TRACK_DEL_VEC(data);
00418                 if( n == 0 )
00419                 {       nunit = 0;
00420                         data = CPPAD_NULL;
00421                 }
00422                 else
00423                 {       nunit    = (n - 1) / BitPerUnit + 1;
00424                         data     = CPPAD_TRACK_NEW_VEC(nunit, data);
00425                 }
00426         }
00427         
00428         inline vectorBool & operator=(const vectorBool &v)
00429         {       size_t i;
00430                 CPPAD_ASSERT_KNOWN(
00431                         length == v.length ,
00432                         "size miss match in assignment operation"
00433                 );
00434                 CPPAD_ASSERT_UNKNOWN( nunit == v.nunit );
00435                 for(i = 0; i < nunit; i++)
00436                         data[i] = v.data[i];
00437                 return *this;
00438         }
00439         
00440         vectorBoolElement operator[](size_t k)
00441         {       size_t i, j;
00442                 CPPAD_ASSERT_KNOWN(
00443                         k < length,
00444                         "vector index greater than or equal vector size"
00445                 );
00446                 i    = k / BitPerUnit;
00447                 j    = k - i * BitPerUnit;
00448                 return vectorBoolElement(data + i , UnitType(1) << j );
00449         }
00450         
00451         bool operator[](size_t k) const
00452         {       size_t i, j;
00453                 UnitType unit;
00454                 UnitType mask;
00455                 CPPAD_ASSERT_KNOWN(
00456                         k < length,
00457                         "vector index greater than or equal vector size"
00458                 );
00459                 i    = k / BitPerUnit;
00460                 j    = k - i * BitPerUnit;
00461                 unit = data[i];
00462                 mask = UnitType(1) << j;
00463                 return (unit & mask) != 0;
00464         }
00465         
00466         void push_back(bool bit)
00467         {       size_t i, j;
00468                 UnitType mask;
00469                 CPPAD_ASSERT_UNKNOWN( length <= nunit * BitPerUnit );
00470                 if( length == nunit * BitPerUnit )
00471                 {       
00472                         data = CPPAD_TRACK_EXTEND(nunit+1, nunit, data);
00473                         nunit++;
00474                 }
00475                 i    = length / BitPerUnit;
00476                 j    = length - i * BitPerUnit;
00477                 mask = UnitType(1) << j;
00478                 if( bit )
00479                         data[i] |= mask;
00480                 else    data[i] &= ~mask;
00481                 length++;
00482         }
00483 };
00484 
00485 
00486 inline std::ostream& operator << (
00487         std::ostream     &os  , 
00488         const vectorBool &v   )
00489 {       size_t i = 0;
00490         size_t n = v.size();
00491 
00492         while(i < n)
00493                 os << v[i++]; 
00494         return os;
00495 }
00496 
00497 } 
00498 
00499 
00500 # endif