最終更新日時: 2025年07月14日 23時04分00秒 (JST)
Koichi Murase が更新

履歴 編集

function
<mdspan>

# std::layout_left_padded::mapping::コンストラクタ(C++26)

    constexpr mapping() noexcept;  // (1)

    constexpr mapping(const mapping&) noexcept = default;  // (2)

    constexpr mapping(const extents_type& ext);  // (3)

    template<class OtherIndexType>
    constexpr mapping(const extents_type& ext, OtherIndexType pad);  // (4)

    template<class OtherExtents>
    constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
      mapping(const layout_left::mapping<OtherExtents>& other);  // (5)

    template<class OtherExtents>
    constexpr explicit(extents_type::rank() > 0)
      mapping(const layout_stride::mapping<OtherExtents>& other);  // (6)

    template<class LayoutLeftPaddedMapping>
    constexpr explicit(see below)
      mapping(const LayoutLeftPaddedMapping& other);  // (7)

    template<class LayoutRightPaddedMapping>
    constexpr explicit(see below)
      mapping(const LayoutRightPaddedMapping& other) noexcept;  // (8)

## 概要

- (1) : デフォルトコンストラクタ
- (2) : コピーコンストラクタ
- (3) : `extents`から構築
- (4) : `extents`とパディングから構築
- (5) : `layout_left::mapping`からの変換コンストラクタ
- (6) : `layout_stride::mapping`からの変換コンストラクタ
- (7) : 他`layout_left_padded<S>::mapping`からの変換コンストラクタ
- (8) : `layout_right::mapping`または`layout_right_padded<S>::mapping`からの変換コンストラクタ

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

- (4) :
  - `is_convertible_v<OtherIndexType, index_type>`が`true`であること。
  - `is_nothrow_constructible_v<index_type, OtherIndexType>`が`true`であること。
- (5), (6) :
  - `is_constructible_v<extents_type, OtherExtents>`が`true`であること。
- (7) :
  - `is-layout-left-padded-mapping-of<LayoutLeftPaddedMapping>`が`true`であること。
  - `is_constructible_v<extents_type, LayoutLeftPaddedMapping::extents_type>`が`true`であること。
- (8) :
  - `is-layout-right-padded-mapping-of<LayoutRightPaddedMapping>`が`true`、または`is-mapping-of<layout_right, LayoutRightPaddedMapping>`が`true`であること。
  - `rank_`が`0`または`1`であること。
  - `is_constructible_v<extents_type, LayoutRightPaddedMapping::extents_type>`が`true`であること。

## 適格要件

- (5) : `OtherExtents::rank() > 1`のとき、`(static-padding-stride == dynamic_extent) || (OtherExtents::static_extent(0) == dynamic_extent) || (static-padding-stride == OtherExtents::static_extent(0))`が`true`であること。
- (7) : `rank_ > 1`のとき、`(padding_value == dynamic_extent) || (LayoutLeftPaddedMapping::padding_value == dynamic_extent) || (padding_value == LayoutLeftPaddedMapping::padding_value)`が`true`であること。

## 事前条件

- (3) :
  - `ext`の多次元インデクス空間のサイズを、`index_type`型で表現できること。
  - `rank_ > 1`かつ`padding_value != dynamic_extent`のとき、`LEAST-MULTIPLE-AT-LEAST(padding_value, ext.extent(0))`を`index_type`型で表現できること。
  - `rank_ > 1`かつ`padding_value != dynamic_extent`のとき、半開区間`[1, rank_)`の全ての値`k`に対して`LEAST-MULTIPLE-AT-LEAST(padding_value, ext.extent(0))`と全ての`ext.extent(k)`を乗算した値を`index_type`型で表現できること。
- (4) :
  - `pad`の値を`index_type`型で表現できること。
  - `extetns_type::index-cast(pad) > 0`
  - `rank_ > 1`のとき、`LEAST-MULTIPLE-AT-LEAST(pad, ext.extent(0))`を`index_type`型で表現できること。
  - `rank_ > 1`のとき、半開区間`[1, rank_)`の全ての値`k`に対して`LEAST-MULTIPLE-AT-LEAST(pad, ext.extent(0))`と全ての`ext.extent(k)`を乗算した値を`index_type`型で表現できること。
  - `padding_value != dynamic_extent`のとき、`padding_value == extetns_type::index-cast(pad)`
- (5) :
  - `extents_type::rank() > 1`かつ`padding_value != dynamic_extent`のとき、`other.stride(1) == LEAST-MULTIPLE-AT-LEAST(padding_value, extents_type::index-cast(other.extents().extent(0)))`
  - `other.required_span_size()`を、`index_type`型で表現できること。
