// Copyright (C) 2026 Kiyotsugu Arai // SPDX-License-Identifier: LGPL-3.0-or-later // vector_view.hpp // // ベクトルビュークラスの定義 // // このファイルでは、MKL代数ライブラリのベクトルビュークラスを定義します。 // ビュークラスは、既存のベクトルの一部または全体への参照を提供し、 // コピーなしでデータにアクセスできるようにします。 // // 主な機能: // - 既存のベクトルへの参照ビュー // - ベクトルの部分ビュー(サブベクトル) // - 読み取り専用ビュー // - 変更可能ビュー #ifndef CALX_VECTOR_VIEW_HPP #define CALX_VECTOR_VIEW_HPP #include "../common.hpp" #include #include #include #include namespace calx { namespace detail { //----------------------------------------------------------------------------- // ベクトルビュークラス //----------------------------------------------------------------------------- template class VectorView { public: // ホスト型から型定義を取得 using value_type = typename std::remove_reference_t::value_type; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using reference = value_type&; using const_reference = const value_type&; using pointer = value_type*; using const_pointer = const value_type*; using iterator = value_type*; using const_iterator = const value_type*; // 元のベクトルへの参照型 using vector_reference = VectorType&; // 完全なベクトルのビューを作成 explicit VectorView(vector_reference vector) : vector_(vector), offset_(0), size_(vector.size()) {} // ベクトルの部分ビューを作成 VectorView(vector_reference vector, size_type offset, size_type size) : vector_(vector), offset_(offset), size_(size) { // 範囲チェック if (offset + size > vector.size()) { throw IndexError("VectorView: view range exceeds vector bounds"); } } // コピーコンストラクタ VectorView(const VectorView&) = default; // コピー代入演算子 VectorView& operator=(const VectorView&) = delete; // ビュー自体のコピーは禁止 // ビューの内容をコピーする代入 template VectorView& operator=(const VectorView& other) { assign(other.begin(), other.end()); return *this; } // ベクトルの内容をコピーする代入 template VectorView& operator=(const OtherVectorType& other) { assign(other.begin(), other.end()); return *this; } // 初期化リストからの代入 VectorView& operator=(std::initializer_list ilist) { assign(ilist.begin(), ilist.end()); return *this; } // 要素アクセス // 添字アクセス(非const) reference operator[](size_type pos) { assert(pos < size_ && "VectorView::operator[]: index out of range"); return vector_[offset_ + pos]; } // 添字アクセス(const) const_reference operator[](size_type pos) const { assert(pos < size_ && "VectorView::operator[]: index out of range"); return vector_[offset_ + pos]; } // 範囲チェック付き添字アクセス(非const) reference at(size_type pos) { if (pos >= size_) { throw IndexError("VectorView::at: index out of range"); } return vector_[offset_ + pos]; } // 範囲チェック付き添字アクセス(const) const_reference at(size_type pos) const { if (pos >= size_) { throw IndexError("VectorView::at: index out of range"); } return vector_[offset_ + pos]; } // 先頭要素アクセス(非const) reference front() { if (empty()) { throw IndexError("VectorView::front: empty view"); } return vector_[offset_]; } // 先頭要素アクセス(const) const_reference front() const { if (empty()) { throw IndexError("VectorView::front: empty view"); } return vector_[offset_]; } // 末尾要素アクセス(非const) reference back() { if (empty()) { throw IndexError("VectorView::back: empty view"); } return vector_[offset_ + size_ - 1]; } // 末尾要素アクセス(const) const_reference back() const { if (empty()) { throw IndexError("VectorView::back: empty view"); } return vector_[offset_ + size_ - 1]; } // データポインタアクセス(非const) pointer data() noexcept { return &vector_[offset_]; } // データポインタアクセス(const) const_pointer data() const noexcept { return &vector_[offset_]; } // イテレータ // 先頭イテレータ(非const) iterator begin() noexcept { return &vector_[offset_]; } // 先頭イテレータ(const) const_iterator begin() const noexcept { return &vector_[offset_]; } // 先頭イテレータ(常にconst) const_iterator cbegin() const noexcept { return &vector_[offset_]; } // 末尾イテレータ(非const) iterator end() noexcept { return &vector_[offset_ + size_]; } // 末尾イテレータ(const) const_iterator end() const noexcept { return &vector_[offset_ + size_]; } // 末尾イテレータ(常にconst) const_iterator cend() const noexcept { return &vector_[offset_ + size_]; } // 容量 // 空かどうかの確認 bool empty() const noexcept { return size_ == 0; } // サイズの取得 size_type size() const noexcept { return size_; } // 元のベクトルのサイズ size_type parent_size() const noexcept { return vector_.size(); } // オフセットの取得 size_type offset() const noexcept { return offset_; } // サブビューの作成 VectorView subview(size_type sub_offset, size_type sub_size) const { if (sub_offset + sub_size > size_) { throw IndexError("VectorView::subview: subview range exceeds view bounds"); } return VectorView(vector_, offset_ + sub_offset, sub_size); } // 全要素のスカラー値への設定 void fill(const value_type& value) { std::fill(begin(), end(), value); } // ゼロクリア void zero() { fill(numeric_traits::zero()); } // イテレータによる範囲からの代入 template void assign(InputIt first, InputIt last) { const auto count = std::distance(first, last); if (count > static_cast(size_)) { throw DimensionError("VectorView::assign: source range too large for view"); } std::copy(first, last, begin()); } // 元のベクトルへの参照の取得 vector_reference parent() noexcept { return vector_; } const vector_reference parent() const noexcept { return vector_; } private: vector_reference vector_; // 元のベクトルへの参照 size_type offset_; // 元のベクトル内でのオフセット size_type size_; // ビューのサイズ }; //----------------------------------------------------------------------------- // 読み取り専用ベクトルビュークラス //----------------------------------------------------------------------------- template class ConstVectorView { public: // ホスト型から型定義を取得 using value_type = typename std::remove_reference_t::value_type; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using reference = const value_type&; // constリファレンス using const_reference = const value_type&; using pointer = const value_type*; // constポインタ using const_pointer = const value_type*; using iterator = const value_type*; // constイテレータ using const_iterator = const value_type*; // 元のベクトルへの参照型(常にconst) using vector_reference = const VectorType&; // 完全なベクトルのビューを作成 explicit ConstVectorView(vector_reference vector) : vector_(vector), offset_(0), size_(vector.size()) {} // ベクトルの部分ビューを作成 ConstVectorView(vector_reference vector, size_type offset, size_type size) : vector_(vector), offset_(offset), size_(size) { // 範囲チェック if (offset + size > vector.size()) { throw IndexError("ConstVectorView: view range exceeds vector bounds"); } } // VectorViewからの変換コンストラクタ explicit ConstVectorView(const VectorView& view) : vector_(view.parent()), offset_(view.offset()), size_(view.size()) {} // コピーコンストラクタ ConstVectorView(const ConstVectorView&) = default; // コピー代入演算子 ConstVectorView& operator=(const ConstVectorView&) = delete; // ビュー自体のコピーは禁止 // 要素アクセス // 添字アクセス(常にconst) const_reference operator[](size_type pos) const { assert(pos < size_ && "ConstVectorView::operator[]: index out of range"); return vector_[offset_ + pos]; } // 範囲チェック付き添字アクセス(常にconst) const_reference at(size_type pos) const { if (pos >= size_) { throw IndexError("ConstVectorView::at: index out of range"); } return vector_[offset_ + pos]; } // 先頭要素アクセス(常にconst) const_reference front() const { if (empty()) { throw IndexError("ConstVectorView::front: empty view"); } return vector_[offset_]; } // 末尾要素アクセス(常にconst) const_reference back() const { if (empty()) { throw IndexError("ConstVectorView::back: empty view"); } return vector_[offset_ + size_ - 1]; } // データポインタアクセス(常にconst) const_pointer data() const noexcept { return &vector_[offset_]; } // イテレータ(すべてconst) // 先頭イテレータ const_iterator begin() const noexcept { return &vector_[offset_]; } const_iterator cbegin() const noexcept { return &vector_[offset_]; } // 末尾イテレータ const_iterator end() const noexcept { return &vector_[offset_ + size_]; } const_iterator cend() const noexcept { return &vector_[offset_ + size_]; } // 容量 // 空かどうかの確認 bool empty() const noexcept { return size_ == 0; } // サイズの取得 size_type size() const noexcept { return size_; } // 元のベクトルのサイズ size_type parent_size() const noexcept { return vector_.size(); } // オフセットの取得 size_type offset() const noexcept { return offset_; } // サブビューの作成 ConstVectorView subview(size_type sub_offset, size_type sub_size) const { if (sub_offset + sub_size > size_) { throw IndexError("ConstVectorView::subview: subview range exceeds view bounds"); } return ConstVectorView(vector_, offset_ + sub_offset, sub_size); } // 元のベクトルへの参照の取得 vector_reference parent() const noexcept { return vector_; } private: vector_reference vector_; // 元のベクトルへの参照(const) size_type offset_; // 元のベクトル内でのオフセット size_type size_; // ビューのサイズ }; // ビュー作成のためのヘルパー関数 // ベクトル全体のビューを作成 template VectorView make_vector_view(VectorType& vector) { return VectorView(vector); } // ベクトルの部分ビューを作成 template VectorView make_vector_view(VectorType& vector, std::size_t offset, std::size_t size) { return VectorView(vector, offset, size); } // ベクトル全体の読み取り専用ビューを作成 template ConstVectorView make_const_vector_view(const VectorType& vector) { return ConstVectorView(vector); } // ベクトルの部分的な読み取り専用ビューを作成 template ConstVectorView make_const_vector_view(const VectorType& vector, std::size_t offset, std::size_t size) { return ConstVectorView(vector, offset, size); } } // namespace detail } // namespace calx #endif // CALX_VECTOR_VIEW_HPP