Simbody
Related Functions

SimTK::Array_< T, X > Class Template Reference

The SimTK::Array_<T> container class is a plug-compatible replacement for the C++ standard template library (STL) std::vector<T> class, but with some important advantages in performance, and functionality, and binary compatibility. More...

#include <Array.h>

Inheritance diagram for SimTK::Array_< T, X >:

List of all members.

Public Types

Typedefs

Types required of STL containers, plus index_type which is an extension, and packed_size_type which is an implementation detail.

typedef T value_type
 The type of object stored in this container.
typedef X index_type
 The index type (an extension).
typedef T * pointer
 A writable pointer to a value_type.
typedef const T * const_pointer
 A const pointer to a value_type.
typedef T & reference
 A writable value_type reference.
typedef const T & const_reference
 A const value_type reference.
typedef T * iterator
 A writable iterator for this container (same as pointer here).
typedef const T * const_iterator
 A const iterator for this container (same as const_pointer here).
typedef std::reverse_iterator
< iterator
reverse_iterator
 A writable reverse iterator for this container.
typedef std::reverse_iterator
< const_iterator
const_reverse_iterator
 A const reverse iterator for this container.
typedef ArrayIndexTraits< X >
::size_type 
size_type
 An integral type suitable for all indices and sizes for this array.
typedef ArrayIndexTraits< X >
::difference_type 
difference_type
 A signed integral type that can represent the difference between any two legitimate index values for this array.
typedef ArrayIndexPackType
< size_type >
::packed_size_type 
packed_size_type
 The integral type we actually use internally to store size_type values.

Public Member Functions

Construction, conversion and destruction

A variety of constructors are provided for this class, including all those required by the C++ standard for std::vector implementations, plus additional ones providing smooth conversions between Array_<T> and std::vector<T> objects.

 Array_ ()
 Default constructor allocates no heap space and is very fast.
 Array_ (size_type n)
 Construct an array containing n default-constructed elements.
 Array_ (size_type n, const T &initVal)
 Construct an array containing n elements each set to a copy of the given initial value.
template<class InputIter >
 Array_ (const InputIter &first, const InputIter &last1)
 Construct an Array_<T> from a range [first,last1) of values identified by a pair of iterators.
template<class T2 >
 Array_ (const T2 *first, const T2 *last1)
 Construct an Array_<T> from a range [first,last1) of values identified by a pair of ordinary pointers to elements of type T2 (where T2 might be the same as T but doesn't have to be).
template<class T2 >
 Array_ (const std::vector< T2 > &v)
 Construct an Array_<T> by copying from an std::vector<T2>, where T2 may be the same type as T but doesn't have to be.
 Array_ (const Array_ &src)
 Copy constructor allocates exactly as much memory as is in use in the source (not its capacity) and copy constructs the elements so that T's copy constructor will be called exactly src.size() times.
template<class T2 , class X2 >
 Array_ (const Array_< T2, X2 > &src)
 Construct this Array_<T,X> as a copy of another Array_<T2,X2> where T2!=T or X2!=X.
 Array_ (T *first, const T *last1, const DontCopy &)
 Construct an Array_<T> by referencing (sharing) a given range of data [first,last1), without copying that data; better to use the corresponding ArrayView_<T> constructor if you can.
template<class A >
 Array_ (std::vector< T, A > &v, const DontCopy &)
 Construct an Array_<T> by referencing (sharing) the data in an std::vector<T>, without copying the data; better to use the ArrayView_<T> constructor instead if you can.
 ~Array_ ()
 The destructor performs a deallocate() operation which may result in element destruction and freeing of heap space; see deallocate() for more information.
Array_deallocate ()
 Empty this array of its contents, returning the array to its default-constructed, all-zero state.
Assignment methods and operators

These methods put new data values in an existing array, but the meaning of assignment is subtly different for resizeable (owner) arrays and fixed (non-owner) arrays.

The standard std::vector type is always an owner so the non-owner description here is an extension applying only to Array_.

For the normal case of resizeable arrays, assignment does not have an elementwise definition because the source will typically have a different number of elements than the array's current size. So regardless of the actual numbers, assignment in the resizeable case is defined as it is for std::vector: first clear the array by erasing (destructing) all the current elements in the array, then reserve sufficient heap space to hold a copy of the source, then use appropriate constructors of type T (most commonly T's copy constructor T(T)) to initialize each element to be a copy of the corresponding source element. T's assignment operators are never used in this case.

