vector.hpp
This header file provides the Vector class and associated functions for managing vectors of elements.
Classes and Types
-
template<class ValueType>
class Vector A contiguous array of elements. The elements can be accesses with a non-negative index. The vector can be the owner of the memory allocated on the heap (automatically aligned to
SCTL_MEM_ALIGNbytes for SIMD vectorization) or it may be constructed from a user provided memory location (using Iterator<ValueType>).- Template Parameters:
ValueType – Type of the elements stored in the vector.
Constructor:
Vector(): Default constructor.
Vector(dim, data, own_data): Constructor with specified dimension, data pointer, and ownership flag.
Vector(const Vector& V): Copy constructor.
Vector(Vector&& V) noexcept: Move constructor.
Vector(ScratchBuf<ValueType>& buf, bool disable_reinit=true): Non-owning, fixed-size view into a ScratchBuf.
Vector(const std::vector<ValueType>& V): Constructor from std::vector.
Vector(std::initializer_list<ValueType> V): Constructor from initializer list.Methods:
Swap(v1): Swaps the contents of two vectors.
ReInit(dim, data, own_data): Reinitializes the vector with specified dimension, data pointer, and ownership flag.
Write(fname): Writes the vector to a file.
Read(fname): Reads the vector from a file.
Dim(): Returns the dimension of the vector.
SetZero(): Sets all elements of the vector to zero.
begin(): Returns an iterator to the beginning of the vector.
end(): Returns an iterator to the end of the vector.
PushBack(x): Appends an element to the end of the vector.
operator[]: Accesses elements of the vector by index.
operator=: Assigns the vector from another vector or std::vector (copy or move).
operator+=,operator-=,operator*=,operator/=: In-place arithmetic operations with another vector.
operator+,operator-,operator*,operator/: Arithmetic operations with another vector.
operator=,operator+=,operator-=,operator*=,operator/=: In-place arithmetic operations with a scalar.
operator+,operator-,operator*,operator/: Arithmetic operations with a scalar.
operator-: Unary negation.
operator<<: Output stream operator for writing a vector to an output stream.Usage guide: Using Vector class
#ifndef _SCTL_VECTOR_HPP_
#define _SCTL_VECTOR_HPP_
#include <ostream> // for ostream
#include <initializer_list> // for initializer_list
#include <vector> // for vector
#include "sctl/common.hpp" // for Long, sctl
#include "sctl/iterator.hpp" // for Iterator, ConstIterator
namespace sctl {
// forward declarations
template <class ValueType> Iterator<ValueType> NullIterator();
template <class ValueType> class ScratchBuf;
/**
* A contiguous array of elements. The elements can be accesses with a non-negative index. The vector can be the
* owner of the memory allocated on the heap (automatically aligned to `SCTL_MEM_ALIGN` bytes for SIMD vectorization) or
* it may be constructed from a user provided memory location (using Iterator<ValueType>).
*
* @tparam ValueType Type of the elements stored in the vector.
*/
template <class ValueType> class Vector {
public:
typedef ValueType value_type; /**< Type of the elements stored in the vector. */
typedef ValueType& reference; /**< Reference to an element in the vector. */
typedef const ValueType& const_reference; /**< Const reference to an element in the vector. */
typedef Iterator<ValueType> iterator; /**< Iterator for traversing the vector. */
typedef ConstIterator<ValueType> const_iterator; /**< Const iterator for traversing the vector. */
typedef Long difference_type; /**< Integer type representing the difference between two iterators. */
typedef Long size_type; /**< Integer type representing the size of the vector. */
/**
* Default constructor.
*/
Vector();
/**
* Constructor with dimension and data pointer.
*
* @param dim Dimension of the vector.
* @param data Pointer to the data.
* @param own_data Flag indicating ownership of data.
* @param disable_reinit If true, this Vector's dim and data_ptr are immutable
* for the rest of its lifetime: ReInit, Swap, and resizing assignment all
* trigger SCTL_ASSERT. Element-wise reads/writes are still allowed.
* Useful for views into externally-owned storage (e.g. ScratchBuf) where
* accidental rebinding would silently decouple the view from its backing.
*/
explicit Vector(Long dim, Iterator<ValueType> data = NullIterator<ValueType>(), bool own_data = true, bool disable_reinit = false);
/**
* Copy constructor.
*
* @param V Another vector to copy from.
*/
Vector(const Vector& V);
/**
* Move constructor. Steals ownership from `V`; leaves `V` empty
* (`Dim() == 0`) and in a valid destructible state.
*/
Vector(Vector&& V) noexcept;
/**
* Constructor from std::vector.
*
* @param V std::vector to construct from.
*/
explicit Vector(const std::vector<ValueType>& V);
/**
* Constructor from initializer list.
*
* @param V Initializer list to construct from.
*/
explicit Vector(std::initializer_list<ValueType> V);
/**
* Construct a non-owning view of a ScratchBuf. The Vector aliases the
* buffer's storage and does not free it; the ScratchBuf owns the lifetime.
*
* The ctor is `explicit` to prevent silent copies on assignment:
* `existing = scratch_buf;` won't compile, because `operator=(Vector&&)`
* cannot reach this ctor through copy-initialization. Use direct-init
* (`Vector<T> v(buf);`) for a view.
*
* By default the view is constructed with `fixed_size = true`, so calls
* that would resize/rebind it (`ReInit`, `Swap`, resizing `operator=`)
* trip `SCTL_ASSERT` in debug — protecting the ScratchBuf storage from
* being silently abandoned. Pass `disable_reinit = false` to opt out
* (e.g. when the view's contents will be moved into an owning Vector
* via `Swap`).
*/
explicit Vector(ScratchBuf<ValueType>& buf, bool disable_reinit = true);
/**
* Destructor.
*/
~Vector();
/**
* Swap the contents of two vectors. O(1) — no elements are copied. Ownership
* travels with the buffer, so it is safe to swap an owning vector with a
* non-owning view.
*
* @param v1 Vector to swap with.
*/
void Swap(Vector<ValueType>& v1);
/**
* Reinitialize the vector.
*
* @param dim New dimension of the vector.
* @param data New data pointer.
* @param own_data Flag indicating ownership of new data.
*/
void ReInit(Long dim, Iterator<ValueType> data = NullIterator<ValueType>(), bool own_data = true, bool disable_reinit = false);
/**
* Write the vector to a file.
*
* @param fname File name to write to.
*/
void Write(const char* fname) const;
/**
* Write the vector to a file with a different data type.
*
* @tparam Type Type of data to write.
* @param fname File name to write to.
*/
template <class Type> void Write(const char* fname) const;
/**
* Read the vector from a file.
*
* @param fname File name to read from.
*/
void Read(const char* fname);
/**
* Read the vector from a file with a different data type.
*
* @tparam Type Type of data to read.
* @param fname File name to read from.
*/
template <class Type> void Read(const char* fname);
/**
* Get the dimension of the vector.
*
* @return Long Dimension of the vector.
*/
[[nodiscard]] Long Dim() const noexcept;
/**
* Set all elements of the vector to zero.
*/
void SetZero();
/**
* Get an iterator pointing to the beginning of the vector.
*
* @return Iterator<ValueType> Iterator pointing to the beginning of the vector.
*/
[[nodiscard]] Iterator<ValueType> begin();
/**
* Get a const iterator pointing to the beginning of the vector.
*
* @return ConstIterator<ValueType> Const iterator pointing to the beginning of the vector.
*/
[[nodiscard]] ConstIterator<ValueType> begin() const;
/**
* Get an iterator pointing to the end of the vector.
*
* @return Iterator<ValueType> Iterator pointing to the end of the vector.
*/
[[nodiscard]] Iterator<ValueType> end();
/**
* Get a const iterator pointing to the end of the vector.
*
* @return ConstIterator<ValueType> Const iterator pointing to the end of the vector.
*/
[[nodiscard]] ConstIterator<ValueType> end() const;
/**
* Add an element to the end of the vector.
*
* @param x Element to be added.
*/
void PushBack(const ValueType& x);
// Element access
/**
* Access an element of the vector.
*
* @param j Index of the element to access.
* @return ValueType& Reference to the accessed element.
*/
ValueType& operator[](Long j);
/**
* Access a const element of the vector.
*
* @param j Index of the element to access.
* @return const ValueType& Const reference to the accessed element.
*/
const ValueType& operator[](Long j) const;
// Vector-Vector operations
/**
* Assignment operator from std::vector.
*
* @param V std::vector to assign from.
* @return Vector& Reference to the modified vector.
*/
Vector& operator=(const std::vector<ValueType>& V);
/**
* Assignment operator.
*
* @param V Vector to assign from.
* @return Vector& Reference to the modified vector.
*/
Vector& operator=(const Vector& V);
/**
* Move assignment. Swaps state with `V` when both sides own their buffers;
* otherwise copies `V`'s contents into `*this` (resizing as needed).
*
* @note If `*this` is a non-owning view and `V`'s size differs, the view
* binding is lost — `*this` becomes an owning vector with a fresh
* buffer. Same applies to copy-assignment.
*/
Vector& operator=(Vector&& V) noexcept;
/**
* Addition assignment operator.
*
* @param V Vector to add.
* @return Vector& Reference to the modified vector.
*/
Vector& operator+=(const Vector& V);
/**
* Subtraction assignment operator.
*
* @param V Vector to subtract.
* @return Vector& Reference to the modified vector.
*/
Vector& operator-=(const Vector& V);
/**
* Multiplication assignment operator.
*
* @param V Vector to multiply.
* @return Vector& Reference to the modified vector.
*/
Vector& operator*=(const Vector& V);
/**
* Division assignment operator.
*
* @param V Vector to divide.
* @return Vector& Reference to the modified vector.
*/
Vector& operator/=(const Vector& V);
/**
* Addition operator.
*
* @param V Vector to add.
* @return Vector Resultant vector after addition.
*/
[[nodiscard]] Vector operator+(const Vector& V) const;
/**
* Subtraction operator.
*
* @param V Vector to subtract.
* @return Vector Resultant vector after subtraction.
*/
[[nodiscard]] Vector operator-(const Vector& V) const;
/**
* Multiplication operator.
*
* @param V Vector to multiply.
* @return Vector Resultant vector after multiplication.
*/
[[nodiscard]] Vector operator*(const Vector& V) const;
/**
* Division operator.
*
* @param V Vector to divide.
* @return Vector Resultant vector after division.
*/
[[nodiscard]] Vector operator/(const Vector& V) const;
/**
* Negation operator.
*
* @return Vector Negated vector.
*/
[[nodiscard]] Vector operator-() const ;
// Vector-Scalar operations
/**
* Assignment operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to assign.
* @return Vector& Reference to the modified vector.
*/
template <class VType> Vector& operator=(VType s);
/**
* Addition assignment operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to add.
* @return Vector& Reference to the modified vector.
*/
template <class VType> Vector& operator+=(VType s);
/**
* Subtraction assignment operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to subtract.
* @return Vector& Reference to the modified vector.
*/
template <class VType> Vector& operator-=(VType s);
/**
* Multiplication assignment operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to multiply.
* @return Vector& Reference to the modified vector.
*/
template <class VType> Vector& operator*=(VType s);
/**
* Division assignment operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to divide.
* @return Vector& Reference to the modified vector.
*/
template <class VType> Vector& operator/=(VType s);
/**
* Addition operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to add.
* @return Vector Resultant vector after addition.
*/
template <class VType> [[nodiscard]] Vector operator+(VType s) const;
/**
* Subtraction operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to subtract.
* @return Vector Resultant vector after subtraction.
*/
template <class VType> [[nodiscard]] Vector operator-(VType s) const;
/**
* Multiplication operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to multiply.
* @return Vector Resultant vector after multiplication.
*/
template <class VType> [[nodiscard]] Vector operator*(VType s) const;
/**
* Division operator with a scalar.
*
* @tparam VType Type of the scalar.
* @param s Scalar value to divide.
* @return Vector Resultant vector after division.
*/
template <class VType> [[nodiscard]] Vector operator/(VType s) const;
private:
/**
* Initialize the vector.
*
* @param dim Dimension of the vector.
* @param data Pointer to the data.
* @param own_data Flag indicating ownership of data.
*/
void Init(Long dim, Iterator<ValueType> data = NullIterator<ValueType>(), bool own_data = true, bool disable_reinit = false);
Long dim; /**< Dimension of the vector. */
Long capacity; /**< Capacity of the vector. */
Iterator<ValueType> data_ptr; /**< Pointer to the data. */
bool own_data; /**< Flag indicating ownership of the data. */
bool disable_reinit_; /**< When true, ReInit/Swap/resizing assignment trigger SCTL_ASSERT. */
};
// Function template declarations for vector-scalar operations...
template <class VType, class ValueType> [[nodiscard]] Vector<ValueType> operator+(VType s, const Vector<ValueType>& V);
template <class VType, class ValueType> [[nodiscard]] Vector<ValueType> operator-(VType s, const Vector<ValueType>& V);
template <class VType, class ValueType> [[nodiscard]] Vector<ValueType> operator*(VType s, const Vector<ValueType>& V);
template <class VType, class ValueType> [[nodiscard]] Vector<ValueType> operator/(VType s, const Vector<ValueType>& V);
template <class ValueType> std::ostream& operator<<(std::ostream& output, const Vector<ValueType>& V);
} // end namespace
#endif // _SCTL_VECTOR_HPP_