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

The 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...

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

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
 
typedef X index_type
 
typedef T * pointer
 
typedef const T * const_pointer
 
typedef T & reference
 
typedef const T & const_reference
 
typedef T * iterator
 
typedef const T * const_iterator
 
typedef std::reverse_iterator< iteratorreverse_iterator
 
typedef std::reverse_iterator< const_iteratorconst_reverse_iterator
 
typedef ArrayIndexTraits< X >::size_type size_type
 
typedef ArrayIndexTraits< X >::difference_type difference_type
 
typedef ArrayIndexPackType< size_type >::packed_size_type packed_size_type
 
- Public Types inherited from SimTK::ArrayView_< T, X >
typedef T value_type
 
typedef X index_type
 
typedef T * pointer
 
typedef const T * const_pointer
 
typedef T & reference
 
typedef const T & const_reference
 
typedef T * iterator
 
typedef const T * const_iterator
 
typedef std::reverse_iterator< iteratorreverse_iterator
 
typedef std::reverse_iterator< const_iteratorconst_reverse_iterator
 
typedef ArrayIndexTraits< X >::size_type size_type
 
typedef ArrayIndexTraits< X >::difference_type difference_type
 
typedef ArrayIndexPackType< size_type >::packed_size_type packed_size_type
 
- Public Types inherited from SimTK::ArrayViewConst_< T, X >
typedef T value_type
 The type of object stored in this container. More...
 
typedef X index_type
 The index type (an extension). More...
 
typedef T * pointer
 A writable pointer to a value_type. More...
 
typedef const T * const_pointer
 A const pointer to a value_type. More...
 
typedef T & reference
 A writable value_type reference. More...
 
typedef const T & const_reference
 A const value_type reference. More...
 
typedef T * iterator
 A writable iterator for this container (same as pointer here). More...
 
typedef const T * const_iterator
 A const iterator for this container (same as const_pointer here). More...
 
typedef std::reverse_iterator< iteratorreverse_iterator
 A writable reverse iterator for this container. More...
 
typedef std::reverse_iterator< const_iteratorconst_reverse_iterator
 A const reverse iterator for this container. More...
 
typedef ArrayIndexTraits< X >::size_type size_type
 An integral type suitable for all indices and sizes for this array. More...
 
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. More...
 
typedef ArrayIndexPackType< size_type >::packed_size_type packed_size_type
 The integral type we actually use internally to store size_type values. More...
 

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. More...
 
 Array_ (size_type n)
 Construct an array containing n default-constructed elements. More...
 
 Array_ (size_type n, const T &initVal)
 Construct an array containing n elements each set to a copy of the given initial value. More...
 
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. More...
 
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). More...
 
 Array_ (std::initializer_list< T > ilist)
 Construct an Array_<T> from an std::initializer_list whose elements were convertible to type T, provided that the number of source elements does not exceed the array's max_size(). More...
 
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. More...
 
 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. More...
 
 Array_ (Array_ &&src)
 Move constructor swaps in the source and leaves the source default constructed. More...
 
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. More...
 
 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. More...
 
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. More...
 
 ~Array_ ()
 The destructor performs a deallocate() operation which may result in element destruction and freeing of heap space; see deallocate() for more information. More...
 
Array_deallocate ()
 Empty this array of its contents, returning the array to its default-constructed, all-zero state. More...
 
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 elements 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. More...
 
void fill (const T &fillValue)
 Assign all current elements of the array to the same fillValue. More...
 
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. More...
 
template<class Iter >
void assign (const Iter &first, const Iter &last1)
 Assign this array from a range [first,last1) given by non-pointer iterators. More...
 
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. More...
 
Array_operator= (Array_ &&src)
 Move assignment operator swaps the contents of this Array_ with the source Array_. More...
 
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. More...
 
template<class T2 , class A >
Array_operator= (const std::vector< T2, A > &src)
 This is assignment from a source std::vector<T2>. More...
 
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. More...
 
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. More...
 
Array_adoptData (T *newData, size_type dataSize)
 A variant of adoptData() that assumes the capacity is the same as the current size. More...
 
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. More...
 
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. More...
 
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. More...
 
size_type max_size () const
 Return the maximum allowable size for this array. More...
 
