1
\$\begingroup\$

I tried to implement my custom mathematical vector which is easy to use. I wanted to write this code modern way, I mean C++11/14.

I create iterator which is a class instance but there is ability to write this really short instead of creating class.

int *begin( A &v )
{
    return &v.v[0];
}
int *end( A &v )
{
    return &v.v[v._size];
}

Which will be better?

Vector.h

#ifndef MATHEMATICAL_VECTOR_VECTOR_H
#define MATHEMATICAL_VECTOR_VECTOR_H

#include "Iterator.h"
#include <cmath>

template<typename T>
class Vector{
private:
    T * storage;
    int _size;
public:
    Vector();
    explicit Vector(int size, T value = 0);
    Vector(const std::initializer_list<T> & v);

    Vector(const Vector<T> & v);
    Vector(Vector<T> && v);

    Vector & operator=(const Vector<T> & v);
    Vector & operator=(Vector<T> && v);

    virtual ~Vector();

    void swap(Vector<T> & other) noexcept;

    Vector operator+(const Vector<T> & v) const;
    Vector operator+(T v) const;
    Vector operator+() const;

    Vector & operator+=(const Vector<T> & v);
    Vector & operator+=(T v);

    Vector operator-(const Vector<T> & v) const;
    Vector operator-(T v) const;
    Vector operator-() const;

    Vector & operator-=(const Vector<T> & v);
    Vector & operator-=(T v);

    T operator*(const Vector<T> & v) const;
    Vector operator*(T v) const;

    Vector & operator *=(T t);

    Vector operator/(T v) const;

    Vector & operator/=(T v);

    bool operator==(const Vector<T> & v) const;
    bool operator!=(const Vector<T> & v) const;

    bool operator>(const Vector<T> & v) const;
    bool operator>=(const Vector<T> & v) const;
    bool operator<(const Vector<T> & v) const;
    bool operator<=(const Vector<T> & v) const;

    auto length() const;
    int size() const;

    T min() const;
    T max() const;

    T & operator[](int pos);
    const T &  operator[](int pos) const;

    Vector abs();

    friend class Iterator<T>;
    Iterator<T> end();
    Iterator<T> begin();
};

template<typename T>
Vector<T>::Vector() : storage(nullptr), _size(0) {}

template<typename T>
Vector<T>::Vector(int size, T value) : storage(new T[size]), _size(size) {
    for (int i = 0; i < _size; i++)
        storage[i] = value;
}

template<typename T>
Vector<T>::Vector(const std::initializer_list<T> & v) : storage(new T[v.size()]),
                                                       _size(v.size()) {
    for (int i = 0; i < v.size(); i++)
        storage[i] = *(v.begin() + i);
}

template<typename T>
Vector<T>::Vector(const Vector<T> & v) : _size(v._size),
                                         storage(!v._size ? nullptr :  new T[v._size]) {
    std::copy(v.storage, v.storage + _size, storage);
}

template<typename T>
Vector<T>::Vector(Vector<T> && v) : Vector(){
    this->swap(v);
}

template<typename T>
Vector<T> & Vector<T>::operator=(const Vector<T> & v){
    Vector<T> copy(v);
    copy.swap(*this);
    return *this;
}

template<typename T>
Vector<T> & Vector<T>::operator=(Vector<T> && v){
    v.swap(*this);
    return *this;
}

template<typename T>
Vector<T>::~Vector() {
    delete [] storage;
}

template<typename T>
void Vector<T>::swap(Vector<T> & other) noexcept {
    std::swap(storage, other.storage);
    std::swap(_size, other._size);
}

template<typename T>
Vector<T> Vector<T>::operator+(const Vector<T> & v) const{
    Vector<T> temp(_size);
    for (int i = 0; i < _size; i++)
        temp.storage[i] = storage[i] + v.storage[i];

    return temp;
}

template<typename T>
Vector<T> Vector<T>::operator+(T v) const{
    Vector<T> temp(_size);
    for (int i = 0; i < _size; i++)
        temp.storage[i] = storage[i] + v;

    return temp;
}

template<typename T>
Vector<T> Vector<T>::operator+() const{
    Vector temp(*this);
    return temp;
}

template<typename T>
Vector<T> & Vector<T>::operator+=(const Vector<T> & v){
    for (int i = 0; i < _size; i++)
        storage[i] += v.storage[i];

    return *this;
}

