LCOV - code coverage report
Current view: top level - include - vectorf.hpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 47 47 100.0 %
Date: 2020-12-14 08:13:14 Functions: 16 16 100.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstring>
       4             : #include <iostream>
       5             : #include <vector>
       6             : #include "exceptions.hpp"
       7             : 
       8             : // ============
       9             : // Declarations
      10             : // ============
      11             : 
      12             : template <typename T>
      13             : class vectorf
      14             : {
      15             :  public:
      16             :   // === Constructors ===
      17             : 
      18             :   // Constructor to create an UNINITIALIZED vector
      19             :   // WARNING: Good for performance, but make sure to never use any uninitialized
      20             :   // elements! First argument: number of elements
      21             :   vectorf(const size_t &);
      22             : 
      23             :   // Constructor to create an initialized vectorf
      24             :   // Argument: a vector containing the elements of vectorf
      25             :   // Number of elements is inferred automatically
      26             :   vectorf(const std::vector<T> &);
      27             : 
      28             :   // Copy constructor to create a new vector with the same elements as an
      29             :   // existing vector
      30             :   vectorf(const vectorf &);
      31             : 
      32             :   // Move constructor to move the elements of an existing vector to a new vector
      33             :   vectorf(vectorf &&);
      34             : 
      35             :   // === Member functions ===
      36             : 
      37             :   // Overloaded operator = to assign the elements of one vector to another
      38             :   // vector
      39             :   vectorf &operator=(const vectorf &);
      40             : 
      41             :   // Overloaded operator = to move the elements of one vector to another vector
      42             :   vectorf &operator=(vectorf &&);
      43             : 
      44             :   // Member function used to obtain (but not modify) the size or length of the
      45             :   // vector
      46             :   size_t get_size() const;
      47             : 
      48             :   // Overloaded operator () used to access vector elements WITHOUT range
      49             :   // checking The indices start from 1: v(2) would be the element at row 2 First
      50             :   // version: returns a reference, thus allows modification of the element
      51             :   T &operator()(const size_t &);
      52             : 
      53             :   // Overloaded operator () used to access vector elements WITHOUT range
      54             :   // checking The indices start from 1: v(2) would be the element at row 2
      55             :   // Second version: does not return a reference and declared as const,
      56             :   // does not allow modification of the element
      57             :   T operator()(const size_t &) const;
      58             : 
      59             :   // Static member function used to set the character width of the elements
      60             :   // when printing a vector (will be used with std::setw)
      61             :   static void set_output_width(const int &);
      62             : 
      63             :   // === Friend functions ===
      64             : 
      65             :   // Overloaded binary operator << used to easily print out a matrix to a stream
      66             :   template <typename U>
      67             :   friend std::ostream &operator<<(std::ostream &, const vectorf<U> &);
      68             : 
      69             :  private:
      70             :   // The number of rows
      71             :   size_t size{0};
      72             : 
      73             :   // A pointer to an array storing the elements of the vector
      74             :   T *elements{nullptr};
      75             : 
      76             :   // A smart pointer to manage the memory allocated for the elements
      77             :   std::unique_ptr<T[]> smart{nullptr};
      78             : 
      79             :   // The character width of the elements when printing a matrix (will be used
      80             :   // with std::setw)
      81             :   static int output_width;
      82             : };
      83             : 
      84             : // Initialize output_width to have a default value of 5
      85             : template <typename T>
      86             : int vectorf<T>::output_width{5};
      87             : 
      88             : // ==============
      89             : // Implementation
      90             : // ==============
      91             : 
      92             : // === Constructors ===
      93             : 
      94             : // Uninitialized constructor
      95             : template <typename T>
      96         225 : vectorf<T>::vectorf(const size_t &input_size) : size(input_size)
      97             : {
      98         223 :   if (size == 0) throw sayMessage{"Size of vector must be positive.\n"};
      99         222 :   smart.reset(new T[ size ]);
     100         221 :   elements = smart.get();
     101         221 : }
     102             : 
     103             : template <typename T>
     104          33 : vectorf<T>::vectorf(const std::vector<T> &v)
     105             : {
     106          33 :   size = v.size();
     107          33 :   smart.reset(new T[ size ]);
     108          33 :   elements = smart.get();
     109          33 :   std::memcpy(elements, &v[ 0 ], size * sizeof(T));
     110          33 : }
     111             : 
     112             : // Copy constructor
     113             : template <typename T>
     114           3 : vectorf<T>::vectorf(const vectorf<T> &v) : size(v.size)
     115             : {
     116           3 :   smart.reset(new T[ size ]);
     117           3 :   elements = smart.get();
     118           3 :   std::memcpy(elements, v.elements, size * sizeof(T));
     119           3 : }
     120             : 
     121             : // Move constructor
     122             : template <typename T>
     123           1 : vectorf<T>::vectorf(vectorf<T> &&v) : size(v.size)
     124             : {
     125           1 :   smart = move(v.smart);
     126           1 :   elements = smart.get();
     127           1 :   v.size = 0;
     128           1 :   v.elements = nullptr;
     129           1 : }
     130             : 
     131             : // === Member functions ===
     132             : 
     133             : // Copy assignment
     134             : template <typename T>
     135           3 : vectorf<T> &vectorf<T>::operator=(const vectorf<T> &v)
     136             : {
     137           3 :   if (v.size != size)
     138           1 :     throw sayMessage{"Copy assignment requires equal vector size.\n"};
     139           2 :   if (elements == v.elements) return *this;
     140           1 :   size = v.size;
     141           1 :   smart.reset(new T[ size ]);
     142           1 :   elements = smart.get();
     143           1 :   std::memcpy(elements, v.elements, size * sizeof(T));
     144           1 :   return *this;
     145             : }
     146             : 
     147             : // Move assignment
     148             : template <typename T>
     149           3 : vectorf<T> &vectorf<T>::operator=(vectorf<T> &&v)
     150             : {
     151           3 :   if (v.size != size)
     152           1 :     throw sayMessage{"Move assignment requires equal vector size.\n"};
     153           2 :   if (elements == v.elements) return *this;
     154           1 :   size = v.size;
     155           1 :   smart = move(v.smart);
     156           1 :   elements = smart.get();
     157           1 :   v.size = 0;
     158           1 :   v.elements = nullptr;
     159           1 :   return *this;
     160             : }
     161             : 
     162             : template <typename T>
     163         132 : inline size_t vectorf<T>::get_size() const
     164             : {
     165         132 :   return size;
     166             : }
     167             : 
     168             : // With reference
     169             : template <typename T>
     170        1451 : inline T &vectorf<T>::operator()(const size_t &row)
     171             : {
     172        1451 :   return elements[ row - 1 ];
     173             : }
     174             : 
     175             : // No reference
     176             : template <typename T>
     177         659 : inline T vectorf<T>::operator()(const size_t &row) const
     178             : {
     179         659 :   return elements[ row - 1 ];
     180             : }
     181             : 
     182             : // For pretty printing
     183             : template <typename T>
     184             : inline void vectorf<T>::set_output_width(const int &w)
     185             : {
     186             :   output_width = w;
     187             : }
     188             : 
     189             : // === Friend functions ===
     190             : 
     191             : template <typename T>
     192             : std::ostream &operator<<(std::ostream &out, const vectorf<T> &v)
     193             : {
     194             :   if (v.size == 0)
     195             :     out << "()\n";
     196             :   else
     197             :   {
     198             :     out << "( ";
     199             :     for (size_t i{1}; i <= v.size; i++)
     200             :     {
     201             :       out << std::setw(v.output_width) << v(i) << ' ';
     202             :     }
     203             :     out << ")\n";
     204             :   }
     205             :   return out;
     206             : }

Generated by: LCOV version 1.14