最終更新日時:
が更新

履歴 編集

function template
<mdspan>

std::copy(C++29)

namespace std {
  template <class Src, class Dst>
  constexpr void copy(const Src& src, const Dst& dst); // (1) C++29

  template <class ExecutionPolicy, class Src, class Dst>
  void copy(ExecutionPolicy&& policy,
            const Src& src, const Dst& dst);           // (2) C++29
}

概要

多次元配列ビューstd::mdspanの全要素を、対応する要素どうしで別のmdspanへコピーする。

  • (1) : 各要素を順次コピーする
  • (2) : 指定した実行ポリシーによって並列にコピーする

コピー元とコピー先は、要素型やレイアウト・アクセサが異なっていてもよい。

テンプレートパラメータ制約

  • SrcおよびDstmdspanの特殊化であること
  • is_assignable_v<typename Dst::reference, typename Src::reference>trueであること
  • is_constructible_v<typename Src::extents_type, typename Dst::extents_type>trueであること
    • この制約は実質的に、両者の次元数(ランク)が等しく、対応する各次元が「同じ値の静的サイズ」またはdynamic_extentであることを検証する

事前条件

  • dst.is_unique()trueであること(レイアウトマッピングが各要素へ一意に対応すること)
  • src.extents()内の各多次元インデックスiについて、src[i]dst[j]が同じ要素を参照するようなdst.extents()内の多次元インデックスjが存在しないこと(コピー元とコピー先の要素が重ならないこと)

堅牢化された事前条件

  • src.extents()dst.extents()と等値であること

効果

srcの各要素を、dstの対応する要素へ代入する。

備考

  • 対象の範囲がstd::mdspanの次元情報として閉じているため、イテレータ範囲のアルゴリズムと違い、終端を越えた書き込みを実装が検査できる(サイズの不一致は堅牢化された事前条件の違反となる)
  • サイズの異なるmdspanどうしの部分的なコピーはサポートされない。コピーしたい領域をstd::submdspan()で部分ビューとして明示的に取り出してからコピーすること
  • 両者が同じ連続レイアウトかつデフォルトアクセサである場合など、レイアウト情報を利用した効率的な実装(memcpy相当への最適化など)が期待できる

#include <mdspan>
#include <iostream>

int main()
{
  double a[] = {1, 2, 3, 4, 5, 6};
  double b[6] = {};

  // 行優先のビューから列優先のビューへ、対応する要素どうしでコピーする
  std::mdspan<double, std::extents<std::size_t, 2, 3>> src{a};
  std::mdspan<double, std::extents<std::size_t, 2, 3>, std::layout_left> dst{b};
  std::copy(src, dst);

  // メモリ上は列優先の並びになる
  for (double x : b) {
    std::cout << x << ' ';
  }
  std::cout << std::endl;
}

このコードはC++29の規則のもとでは適格だが、2026年9月時点で本関数を実装した処理系はない。

出力

1 4 2 5 3 6 

バージョン

言語

  • C++29

処理系

関連項目

参照