template<typename T>
Vector<T> & Vector<T>::operator+=(T v){
    for (int i = 0; i < _size; i++)
        storage[i] += v;

    return *this;
}

template<typename T>
Vector<T> Vector<T>::operator-(const Vector<T> & v) const{
    Vector<T> temp(_size);
    for (int i = 0; i < _size; i++)
        temp.storage[i] = storage[i] - v.storage[i];

    return temp;
}

template<typename T>
Vector<T> Vector<T>::operator-(T v) const{
    Vector<T> temp(_size);
    for (int i = 0; i < _size; i++)
        temp.storage[i] = storage[i] - v;

    return temp;
}

template<typename T>
Vector<T> Vector<T>::operator-() const{
    Vector<T> temp(_size);
    for(int i = 0; i < _size; i++)
        temp.storage[i] = -storage[i];

    return temp;
}

template<typename T>
Vector<T> & Vector<T>::operator-=(const Vector<T> & v){
    for(int i = 0; i < _size; i++)
        storage[i] -= v.storage[i];

    return *this;
}

template<typename T>
Vector<T> & Vector<T>::operator-=(T v){
    for (int i = 0; i < _size; i++)
        storage[i] -= v;

    return *this;
}

template<typename T>
T Vector<T>::operator*(const Vector<T> & v) const{
    T result = 0;
    for (int i = 0; i < _size; i++)
        result += storage[i] * v.storage[i];

    return result;
}
template<typename T>
Vector<T> Vector<T>::operator*(T v) const {
    Vector<T> temp(_size);
    for(int i = 0; i < _size; i++)
        temp.storage[i] = storage[i] * v;

    return temp;
}

template<typename T>
Vector<T> & Vector<T>::operator*=(T t){
    for(int i = 0; i < _size; i++)
        storage[i] *= t;

    return *this;
}

template<typename T>
Vector<T> Vector<T>::operator/(T v) const{
    Vector<T> temp(_size);
    for (int i = 0; i < _size; i++)
        temp.storage[i] = storage[i] / v;

    return temp;
}

template<typename T>
Vector<T> & Vector<T>::operator/=(T v){
    for (int i = 0; i < _size; i++)
        storage[i] /= v;

    return *this;
}

template<typename T>
bool Vector<T>::operator==(const Vector<T> & v) const{
    if (_size != v._size)
        return false;

    for (int i = 0; i < _size; i++)
        if(storage[i] != v.storage[i])
            return false;

    return true;
}

template<typename T>
bool Vector<T>::operator!=(const Vector<T> & v) const{
    return !(*this == v);
}


template<typename T>
bool Vector<T>::operator>(const Vector<T> & v) const{
    return this->length() > v.length();
}

template<typename T>
bool Vector<T>::operator>=(const Vector<T> & v) const{
    return this->length() >= v.length();
}

template<typename T>
bool Vector<T>::operator<(const Vector<T> & v) const{
        return *this >= v;
}

template<typename T>
bool Vector<T>::operator<=(const Vector<T> & v) const{
        return !(*this > v);
}

template<typename T>
auto Vector<T>::length() const{
    auto temp = 0;
    for (int i = 0; i < _size; i++)
        temp += storage[i] * storage[i];

    auto result = sqrt(temp);
    return  result;
}

template<typename T>
int Vector<T>::size() const{
    return _size;
}

template<typename T>
T Vector<T>::min() const{
    T temp = storage[0];
    for (int i = 1; i < _size; i++)
        if (storage[i] < temp)
            temp = storage[i];

    return temp;
}

template<typename T>
T Vector<T>::max() const{
    T temp = storage[0];
    for (int i = 1; i < _size; i++)
        if (storage[i] > temp)
            temp = storage[i];

    return temp;
}

template<typename T>
const T &  Vector<T>::operator[](int pos) const{
    return storage[pos];
}

template<typename T>
T & Vector<T>::operator[](int pos){
    return storage[pos];
}

template<typename T>
Vector<T> Vector<T>::abs(){
    Vector<T> temp(_size);
    for (int i = 0; i < _size; i++)
        temp.storage[i] = ::abs(storage[i]);

    return temp;
}

template<typename T>
Iterator<T> Vector<T>::end(){
    Iterator<T> temp(storage + _size);
    return temp;
}

template<typename T>
Iterator<T> Vector<T>::begin(){
    Iterator<T> temp(storage);
    return temp;
}

template<typename T>
Vector<T> operator+(T t, const Vector<T> & v ){
    return v + t;
}