For fixed arrays, the source must have the same number of elments as are currently in the array and the meaning is conventional elementwise assignment; that is, an appropriate assignment operator of type T (most commonly T's copy assignment operator T=T) is used to change the value of each existing element.

So there are different requirements on the value type T for owner and non-owner assignments to type T2: for owner assignment T must have a constructor T(T2) available; for non-owner assignment, T must have an assignment operator T=T2 available; .

Remarks:
  • When reallocating the destination array, we may reuse the existing heap allocation if it is sufficient and not too big; otherwise we'll reallocate before copying.
  • The fill() method here has elementwise assignment semantics regardless of whether the array is an owner or non-owner.
void assign (size_type n, const T &fillValue)
 Set this array to be n copies of the supplied fillValue.
void fill (const T &fillValue)
 Assign all current elements of the array to the same fillValue.
template<class T2 >
void assign (const T2 *first, const T2 *last1)
 Assign to this array to to make it a copy of the elements in range [first,last1) given by ordinary pointers.
template<class Iter >
void assign (const Iter &first, const Iter &last1)
 Assign this array from a range [first,last1) given by non-pointer iterators.
Array_operator= (const Array_ &src)
 Copy assignment operator destructs the current contents of this array and then makes it a copy of the source array by repeated calls to the element type's copy constructor.
template<class T2 , class X2 >
Array_operator= (const Array_< T2, X2 > &src)
 This is assignment from a source array whose element type T2 and/or index type X2 are different from this array's T and X.
template<class T2 , class A >
Array_operator= (const std::vector< T2, A > &src)
 This is assignment from a source std::vector<T2>.
void swap (Array_ &other)
 This is a specialized algorithm providing constant time exchange of data with another array that has identical element and index types.
Array_adoptData (T *newData, size_type dataSize, size_type dataCapacity)
 This dangerous extension allows you to supply your own already-allocated heap space for use by this array, which then becomes the owner of the supplied heap space.
Array_adoptData (T *newData, size_type dataSize)
 A variant of adoptData() that assumes the capacity is the same as the current size.
Array_shareData (T *newData, size_type dataSize)
 This dangerous extension allows you to make this array handle refer to someone else's data without copying it.
Array_shareData (T *first, const T *last1)
 Same as shareData(data,size) but uses a pointer range [first,last1) to identify the data to be referenced.
Size and capacity

These methods examine and alter the number of elements (size) or the amount of allocated heap space (capacity) or both.

size_type size () const
 Return the current number of elements stored in this array.
size_type max_size () const
 Return the maximum allowable size for this array.
bool empty () const
 Return true if there are no elements currently stored in this array.
size_type capacity () const
 Return the number of elements this array can currently hold without requiring reallocation.
void resize (size_type n)
 Change the size of this Array, preserving all the elements that will still fit, and default constructing any new elements that are added.
void resize (size_type n, const T &initVal)
 Change the size of this array, preserving all the elements that will still fit, and initializing any new elements that are added by repeatedly copy- constructing from the supplied value.
void reserve (size_type n)
 Ensure that this array has enough allocated capacity to hold the indicated number of elements.
void shrink_to_fit ()
 Request that the capacity of this array be reduced to the minimum necessary to hold the number of elements currently in use.
size_type allocated () const
 Return the amount of heap space owned by this array; this is the same as capacity() for owner arrays but is zero for non-owners.
bool isOwner () const
 Does this array own the data to which it refers? If not, it can't be resized, and the destructor will not free any heap space nor call any element destructors.
Iterators

These methods deal in iterators, which are STL generalized pointers.

For this class, iterators are just ordinary pointers to T, and you may depend on that. By necessity, reverse iterators can't be just pointers; however, they contain an ordinary iterator (i.e. a pointer) that can be obtained by calling the reverse iterator's base() method.

const T * cbegin () const
 Return a const pointer to the first element of this array if any, otherwise cend(), which may be null (0) in that case but does not have to be.
const T * begin () const
 The const version of begin() is the same as cbegin().
T * begin ()
 Return a writable pointer to the first element of this array if any, otherwise end().
const T * cend () const
 Return a const pointer to what would be the element just after the last one in the array; this may be null (0) if there are no elements but doesn't have to be.
const T * end () const
 The const version of end() is the same as cend().
T * end ()
 Return a writable pointer to what would be the element just after the last one in this array.
const_reverse_iterator crbegin () const
 Return a const reverse iterator pointing to the last element in the array or crend() if the array is empty.
const_reverse_iterator rbegin () const
 The const version of rbegin() is the same as crbegin().
reverse_iterator rbegin ()
 Return a writable reverse iterator pointing to the last element in the array or rend() if the array is empty.
const_reverse_iterator crend () const
 Return the past-the-end reverse iterator that tests equal to a reverse iterator that has been incremented past the front of the array.
const_reverse_iterator rend () const
 The const version of rend() is the same as crend().
reverse_iterator rend ()
 Return a writable past-the-end reverse iterator that tests equal to a reverse iterator that has been incremented past the front of the array.
const T * cdata () const
 Return a const pointer to the first element of the array, or possibly (but not necessarily) null (0) if the array is empty.
const T * data () const
 The const version of the data() method is identical to cdata().
T * data ()
 Return a writable pointer to the first allocated element of the array, or a null pointer if no space is associated with the array.
Element access

These methods provide read and write access to individual elements, or groups of elements, that are currently present in the array.

const T & operator[] (index_type i) const
 Select an element by its index, returning a const reference.
T & operator[] (index_type i)
 Select an element by its index, returning a writable (lvalue) reference.
const T & at (index_type i) const
 Same as operator[] but always range-checked, even in a Release build.
T & at (index_type i)
 Same as operator[] but always range-checked, even in a Release build.
const T & getElt (index_type i) const
 Same as the const form of operator[]; exists to provide a non-operator method for element access in case that's needed.
T & updElt (index_type i)
 Same as the non-const form of operator[]; exists to provide a non-operator method for element access in case that's needed.
const T & front () const
 Return a const reference to the first element in this array, which must not be empty.
T & front ()
 Return a writable reference to the first element in this array, which must not be empty.
const T & back () const
 Return a const reference to the last element in this array, which must not be empty.
T & back ()
 Return a writable reference to the last element in this array, which must not be empty.
ArrayViewConst_< T, X > operator() (index_type index, size_type length) const
 Select a subrange of this const array by starting index and length, and return a ArrayViewConst_ referencing that data without copying it.
ArrayViewConst_< T, X > getSubArray (index_type index, size_type length) const
 Same as const form of operator()(index,length); exists to provide non-operator access to that functionality in case it is needed.
ArrayView_< T, X > operator() (index_type index, size_type length)
 Select a subrange of this array by starting index and length, and return an ArrayView_ referencing that data without copying it.
ArrayView_< T, X > updSubArray (index_type index, size_type length)
 Same as non-const operator()(index,length); exists to provide non-operator access to that functionality in case it is needed.
Element insertion and removal

These are methods that change the number of elements in the array by insertion or erasure.

void push_back (const T &value)
 This method increases the size of the Array by one element at the end and initializes that element by copy constructing it from the given value.
void push_back ()
 This is a non-standard version of push_back() that increases the size of the array by one default-constructed element at the end.
T * raw_push_back ()
 This dangerous method increases the Array's size by one element at the end but doesn't perform any construction so the memory is filled with garbage.
void pop_back ()
 Remove the last element from this array, which must not be empty.
T * erase (T *first, const T *last1)
 Erase elements in range [first,last1), packing in any later elements into the newly-available space and reducing the array's size by the number of elements erased.
T * erase (T *p)
 Erase just one element, moving all subsequent elements down one slot and reducing the array's size by one.
T * eraseFast (T *p)
 Be careful with this non-standard extension; it erases one element and then moves the last one in its place which changes the element order from what it was before (unlike the standard erase() method).
void clear ()
 Erase all the elements currently in this array without changing the capacity; equivalent to erase(begin(),end()) but a little faster.
T * insert (T *p, size_type n, const T &value)
 Insert n copies of a given value at a particular location within this array, moving all following elements up by n positions.
T * insert (T *p, const T &value)
 Insert a new element at a given location within this array, initializing it to a copy of a given value and moving all following elements up one position.
template<class T2 >
T * insert (T *p, const T2 *first, const T2 *last1)
 Insert elements in a range [first,last1) into this array at a given position p, moving all following elements up by n=(last1-first) positions.
template<class Iter >
T * insert (T *p, const Iter &first, const Iter &last1)
 Insert elements in a range [first,last1) where the range is given by non-pointer iterators.

Related Functions

(Note that these are not member functions.)
template<class T , class X >
void swap (SimTK::Array_< T, X > &a1, SimTK::Array_< T, X > &a2)
 This is a specialization of the STL std::swap() algorithm which uses the constant time built-in swap() member of the Array_ class.
Array_<T> serialization and I/O

These methods are at namespace scope but are logically part of the Array classes.

These deal with reading and writing Arrays from and to streams, which places an additional requirement on the element type T: the element must support the same operation you are trying to do on the Array as a whole.

template<class T , class X >
std::ostream & operator<< (std::ostream &o, const ArrayViewConst_< T, X > &a)
 Output a human readable representation of an array to an std::ostream (like std::cout).
template<class T , class X >
static std::istream & readArrayFromStream (std::istream &in, Array_< T, X > &out)
 Read in an Array_<T> from a stream, as a sequence of space-separated or comma-separated values optionally surrounded by parentheses (), square brackets [], or curly braces {}.
template<class T , class X >
static std::istream & fillArrayFromStream (std::istream &in, Array_< T, X > &out)
 Read in a fixed number of elements from a stream into an Array.
template<class T , class X >
std::istream & operator>> (std::istream &in, Array_< T, X > &out)
 Read an Array_<T> from a stream as a sequence of space- or comma-separated values of type T, optionally delimited by parentheses, brackets, or braces.
Comparison operators

These operators permit lexicographical comparisons between two comparable Array_ objects, possibly with differing element and index types, and between an Array_ object and a comparable std::vector object.

template<class T1 , class X1 , class T2 , class X2 >
bool operator== (const ArrayViewConst_< T1, X1 > &a1, const ArrayViewConst_< T2, X2 > &a2)
 Two Array_ objects are equal if and only if they are the same size() and each element compares equal using an operator T1==T2.
template<class T1 , class X1 , class T2 , class X2 >
bool operator!= (const ArrayViewConst_< T1, X1 > &a1, const ArrayViewConst_< T2, X2 > &a2)
 The not equal operator is implemented using the equal operator.
template<class T1 , class X1 , class T2 , class X2 >
bool operator< (const ArrayViewConst_< T1, X1 > &a1, const ArrayViewConst_< T2, X2 > &a2)
 Array_ objects are ordered lexicographically; that is, by first differing element or by length if there are no differing elements up to the length of the shorter array (in which case the shorter one is "less than" the longer).
template<class T1 , class X1 , class T2 , class X2 >
bool operator>= (const ArrayViewConst_< T1, X1 > &a1, const ArrayViewConst_< T2, X2 > &a2)
 The greater than or equal operator is implemented using the less than operator.
template<class T1 , class X1 , class T2 , class X2 >
bool operator> (const ArrayViewConst_< T1, X1 > &a1, const ArrayViewConst_< T2, X2 > &a2)
 The greater than operator is implemented by using less than with the arguments reversed, meaning the elements must have working comparison operators of the form T2==T1 and T2<T1.
template<class T1 , class X1 , class T2 , class X2 >
bool operator<= (const ArrayViewConst_< T1, X1 > &a1, const ArrayViewConst_< T2, X2 > &a2)
 The less than or equal operator is implemented using the greater than operator.
template<class T1 , class X1 , class T2 , class A2 >
bool operator== (const ArrayViewConst_< T1, X1 > &a1, const std::vector< T2, A2 > &v2)
 An Array_<T1> and an std::vector<T2> are equal if and only if they are the same size() and each element compares equal using an operator T1==T2.
template<class T1 , class A1 , class T2 , class X2 >
bool operator== (const std::vector< T1, A1 > &v1, const ArrayViewConst_< T2, X2 > &a2)
 An std::vector<T1> and an Array_<T2> are equal if and only if they are the same size() and each element compares equal using an operator T2==T1.
template<class T1 , class X1 , class T2 , class A2 >
bool operator!= (const ArrayViewConst_< T1, X1 > &a1, const std::vector< T2, A2 > &v2)
 The not equal operator is implemented using the equal operator.
template<class T1 , class A1 , class T2 , class X2 >
bool operator!= (const std::vector< T1, A1 > &v1, const ArrayViewConst_< T2, X2 > &a2)
 The not equal operator is implemented using the equal operator.
template<class T1 , class X1 , class T2 , class A2 >
bool operator< (const ArrayViewConst_< T1, X1 > &a1, const std::vector< T2, A2 > &v2)
 An Array_<T1> and std::vector<T2> are ordered lexicographically; that is, by first differing element or by length if there are no differing elements up to the length of the shorter container (in which case the shorter one is "less than" the longer).
template<class T1 , class A1 , class T2 , class X2 >
bool operator< (const std::vector< T1, A1 > &v1, const ArrayViewConst_< T2, X2 > &a2)
 An std::vector<T1> and Array_<T2> are ordered lexicographically; that is, by first differing element or by length if there are no differing elements up to the length of the shorter container (in which case the shorter one is "less than" the longer).
template<class T1 , class X1 , class T2 , class A2 >
bool operator>= (const ArrayViewConst_< T1, X1 > &a1, const std::vector< T2, A2 > &v2)
 The greater than or equal operator is implemented using the less than operator.
template<class T1 , class A1 , class T2 , class X2 >
bool operator>= (const std::vector< T1, A1 > &v1, const ArrayViewConst_< T2, X2 > &a2)
 The greater than or equal operator is implemented using the less than operator.
template<class T1 , class X1 , class T2 , class A2 >
bool operator> (const ArrayViewConst_< T1, X1 > &a1, const std::vector< T2, A2 > &v2)
 The greater than operator is implemented by using less than with the arguments reversed, meaning the elements must have working comparison operators of the form T2==T1 and T2<T1.
template<class T1 , class A1 , class T2 , class X2 >
bool operator> (const std::vector< T1, A1 > &v1, const ArrayViewConst_< T2, X2 > &a2)
 The greater than operator is implemented by using less than with the arguments reversed, meaning the elements must have working comparison operators of the form T2==T1 and T2<T1.
template<class T1 , class X1 , class T2 , class A2 >
bool operator<= (const ArrayViewConst_< T1, X1 > &a1, const std::vector< T2, A2 > &v2)
 The less than or equal operator is implemented using the greater than operator.
template<class T1 , class A1 , class T2 , class X2 >
bool operator<= (const std::vector< T1, A1 > &v1, const ArrayViewConst_< T2, X2 > &a2)
 The less than or equal operator is implemented using the greater than operator.

Detailed Description

template<class T, class X>
class SimTK::Array_< T, X >

The SimTK::Array_<T> container class is a plug-compatible replacement for the C++ standard template library (STL) std::vector<T> class, but with some important advantages in performance, and functionality, and binary compatibility.

Template Parameters:
TThe type of object to be stored in this container.
XThe type to be used for indexing this container, with default unsigned (not size_t). Any integral type may be used, as well as user types that satisfy the requirements discussed with class ArrayIndexTraits.
Performance:
There are several performance and memory footprint problems with the C++ standard STL design in general, and with Microsoft's implementation in particular, that are addressed here. Microsoft in its wisdom decided that STL containers should still do runtime range checks in Release builds for safety, but that makes them too slow for use in some high-performance contexts (and also breaks the promise of generic programming but that's another rant). In practice, VC++9 std::vector runs about half speed for simple operations like indexing and push_back. Attempting to disable these runtime checks with _SECURE_SCL breaks binary compatibility. In contrast the performance of this Array_<T> class on any platform is indistinguishable from what you would get by managing your own heap-allocated arrays.
Regarding memory footprint, the typical implementation of std::vector uses three pointers: 12 bytes for 32 bit machines; 24 bytes for 64 bit machines. Microsoft somehow manages to trump this with 20 to 24 bytes on a 32 bit machine -- I don't know what they do on a 64 bit machine but I'm not optimistic! Array_ instead uses one pointer and two lengths for a total size as little as 8 bytes on 32 bits and 16 on 64 bits; see below for details.
Some nuts and bolts:
Functionality:
For the most part Array_<T> is a plug-compatible replacement for std::vector<T>, and everything that both classes can do is done with an identical API. However, there are a few additions and subtractions:
Compatibility:
Included here are binary compatibility issues and compatibility with the C++ standard STL objects.
See also:
Array_, ArrayViewConst_, ArrayIndexTraits