bool empty () const
 Return true if there are no elements currently stored in this array. More...
 
size_type capacity () const
 Return the number of elements this array can currently hold without requiring reallocation. More...
 
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. More...
 
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. More...
 
void reserve (size_type n)
 Ensure that this array has enough allocated capacity to hold the indicated number of elements. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
const T * begin () const
 The const version of begin() is the same as cbegin(). More...
 
T * begin ()
 Return a writable pointer to the first element of this array if any, otherwise end(). More...
 
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. More...
 
const T * end () const
 The const version of end() is the same as cend(). More...
 
T * end ()
 Return a writable pointer to what would be the element just after the last one in this array. More...
 
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. More...
 
const_reverse_iterator rbegin () const
 The const version of rbegin() is the same as crbegin(). More...
 
reverse_iterator rbegin ()
 Return a writable reverse iterator pointing to the last element in the array or rend() if the array is empty. More...
 
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. More...
 
const_reverse_iterator rend () const
 The const version of rend() is the same as crend(). More...
 
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. More...
 
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. More...
 
const T * data () const
 The const version of the data() method is identical to cdata(). More...
 
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. More...
 
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. More...
 
T & operator[] (index_type i)
 Select an element by its index, returning a writable (lvalue) reference. More...
 
const T & at (index_type i) const
 Same as operator[] but always range-checked, even in a Release build. More...
 
T & at (index_type i)
 Same as operator[] but always range-checked, even in a Release build. More...
 
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. More...
 
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. More...
 
const T & front () const
 Return a const reference to the first element in this array, which must not be empty. More...
 
T & front ()
 Return a writable reference to the first element in this array, which must not be empty. More...
 
const T & back () const
 Return a const reference to the last element in this array, which must not be empty. More...
 
T & back ()
 Return a writable reference to the last element in this array, which must not be empty. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
- Public Member Functions inherited from SimTK::ArrayView_< T, X >
 ArrayView_ ()
 Default constructor allocates no heap space and is very fast. More...
 
 ArrayView_ (const ArrayView_ &src)
 Copy constructor is shallow. More...
 
 ArrayView_ (T *first, const T *last1)
 Construct from a range of writable memory. More...
 
template<class A >
 ArrayView_ (std::vector< T, A > &v)
 Construct to reference memory owned by a writable std::vector. More...
 
 operator const Array_< T, X > & () const
 Implicit conversion of const ArrayView_ to const Array_& (zero cost). More...
 
 operator Array_< T, X > & ()
 Implicit conversion of non-const ArrayView_ to Array_& (zero cost). More...
 
void disconnect ()
 Forward to base class disconnect() method – clears the handle without doing anything to the data. More...
 
 ~ArrayView_ ()
 The destructor just disconnects the array view handle from its data; see ArrayViewConst_<T,X>::disconnect() for more information. More...
 
ArrayView_operator= (const ArrayView_ &src)
 Copy assignment; source must be the same size as this array. More...
 
template<class T2 , class X2 >
ArrayView_operator= (const ArrayViewConst_< T2, X2 > &src)
 Assignment from any other array object is allowed as long as the number of elements matches and the types are assignment compatible. More...
 
template<class T2 , class X2 >
ArrayView_operator= (const ArrayView_< T2, X2 > &src)
 Assignment from any other array object is allowed as long as the number of elements matches and the types are assignment compatible. More...
 
template<class T2 , class X2 >
ArrayView_operator= (const Array_< T2, X2 > &src)
 Assignment from any other array object is allowed as long as the number of elements matches and the types are assignment compatible. More...
 
template<class T2 , class A2 >
ArrayView_operator= (const std::vector< T2, A2 > &src)
 Assignment from any std::vector object is allowed as long as the number of elements matches and the types are assignment compatible. More...
 
ArrayView_operator= (const T &fillValue)
 Fill assignment – all elements are set to fillValue. More...
 
ArrayView_fill (const T &fillValue)
 Assign the supplied fill value to each element of this array, using T's copy assignment operator for each element. More...
 
void assign (size_type n, const T &fillValue)
 This is the same as fill() but has the usual std::vector signature for compatibility; it will only work if the given number of elements is the same as this array's (fixed) size. More...
 