template<typename T>
Vector<T> operator-(T t, const Vector<T> & v){
    return -(v - t);
}

template<typename T>
Vector<T> operator*(T t, const Vector<T> & v){
    return v * t;
}

#endif //MATHEMATICAL_VECTOR_VECTOR_H

Iterator.h

#ifndef MATHEMATICAL_VECTOR_ITERATOR_H
#define MATHEMATICAL_VECTOR_ITERATOR_H


template<typename T>
class Iterator {
private:
    T * point;
public:
    typedef std::ptrdiff_t                    difference_type;
    typedef T                                 value_type;
    typedef T *                               pointer;
    typedef T &                               reference;
    typedef std::random_access_iterator_tag   iterator_category ;

    Iterator(): point(nullptr){};
    explicit Iterator(T * item) : point(item){}

    Iterator<T> & operator=(const Iterator<T> & iter) = default;
    ~Iterator() = default;

    Iterator operator+(int add);
    Iterator operator-(int sub);

    bool operator!=(const Iterator<T> & iter) const;
    bool operator==(const Iterator<T> & iter) const;
    bool operator<(const Iterator<T> & iter) const;
    bool operator<=(const Iterator<T> & iter) const;
    bool operator>(const Iterator<T> & iter) const;
    bool operator>=(const Iterator<T> & iter) const;

    Iterator & operator++();
    Iterator operator++(int);
    Iterator & operator--();
    Iterator operator--(int);

    T & operator[](int n);
    T & operator*();
};

template<typename T>
bool Iterator<T>::operator==(const Iterator<T> & iter) const {
    return point == iter.point;
}

template<typename T>
bool Iterator<T>::operator!=(const Iterator<T> & iter) const {
    return !(*this == iter);
}

template<typename T>
bool Iterator<T>::operator<(const Iterator<T> & iter) const{
    return point < iter.point;
}

template<typename T>
bool Iterator<T>::operator<=(const Iterator<T> & iter) const{
    return point <= iter.point;
}

template<typename T>
bool Iterator<T>::operator>(const Iterator<T> &iter) const {
    return !(*this <=  iter);
}

template<typename T>
bool Iterator<T>::operator>=(const Iterator<T> &iter) const {
    return !(*this < iter);
}

template<typename T>
T & Iterator<T>::operator[](int n) {
    return *(point + n);
}

template<typename T>
Iterator<T> Iterator<T>::operator+(int add) {
    Iterator<T> temp(point + add);
    return temp;
}

template<typename T>
Iterator<T> Iterator<T>::operator-(int sub){
    Iterator<T> temp(point - sub);
    return temp;
}

template<typename T>
Iterator<T> operator+(int add, const Iterator<T> & iter){
    return iter + add;
}

template<typename T>
Iterator<T> & Iterator<T>::operator++(){
    point++;
    return *this;
}

template<typename T>
Iterator<T> Iterator<T>::operator++(int){
    Iterator<T> temp = *this;
    point++;
    return temp;
}

template<typename T>
Iterator<T> & Iterator<T>::operator--(){
    point--;
    return *this;
}

template<typename T>
Iterator<T> Iterator<T>::operator--(int){
    Iterator<T> temp = *this;
    point--;
    return temp;
}

template<typename T>
T & Iterator<T>::operator*(){
    return *point;
}


#endif //MATHEMATICAL_VECTOR_ITERATOR_H
| improve this question | | | | |
\$\endgroup\$
  • 2
    \$\begingroup\$ What's wrong with std::valarray? Would you like to add the reinventing-the-wheel tag? \$\endgroup\$ – πάντα ῥεῖ Feb 3 '17 at 18:42
  • \$\begingroup\$ Only for practice. \$\endgroup\$ – Newbie Feb 3 '17 at 18:47
  • 1
    \$\begingroup\$ If you really want to go nuts, implement a matrix class with template parameterized rows and columns. A vector will just 'fall out' of said implementation as a matrix with 1 row. Vector3f = Matrix<float, 3, 1>, for example \$\endgroup\$ – David Feb 3 '17 at 20:12
  • 2
    \$\begingroup\$ In c++11/14 you don't use new or delete manually with very few exceptions (and your code isn't an exception). I also think it's a useless feature to have a dynamically allocated math vector, parameterizing the length in the template type is the way to go. \$\endgroup\$ – David Feb 3 '17 at 22:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.