- (6) :
  - `rank_ > 1`かつ`padding_value != dynamic_extent`のとき、`other.stride(1) == LEAST-MULTIPLE-AT-LEAST(padding_value, extents_type::index-cast(other.extents().extent(0)))`
  - `rank_ > 0`のとき、`other.stride(0) == 1`
  - `rank_ > 2`のとき、半開区間`[2, rank_)`の全ての値`r`に対して`other.stride(r) == (other.extents().fwd-prod-of-extents(r) / other.extents().extent(0)) * other.stride(1)`
  - `other.required_span_size()`を、`index_type`型で表現できること。
- (7) :
  - `rank_ > 1`かつ`padding_value != dynamic_extent`のとき、`other.stride(1) == LEAST-MULTIPLE-AT-LEAST(padding_value, extents_type::index-cast(other.extent(0)))`
  - `other.required_span_size()`を、`index_type`型で表現できること。
- (8) :
  - `other.required_span_size()`を、`index_type`型で表現できること。

## 効果

- (1) :
  - `mapping(extents_type{})`と等価。
- (3) :
  - `ext`を用いて`extents_`を直接非リスト初期化する。
  - `rank_ > 1`のとき、次の値を用いて`stride-1`を直接非リスト初期化する。
    - `padding_value == dynamic_extent`のとき、`ext.extent(0)`
    - そうでなければ、`LEAST-MULTIPLE-AT-LEAST(padding_value, ext.extent(0))`
- (4) :
  - `ext`を用いて`extents_`を直接非リスト初期化する。
  - `rank_ > 1`のとき、`LEAST-MULTIPLE-AT-LEAST(pad, ext.extent(0))`を用いて`stride-1`を直接非リスト初期化する。
- (5) :
  - `mapping(other.extents())`と等価。
- (6), (7) :
  - `other.extents()`を用いて`extents_`を直接非リスト初期化する。
  - `rank_ > 1`のとき、`other.stride(1)`を用いて`stride-1`を直接非リスト初期化する。
- (8) :
  - `other.extents()`を用いて`extents_`を直接非リスト初期化する。

## 例外

- (1), (2), (8) : 投げない

## explicitになる条件

- (5) : `!is_convertible_v<OtherExtents, extents_type>`
- (6) : `extents_type::rank() > 0`
- (7) : `rank_ > 1 && (padding_value != dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent)`
- (8) : `!is_convertible_v<LayoutRightPaddedMapping::extents_type, extents_type>`

## 例

    #include <cassert>
    #include <array>
    #include <mdspan>

    using Ext3x3 = std::extents<size_t, 3, 3>;
    using Ext2D = std::dims<2>;

    int main()
    {
      // (1) : デフォルトコンストラクタ
      {
        std::layout_left_padded<4>::mapping<Ext3x3> map1s;
        std::layout_left_padded<>::mapping<Ext3x3> map1d;
        assert(map1s.stride(1) == 4);
        assert(map1d.stride(1) == 3);
      }
      // (2) : コピーコンストラクタ
      {
        std::layout_left_padded<4>::mapping<Ext3x3> map2_a;
        std::layout_left_padded<4>::mapping<Ext3x3> map2_b = map2_a;
        assert(map2_a == map2_b);
      }
      // (3) : extentsから構築
      {
        Ext2D ext{3, 3};
        std::layout_left_padded<>::mapping<Ext2D> map3 = ext;
        assert(map3.extents() == ext);
      }
      // (4) : extentsとパディングから構築
      {
        Ext2D ext{3, 3};
        std::layout_left_padded<>::mapping<Ext2D> map4{ext, 4};
        assert(map4.extents() == ext && map4.stride(1) == 4);
      }
      // (5) : layout_left::mappingからの変換コンストラクタ
      {
        std::layout_left::mapping src5{Ext3x3{}};
        std::layout_left_padded<>::mapping<Ext2D> dst5 = src5;
        assert(dst5.stride(1) == 3);
      }
      // (6) : layout_stride::mappingからの変換コンストラクタ
      {
        std::array<int, 2> strides{1, 4};
        std::layout_stride::mapping src6{Ext3x3{}, strides};
        std::layout_left_padded<>::mapping<Ext2D> dst6{src6};
        assert(dst6.stride(1) == 4);
      }
      // (7) : 他layout_left_padded::mappingからの変換コンストラクタ
      {
        std::layout_left_padded<4>::mapping<Ext3x3> src7;
        std::layout_left_padded<>::mapping<Ext2D> dst7{src7};
        assert(dst7.extents() == Ext3x3{} && dst7.stride(1) == 4);
      }
      // (8) : layout_right(_padded)::mappingからの変換コンストラクタ
      {
        using Ext1D = std::dims<1>;
        std::layout_right::mapping<Ext1D> src8{Ext1D{5}};
        std::layout_left_padded<>::mapping<Ext1D> dst8{src8};
        assert(dst8.extent(0) == 5);
      }
    }

### 出力

## バージョン

### 言語

- C++26

### 処理系

- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??

## 関連項目

- `layout_left::mapping`
- `layout_right::mapping`
- `layout_right_padded::mapping`
- `layout_stride::mapping`

## 参照

- P2642R6 Padded mdspan layouts