template<class T2 >
void assign (const T2 *first, const T2 *last1)
 Assign to this array to make it a copy of the elements in range [first,last1) given by ordinary pointers, provided that the range is the same size as the array. More...
 
template<class Iter >
void assign (const Iter &first, const Iter &last1)
 Assign to this array to make it a copy of the elements in range [first,last1) given by non-pointer iterators (the pointer case is handled with a specialized assign() variant). More...
 
const T & operator[] (index_type i) const
 Select an element by its index, returning a const reference. More...
 
T & operator[] (index_type i)
 Select an element by its index, returning a writable (lvalue) reference. More...
 
const T & at (index_type i) const
 Same as operator[] but always range-checked, even in a Release build. More...
 
T & at (index_type i)
 Same as operator[] but always range-checked, even in a Release build. More...
 
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. More...
 
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. More...
 
const T & front () const
 Return a const reference to the first element in this array, which must not be empty. More...
 
T & front ()
 Return a writable reference to the first element in this array, which must not be empty. More...
 
const T & back () const
 Return a const reference to the last element in this array, which must not be empty. More...
 
T & back ()
 Return a writable reference to the last element in this array, which must not be empty. More...
 
ArrayView_ operator() (index_type index, size_type length)
 Select a contiguous subarray of the elements of this array and create another ArrayView_ that refers only to those element (without copying). More...
 
ArrayView_ 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. More...
 
const T * cbegin () const
 Return a const pointer to the first element of this array if any, otherwise end(), which may be null (0) in that case but does not have to be. More...
 
const T * begin () const
 The const version of begin() is the same as cbegin(). More...
 
T * begin ()
 Return a writable pointer to the first element of this array if any, otherwise end(). More...
 
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. More...
 
const T * end () const
 The const version of end() is the same as cend(). More...
 
T * end ()
 Return a writable pointer to what would be the element just after the last one in this array. More...
 
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. More...
 
const_reverse_iterator rbegin () const
 The const version of rbegin() is the same as crbegin(). More...
 
reverse_iterator rbegin ()
 Return a writable reverse iterator pointing to the last element in the array or rend() if the array is empty. More...
 
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. More...
 
const_reverse_iterator rend () const
 The const version of rend() is the same as crend(). More...
 
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. More...
 
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. More...
 
const T * data () const
 The const version of the data() method is identical to cdata(). More...
 
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. More...
 
size_type size () const
 
size_type max_size () const
 
bool empty () const
 
size_type capacity () const
 
size_type allocated () const
 
bool isOwner () const
 
- Public Member Functions inherited from SimTK::ArrayViewConst_< T, X >
 ArrayViewConst_ ()
 Default constructor allocates no heap space and is very fast. More...
 
 ArrayViewConst_ (const ArrayViewConst_ &src)
 Copy constructor is shallow; the constructed const array object will be referencing the original source data. More...
 
 ArrayViewConst_ (const T *first, const T *last1)
 Construct an ArrayViewConst_<T> by referencing (sharing) a given range of const data [first,last1), without copying that data. More...
 
template<class A >
 ArrayViewConst_ (const std::vector< T, A > &src)
 Construct a ArrayViewConst_<T> by referencing (sharing) the data in a const std::vector<T>, without copying the data; this is also an implicit conversion. More...
 
 operator const ArrayView_< T, X > & () const
 This is an implicit conversion to const ArrayView_<T,X>&, which is harmless since the const result won't permit writing on the elements. More...
 
 operator const Array_< T, X > & () const
 This is an implicit conversion to const Array_<T,X>&, which is harmless since the const result can't be used to write on or resize the data. More...
 
void disconnect ()
 Disconnect this array handle from any data to which it refers, restoring it to the condition it would be in if it had just been default-constructed. More...
 
 ~ArrayViewConst_ ()
 The destructor just disconnects the array view handle from its data; see disconnect() for more information. More...
 
size_type size () const
 Return the current number of elements stored in this array. More...
 
size_type max_size () const
 Return the maximum allowable size for this array. More...
 
bool empty () const
 Return true if there are no elements currently stored in this array. More...
 
size_type capacity () const
 Return the number of elements this array can currently hold without requiring reallocation. More...
 
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. More...
 
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. More...
 
