After looking at your question and the code you provided; as others have stated you are not able to advance a pointer using the bit shift or stream manipulator operators. Basic pointer arithmetic would be more than enough. If you want something a little more elaborate with a bit of encapsulation then check out what I've done here by creating 2 sets of class templates. The first takes just a size_t
and is always char
, the 2nd takes both type T
& a size_t
. These are simple structs that just contain an internal array (left in public for demonstration purposes), the size, a default constructor and variadic initialization constructor. Once I created these classes, instead of performing "pointer arithmetic" I instead created both pre & post inc/dec operators
for both classes. Within these operators instead of doing "pointer-arithmetic" I just used the internal arrays to manipulate the data with the behavior that you were desiring. Here is the code:
Arrays.h
#ifndef ARRAYS_H
#define ARRAYS_H
template<size_t n>
struct charArray {
static const size_t SIZE = n;
char arr_[SIZE];
charArray() {}
template<class... U>
charArray( U ... pack ) : arr_ { pack... } {
static_assert(sizeof...(U) <= n, "too many values");
}
};
template<size_t n>
inline charArray<n>& operator--( charArray<n>& arr );
template<size_t n>
inline charArray<n> operator--( charArray<n>& arr, int );
template<size_t n>
inline charArray<n>& operator++( charArray<n>& arr );
template<size_t n>
inline charArray<n> operator++( charArray<n>& arr, int );
template<typename T, size_t n>
struct myArray {
static const size_t SIZE = n;
T arr_[SIZE];
myArray() {}
template<class... U>
myArray( U ... pack ) : arr_ { pack... } {
static_assert(sizeof...(U) <= n, "too many values");
}
};
template<typename T, size_t n>
inline myArray<T, n>& operator--( myArray<T,n>& arr );
template<typename T, size_t n>
inline myArray<T, n> operator--( myArray<T, n>& arr, int );
template<typename T, size_t n>
inline myArray<T, n>& operator++( myArray<T, n>& arr );
template<typename T, size_t n>
inline myArray<T, n> operator++( myArray<T, n>& arr, int );
#include "Arrays.inl"
#endif // ARRAYS_H
Arrays.inl
template<size_t n>
inline charArray<n>& operator--( charArray<n>& arr ) {
int i = 0;
for ( ; i < arr.SIZE - 1; ++i ) {
char temp = arr.arr_[i];
arr.arr_[i] = arr.arr_[i + 1];
arr.arr_[i + 1] = temp;
}
arr.arr_[i] = ' ';
// return reference
return arr;
}
template<size_t n>
inline charArray<n> operator--( charArray<n>& arr, int ) {
charArray<n> temp = arr;
--arr;
return temp;
}
template<size_t n>
inline charArray<n>& operator++( charArray<n>& arr ) {
int i = arr.SIZE-1;
for ( ; i > 0; --i ) {
char temp = arr.arr_[i];
arr.arr_[i] = arr.arr_[i-1];
arr.arr_[i-1] = temp;
}
arr.arr_[0] = ' ';
// return reference
return arr;
}
template<size_t n>
inline charArray<n> operator++( charArray<n>& arr, int ) {
charArray<n> temp = arr;
++arr;
return temp;
}
template<typename T, size_t n>
inline myArray<T, n>& operator--( myArray<T,n>& arr ) {
int i = 0;
for ( ; i < arr.SIZE - 1; ++i ) {
T temp = arr.arr_[i];
arr.arr_[i] = arr.arr_[i + 1];
arr.arr_[i + 1] = temp;
}
arr.arr_[i] = static_cast<T>( 0 );
return arr;
}
template<typename T, size_t n>
inline myArray<T, n> operator--( myArray<T, n>& arr, int ) {
myArray<T, n> temp = arr;
--arr;
return temp;
}
template<typename T, size_t n>
inline myArray<T, n>& operator++( myArray<T, n>& arr ) {
int i = arr.SIZE-1;
for ( ; i > 0; --i ) {
T temp = arr.arr_[i];
arr.arr_[i] = arr.arr_[i-1];
arr.arr_[i-1] = temp;
}
arr.arr_[0] = static_cast<T>(0);
return arr;
}
template<typename T, size_t n>
inline myArray<T, n> operator++( myArray<T, n>& arr, int ) {
myArray<T, n> temp = arr;
++arr;
return temp;
}
Arrays.cpp
#include "Arrays.h";
main.cpp
#include <iostream>
#include "Arrays.h"
int main() {
// Start with the char array, initilize it & print to screen
std::cout << "Working with charArray<6>.\n";
charArray<6> cArr = { 'a', 'b', 'c', 'd', 'e', 'f' };
for ( int i = 0; i < cArr.SIZE; i++ ) {
std::cout << cArr.arr_[i] << " ";
}
std::cout << std::endl;
// Pre - Decrement
--cArr;
// Reprint
std::cout << "After Pre-Decrement operator.\n";
for ( int i = 0; i < cArr.SIZE; i++ ) {
std::cout << cArr.arr_[i] << " ";
}
std::cout << std::endl;
// Post - Decrement
cArr--;
// Reprint
std::cout << "After Post-decrement operator.\n";
for ( int i = 0; i < cArr.SIZE; i++ ) {
std::cout << cArr.arr_[i] << " ";
}
std::cout << std::endl;
// Pre - Decrement again
std::cout << "Pre-decrement again after post-decrement.\n";
--cArr;
for ( int i = 0; i < cArr.SIZE; i++ ) {
std::cout << cArr.arr_[i] << " ";
}
std::cout << std::endl << std::endl;
// ==================================================================
// Do Same for templated arrays:
std::cout << "Working with myArray<char,6>.\n";
myArray<char, 6> arr = { 'a', 'b', 'c', 'd', 'e', 'f' };
for ( int i = 0; i < arr.SIZE; i++ ) {
std::cout << arr.arr_[i] << " ";
}
std::cout << std::endl;
// Pre - Decrement
--arr;
std::cout << "After Pre-decrement operator.\n";
for ( int i = 0; i < arr.SIZE; i++ ) {
std::cout << arr.arr_[i] << " ";
}
std::cout << std::endl;
// Post - decrement
arr--;
std::cout << "After Post-decrement operator.\n";
for ( int i = 0; i < arr.SIZE; i++ ) {
std::cout << arr.arr_[i] << " ";
}
std::cout << std::endl;
// Pre - Decrement again
std::cout << "Pre-decrement again after post-decrement.\n";
--arr;
for ( int i = 0; i < arr.SIZE; i++ ) {
std::cout << arr.arr_[i] << " ";
}
std::cout << std::endl << std::endl;
// ==============================================================
std::cout << "Working with myArray<int,4>.\n";
myArray<int, 4> arr2 = { 1,2,3,4 };
for ( int i = 0; i < arr2.SIZE; i++ ) {
std::cout << arr2.arr_[i] << " ";
}
std::cout << std::endl;
// Pre - Decrement
--arr2;
std::cout << "After Pre-decrement operator.\n";
for ( int i = 0; i < arr2.SIZE; i++ ) {
std::cout << arr2.arr_[i] << " ";
}
std::cout << std::endl;
// Post - Decrement
arr2--;
std::cout << "After Post-decrement operator.\n";
for ( int i = 0; i < arr2.SIZE; i++ ) {
std::cout << arr2.arr_[i] << " ";
}
std::cout << std::endl;
// Pre - Decrement again
std::cout << "Pre-decrement again after post-decrement.\n";
--arr2;
for ( int i = 0; i < arr2.SIZE; i++ ) {
std::cout << arr2.arr_[i] << " ";
}
std::cout << std::endl << std::endl;
std::cout << "===========================================================.\n";
// ====================================================================
std::cout << "Testing charArray<5> With Pre-Increment.\n";
charArray<5> cArr2 = { 'j', 'k', 'l', 'm', 'n' };
for ( int i = 0; i < cArr2.SIZE; i++ ) {
std::cout << cArr2.arr_[i] << " ";
}
std::cout << std::endl;
std::cout << "Pre - Increment\n";
++cArr2;
std::cout << "After Pre-increment operator.\n";
for ( unsigned i = 0; i < cArr2.SIZE; i++ ) {
std::cout << cArr2.arr_[i] << " ";
}
std::cout << std::endl << std::endl;
std::cout << "Testing myArray<float, 7> With Pre-Increment.\n";
myArray<float, 7> fArr = { 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f };
for ( int i = 0; i < fArr.SIZE; i++ ) {
std::cout << fArr.arr_[i] << " ";
}
std::cout << std::endl;
std::cout << "Pre - Increment\n";
++fArr;
std::cout << "After Pre-increment operator.\n";
for ( unsigned i = 0; i < fArr.SIZE; i++ ) {
std::cout << fArr.arr_[i] << " ";
}
std::cout << std::endl << std::endl;
std::cout << "Post-increment operator.\n";
cArr2++;
fArr++;
std::cout << "After Post-Increment.\n";
for ( int i = 0; i < cArr2.SIZE; i++ ) {
std::cout << cArr2.arr_[i] << " ";
}
std::cout << std::endl;
for ( int i = 0; i < fArr.SIZE; i++ ) {
std::cout << fArr.arr_[i] << " ";
}
std::cout << std::endl;
// Pre-Increment again
std::cout << "Pre-increment again.\n";
++cArr2;
++fArr;
std::cout << "Pre-Increment after post-increment.\n";
for ( int i = 0; i < cArr2.SIZE; i++ ) {
std::cout << cArr2.arr_[i] << " ";
}
std::cout << std::endl;
for ( int i = 0; i < fArr.SIZE; i++ ) {
std::cout << fArr.arr_[i] << " ";
}
std::cout << std::endl;
std::cout << "\nPress any key and enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
Mind the fact that the internal arrays are public, and that all loops and []
or array access is using the internal SIZE
variable as there is no array bounds checking. This just demonstrates that you can use the ++()
& --()
operators
to do the same thing that you was describing in either order.
Now if you wanted to you could change the Pre --
& Pre ++
slightly to do a wrap around in either direction so that if you were doing --()
the first element would move to the end instead of replacing it with 0
and if you are doing ++()
the last element would become the first, but I'll leave that as a challenge to you.