CArrayP
The CArrayP class template provides a lightweight, memory-managed wrapper for the classic C-style array with a proxy capability:
- The interface is similar to that of std::vector in some respects.
- Index and iterator based element access are supported.
- 0-based subscripting is provided by the [] operator, as in v[ i ].
- 1-based subscripting is provided by the () operator, as in v( i ).
- Subscripting does bounds checking in debug builds.
- Array size and indexing types are std::size_t so very large arrays are supported on 64-bit platforms where std::size_t is a 64-bit unsigned integer.
- CArrayPs can be owners of their data or proxies to other CArrayPs. Proxies have zero lookup overhead compared to owning CArrayPs, CArrays, or C-style arrays.
Shorthand (typedef) names are provided for the common value header so, for example, we use CArrayP_int instead of CArrayP< int > on this page.
Construction
CArrayPs are created in a straightforward fashion:
// CArrayP with n elements
CArrayP_int v( n ); // Elements are uninitialized
CArrayP_int w( n, 0 ); // Initialize elements to 0 |
The first constructor shown does not initialize the elements of built-in types such as int and float, for efficiency when constructing very large arrays that will be initialized after construction.
CArrayPs can be constructed from C arrays and a length:
int * s = new int[ n ];
...
CArrayP_int v( s, n ); |
and from an iterator range:
CArrayP_int v( s.begin(), s.end(), p ); // Chunk size is 2^p |
CArrayPs can also be default constructed and later sized:
CArrayP_int v;
...
v.resize( n ); // Now size and allocate it |
CArrayPs can also be copy constructed from any CArrayP with assignment-compatible values:
CArrayP_int v( n );
...
CArrayP_double z( v );
|
Proxy CArrayPs can be constructed from a CArrayP holding the same type using the Proxy named constructor:
CArrayP_int v( n );
...
CArrayP_int y( CArrayP_int::Proxy( v ) );
CArrayP_int z( CArrayP_int::Proxy( v, n-9 ) ); // Proxy size can be smaller |
Subscripting
CArrayP elements can be accessed by 0-based or 1-based index:
CArrayP_int v( n );
...
int i = v[ 0 ]; // First element
int j = v( 1 ); // First element |
Subscripting accesses to a CArrayP's elements are bounds-checked via assertions in a debug build.
Front and Back Elements
The first and last elements of a CArrayP elements can be read or write accessed with the STL-compatible front and back functions:
CArrayP_int v( n );
...
j = v.front(); // First element
v.back() = k; // Last element |
Assignment
CArrayPs support assignment of any CArrayP or std::vector with assignment-compatible values using the operators { =, +=, -= }:
CArrayP_int v( n );
CArrayP_double z( n );
... z = v;
...
z += v; |
and assignment of any assignment-compatible value with the operators { =, +=, -=, *=, /= }:
CArrayP_int v( n );
... v = 123; // All elements set to 123
v += 4.2; // Now all elements are 127 |
Additional assignment functions are available for assigning from an iterator range:
v.assign( s.begin(), s.end() ); |
or assigning a specified number of uniform-value elements:
v.assign( 1000, 123 ); // 1000 elements with value 123 |
Proxy CArrayPs cannot be assigned arrays of a different size.
Comparison
CArrayPs can be compared with CArrayPs and uniform values using the operators { ==, !=, <, <=, >=, > }.
Resizing
CArrayPs can be resized with the size and resize functions. The resize function preserves the values of the array that fit within the new size range and sets any new values to a specified fill value that defaults to the default-constructed value of the value type. If the values do not need to be preserved the size function is more efficient. Proxy CArrayPs cannot be resized.
Special Functions
CArrayPs can be reset to a default-constructed state with the clear member function. Two CArrayPs can efficiently swap their contents with the swap member and free functions. CArrayPs have length and length_squared member functions to compute their L2 length and squared length and the normalize function to normalize the array to unit length. The dot_product function computes the dot (inner) product of two CArrayPs. The distance and distance_squared functions compute the L2 distance and squared distance between two CArrayPs.
CArrayPs can be made into proxies with the attach member function and made into non-proxies with the detach member function.
Output
Stream input and output operators are provided.
Debugging
For performance, CArrayP doesn't check for bounds errors in release builds (when NDEBUG is defined). It is therefore important to test assertion-enabled debug builds of code using CArrayPs.
Const-Correctness
Proxy CArrayPs have proxy semantics and share the const-correctness semantics of pointers. The constness of the proxy and the data it is a proxy for are distinct and both are needed to get full constness.
One approach sometimes used to address this issue is to provide always-const versions of the proxy classes. This has the benefit of compile-time const correctness checks but forces a lot of code changes and limits the legal attach operations.
Argument Arrays (see below) are typically created via pass-by-value function arguments. If the functions do not need to alter the array values then qualify them with const in the function declaration so that the const array subscript operators will be used, avoiding const-correctness violations. Alternatively, a const reference to the proxy CArrayPs can be used for subscripting operations.
|