const T & operator[] (index_type i) const
 Select an element by its index, returning a const reference. More...
 
const T & at (index_type i) const
 Same as operator[] but always range-checked, even in a Release build. More...
 
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. More...
 
const T & front () const
 Return a const reference to the first element in this array, which must not be empty (we'll check in a Debug build but not Release). More...
 
const T & back () const
 Return a const reference to the last element in this array, which must not be empty (we'll check in a Debug build but not Release). More...
 
ArrayViewConst_ operator() (index_type index, size_type length) const
 Select a contiguous subarray of the elements of this array and create another ArrayViewConst_ that refers only to those element (without copying). More...
 
ArrayViewConst_ 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. More...
 
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. More...
 
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. More...
 
const T * begin () const
 The const version of begin() is the same as cbegin(). More...
 
const T * end () const
 The const version of end() is the same as cend(). More...
 
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. More...
 
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. More...
 
const_reverse_iterator rbegin () const
 The const version of rbegin() is the same as crbegin(). More...
 
const_reverse_iterator rend () const
 The const version of rend() is the same as crend(). More...
 
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. More...
 
const T * data () const
 The const version of the data() method is identical to cdata(). More...
 

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. More...
 
template<class T , class X >
Xml::Element toXmlElement (const Array_< T, X > &thing, const std::string &name="")
 Partial specialization for XML serialization of Array_ objects. More...
 
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 >
void writeUnformatted (std::ostream &o, const Array_< T, X > &v)
 Specialize writeUnformatted() for Array_<E,X> to delegate to element type E, with spaces separating the elements. More...
 
template<class T , class X >
void writeFormatted (std::ostream &o, const Array_< T, X > &v)
 Specialize writeFormatted() for Array_<E,X> to delegate to element type E, with surrounding parentheses and commas separating the elements. More...
 
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). More...
 
template<class T , class X >
bool readUnformatted (std::istream &in, Array_< T, X > &v)
 Specialization of readUnformatted() for variable-length Array_<T,X>; continues reading whitespace-separated tokens until error or eof. More...
 
template<class T , class X >
bool readFormatted (std::istream &in, Array_< T, X > &v)
 Specialization of readFormatted() for variable-length Array_<T,X>; uses readArrayFromStream() to consume an appropriately-formatted array until error, closing parenthesis or bracket, or eof. More...
 
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 {}. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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). More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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). More...
 
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). More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 

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. More...
 
void push_back (T &&value)
 This is the move form of push_back(), taking an rvalue reference rather than an lvalue reference. More...
 
template<class... Args>
void emplace_back (Args &&... args)
 This is similar to push_back() but rather than copying, it constructs the element in place at the end of the array. More...
 
void push_back ()
 (Deprecated, use emplace_back() instead) This is a non-standard version of push_back() that increases the size of the array by one default-constructed element at the end. More...
 
T * raw_push_back ()
 (Deprecated, use emplace_back() instead) This dangerous non-standard 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. More...
 
void pop_back ()
 Remove the last element from this array, which must not be empty. More...
 
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. More...
 
T * erase (T *p)
 Erase just one element, moving all subsequent elements down one slot and reducing the array's size by one. More...
 
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). More...
 
void clear ()
 Erase all the elements currently in this array without changing the capacity; equivalent to erase(begin(),end()) but a little faster. More...
 
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. More...
 
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. More...
 
template<class... Args>
T * emplace (T *p, Args &&... args)
 Insert a new element at a given location within this array, by invoking T's constructor whose signature matches the supplied arguments. More...
 
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. More...
 
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. More...
 

Detailed Description

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

The 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++12 (2013) std::vector runs about half speed for simple operations like indexing and push_back (see Simbody's TestArray regression test for an executable performance comparison). Attempting to disable these runtime checks with _SECURE_SCL breaks binary compatibility with other code built with the same compiler but without the flag. 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. 64 bit compilers vary on how well they handle 32 bit integers though, so in some cases the default index type (32 bit unsigned) won't be as fast as if you use a 64 bit unsigned type as does std::vector.
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 (last checked in VC++9); they are at 24 bytes for 64 bit Release builds in VC++12, 32 bytes in Debug builds. 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. The binary representation for Array_ is the same in Release and Debug builds.
Some nuts and bolts:
  • We promise that no heap allocation occurs when an empty Array_<T> object is declared (that is, when an Array_<T> is default-constructed); in that case both begin() and end() are null.
  • Array_<T> methods are extremely fast in Release builds with zero overhead, inline, unchecked methods. The implementations of inline methods are kept small to ensure that they are actually inlined in practice; and generated assembly code was examined to make sure.
  • There are some dangerous extensions provided that permit the expert user to construct objects directly into the array without having to copy them, a big win for complicated objects and even bigger for those that don't have copy constructors!
  • There is a constant-time eraseFast() method you can use if you don't mind the array being reordered after the erase. This avoids the extremely expensive "compress" activity required by the standard erase() method.
  • The optional index-type template parameter can be used to reduce the memory footprint to as little as 8 bytes on a 32 bit machine (e.g., a 32 bit pointer and two shorts).
  • The default size_type for an Array_<T> is a 32-bit unsigned integer rather than a size_t. On a 64-bit machine that keeps the memory footprint down substantially since the structure is then one 64-bit pointer and two 32-bit integers, fitting tightly into a cleanly alignable 16 bytes.
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:
  • This class always uses the default new/delete allocator; there is no option to specify your own as there is in std::vector.
  • Instead of an allocator, the second template argument X to Array_<T,X> is an optional index type which can be used to provide type-safe indexing (i.e. the array can only be indexed by indices of a particular type, like MobilizedBodyIndex). This has zero performance cost if the index is an integral type or class consisting of only an integral value such as those produced by the SimTK_DEFINE_UNIQUE_INDEX_TYPE macro.
  • You can create uninitialized slots in the array and construct directly into them rather than having to construct a temporary object which must then be copied into the array.
  • You can create Array_<T> objects that reference existing data, including the contents of std::vectors.
  • This class implements the std::vector features from the C++11 standard (with a few exceptions; see below).
Compatibility:
Included here are binary compatibility issues and compatibility with the C++ standard STL objects.
  • Most important, it is safe to pass an Array_<T> through an API to a binary library without worrying about compiler version or Release/Debug compatibility issues. For a given compiler (e.g. gcc or Microsoft cl) and word size (64 bit vs. 32 bit), Array_<T> has an extremely stable memory layout that is preserved across compiler versions, and between Release and Debug builds. This allows us to use Array_<T> in the SimTK API where use of std::vector<T> would be desirable but problematic.
  • It supports all standard types, methods, iterators, and operators of the C++11 standard std::vector, so it works smoothly with all STL containers and algorithms. However, it does not provide the same guarantees of behavior when exceptions occur. In particular, when resizing Array_ will use move construction if available even if the move constructor hasn't been marked "nothrow".
  • It is convertible to and from std::vector, usually without copying the elements. It is easy to provide APIs that accept either Array_<T> or std::vector<T>; the std::vector's data is referenced by an Array_ handle that is used to convey the data across the API without binary compatibility problems.
See also
Array_, ArrayViewConst_, ArrayIndexTraits

Member Typedef Documentation

◆ value_type

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

◆ index_type

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

◆ pointer

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

◆ const_pointer

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

◆ reference

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

◆ const_reference

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

◆ iterator

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

◆ const_iterator

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

◆ reverse_iterator

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

◆ const_reverse_iterator

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

◆ size_type

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

◆ difference_type

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

◆ packed_size_type

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

Constructor & Destructor Documentation

◆ Array_() [1/12]

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

Default constructor allocates no heap space and is very fast.

◆ Array_() [2/12]

template<class T, class X>
SimTK::Array_< T, X >::Array_ ( size_type  n)
inlineexplicit

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.

◆ Array_() [3/12]

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.

◆ Array_() [4/12]

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.

◆ Array_() [5/12]

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 which is either T or implicitly convertible to T, provided that the number of source elements does not exceed the array's max_size().

◆ Array_() [6/12]

template<class T, class X>
SimTK::Array_< T, X >::Array_ ( std::initializer_list< T >  ilist)
inline

Construct an Array_<T> from an std::initializer_list whose elements were convertible to type T, provided that the number of source elements does not exceed the array's max_size().

Note that this constructor is not explicit, so a suitable std::initializer_list will implicitly convert to an Array_<T>.

◆ Array_() [7/12]

template<class T, class X>
template<class T2 >
SimTK::Array_< T, X >::Array_ ( const std::vector< T2 > &  v)
inlineexplicit

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.

◆ Array_() [8/12]

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.

◆ Array_() [9/12]

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

Move constructor swaps in the source and leaves the source default constructed.

◆ Array_() [10/12]

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).