Member Typedef Documentation

template<class T, class X>
typedef T SimTK::Array_< T, X >::value_type

The type of object stored in this container.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef X SimTK::Array_< T, X >::index_type

The index type (an extension).

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef T* SimTK::Array_< T, X >::pointer

A writable pointer to a value_type.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef const T* SimTK::Array_< T, X >::const_pointer

A const pointer to a value_type.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef T& SimTK::Array_< T, X >::reference

A writable value_type reference.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef const T& SimTK::Array_< T, X >::const_reference

A const value_type reference.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef T* SimTK::Array_< T, X >::iterator

A writable iterator for this container (same as pointer here).

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef const T* SimTK::Array_< T, X >::const_iterator

A const iterator for this container (same as const_pointer here).

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef std::reverse_iterator<iterator> SimTK::Array_< T, X >::reverse_iterator

A writable reverse iterator for this container.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef std::reverse_iterator<const_iterator> SimTK::Array_< T, X >::const_reverse_iterator

A const reverse iterator for this container.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef ArrayIndexTraits<X>::size_type SimTK::Array_< T, X >::size_type

An integral type suitable for all indices and sizes for this array.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef ArrayIndexTraits<X>::difference_type SimTK::Array_< T, X >::difference_type

A signed integral type that can represent the difference between any two legitimate index values for this array.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
typedef ArrayIndexPackType<size_type>::packed_size_type SimTK::Array_< T, X >::packed_size_type

The integral type we actually use internally to store size_type values.

Reimplemented from SimTK::ArrayView_< T, X >.


Constructor & Destructor Documentation

template<class T, class X>
SimTK::Array_< T, X >::Array_ ( ) [inline]

Default constructor allocates no heap space and is very fast.

template<class T, class X>
SimTK::Array_< T, X >::Array_ ( size_type  n) [inline, explicit]

Construct an array containing n default-constructed elements.

T's default constructor (if any) is called exactly n times. If n is zero no heap space will be allocated; although in that case it is preferable to use the default constructor if you can since that will be somewhat faster.

template<class T, class X>
SimTK::Array_< T, X >::Array_ ( size_type  n,
const T &  initVal 
) [inline]

Construct an array containing n elements each set to a copy of the given initial value.

