'Reverse array using generic function

I need to make a generic function which will allocate an array that has same elements as vector in the main function, but the order of elements is reversed. Function should accept iterator/pointer to beginning and to end of array.

#include <iostream>
#include <new>
#include <vector>
#include <exception>
template <typename iterator_tip> 
auto *MakeReverseArray(iterator_tip start, iterator_tip after_end) {
 size_t n = static_cast<size_t>(std::distance(start, after_end));
  using type_of_object=typename std::decay<decltype(*start)>::type;
  type_of_object *arr = nullptr;
  arr = new type_of_object[n]; 
  after_end--;
  for(int i=0;i<n;i++){
      arr[i]=*after_end;
      after_end--;
  }   
  return arr;
}
int main() {
    int n=5;
    std::vector<double>a{1.1,2.2,3.3,4.4,5.5};
    double *arr=nullptr;
    try{
    arr = MakeReverseArray(a.begin(),a.end());
    for(int i=0;i<n;i++)
    std::cout<<arr[i]<<" ";
  } catch (const std::bad_alloc e) {
    std::cout << "Not enough memory!";
  }
  return 0;
}

The only problem here is task setting: No operations other than assignment (“=”), dereferencing (“*”), equality and difference comparisons (“==” and “! =”) are allowed to be used over pointers or iterators passed as function parameters, and moving forward (“++”).

Could you help me modify this code without moving backwards?



Solution 1:[1]

If reverse iterators are allowed, then life would be simple.

The resulting code is simple. Nothing to explain here. Please see:

#include <iostream>
#include <vector>
#include <iterator>

template <typename T>
auto MakeReverseArray(T start, T end) {

    // Allocate new dynamic memory to store the reversed data
    typename T::value_type* arr = new T::value_type[std::distance(start, end)];
    typename T::value_type* dynPtr = arr;

    // Copy data
    for (T iter = start; iter != end; ++iter) 
        *dynPtr++ = *iter;
    return arr;
}
int main() {
    // Test data
    std::vector<double> a { 1.1,2.2,3.3,4.4,5.5 };

    // Create a dynamic array and filled it with the reversed vector
    double* arr = MakeReverseArray(a.rbegin(), a.rend());

    // Show output
    for (size_t i = 0; i < a.size(); i++)
        std::cout << arr[i] << " ";

    // Release dynamically allocated memory
    delete[]arr;
}

.


Without reverse iterators, we can at least subtract indices. Then the code would look like that:

#include <iostream>
#include <vector>
#include <iterator>

template <typename T>
auto MakeReverseArray(T start, T end) {

    // Get the number of elements from the given vector
    const size_t n = std::distance(start, end);

    // Allocate new dynamic memory to store the reversed data
    typename T::value_type* arr = new T::value_type[n];

    // Reverse and store
    size_t i = n - 1;
    for (T iter = start; iter != end; ++iter) {
        arr[i] = *iter;
        i = i - 1;
    }
    return arr;
}
int main() {
    // Test data
    std::vector<double>a{ 1.1,2.2,3.3,4.4,5.5 };

    // Create a dynamic array and filled it with the reversed vector
    double* arr = MakeReverseArray(a.begin(), a.end());

    // Show output
    for (size_t i = 0; i < a.size(); i++)
        std::cout << arr[i] << " ";

    // Release dynamically allocated memory
    delete[]arr;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Armin Montigny