◆ Array_() [11/12]

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()

◆ Array_() [12/12]

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 untouched 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()

◆ ~Array_()

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

◆ deallocate()

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.

◆ assign() [1/3]

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()

◆ fill()

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.

◆ assign() [2/3]

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.

◆ assign() [3/3]

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)

◆ operator=() [1/4]

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.

◆ operator=() [2/4]

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

Move assignment operator swaps the contents of this Array_ with the source Array_.

◆ operator=() [3/4]

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.

◆ operator=() [4/4]

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.

◆ swap()

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 default std::swap() algorithm on the arrays since that would involve O(n) copying operations; we provide a specialization for std::swap() that uses the method here instead. 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.

◆ adoptData() [1/2]

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()

◆ adoptData() [2/2]

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)

◆ shareData() [1/2]

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()

◆ shareData() [2/2]

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.

◆ size()

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

Return the current number of elements stored in this array.

◆ max_size()

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

Return the maximum allowable size for this array.

◆ empty()

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.

◆ capacity()

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.

◆ resize() [1/2]

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.

◆ resize() [2/2]

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.

◆ reserve()

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.

◆ shrink_to_fit()

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 matches the C++11 std::vector method, 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 move constructor and destructor (if any) for each element currently in the array. Otherwise this is very fast.

◆ allocated()

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.

◆ isOwner()

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.

◆ cbegin()

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 C++11 standard; there is also an overloaded begin() from the original standard that returns a const pointer.

◆ begin() [1/2]

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

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

◆ begin() [2/2]

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.

◆ cend()

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 C++11 standard; there is also an overloaded end() from the original standard that returns a const pointer.

◆ end() [1/2]

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

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

◆ end() [2/2]

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.

◆ crbegin()

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.

◆ rbegin() [1/2]

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().

◆ rbegin() [2/2]

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.

◆ crend()

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.

◆ rend() [1/2]

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().

◆ rend() [2/2]

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.

◆ cdata()

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() is not in the C++11 standard although it would seem obvious in view of the cbegin() and cend() methods that had to be added. The C++11 overloaded const data() method is also available.

◆ data() [1/2]

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 C++11 std::vector.

◆ data() [2/2]

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 C++11 std::vector.

◆ operator[]() [1/2]

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.

◆ operator[]() [2/2]

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.

◆ at() [1/2]

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.

◆ at() [2/2]

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.

◆ getElt()

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.

◆ updElt()

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.

◆ front() [1/2]

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.

◆ front() [2/2]

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.

◆ back() [1/2]

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.

◆ back() [2/2]

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.

◆ operator()() [1/2]

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.

◆ getSubArray()

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.

◆ operator()() [2/2]

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.

◆ updSubArray()

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.

◆ push_back() [1/3]

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 moved to new space, costing one call to T's move 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.

◆ push_back() [2/3]

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

This is the move form of push_back(), taking an rvalue reference rather than an lvalue reference.

See the other signature for information, with move-construction instead of copy-construction (reallocation is the same in either case).

◆ emplace_back()

template<class T, class X>
template<class... Args>
void SimTK::Array_< T, X >::emplace_back ( Args &&...  args)
inline

This is similar to push_back() but rather than copying, it constructs the element in place at the end of the array.

To do that it invokes the constructor of T whose signature matches the supplied argument pack. This has the same effect as push_back(T(Args...)) would have but avoids the extra copy that would be required. Reallocation is handled the same as for push_back().

Note
This method should be preferred to the nonstandard raw_push_back() method.

◆ push_back() [3/3]

template<class T, class X>
void SimTK::Array_< T, X >::push_back ( )
inline

(Deprecated, use emplace_back() instead) 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 or move-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 or move constructor, which is prohibited by the standard std::vector<T> definition.