T's copy constructor will be called exactly n times. If n is zero no space will be allocated.

template<class T, class X>
template<class InputIter >
SimTK::Array_< T, X >::Array_ ( const InputIter &  first,
const InputIter &  last1 
) [inline]

Construct an Array_<T> from a range [first,last1) of values identified by a pair of iterators.

Note:
The standard requires that if an integral type matches this signature, it must behave as the Array_(size_type,value_type) constructor.
Complexity:
The performance of this constructor depends on the type of iterator:
  • random_access_iterator: n=(last1-first); a single space allocation; n calls to T's copy constructor.
  • forward or bidirectional iterator: must increment from first to last1 to determine n; otherwise same as random access.
  • input iterator: can't determine n in advance; expect log n reallocations during construction as we "push back" one input element at a time.
template<class T, class X>
template<class T2 >
SimTK::Array_< T, X >::Array_ ( const T2 *  first,
const T2 *  last1 
) [inline]

Construct an Array_<T> from a range [first,last1) of values identified by a pair of ordinary pointers to elements of type T2 (where T2 might be the same as T but doesn't have to be).

This is templatized so can be used with any source type T2 for which there is a working conversion constructor T(T2), provided that the number of source elements does not exceed the array's max_size().

template<class T, class X>
template<class T2 >
SimTK::Array_< T, X >::Array_ ( const std::vector< T2 > &  v) [inline, explicit]

Construct an Array_<T> by copying from an std::vector<T2>, where T2 may be the same type as T but doesn't have to be.

This will work as long as the size of the vector does not exceed the array's max_size(), and provided there is a working T(T2) conversion constructor.

template<class T, class X>
SimTK::Array_< T, X >::Array_ ( const Array_< T, X > &  src) [inline]

Copy constructor allocates exactly as much memory as is in use in the source (not its capacity) and copy constructs the elements so that T's copy constructor will be called exactly src.size() times.

If the source is empty, no heap space will be allocated.

template<class T, class X>
template<class T2 , class X2 >
SimTK::Array_< T, X >::Array_ ( const Array_< T2, X2 > &  src) [inline]

Construct this Array_<T,X> as a copy of another Array_<T2,X2> where T2!=T or X2!=X.

This will work as long as the source is not larger than will fit here, and as long as the source element type T2 is assignment compatible with this array's element type T. One of T's constructors will be called exactly src.size() times; the particular constructor is whichever one best matches T(T2).

template<class T, class X>
SimTK::Array_< T, X >::Array_ ( T *  first,
const T *  last1,
const DontCopy &   
) [inline]

Construct an Array_<T> by referencing (sharing) a given range of data [first,last1), without copying that data; better to use the corresponding ArrayView_<T> constructor if you can.

This is very fast but can be dangerous -- it is most useful for argument passing where the array handle will be discarded immediately after use. Note that this is available only if you have write access to the data because there is no way to construct a non-writable array. This will work as long as the size of the data does not exceed the array's max_size. The resulting array object is not resizeable but can be used to read and write elements of the original data. The array is invalid if the original data is destructed or resized, but there is no way for the array class to detect that.

Remarks:
  • If the source data is empty, the resulting array will also be empty and will look just like a default-constructed array. It will therefore not have any connection to the source and will be an ordinary resizable array.
  • This is quite dangerous to use since the connection between the array and the data is tenuous and subject to the data remaining untouched during the lifetime of the array handle. There is no reference counting; destructing the original data would leave the array referring to garbage. Be careful!
  • You can break the connection between the array and the data it was constructed from by calling deallocate().
Complexity:
Dirt cheap. There will be no construction, destruction, or heap allocation performed.
See also:
deallocate()
template<class T, class X>
template<class A >
SimTK::Array_< T, X >::Array_ ( std::vector< T, A > &  v,
const DontCopy &   
) [inline]

Construct an Array_<T> by referencing (sharing) the data in an std::vector<T>, without copying the data; better to use the ArrayView_<T> constructor instead if you can.

This is very fast but can be dangerous -- it is most useful for argument passing where the array handle will be discarded immediately after use. Note that this is available only if you have write access to the std::vector because there is no way to construct a non-writable array. This will work as long as the size of the vector does not exceed the array's max_size. The resulting array object is not resizeable but can be used to read and write elements of the original std::vector. The array is invalid if the original std::vector is destructed or resized.

Remarks:
  • If the source std::vector is empty, the resulting array will also be empty and will look just like a default-constructed array. It will therefore not have any connection to the source vector and will be an ordinary resizable array.
  • This is quite dangerous to use since the connection between the array and the vector is tenuous and subject to the vector remaining untouchged during the lifetime of the array handle. There is no reference counting; destructing the vector leaves the array referring to garbage. Be careful!
  • You can break the connection between the array and the vector it was constructed from by calling deallocate().
Complexity:
Dirt cheap. There will be no construction, destruction, or heap allocation performed.
See also:
deallocate()
template<class T, class X>
SimTK::Array_< T, X >::~Array_ ( ) [inline]

The destructor performs a deallocate() operation which may result in element destruction and freeing of heap space; see deallocate() for more information.

See also:
deallocate()

Member Function Documentation

template<class T, class X>
Array_& SimTK::Array_< T, X >::deallocate ( ) [inline]

Empty this array of its contents, returning the array to its default-constructed, all-zero state.

If this array is the owner of its data, the destructor (if any) is called for each data element and the array's allocated heap space is freed. If it is a non-owner the array handle is cleaned out using disconnect() but the referenced data is untouched.

Note:
There is no equivalent to this method for std::vector.
Returns:
A reference to the now-empty, default-constructed array, ready for reassignment.
template<class T, class X>
void SimTK::Array_< T, X >::assign ( size_type  n,
const T &  fillValue 
) [inline]

Set this array to be n copies of the supplied fillValue.

Note that this serves to allow fill from an object whose type T2 is different from T, as long as there is a constructor T(T2) that works since that can be invoked (implicitly or explicitly) to convert the T2 object to type T prior to the call. If this is a non-owner array then n must be the same as the current size(); consider using the fill() method instead.

Parameters:
[in]nThe number of elements to be in the result.
[in]fillValueThe value to which to initialize each element.
Precondition:
n <= max_size()
for non-owner, n==size()
Complexity:
For a non-owner with n==size(), there will be exactly n calls to T's copy assignment operator. For an owner, there will be size() calls to T's destructor (if it has one), possibly a heap reallocation (but with no element copying), followed by n calls to T's copy constructor.
See also:
fill()

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
void SimTK::Array_< T, X >::fill ( const T &  fillValue) [inline]

Assign all current elements of the array to the same fillValue.

This is similar to assign(size(),fillValue) but the semantics are subtly different. Here we use repeated application of T's copy assignment operator T=fillValue, whereas the assign() semantics are to first destruct all the existing elements, then allocate if necessary, then use the copy constructor to initialize the new elements. Note that you can use this to fill from a source type T2 that is different from T as long as there exists a suitable constructor T(T2) that can be used to create the type T fillValue from the original T2 source.

Note:
Unlike other assignment methods, the behavior of fill() is identical for owner and non-owner arrays.
Parameters:
[in]fillValueThe value to which all existing elements are set.
Complexity:
Just size() calls to T's copy assignment operator.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
template<class T2 >
void SimTK::Array_< T, X >::assign ( const T2 *  first,
const T2 *  last1 
) [inline]

Assign to this array to to make it a copy of the elements in range [first,last1) given by ordinary pointers.

It is not allowed for this range to include any of the elements currently in the array. The source elements can be of a type T2 that may be the same or different than this array's element type T as long as there is a working constructor T(T2) (for owner arrays) or a working assignment operator T=T2 (for non-owner arrays). Note that although the source arguments are pointers, those may be iterators for some container depending on implementation details of the container. Specifically, any Array_<T2>::iterator or const_iterator is an ordinary pointer.

Parameters:
[in]firstA pointer to the first source element to be copied.
[in]last1A pointer to one element past the last source element.
Complexity:
For non-owner arrays, n=last1-first must equal the current size() in which case there will be exactly size() calls to the T=T2 assignment operator. For owner arrays, say the array initially has capacity c, and the source provides n new elements. If type T has a destructor, it will be called exactly size() times. Reallocation will then occur if c < n and may occur if c >> n to avoid leaving a lot of unused space. Then the constructor T(T2) will be called exactly n times.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
template<class Iter >
void SimTK::Array_< T, X >::assign ( const Iter &  first,
const Iter &  last1 
) [inline]

Assign this array from a range [first,last1) given by non-pointer iterators.

See the assign(first,last1) method with pointer arguments for a relevant discussion.

Remarks:
  • For a non-owner array this is only allowed if we can calculate the number of source elements, and if that number is exactly the same as the current size().
  • See Complexity discussion below for behavior for the different kinds of iterators that might be supplied.
  • It is not permitted for any of the source elements to overlap in memory with the initial contents of the array.
Parameters:
[in]firstAn iterator pointing to the first source element to be copied.
[in]last1A iterator pointing one element past the last source element.
Precondition:
last1-first <= max_size()
for non-owner array, last1-first == size()
Complexity:
For a non-owner array, this is only allowed if n=last1-first equals the current size(), in which case we'll perform exactly n calls to the appropriate assignment operator of element type T. For owner arrays, if we can determine how many elements n=last1-first the source contains in advance, we'll do only a single allocation here and call one of T's constructors exactly n times after just size() destructor calls needed to erase the original data. If the iterators are random access iterators, calculating n is a fast constant-time operation. For forward or bidirectional iterators, we have to advance through the iterators once to count the source elements prior to allocating space, adding an O(n) cost. For input iterators, we can't count them in advance so we just have to add elements as we find them using push_back() meaning we may need to reallocate log(n) times, calling the destructor and copy constructor each time to move the elements around.
See also:
assign(T2* first, T2* last1)

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
Array_& SimTK::Array_< T, X >::operator= ( const Array_< T, X > &  src) [inline]

Copy assignment operator destructs the current contents of this array and then makes it a copy of the source array by repeated calls to the element type's copy constructor.

At most one reallocation of heap space occurs that may result in this array having a larger or smaller capacity, although of course it will be at least as large as the source.

template<class T, class X>
template<class T2 , class X2 >
Array_& SimTK::Array_< T, X >::operator= ( const Array_< T2, X2 > &  src) [inline]

This is assignment from a source array whose element type T2 and/or index type X2 are different from this array's T and X.

This will work as long as this array can accommodate all the elements in the source and T2 is assignment compatible with T. See discussion for the copy assignment operator for more information.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
template<class T2 , class A >
Array_& SimTK::Array_< T, X >::operator= ( const std::vector< T2, A > &  src) [inline]

This is assignment from a source std::vector<T2>.

This will work as long as this array can accommodate all the elements in the source and T2 is assignment compatible with T. See discussion for the copy assignment operator for more information.

template<class T, class X>
void SimTK::Array_< T, X >::swap ( Array_< T, X > &  other) [inline]

This is a specialized algorithm providing constant time exchange of data with another array that has identical element and index types.

This is much faster than using the std::swap() algorithm on the arrays since that would involve O(n) copying operations. This method makes no calls to any constructors or destructors. This is allowable even for non-owner arrays; the non-owner attribute will follow the non-owned data.

template<class T, class X>
Array_& SimTK::Array_< T, X >::adoptData ( T *  newData,
size_type  dataSize,
size_type  dataCapacity 
) [inline]

This dangerous extension allows you to supply your own already-allocated heap space for use by this array, which then becomes the owner of the supplied heap space.

Any memory currently associated with the array is deallocated; see deallocate() for more information.

See also:
deallocate(), shareData()
template<class T, class X>
Array_& SimTK::Array_< T, X >::adoptData ( T *  newData,
size_type  dataSize 
) [inline]

A variant of adoptData() that assumes the capacity is the same as the current size.

See also:
adoptData(data,size,capacity)
template<class T, class X>
Array_& SimTK::Array_< T, X >::shareData ( T *  newData,
size_type  dataSize 
) [inline]

This dangerous extension allows you to make this array handle refer to someone else's data without copying it.

Any memory currently associated with the array is deallocated; see deallocate() for more information. This method makes the array a fixed-size, non-owner array that cannot be reallocated, and no element destruction nor heap deallocation will occur when the handle is subsequently destructed or deallocated.

Note:
  • A null (0) pointer is allowed for the pointer as long as dataSize==0, however in that case the array handle ends up deallocated (that is, indistinguishable from a default-constructed array) so is resizeable.
  • This is implemented by setting the nAllocated data member to zero while the nUsed data member is set to the given dataSize.
See also:
deallocate(), adoptData()
template<class T, class X>
Array_& SimTK::Array_< T, X >::shareData ( T *  first,
const T *  last1 
) [inline]

Same as shareData(data,size) but uses a pointer range [first,last1) to identify the data to be referenced.

template<class T, class X>
size_type SimTK::Array_< T, X >::size ( ) const [inline]

Return the current number of elements stored in this array.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
size_type SimTK::Array_< T, X >::max_size ( ) const [inline]

Return the maximum allowable size for this array.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
bool SimTK::Array_< T, X >::empty ( ) const [inline]

Return true if there are no elements currently stored in this array.

This is equivalent to the tests begin() == end() or size()==0.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
size_type SimTK::Array_< T, X >::capacity ( ) const [inline]

Return the number of elements this array can currently hold without requiring reallocation.

The value returned by capacity() is always greater than or equal to size(), even if the data is not owned by this array in which case we have capacity() == size() and the array is not reallocatable.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
void SimTK::Array_< T, X >::resize ( size_type  n) [inline]

Change the size of this Array, preserving all the elements that will still fit, and default constructing any new elements that are added.

This is not allowed for non-owner arrays unless the requested size is the same as the current size.

template<class T, class X>
void SimTK::Array_< T, X >::resize ( size_type  n,
const T &  initVal 
) [inline]

Change the size of this array, preserving all the elements that will still fit, and initializing any new elements that are added by repeatedly copy- constructing from the supplied value.

This is not allowed for non-owner arrays unless the requested size is the same as the current size.

template<class T, class X>
void SimTK::Array_< T, X >::reserve ( size_type  n) [inline]

Ensure that this array has enough allocated capacity to hold the indicated number of elements.

No heap reallocation will occur after this until the array is grown beyond this capacity, meaning that adding elements will not invalidate any iterators or element addresses until that point. This method will never reduce the capacity of the array. It is OK to call this on a non-owner array as long as you are not asking for an increase in capacity.

template<class T, class X>
void SimTK::Array_< T, X >::shrink_to_fit ( ) [inline]

Request that the capacity of this array be reduced to the minimum necessary to hold the number of elements currently in use.

In practice no shrinkage will occur if the current size is just slightly too big, unless the current size is exactly zero in which case we guarantee to deallocate all heap space associated with this array leaving a null data pointer and begin()==end()==0, exactly as though the array had just been default-constructed. Otherwise you can check capacity() afterwards to see what happened. If the capacity() is reduced by this method, then all the elements will have been moved to new locations so existing iterators and references into the array will become invalid.

Note:
  • This method is from the proposed C++0x standard for std::vector, except for the guaranteed behavior for a zero-size container.
  • It is OK to call this on a non-owner array but it has no effect since capacity()==size() already in that case.
Complexity:
If the capacity is reduced, there will be one call to T's copy constructor and destructor (if any) for each element currently in the array. Otherwise this is very fast.
template<class T, class X>
size_type SimTK::Array_< T, X >::allocated ( ) const [inline]

Return the amount of heap space owned by this array; this is the same as capacity() for owner arrays but is zero for non-owners.

Note:
There is no equivalent of this method for std::vector.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
bool SimTK::Array_< T, X >::isOwner ( ) const [inline]

Does this array own the data to which it refers? If not, it can't be resized, and the destructor will not free any heap space nor call any element destructors.

If the array does not refer to any data it is considered to be an owner and it is resizeable.

Note:
There is no equivalent of this method for std::vector.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T* SimTK::Array_< T, X >::cbegin ( ) const [inline]

Return a const pointer to the first element of this array if any, otherwise cend(), which may be null (0) in that case but does not have to be.

This method is from the proposed C++0x standard; there is also an overloaded begin() from the original standard that returns a const pointer.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T* SimTK::Array_< T, X >::begin ( ) const [inline]

The const version of begin() is the same as cbegin().

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
T* SimTK::Array_< T, X >::begin ( ) [inline]

Return a writable pointer to the first element of this array if any, otherwise end().

If the array is empty, this may return null (0) but does not have to -- the only thing you can be sure of is that begin() == end() for an empty array.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T* SimTK::Array_< T, X >::cend ( ) const [inline]

Return a const pointer to what would be the element just after the last one in the array; this may be null (0) if there are no elements but doesn't have to be.

This method is from the proposed C++0x standard; there is also an overloaded end() from the original standard that returns a const pointer.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T* SimTK::Array_< T, X >::end ( ) const [inline]

The const version of end() is the same as cend().

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
T* SimTK::Array_< T, X >::end ( ) [inline]

Return a writable pointer to what would be the element just after the last one in this array.

If the array is empty, this may return null (0) but does not have to -- the only thing you can be sure of is that begin()==end() for an empty array.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const_reverse_iterator SimTK::Array_< T, X >::crbegin ( ) const [inline]

Return a const reverse iterator pointing to the last element in the array or crend() if the array is empty.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const_reverse_iterator SimTK::Array_< T, X >::rbegin ( ) const [inline]

The const version of rbegin() is the same as crbegin().

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
reverse_iterator SimTK::Array_< T, X >::rbegin ( ) [inline]

Return a writable reverse iterator pointing to the last element in the array or rend() if the array is empty.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const_reverse_iterator SimTK::Array_< T, X >::crend ( ) const [inline]

Return the past-the-end reverse iterator that tests equal to a reverse iterator that has been incremented past the front of the array.

You cannot dereference this iterator.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const_reverse_iterator SimTK::Array_< T, X >::rend ( ) const [inline]

The const version of rend() is the same as crend().

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
reverse_iterator SimTK::Array_< T, X >::rend ( ) [inline]

Return a writable past-the-end reverse iterator that tests equal to a reverse iterator that has been incremented past the front of the array.

You cannot dereference this iterator.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T* SimTK::Array_< T, X >::cdata ( ) const [inline]

Return a const pointer to the first element of the array, or possibly (but not necessarily) null (0) if the array is empty.

Note:
cdata() does not appear to be in the C++0x standard although it would seem obvious in view of the cbegin() and cend() methods that had to be added. The C++0x overloaded const data() method is also available.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T* SimTK::Array_< T, X >::data ( ) const [inline]

The const version of the data() method is identical to cdata().

Note:
This method is from the proposed C++0x std::vector.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
T* SimTK::Array_< T, X >::data ( ) [inline]

Return a writable pointer to the first allocated element of the array, or a null pointer if no space is associated with the array.

Note:
This method is from the proposed C++0x std::vector.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T& SimTK::Array_< T, X >::operator[] ( index_type  i) const [inline]

Select an element by its index, returning a const reference.

Note that only a value of the Array's templatized index type is allowed (default is unsigned). This will be range-checked in a Debug build but not in Release.

Precondition:
0 <= i < size()
Complexity:
Constant time.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
T& SimTK::Array_< T, X >::operator[] ( index_type  i) [inline]

Select an element by its index, returning a writable (lvalue) reference.

Note that only a value of the Array's templatized index type is allowed (default is unsigned). This will be range-checked in a Debug build but not in Release.

Precondition:
0 <= i < size()
Complexity:
Constant time.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T& SimTK::Array_< T, X >::at ( index_type  i) const [inline]

Same as operator[] but always range-checked, even in a Release build.

Precondition:
0 <= i < size()
Complexity:
Constant time.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
T& SimTK::Array_< T, X >::at ( index_type  i) [inline]

Same as operator[] but always range-checked, even in a Release build.

Precondition:
0 <= i < size()
Complexity:
Constant time.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T& SimTK::Array_< T, X >::getElt ( index_type  i) const [inline]

Same as the const form of operator[]; exists to provide a non-operator method for element access in case that's needed.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
T& SimTK::Array_< T, X >::updElt ( index_type  i) [inline]

Same as the non-const form of operator[]; exists to provide a non-operator method for element access in case that's needed.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T& SimTK::Array_< T, X >::front ( ) const [inline]

Return a const reference to the first element in this array, which must not be empty.

Precondition:
The array is not empty.
Complexity:
Constant time.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
T& SimTK::Array_< T, X >::front ( ) [inline]

Return a writable reference to the first element in this array, which must not be empty.

Precondition:
The array is not empty.
Complexity:
Constant time.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
const T& SimTK::Array_< T, X >::back ( ) const [inline]

Return a const reference to the last element in this array, which must not be empty.

Precondition:
The array is not empty.
Complexity:
Constant time.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
T& SimTK::Array_< T, X >::back ( ) [inline]

Return a writable reference to the last element in this array, which must not be empty.

Precondition:
The array is not empty.
Complexity:
Constant time.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
ArrayViewConst_<T,X> SimTK::Array_< T, X >::operator() ( index_type  index,
size_type  length 
) const [inline]

Select a subrange of this const array by starting index and length, and return a ArrayViewConst_ referencing that data without copying it.

Reimplemented from SimTK::ArrayViewConst_< T, X >.

template<class T, class X>
ArrayViewConst_<T,X> SimTK::Array_< T, X >::getSubArray ( index_type  index,
size_type  length 
) const [inline]

Same as const form of operator()(index,length); exists to provide non-operator access to that functionality in case it is needed.

Reimplemented from SimTK::ArrayViewConst_< T, X >.

template<class T, class X>
ArrayView_<T,X> SimTK::Array_< T, X >::operator() ( index_type  index,
size_type  length 
) [inline]

Select a subrange of this array by starting index and length, and return an ArrayView_ referencing that data without copying it.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
ArrayView_<T,X> SimTK::Array_< T, X >::updSubArray ( index_type  index,
size_type  length 
) [inline]

Same as non-const operator()(index,length); exists to provide non-operator access to that functionality in case it is needed.

Reimplemented from SimTK::ArrayView_< T, X >.

template<class T, class X>
void SimTK::Array_< T, X >::push_back ( const T &  value) [inline]

This method increases the size of the Array by one element at the end and initializes that element by copy constructing it from the given value.

If capacity() > size(), that's all that will happen. If capacity()==size(), there is no room for another element so we'll allocate more space and move all the elements there. A reference to the just-inserted element can be obtained using the back() method after the call to push_back().

Parameters:
[in]valueAn object of type T from which the new element is copy-constructed.
Remarks:
  • If you are appending a default-constructed object of type T, consider using the alternate non-standard but safe push_back() method rather than push_back(T()). The non-standard method default-constructs the new element internally. That avoids a call to the copy constructor which can be expensive for some objects, and nonexistent for others.
  • If you are constructing the source object with a non-default constructor, and the object is expensive or impossible to default-construct and/or copy-construct, consider using the non-standard and dangerous method raw_push_back() which enables you to construct the new element in place.
Complexity:
Constant time if no reallocation is required; otherwise the current contents of the array must be copied to new space, costing one call to T's copy constructor and destructor (if any) for each element currently in the array. Either way there is also one call to T's copy constructor to construct the new element from the supplied value.
template<class T, class X>
void SimTK::Array_< T, X >::push_back ( ) [inline]

This is a non-standard version of push_back() that increases the size of the array by one default-constructed element at the end.

This avoids having to default-construct the argument to the standard push_back(value) method which then has to copy-construct it into the array. By carefully avoiding reallocation and using this form of push_back() you can use the Array_<T> class to hold objects of type T even if T has no copy constructor, which is prohibited by the standard std::vector<T> definition.

Complexity:
Same as the standard push_back(value) method except without the final call to T's copy constructor.
See also:
push_back(value)
template<class T, class X>
T* SimTK::Array_< T, X >::raw_push_back ( ) [inline]

This dangerous method increases the Array's size by one element at the end but doesn't perform any construction so the memory is filled with garbage.

You must immediately construct into this space, using code like:

    new(a.raw_push_back()) MyConstructor(...args...);       

This is a substantial performance improvement when the element type is something complicated since the constructor is called once and not copied; it can also be used for objects that have neither default nor copy constructors.

Returns:
An iterator (pointer) pointing at the unconstructed element.
Complexity:
Same as ordinary push_back().
See also:
push_back(value), push_back()
template<class T, class X>
void SimTK::Array_< T, X >::pop_back ( ) [inline]

Remove the last element from this array, which must not be empty.

The element is destructed, not returned. The array's size() is reduced by one.

template<class T, class X>
T* SimTK::Array_< T, X >::erase ( T *  first,
const T *  last1 
) [inline]

Erase elements in range [first,last1), packing in any later elements into the newly-available space and reducing the array's size by the number of elements erased.

Capacity is unchanged. If the range is empty nothing happens.

Precondition:
begin() <= first <= last1 <= end()
Parameters:
firstPoints to the first element that will be erased.
last1Points one element past the last element to be erased.
Returns:
An iterator pointing to the new location of the element immediately following the erased ones, or end() if there are none. Either way, this is the same memory address as the passed-in first argument since there can be no reallocation here.
Complexity:
Calls T's destructor once for each erased element and calls T's copy constructor and destructor once for each element that has to be moved.
template<class T, class X>
T* SimTK::Array_< T, X >::erase ( T *  p) [inline]

Erase just one element, moving all subsequent elements down one slot and reducing the array's size by one.

This is equivalent to erase(p,p+1) but faster; that means p cannot be end() because end()+1 is not defined. Capacity is unchanged.

Note:
If you don't mind the elements being reordered, you can erase an element in constant time using the non-standard extension eraseFast().
Parameters:
pPoints to the element that will be erased; p cannot be end().
Returns:
A pointer to the element that replaced the one at p, or end() if p was the last element. Either way, this is the same memory address as the erased element had since there can be no reallocation here.
Precondition:
begin() <= p < end()
Complexity:
Calls T's destructor once for the erased element and calls T's copy constructor and destructor once for each element that has to be moved.
See also:
eraseFast()
template<class T, class X>
T* SimTK::Array_< T, X >::eraseFast ( T *  p) [inline]

Be careful with this non-standard extension; it erases one element and then moves the last one in its place which changes the element order from what it was before (unlike the standard erase() method).

This avoids having to compress the elements so this runs in constant time: the element is destructed; then if it wasn't the last element the copy constructor is used to copy the last element into the vacated space, and the destructor is called to clear the last element. The size is reduced by 1 but the capacity does not change.

Parameters:
pPoints to the element that will be erased; p cannot be end().
Returns:
A pointer to the element that replaced the one at p, or end() if p was the last element. Either way, this is the same memory address as the erased element had since there can be no reallocation here.
Precondition:
begin() <= p < end()
Complexity:
Calls T's destructor once for the erased element and calls T's copy constructor and destructor once for each element that has to be moved.
See also:
erase()
template<class T, class X>
void SimTK::Array_< T, X >::clear ( ) [inline]

Erase all the elements currently in this array without changing the capacity; equivalent to erase(begin(),end()) but a little faster.

Size is zero after this call. T's destructor is called exactly once for each element in the array.

Complexity:
O(n) if T has a destructor; constant time otherwise.
template<class T, class X>
T* SimTK::Array_< T, X >::insert ( T *  p,
size_type  n,
const T &  value 
) [inline]

Insert n copies of a given value at a particular location within this array, moving all following elements up by n positions.

Parameters:
[in]pWhere to insert the new elements. This must be an iterator (pointer) that is valid for this array, that is, begin() <= p <= end().
[in]nHow many copies of the given value to insert. Nothing happens if n is zero.
[in]valueA value of the element type that is copied into the newly-created elements using T's copy constructor.
Returns:
A pointer to the first of the newly-created elements in the array. This will be different from p if reallocation occurred, otherwise it is the same as p was on entry.
Precondition:
begin() <= p <= end()
Complexity:
If size() + n > capacity() then the array must be reallocated, resulting in size() copy constructor/destructor call pairs to move the old data to the new location. Otherwise, the m=(end()-p) elements above the insertion point must be moved up n positions resulting in m copy/destruct pairs. Then there are n additional copy constructor calls to construct the new elements from the given value.
template<class T, class X>
T* SimTK::Array_< T, X >::insert ( T *  p,
const T &  value 
) [inline]

Insert a new element at a given location within this array, initializing it to a copy of a given value and moving all following elements up one position.

This is identical to insert(p,1,value) but slightly faster; see that method for full documentation.

template<class T, class X>
template<class T2 >
T* SimTK::Array_< T, X >::insert ( T *  p,
const T2 *  first,
const T2 *  last1 
) [inline]

Insert elements in a range [first,last1) into this array at a given position p, moving all following elements up by n=(last1-first) positions.

This variant of insert() takes iterators which are ordinary pointers, although the source elements do not have to be of type T as long as there is a constructor T(T2) that works.

Parameters:
[in]pWhere to insert the new elements. This must be an iterator (pointer) that is valid for this array, that is, begin() <= p <= end().
[in]firstThis is a pointer to the first element of the source to be copied.
[in]last1This points one element past the last element of the source to be copied.
Returns:
A pointer to the first of the newly-created elements in the array. This will be different from p if reallocation occurred, otherwise it is the same as p was on entry.
Precondition:
begin() <= p <= end()
first <= last1
The range [first,last1) does not include any of the current contents of this array.
Complexity:
If capacity() < size()+n then the array must be reallocated, resulting in size() calls to T's copy constructor and destructor (if any)to move the old data to the new location. Otherwise, the m=(end()-p) elements above the insertion point must be moved up n positions resulting in m copy/destruct pairs. Then there are n additional copy constructor calls to construct the new elements from the given value.
template<class T, class X>
template<class Iter >
T* SimTK::Array_< T, X >::insert ( T *  p,
const Iter &  first,
const Iter &  last1 
) [inline]

Insert elements in a range [first,last1) where the range is given by non-pointer iterators.


Friends And Related Function Documentation

template<class T , class X >
std::ostream & operator<< ( std::ostream &  o,
const ArrayViewConst_< T, X > &  a 
) [related]

Output a human readable representation of an array to an std::ostream (like std::cout).

The format is ( elements ) where elements is a comma-separated list of the Array's contents output by invoking the "<<" operator on the elements. This function will not compile if the element type does not support the "<<" operator. No newline is issued before or after the output.

template<class T , class X >
static std::istream & readArrayFromStream ( std::istream &  in,
Array_< T, X > &  out 
) [related]

Read in an Array_<T> from a stream, as a sequence of space-separated or comma-separated values optionally surrounded by parentheses (), square brackets [], or curly braces {}.

We will continue to read elements of type T from the stream until we find a reason to stop, using type T's stream extraction operator>>() to read in each element and resizing the Array as necessary. If the data is bracketed, we'll read until we hit the closing bracket. If it is not bracketed, we'll read until we hit eof() or get an error such as the element extractor setting the stream's fail bit due to bad formatting. On successful return, the stream will be positioned right after the final read-in element or terminating bracket, and the stream's status will be good() or eof(). We will not consume trailing whitespace after bracketed elements; that means the stream might actually be empty even if we don't return eof(). If you want to know whether there is anything else in the stream, follow this call with the STL whitespace skipper std::ws() like this:

    if (readArrayFromStream(in,array) && !in.eof()) 
        std::ws(in); // might take us to eof
    if (in.fail()) {...} // probably a formatting error
    else {
        // Here if the stream is good() then there is more to read; if the
        // stream got used up the status is guaranteed to be eof().
    }

A compilation error will occur if you try to use this method on an Array_<T> for a type T for which there is no stream extraction operator>>().

Note:
If you want to fill an owner Array_<T> with a fixed amount of data from the stream, resize() the array to the appropriate length and then use fillArrayFromStream() instead.
See also:
fillArrayFromStream()
template<class T , class X >
static std::istream & fillArrayFromStream ( std::istream &  in,
Array_< T, X > &  out 
) [related]

Read in a fixed number of elements from a stream into an Array.

We expect to read in exactly size() elements of type T, using type T's stream extraction operator>>(). This will stop reading when we've read size() elements, or set the fail bit in the stream if we run out of elements or if any element's extract operator sets the fail bit. On successful return, all size() elements will have been set, the stream will be positioned right after the final read-in element or terminating bracket, and the stream's status will be good() or eof(). We will not consume trailing whitespace after reading all the elements; that means the stream might actually be empty even if we don't return eof(). If you want to know whether there is anything else in the stream, follow this call with std::ws() like this:

    if (fillArrayFromStream(in,array))
        if (!in.eof()) std::ws(in); // might take us to eof
    if (in.fail()) {...} // deal with I/O or formatting error
    // Here if the stream is good() then there is more to read; if the
    // stream got used up the status is guaranteed to be eof().

A compilation error will occur if you try to use this method on an Array_<T> for a type T for which there is no stream extraction operator>>().

Note:
If you want to read in a variable number of elements and have the Array_<T> resized as needed, use readArrayFromStream() instead.
See also:
readArrayFromStream()
template<class T , class X >
std::istream & operator>> ( std::istream &  in,
Array_< T, X > &  out 
) [related]

Read an Array_<T> from a stream as a sequence of space- or comma-separated values of type T, optionally delimited by parentheses, brackets, or braces.

The Array_<T> may be an owner (variable size) or a view (fixed size n). In the case of an owner, we'll read all the elements in brackets or until eof if there are no brackets. In the case of a view, there must be exactly n elements in brackets, or if there are no brackets we'll consume exactly n elements and then stop. Each element is read in with its own operator ">>" so this won't work if no such operator is defined for type T.

template<class T1 , class X1 , class T2 , class X2 >
bool operator== ( const ArrayViewConst_< T1, X1 > &  a1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

Two Array_ objects are equal if and only if they are the same size() and each element compares equal using an operator T1==T2.

template<class T1 , class X1 , class T2 , class X2 >
bool operator!= ( const ArrayViewConst_< T1, X1 > &  a1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

The not equal operator is implemented using the equal operator.

template<class T1 , class X1 , class T2 , class X2 >
bool operator< ( const ArrayViewConst_< T1, X1 > &  a1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

Array_ objects are ordered lexicographically; that is, by first differing element or by length if there are no differing elements up to the length of the shorter array (in which case the shorter one is "less than" the longer).

This depends on T1==T2 and T1<T2 operators working.

template<class T1 , class X1 , class T2 , class X2 >
bool operator>= ( const ArrayViewConst_< T1, X1 > &  a1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

The greater than or equal operator is implemented using the less than operator.

template<class T1 , class X1 , class T2 , class X2 >
bool operator> ( const ArrayViewConst_< T1, X1 > &  a1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

The greater than operator is implemented by using less than with the arguments reversed, meaning the elements must have working comparison operators of the form T2==T1 and T2<T1.

template<class T1 , class X1 , class T2 , class X2 >
bool operator<= ( const ArrayViewConst_< T1, X1 > &  a1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

The less than or equal operator is implemented using the greater than operator.

template<class T1 , class X1 , class T2 , class A2 >
bool operator== ( const ArrayViewConst_< T1, X1 > &  a1,
const std::vector< T2, A2 > &  v2 
) [related]

An Array_<T1> and an std::vector<T2> are equal if and only if they are the same size() and each element compares equal using an operator T1==T2.

template<class T1 , class A1 , class T2 , class X2 >
bool operator== ( const std::vector< T1, A1 > &  v1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

An std::vector<T1> and an Array_<T2> are equal if and only if they are the same size() and each element compares equal using an operator T2==T1.

template<class T1 , class X1 , class T2 , class A2 >
bool operator!= ( const ArrayViewConst_< T1, X1 > &  a1,
const std::vector< T2, A2 > &  v2 
) [related]

The not equal operator is implemented using the equal operator.

template<class T1 , class A1 , class T2 , class X2 >
bool operator!= ( const std::vector< T1, A1 > &  v1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

The not equal operator is implemented using the equal operator.

template<class T1 , class X1 , class T2 , class A2 >
bool operator< ( const ArrayViewConst_< T1, X1 > &  a1,
const std::vector< T2, A2 > &  v2 
) [related]

An Array_<T1> and std::vector<T2> are ordered lexicographically; that is, by first differing element or by length if there are no differing elements up to the length of the shorter container (in which case the shorter one is "less than" the longer).

This depends on having working element operators T1==T2 and T1<T2.

template<class T1 , class A1 , class T2 , class X2 >
bool operator< ( const std::vector< T1, A1 > &  v1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

An std::vector<T1> and Array_<T2> are ordered lexicographically; that is, by first differing element or by length if there are no differing elements up to the length of the shorter container (in which case the shorter one is "less than" the longer).

This depends on having working element operators T1==T2 and T1<T2.

template<class T1 , class X1 , class T2 , class A2 >
bool operator>= ( const ArrayViewConst_< T1, X1 > &  a1,
const std::vector< T2, A2 > &  v2 
) [related]

The greater than or equal operator is implemented using the less than operator.

template<class T1 , class A1 , class T2 , class X2 >
bool operator>= ( const std::vector< T1, A1 > &  v1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

The greater than or equal operator is implemented using the less than operator.

template<class T1 , class X1 , class T2 , class A2 >
bool operator> ( const ArrayViewConst_< T1, X1 > &  a1,
const std::vector< T2, A2 > &  v2 
) [related]

The greater than operator is implemented by using less than with the arguments reversed, meaning the elements must have working comparison operators of the form T2==T1 and T2<T1.

template<class T1 , class A1 , class T2 , class X2 >
bool operator> ( const std::vector< T1, A1 > &  v1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

The greater than operator is implemented by using less than with the arguments reversed, meaning the elements must have working comparison operators of the form T2==T1 and T2<T1.

template<class T1 , class X1 , class T2 , class A2 >
bool operator<= ( const ArrayViewConst_< T1, X1 > &  a1,
const std::vector< T2, A2 > &  v2 
) [related]

The less than or equal operator is implemented using the greater than operator.

template<class T1 , class A1 , class T2 , class X2 >
bool operator<= ( const std::vector< T1, A1 > &  v1,
const ArrayViewConst_< T2, X2 > &  a2 
) [related]

The less than or equal operator is implemented using the greater than operator.

template<class T , class X >
void swap ( SimTK::Array_< T, X > &  a1,
SimTK::Array_< T, X > &  a2 
) [related]

This is a specialization of the STL std::swap() algorithm which uses the constant time built-in swap() member of the Array_ class.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines