// Copyright (C) 2026 Kiyotsugu Arai // SPDX-License-Identifier: LGPL-3.0-or-later // vector_base.hpp // // Definition of the vector base class // // This file defines the base class for the vector classes of the MKL // algebra library. The base class provides functionality common to // vector classes that may use different storage strategies. // // Main features: // - Common vector interface // - Storage-independent operations // - Iterators and accessors #ifndef SANGI_VECTOR_BASE_HPP #define SANGI_VECTOR_BASE_HPP #include "vector_storage.hpp" #include "../common.hpp" #include #include #include #include #include namespace sangi { namespace detail { //----------------------------------------------------------------------------- // Vector base class //----------------------------------------------------------------------------- template requires concepts::AdditiveGroup // Require the additive group concept class VectorBase { public: using value_type = T; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using reference = T&; using const_reference = const T&; using pointer = T*; using const_pointer = const T*; using iterator = typename StoragePolicy::iterator; using const_iterator = typename StoragePolicy::const_iterator; // Default constructor (depends on the storage policy) VectorBase() = default; // Size-specifying constructor explicit VectorBase(size_type size) : storage_(size) {} // Constructor specifying size and initial value VectorBase(size_type size, const T& value) : storage_(size, value) {} // Iterator-range constructor template VectorBase(InputIt first, InputIt last) : storage_(first, last) {} // Initializer-list constructor VectorBase(std::initializer_list init) : storage_(init) {} // Copy/move constructors and copy/move assignment operators (default) VectorBase(const VectorBase&) = default; VectorBase(VectorBase&&) noexcept = default; VectorBase& operator=(const VectorBase&) = default; VectorBase& operator=(VectorBase&&) noexcept = default; // Destructor ~VectorBase() = default; // Element access // Subscript access (non-const) reference operator[](size_type pos) { return storage_[pos]; } // Subscript access (const) const_reference operator[](size_type pos) const { return storage_[pos]; } // Range-checked subscript access (non-const) reference at(size_type pos) { return storage_.at(pos); } // Range-checked subscript access (const) const_reference at(size_type pos) const { return storage_.at(pos); } // Front element access (non-const) reference front() { if (empty()) { throw IndexError("VectorBase::front: empty container"); } return storage_.front(); } // Front element access (const) const_reference front() const { if (empty()) { throw IndexError("VectorBase::front: empty container"); } return storage_.front(); } // Back element access (non-const) reference back() { if (empty()) { throw IndexError("VectorBase::back: empty container"); } return storage_.back(); } // Back element access (const) const_reference back() const { if (empty()) { throw IndexError("VectorBase::back: empty container"); } return storage_.back(); } // Data pointer access (non-const) T* data() noexcept { return storage_.data(); } // Data pointer access (const) const T* data() const noexcept { return storage_.data(); } // Iterators // Begin iterator (non-const) iterator begin() noexcept { return storage_.begin(); } // Begin iterator (const) const_iterator begin() const noexcept { return storage_.begin(); } // Begin iterator (always const) const_iterator cbegin() const noexcept { return storage_.cbegin(); } // End iterator (non-const) iterator end() noexcept { return storage_.end(); } // End iterator (const) const_iterator end() const noexcept { return storage_.end(); } // End iterator (always const) const_iterator cend() const noexcept { return storage_.cend(); } // Capacity // Check whether the container is empty bool empty() const noexcept { return storage_.empty(); } // Get the size size_type size() const noexcept { return storage_.size(); } // Set every element to a scalar value void fill(const T& value) { std::fill(begin(), end(), value); } // Zero-clear void zero() { fill(numeric_traits::zero()); } // Get the underlying storage (implementation detail) StoragePolicy& storage() noexcept { return storage_; } const StoragePolicy& storage() const noexcept { return storage_; } protected: StoragePolicy storage_; }; } // namespace detail } // namespace sangi #endif // SANGI_VECTOR_BASE_HPP