Note
Since C++11 added emplace_back() you can accomplish the same thing by calling emplace_back() with no arguments.
Complexity:
Same as the standard push_back(value) method except without the final call to T's copy constructor.
See also
emplace_back(), push_back(value)

◆ raw_push_back()

template<class T, class X>
T* SimTK::Array_< T, X >::raw_push_back ( )
inline

(Deprecated, use emplace_back() instead) This dangerous non-standard 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.
Note
Since C++11 added emplace_back() you can accomplish the same thing safely by calling emplace_back(args...) with the constructor arguments.
Complexity:
Same as ordinary push_back().
See also
emplace_back(), push_back(value)

◆ pop_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.

◆ erase() [1/2]

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 move constructor and destructor once for each element that has to be moved.

◆ erase() [2/2]

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 move constructor and destructor once for each element that has to be moved.
See also
eraseFast()

◆ 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 move constructor is used to move 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 move constructor and destructor once for each element that has to be moved.
See also
erase()

◆ clear()

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.

◆ insert() [1/4]

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() move 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 move/destruct pairs. Then there are n copy constructor calls to construct the new elements from the given value.

◆ insert() [2/4]

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.

◆ emplace()

template<class T, class X>
template<class... Args>
T* SimTK::Array_< T, X >::emplace ( T *  p,
Args &&...  args 
)
inline

Insert a new element at a given location within this array, by invoking T's constructor whose signature matches the supplied arguments.

All following elements are moved up one position. This is identical in effect to insert(p,T(Args...)) but avoids the extra copy that would be required in that case.

◆ insert() [3/4]

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 move 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 move/destruct pairs. Then there are n T(T2) constructor calls to construct the new elements from the given value.

◆ insert() [4/4]

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

◆ writeUnformatted()

template<class T , class X >
void writeUnformatted ( std::ostream &  o,
const Array_< T, X > &  v 
)
related

Specialize writeUnformatted() for Array_<E,X> to delegate to element type E, with spaces separating the elements.

◆ writeFormatted()

template<class T , class X >
void writeFormatted ( std::ostream &  o,
const Array_< T, X > &  v 
)
related

Specialize writeFormatted() for Array_<E,X> to delegate to element type E, with surrounding parentheses and commas separating the elements.

◆ operator<<()

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.

◆ readUnformatted()

template<class T , class X >
bool readUnformatted ( std::istream &  in,
Array_< T, X > &  v 
)
related

Specialization of readUnformatted() for variable-length Array_<T,X>; continues reading whitespace-separated tokens until error or eof.

◆ readFormatted()

template<class T , class X >
bool readFormatted ( std::istream &  in,
Array_< T, X > &  v 
)
related

Specialization of readFormatted() for variable-length Array_<T,X>; uses readArrayFromStream() to consume an appropriately-formatted array until error, closing parenthesis or bracket, or eof.

See also
readArrayFromStream() for details

◆ readArrayFromStream()

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()

◆ 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()

◆ operator>>()

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.

◆ operator==() [1/3]

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.

◆ operator!=() [1/3]

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.

◆ operator<() [1/3]

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.

◆ operator>=() [1/3]

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.

◆ operator>() [1/3]

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.

◆ operator<=() [1/3]

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.

◆ operator==() [2/3]

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.

◆ operator==() [3/3]

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.

◆ operator!=() [2/3]

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.

◆ operator!=() [3/3]

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.

◆ operator<() [2/3]

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.

◆ operator<() [3/3]

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.

◆ operator>=() [2/3]

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.

◆ operator>=() [3/3]

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.

◆ operator>() [2/3]

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.

◆ operator>() [3/3]

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.

◆ operator<=() [2/3]

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.

◆ operator<=() [3/3]

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.

◆ swap()

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.

◆ toXmlElement()

template<class T , class X >
Xml::Element toXmlElement ( const Array_< T, X > &  thing,
const std::string &  name = "" 
)
related

Partial specialization for XML serialization of Array_ objects.

The result is a single element with tag word <Array> with the given name (if any) and a version number as attributes. Then each entry is a subelement, as produced by type T's toXmlElement() method.


The documentation for this class was generated from the following files: