CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
vector.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_UTILITY_VECTOR_HPP
2 # define CPPAD_UTILITY_VECTOR_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 
15 /*
16 $begin CppAD_vector$$
17 $spell
18  rvalues
19  thread_alloc
20  cppad.hpp
21  Bool
22  resize
23  cout
24  endl
25  std
26  Cpp
27  const
28  vec
29  ostream
30  elem
31 $$
32 
33 
34 $section The CppAD::vector Template Class$$
35 $mindex vector CppAD [] push thread_alloc$$
36 
37 $head Syntax$$
38 $codei%# include <cppad/utility/vector.hpp>%$$
39 
40 $head Description$$
41 The include file $code cppad/vector.hpp$$ defines the
42 vector template class $code CppAD::vector$$.
43 This is a $cref SimpleVector$$ template class and in addition
44 it has the features listed below:
45 
46 $head Include$$
47 The file $code cppad/vector.hpp$$ is included by $code cppad/cppad.hpp$$
48 but it can also be included separately with out the rest of the
49 CppAD include files.
50 
51 $head capacity$$
52 If $icode x$$ is a $codei%CppAD::vector<%Scalar%>%$$,
53 and $icode cap$$ is a $code size_t$$ object,
54 $codei%
55  %cap% = %x%.capacity()
56 %$$
57 set $icode cap$$ to the number of $icode Scalar$$ objects that
58 could fit in the memory currently allocated for $icode x$$.
59 Note that
60 $codei%
61  %x%.size() <= %x%.capacity()
62 %$$
63 
64 $head Assignment$$
65 If $icode x$$ and $icode y$$ are
66 $codei%CppAD::vector<%Scalar%>%$$ objects,
67 $codei%
68  %y% = %x%
69 %$$
70 has all the properties listed for a
71 $cref/simple vector assignment/SimpleVector/Assignment/$$
72 plus the following:
73 
74 $subhead Check Size$$
75 The $code CppAD::vector$$ template class will check that
76 the size of $icode x$$ is either zero or the size of $icode y$$
77 before doing the assignment.
78 If this is not the case, $code CppAD::vector$$ will use
79 $cref ErrorHandler$$
80 to generate an appropriate error report.
81 Allowing for assignment to a vector with size zero makes the following
82 code work:
83 $codei%
84  CppAD::vector<%Scalar%> %y%;
85  %y% = %x%;
86 %$$
87 
88 $subhead Return Reference$$
89 A reference to the vector $icode y$$ is returned.
90 An example use of this reference is in multiple assignments of the form
91 $codei%
92  %z% = %y% = %x%
93 %$$
94 
95 $subhead Move Semantics$$
96 If the C++ compiler supports move semantic rvalues using the $code &&$$
97 syntax, then it will be used during the vector assignment statement.
98 This means that return values and other temporaries are not be copied,
99 but rather pointers are transferred.
100 
101 $head Element Access$$
102 If $icode x$$ is a $codei%CppAD::vector<%Scalar%>%$$ object
103 and $icode i$$ has type $code size_t$$,
104 $codei%
105  %x%[%i%]
106 %$$
107 has all the properties listed for a
108 $cref/simple vector element access/SimpleVector/Element Access/$$
109 plus the following:
110 $pre
111 
112 $$
113 The object $icode%x%[%i%]%$$ has type $icode Scalar$$
114 (is not possibly a different type that can be converted to $icode Scalar$$).
115 $pre
116 
117 $$
118 If $icode i$$ is not less than the size of the $icode x$$,
119 $code CppAD::vector$$ will use
120 $cref ErrorHandler$$
121 to generate an appropriate error report.
122 
123 $head push_back$$
124 If $icode x$$ is a $codei%CppAD::vector<%Scalar%>%$$ object
125 with size equal to $icode n$$ and
126 $icode s$$ has type $icode Scalar$$,
127 $codei%
128  %x%.push_back(%s%)
129 %$$
130 extends the vector $icode x$$ so that its new size is $icode n$$ plus one
131 and $icode%x%[%n%]%$$ is equal to $icode s$$
132 (equal in the sense of the $icode Scalar$$ assignment operator).
133 
134 $head push_vector$$
135 If $icode x$$ is a $codei%CppAD::vector<%Scalar%>%$$ object
136 with size equal to $icode n$$ and
137 $icode v$$ is a $cref/simple vector/SimpleVector/$$
138 with elements of type $icode Scalar$$ and size $icode m$$,
139 $codei%
140  %x%.push_vector(%v%)
141 %$$
142 extends the vector $icode x$$ so that its new size is $icode%n%+%m%$$
143 and $icode%x%[%n% + %i%]%$$ is equal to $icode%v%[%i%]%$$
144 for $icode%i = 1 , ... , m-1%$$
145 (equal in the sense of the $icode Scalar$$ assignment operator).
146 
147 $head Output$$
148 If $icode x$$ is a $codei%CppAD::vector<%Scalar%>%$$ object
149 and $icode os$$ is an $code std::ostream$$,
150 and the operation
151 $codei%
152  %os% << %x%
153 %$$
154 will output the vector $icode x$$ to the standard
155 output stream $icode os$$.
156 The elements of $icode x$$ are enclosed at the beginning by a
157 $code {$$ character,
158 they are separated by $code ,$$ characters,
159 and they are enclosed at the end by $code }$$ character.
160 It is assumed by this operation that if $icode e$$
161 is an object with type $icode Scalar$$,
162 $codei%
163  %os% << %e%
164 %$$
165 will output the value $icode e$$ to the standard
166 output stream $icode os$$.
167 
168 $head resize$$
169 The call $icode%x%.resize(%n%)%$$ set the size of $icode x$$ equal to
170 $icode n$$.
171 If $icode%n% <= %x%.capacity()%$$,
172 no memory is freed or allocated, the capacity of $icode x$$ does not change,
173 and the data in $icode x$$ is preserved.
174 If $icode%n% > %x%.capacity()%$$,
175 new memory is allocated and the data in $icode x$$ is lost
176 (not copied to the new memory location).
177 
178 $head clear$$
179 All memory allocated for the vector is freed
180 and both its size and capacity are set to zero.
181 This can be useful when using very large vectors
182 and when checking for memory leaks (and there are global vectors)
183 see the $cref/memory/CppAD_vector/Memory and Parallel Mode/$$ discussion.
184 
185 $head data$$
186 If $icode x$$ is a $codei%CppAD::vector<%Scalar%>%$$ object
187 $codei%
188  %x%.data()
189 %$$
190 returns a pointer to a $icode Scalar$$ object such that for
191 $codei%0 <= %i% < %x%.size()%$$,
192 $icode%x%[%i%]%$$ and $icode%x%.data()[%i%]%$$
193 are the same $icode Scalar$$ object.
194 If $icode x$$ is $code const$$, the pointer is $code const$$.
195 If $icode%x%.capacity()%$$ is zero, the value of the pointer is not defined.
196 The pointer may no longer be valid after the following operations on
197 $icode x$$:
198 its destructor,
199 $code clear$$,
200 $code resize$$,
201 $code push_back$$,
202 $code push_vector$$,
203 assignment to another vector when original size of $icode x$$ is zero.
204 
205 $head vectorBool$$
206 The file $code <cppad/vector.hpp>$$ also defines the class
207 $code CppAD::vectorBool$$.
208 This has the same specifications as $code CppAD::vector<bool>$$
209 with the following exceptions:
210 
211 $subhead Memory$$
212 The class $code vectorBool$$ conserves on memory
213 (on the other hand, $code CppAD::vector<bool>$$ is expected to be faster
214 than $code vectorBool$$).
215 
216 $subhead bit_per_unit$$
217 The static function call
218 $codei%
219  %s% = vectorBool::bit_per_unit()
220 %$$
221 returns the $code size_t$$ value $icode s$$
222 which is equal to the number of boolean values (bits) that are
223 packed into one operational unit.
224 For example, a logical $code or$$
225 acts on this many boolean values with one operation.
226 
227 $subhead data$$
228 The $cref/data/CppAD_vector/data/$$ function is not supported by
229 $code vectorBool$$.
230 
231 $subhead Output$$
232 The $code CppAD::vectorBool$$ output operator
233 prints each boolean value as
234 a $code 0$$ for false,
235 a $code 1$$ for true,
236 and does not print any other output; i.e.,
237 the vector is written a long sequence of zeros and ones with no
238 surrounding $code {$$, $code }$$ and with no separating commas or spaces.
239 
240 $subhead Element Type$$
241 If $icode x$$ has type $code vectorBool$$
242 and $icode i$$ has type $code size_t$$,
243 the element access value $icode%x%[%i%]%$$ has an unspecified type,
244 referred to here as $icode elementType$$, that supports the following
245 operations:
246 
247 $list number$$
248 $icode elementType$$ can be converted to $code bool$$; e.g.
249 the following syntax is supported:
250 $codei%
251  static_cast<bool>( %x%[%i%] )
252 %$$
253 
254 $lnext
255 $icode elementType$$ supports the assignment operator $code =$$ where the
256 right hand side is a $code bool$$ or an $icode elementType$$ object; e.g.,
257 if $icode y$$ has type $code bool$$, the following syntax is supported:
258 $codei%
259  %x%[%i%] = %y%
260 %$$
261 
262 $lnext
263 The result of an assignment to an $icode elementType$$
264 also has type $icode elementType$$.
265 Thus, if $icode z$$ has type $code bool$$, the following syntax is supported:
266 $codei%
267  %z% = %x%[%i%] = %y%
268 %$$
269 $lend
270 
271 $head Memory and Parallel Mode$$
272 These vectors use the multi-threaded fast memory allocator
273 $cref thread_alloc$$:
274 
275 $list number$$
276 The routine $cref/parallel_setup/ta_parallel_setup/$$ must
277 be called before these vectors can be used
278 $cref/in parallel/ta_in_parallel/$$.
279 $lnext
280 Using these vectors affects the amount of memory
281 $cref/in_use/ta_inuse/$$ and $cref/available/ta_available/$$.
282 $lnext
283 Calling $cref/clear/CppAD_vector/clear/$$,
284 makes the corresponding memory available (though $code thread_alloc$$)
285 to the current thread.
286 $lnext
287 Available memory
288 can then be completely freed using $cref/free_available/ta_free_available/$$.
289 $lend
290 
291 $head Example$$
292 $children%
293  example/utility/cppad_vector.cpp%
294  example/utility/vector_bool.cpp
295 %$$
296 The files
297 $cref cppad_vector.cpp$$ and
298 $cref vector_bool.cpp$$ each
299 contain an example and test of this template class.
300 They return true if they succeed and false otherwise.
301 
302 $head Exercise$$
303 Create and run a program that contains the following code:
304 $codep
305  CppAD::vector<double> x(3);
306  size_t i;
307  for(i = 0; i < 3; i++)
308  x[i] = 4. - i;
309  std::cout << "x = " << x << std::endl;
310 $$
311 
312 $end
313 
314 
315 $end
316 
317 ------------------------------------------------------------------------
318 */
319 
320 # include <cstddef>
321 # include <iostream>
322 # include <limits>
323 # include <cppad/core/cppad_assert.hpp>
326 
327 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
328 /*!
329 \file vector.hpp
330 File used to define CppAD::vector and CppAD::vectorBool
331 */
332 
333 // ---------------------------------------------------------------------------
334 /*!
335 The CppAD Simple Vector template class.
336 */
337 template <class Type>
338 class vector {
339 private:
340  /// maximum number of Type elements current allocation can hold
341  size_t capacity_;
342  /// number of Type elements currently in this vector
343  size_t length_;
344  /// pointer to the first type elements
345  /// (not defined and should not be used when capacity_ = 0)
346  Type* data_;
347  /// delete data pointer
348  void delete_data(Type* data_ptr)
349  { thread_alloc::delete_array(data_ptr); }
350 public:
351  /// type of the elements in the vector
352  typedef Type value_type;
353 
354  /// default constructor sets capacity_ = length_ = data_ = 0
355  inline vector(void)
356  : capacity_(0), length_(0), data_(CPPAD_NULL)
357  { }
358  /// sizing constructor
359  inline vector(
360  /// number of elements in this vector
361  size_t n
362  ) : capacity_(0), length_(0), data_(CPPAD_NULL)
363  { resize(n); }
364 
365  /// copy constructor
366  inline vector(
367  /// the *this vector will be a copy of \c x
368  const vector& x
369  ) : capacity_(0), length_(0), data_(CPPAD_NULL)
370  { resize(x.length_);
371 
372  // copy the data
373  for(size_t i = 0; i < length_; i++)
374  data_[i] = x.data_[i];
375  }
376  /// destructor
377  ~vector(void)
378  { if( capacity_ > 0 )
380  }
381 
382  /// maximum number of elements current allocation can store
383  inline size_t capacity(void) const
384  { return capacity_; }
385 
386  /// number of elements currently in this vector.
387  inline size_t size(void) const
388  { return length_; }
389 
390  /// raw pointer to the data
391  inline Type* data(void)
392  { return data_; }
393 
394  /// const raw pointer to the data
395  inline const Type* data(void) const
396  { return data_; }
397 
398  /// change the number of elements in this vector.
399  inline void resize(
400  /// new number of elements for this vector
401  size_t n
402  )
403  { length_ = n;
404 
405  // check if we must allocate new memory
406  if( capacity_ < length_ )
407  {
408  // check if there is old memory to be freed
409  if( capacity_ > 0 )
411 
412  // get new memory and set capacity
413  data_ = thread_alloc::create_array<Type>(length_, capacity_);
414  }
415  }
416 
417  /// free memory and set number of elements to zero
418  inline void clear(void)
419  { length_ = 0;
420  // check if there is old memory to be freed
421  if( capacity_ > 0 )
423  capacity_ = 0;
424  }
425 
426  /// vector assignment operator
427  inline vector& operator=(
428  /// right hand size of the assingment operation
429  const vector& x
430  )
431  { size_t i;
432  // If original length is zero, then resize it.
433  // Otherwise a length mismatch is an error.
434  if( length_ == 0 )
435  resize( x.length_ );
437  length_ == x.length_ ,
438  "vector: size miss match in assignment operation"
439  );
440  for(i = 0; i < length_; i++)
441  data_[i] = x.data_[i];
442  return *this;
443  }
444 # if CPPAD_USE_CPLUSPLUS_2011
445  /// vector assignment operator with move semantics
446  inline vector& operator=(
447  /// right hand size of the assingment operation
448  vector&& x
449  )
451  length_ == x.length_ || (length_ == 0),
452  "vector: size miss match in assignment operation"
453  );
454  if( this != &x )
455  { clear();
456  //
457  length_ = x.length_;
458  capacity_ = x.capacity_;
459  data_ = x.data_;
460  //
461  x.length_ = 0;
462  x.capacity_ = 0;
463  x.data_ = CPPAD_NULL;
464  }
465  return *this;
466  }
467 # endif
468  /// non-constant element access; i.e., we can change this element value
469  Type& operator[](
470  /// element index, must be less than length
471  size_t i
472  )
474  i < length_,
475  "vector: index greater than or equal vector size"
476  );
477  return data_[i];
478  }
479  /// constant element access; i.e., we cannot change this element value
480  const Type& operator[](
481  /// element index, must be less than length
482  size_t i
483  ) const
485  i < length_,
486  "vector: index greater than or equal vector size"
487  );
488  return data_[i];
489  }
490  /// add an element to the back of this vector
491  void push_back(
492  /// value of the element
493  const Type& s
494  )
495  { // case where no allocation is necessary
496  if( length_ + 1 <= capacity_ )
497  { data_[length_++] = s;
498  return;
499  }
501 
502  // store old length, capacity and data
503  size_t old_length = length_;
504  size_t old_capacity = capacity_;
505  Type* old_data = data_;
506 
507  // set the new length, capacity and data
508  length_ = 0;
509  capacity_ = 0;
510  resize(old_length + 1);
511 
512  // copy old data values
513  for(size_t i = 0; i < old_length; i++)
514  data_[i] = old_data[i];
515 
516  // put the new element in the vector
517  CPPAD_ASSERT_UNKNOWN( old_length + 1 <= capacity_ );
518  data_[old_length] = s;
519 
520  // free old data
521  if( old_capacity > 0 )
522  delete_data(old_data);
523 
524  CPPAD_ASSERT_UNKNOWN( old_length + 1 == length_ );
526  }
527 
528  /*! add vector to the back of this vector
529  (we could not use push_back because MS V++ 7.1 did not resolve
530  to non-template member function when scalar is used.)
531  */
532  template <class Vector>
534  /// value of the vector that we are adding
535  const Vector& v
536  )
537  { CheckSimpleVector<Type, Vector>();
538  size_t m = v.size();
539 
540  // case where no allcoation is necessary
541  if( length_ + m <= capacity_ )
542  { for(size_t i = 0; i < m; i++)
543  data_[length_++] = v[i];
544  return;
545  }
546 
547  // store old length, capacity and data
548  size_t old_length = length_;
549  size_t old_capacity = capacity_;
550  Type* old_data = data_;
551 
552  // set new length, capacity and data
553  length_ = 0;
554  capacity_ = 0;
555  resize(old_length + m);
556 
557  // copy old data values
558  for(size_t i = 0; i < old_length; i++)
559  data_[i] = old_data[i];
560 
561  // put the new elements in the vector
562  CPPAD_ASSERT_UNKNOWN( old_length + m <= capacity_ );
563  for(size_t i = 0; i < m; i++)
564  data_[old_length + i] = v[i];
565 
566  // free old data
567  if( old_capacity > 0 )
568  delete_data(old_data);
569 
570  CPPAD_ASSERT_UNKNOWN( old_length + m == length_ );
572  }
573 };
574 
575 /// output a vector
576 template <class Type>
577 inline std::ostream& operator << (
578  /// stream to write the vector to
579  std::ostream& os ,
580  /// vector that is output
581  const CppAD::vector<Type>& vec )
582 { size_t i = 0;
583  size_t n = vec.size();
584 
585  os << "{ ";
586  while(i < n)
587  { os << vec[i++];
588  if( i < n )
589  os << ", ";
590  }
591  os << " }";
592  return os;
593 }
594 
595 // ---------------------------------------------------------------------------
596 /*!
597 Class that is used to hold a non-constant element of a vector.
598 */
600  /// the boolean data is packed with sizeof(UnitType) bits per value
601  typedef size_t UnitType;
602 private:
603  /// pointer to the UnitType value holding this eleemnt
605  /// mask for the bit corresponding to this element
606  /// (all zero except for bit that corresponds to this element)
608 public:
609  /// constructor from member values
611  /// unit for this element
612  UnitType* unit ,
613  /// mask for this element
614  UnitType mask )
615  : unit_(unit) , mask_(mask)
616  { }
617  /// constuctor from another element
619  /// other element
620  const vectorBoolElement& e )
621  : unit_(e.unit_) , mask_(e.mask_)
622  { }
623  /// conversion to a boolean value
624  operator bool() const
625  { return (*unit_ & mask_) != 0; }
626  /// assignment of this element to a bool
628  /// right hand side for assignment
629  bool bit
630  )
631  { if(bit)
632  *unit_ |= mask_;
633  else *unit_ &= ~mask_;
634  return *this;
635  }
636  /// assignment of this element to another element
638  { if( *(e.unit_) & e.mask_ )
639  *unit_ |= mask_;
640  else *unit_ &= ~mask_;
641  return *this;
642  }
643 };
644 
645 class vectorBool {
646  /// the boolean data is packed with sizeof(UnitType) bits per value
647  typedef size_t UnitType;
648 private:
649  /// number of bits packed into each UnitType value in data_
650  static const size_t bit_per_unit_
651  = std::numeric_limits<UnitType>::digits;
652  /// number of UnitType values in data_
653  size_t n_unit_;
654  /// number of bits currently stored in this vector
655  size_t length_;
656  /// pointer to where the bits are stored
658 
659  /// minimum number of UnitType values that can store length_ bits
660  /// (note that this is really a function of length_)
661  size_t unit_min(void)
662  { if( length_ == 0 )
663  return 0;
664  return (length_ - 1) / bit_per_unit_ + 1;
665  }
666 public:
667  /// type corresponding to the elements of this vector
668  /// (note that non-const elements actually use vectorBoolElement)
669  typedef bool value_type;
670 
671  // static member function
672  static size_t bit_per_unit(void)
673  { return bit_per_unit_; }
674 
675  /// default constructor (sets all member data to zero)
676  inline vectorBool(void) : n_unit_(0), length_(0), data_(CPPAD_NULL)
677  { }
678  /// sizing constructor
679  inline vectorBool(
680  /// number of bits in this vector
681  size_t n
682  ) : n_unit_(0), length_(n), data_(CPPAD_NULL)
683  { if( length_ > 0 )
684  { // set n_unit and data
685  size_t min_unit = unit_min();
686  data_ = thread_alloc::create_array<UnitType>(min_unit, n_unit_);
687  }
688  }
689  /// copy constructor
690  inline vectorBool(
691  /// the *this vector will be a copy of \c v
692  const vectorBool& v
693  ) : n_unit_(0), length_(v.length_), data_(CPPAD_NULL)
694  { if( length_ > 0 )
695  { // set n_unit and data
696  size_t min_unit = unit_min();
697  data_ = thread_alloc::create_array<UnitType>(min_unit, n_unit_);
698 
699  // copy values using UnitType assignment operator
700  CPPAD_ASSERT_UNKNOWN( min_unit <= v.n_unit_ );
701  size_t i;
702  for(i = 0; i < min_unit; i++)
703  data_[i] = v.data_[i];
704  }
705  }
706  /// destructor
708  { if( n_unit_ > 0 )
710  }
711 
712  /// number of elements in this vector
713  inline size_t size(void) const
714  { return length_; }
715 
716  /// maximum number of elements current allocation can store
717  inline size_t capacity(void) const
718  { return n_unit_ * bit_per_unit_; }
719 
720  /// change number of elements in this vector
721  inline void resize(
722  /// new number of elements for this vector
723  size_t n
724  )
725  { length_ = n;
726  // check if we can use the current memory
727  size_t min_unit = unit_min();
728  if( n_unit_ >= min_unit )
729  return;
730  // check if there is old memory to be freed
731  if( n_unit_ > 0 )
733  // get new memory and set n_unit
734  data_ = thread_alloc::create_array<UnitType>(min_unit, n_unit_);
735  }
736 
737  /// free memory and set number of elements to zero
738  inline void clear(void)
739  { length_ = 0;
740  // check if there is old memory to be freed
741  if( n_unit_ > 0 )
743  n_unit_ = 0;
744  }
745 
746  /// vector assignment operator
748  /// right hand size of the assingment operation
749  const vectorBool& v
750  )
751  { size_t i;
752  // If original length is zero, then resize it.
753  // Otherwise a length mismatch is an error.
754  if( length_ == 0 )
755  resize( v.length_ );
757  length_ == v.length_ ,
758  "vectorBool: size miss match in assignment operation"
759  );
760  size_t min_unit = unit_min();
761  CPPAD_ASSERT_UNKNOWN( min_unit <= n_unit_ );
762  CPPAD_ASSERT_UNKNOWN( min_unit <= v.n_unit_ );
763  for(i = 0; i < min_unit; i++)
764  data_[i] = v.data_[i];
765  return *this;
766  }
767 # if CPPAD_USE_CPLUSPLUS_2011
768  /// vector assignment operator with move semantics
770  /// right hand size of the assingment operation
771  vectorBool&& x
772  )
774  length_ == x.length_ || (length_ == 0),
775  "vectorBool: size miss match in assignment operation"
776  );
777  if( this != &x )
778  { clear();
779  //
780  length_ = x.length_;
781  n_unit_ = x.n_unit_;
782  data_ = x.data_;
783  //
784  x.length_ = 0;
785  x.n_unit_ = 0;
786  x.data_ = CPPAD_NULL;
787  }
788  return *this;
789  }
790 # endif
791 
792 
793  /// non-constant element access; i.e., we can change this element value
795  /// element index, must be less than length
796  size_t k
797  )
798  { size_t i, j;
800  k < length_,
801  "vectorBool: index greater than or equal vector size"
802  );
803  i = k / bit_per_unit_;
804  j = k - i * bit_per_unit_;
805  return vectorBoolElement(data_ + i , UnitType(1) << j );
806  }
807  /// constant element access; i.e., we cannot change this element value
808  bool operator[](size_t k) const
809  { size_t i, j;
810  UnitType unit, mask;
812  k < length_,
813  "vectorBool: index greater than or equal vector size"
814  );
815  i = k / bit_per_unit_;
816  j = k - i * bit_per_unit_;
817  unit = data_[i];
818  mask = UnitType(1) << j;
819  return (unit & mask) != 0;
820  }
821  /// add an element to the back of this vector
822  void push_back(
823  /// value of the element
824  bool bit
825  )
827  size_t i, j;
828  UnitType mask;
829  if( length_ + 1 > n_unit_ * bit_per_unit_ )
831  // store old n_unit and data values
832  size_t old_n_unit = n_unit_;
833  UnitType* old_data = data_;
834  // set new n_unit and data values
835  data_ = thread_alloc::create_array<UnitType>(n_unit_+1, n_unit_);
836  // copy old data values
837  for(i = 0; i < old_n_unit; i++)
838  data_[i] = old_data[i];
839  // free old data
840  if( old_n_unit > 0 )
841  thread_alloc::delete_array(old_data);
842  }
843  i = length_ / bit_per_unit_;
844  j = length_ - i * bit_per_unit_;
845  mask = UnitType(1) << j;
846  if( bit )
847  data_[i] |= mask;
848  else data_[i] &= ~mask;
849  length_++;
850  }
851  /// add vector to the back of this vector
852  template <class Vector>
854  /// value of the vector that we are adding
855  const Vector& v
856  )
857  { CheckSimpleVector<bool, Vector>();
858  size_t min_unit = unit_min();
860  // some temporaries
861  size_t i, j, k, ell;
862  UnitType mask;
863  bool bit;
864  // store old length
865  size_t old_length = length_;
866  // new length and minium number of units;
867  length_ = length_ + v.size();
868  min_unit = unit_min();
869  if( length_ >= n_unit_ * bit_per_unit_ )
870  { // store old n_unit and data value
871  size_t old_n_unit = n_unit_;
872  UnitType* old_data = data_;
873  // set new n_unit and data values
874  data_ = thread_alloc::create_array<UnitType>(min_unit, n_unit_);
875  // copy old data values
876  for(i = 0; i < old_n_unit; i++)
877  data_[i] = old_data[i];
878  // free old data
879  if( old_n_unit > 0 )
880  thread_alloc::delete_array(old_data);
881  }
882  ell = old_length;
883  for(k = 0; k < v.size(); k++)
884  {
885  i = ell / bit_per_unit_;
886  j = ell - i * bit_per_unit_;
887  bit = v[k];
888  mask = UnitType(1) << j;
889  if( bit )
890  data_[i] |= mask;
891  else data_[i] &= ~mask;
892  ell++;
893  }
894  CPPAD_ASSERT_UNKNOWN( length_ == ell );
895  CPPAD_ASSERT_UNKNOWN( length_ <= n_unit_ * bit_per_unit_ );
896  }
897 };
898 
899 /// output a vector
900 inline std::ostream& operator << (
901  /// steam to write the vector to
902  std::ostream& os ,
903  /// vector that is output
904  const vectorBool& v )
905 { size_t i = 0;
906  size_t n = v.size();
907 
908  while(i < n)
909  os << v[i++];
910  return os;
911 }
912 
913 } // END_CPPAD_NAMESPACE
914 # endif
Type * data_
pointer to the first type elements (not defined and should not be used when capacity_ = 0) ...
Definition: vector.hpp:346
size_t length_
number of bits currently stored in this vector
Definition: vector.hpp:655
vector(size_t n)
sizing constructor
Definition: vector.hpp:359
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
void push_back(bool bit)
add an element to the back of this vector
Definition: vector.hpp:822
Class that is used to hold a non-constant element of a vector.
Definition: vector.hpp:599
vectorBool(size_t n)
sizing constructor
Definition: vector.hpp:679
size_t capacity_
maximum number of Type elements current allocation can hold
Definition: vector.hpp:341
The CppAD Simple Vector template class.
Definition: vector.hpp:338
size_t unit_min(void)
minimum number of UnitType values that can store length_ bits (note that this is really a function of...
Definition: vector.hpp:661
static size_t bit_per_unit(void)
Definition: vector.hpp:672
vector(void)
default constructor sets capacity_ = length_ = data_ = 0
Definition: vector.hpp:355
std::ostream & operator<<(std::ostream &os, const CppAD::vector< Type > &vec)
output a vector
Definition: vector.hpp:577
UnitType mask_
mask for the bit corresponding to this element (all zero except for bit that corresponds to this elem...
Definition: vector.hpp:607
size_t n_unit_
number of UnitType values in data_
Definition: vector.hpp:653
void clear(void)
free memory and set number of elements to zero
Definition: vector.hpp:418
vectorBoolElement & operator=(bool bit)
assignment of this element to a bool
Definition: vector.hpp:627
vector(const vector &x)
copy constructor
Definition: vector.hpp:366
Type * data(void)
raw pointer to the data
Definition: vector.hpp:391
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
Type & operator[](size_t i)
non-constant element access; i.e., we can change this element value
Definition: vector.hpp:469
const Type * data(void) const
const raw pointer to the data
Definition: vector.hpp:395
void resize(size_t n)
change the number of elements in this vector.
Definition: vector.hpp:399
void clear(void)
free memory and set number of elements to zero
Definition: vector.hpp:738
vector & operator=(vector &&x)
vector assignment operator with move semantics
Definition: vector.hpp:446
~vectorBool(void)
destructor
Definition: vector.hpp:707
vector & operator=(const vector &x)
vector assignment operator
Definition: vector.hpp:427
bool value_type
type corresponding to the elements of this vector (note that non-const elements actually use vectorBo...
Definition: vector.hpp:669
size_t capacity(void) const
maximum number of elements current allocation can store
Definition: vector.hpp:383
size_t length_
number of Type elements currently in this vector
Definition: vector.hpp:343
vectorBool & operator=(vectorBool &&x)
vector assignment operator with move semantics
Definition: vector.hpp:769
size_t size(void) const
number of elements currently in this vector.
Definition: vector.hpp:387
vectorBool & operator=(const vectorBool &v)
vector assignment operator
Definition: vector.hpp:747
static void delete_array(Type *array)
Return Memory Used for an Array to the Available Pool (include destructor call for each element)...
vectorBoolElement(const vectorBoolElement &e)
constuctor from another element
Definition: vector.hpp:618
void push_back(const Type &s)
add an element to the back of this vector
Definition: vector.hpp:491
size_t capacity(void) const
maximum number of elements current allocation can store
Definition: vector.hpp:717
bool operator[](size_t k) const
constant element access; i.e., we cannot change this element value
Definition: vector.hpp:808
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
void delete_data(Type *data_ptr)
delete data pointer
Definition: vector.hpp:348
UnitType * unit_
pointer to the UnitType value holding this eleemnt
Definition: vector.hpp:604
static const size_t bit_per_unit_
number of bits packed into each UnitType value in data_
Definition: vector.hpp:651
vectorBoolElement(UnitType *unit, UnitType mask)
constructor from member values
Definition: vector.hpp:610
Type value_type
type of the elements in the vector
Definition: vector.hpp:352
~vector(void)
destructor
Definition: vector.hpp:377
void push_vector(const Vector &v)
add vector to the back of this vector
Definition: vector.hpp:853
UnitType * data_
pointer to where the bits are stored
Definition: vector.hpp:657
size_t UnitType
the boolean data is packed with sizeof(UnitType) bits per value
Definition: vector.hpp:601
File used to define the CppAD multi-threading allocator class.
void resize(size_t n)
change number of elements in this vector
Definition: vector.hpp:721
vectorBoolElement & operator=(const vectorBoolElement &e)
assignment of this element to another element
Definition: vector.hpp:637
size_t UnitType
the boolean data is packed with sizeof(UnitType) bits per value
Definition: vector.hpp:647
vectorBoolElement operator[](size_t k)
non-constant element access; i.e., we can change this element value
Definition: vector.hpp:794
vectorBool(const vectorBool &v)
copy constructor
Definition: vector.hpp:690
vectorBool(void)
default constructor (sets all member data to zero)
Definition: vector.hpp:676
const Type & operator[](size_t i) const
constant element access; i.e., we cannot change this element value
Definition: vector.hpp:480
size_t size(void) const
number of elements in this vector
Definition: vector.hpp:713
void push_vector(const Vector &v)
add vector to the back of this vector (we could not use push_back because MS V++ 7...
Definition: vector.hpp:533