Title
List-initialization of iterators in [simd.mask.overview]
Status
new
Section
[simd.mask.overview]
Submitter
Arthur O'Dwyer

Created on 2025-10-02.00:00:00 last changed 1 week ago

Messages

Date: 2025-10-04.15:05:06

Proposed resolution:

This wording is relative to N5014.

  1. Modify [simd.iterator] as indicated:

    namespace std::simd {
      template<class V>
      class simd-iterator {                                                  // exposition only
        V* data_ = nullptr;                                                  // exposition only
        simd-size-type offset_ = 0;                                          // exposition only
        constexpr explicit simd-iterator(V& d, simd-size-type off) noexcept; // exposition only
        
        […]
      };
    }
    
  2. Modify [simd.overview] as indicated:

    namespace std::simd {
      template<size_t T, class Abi> class basic_vec {
      public:
        using value_type = T;
        using mask_type = basic_mask<sizeof(T), Abi>;
        using abi_type = Abi;
        using iterator = simd-iterator<basic_vec>;
        using const_iterator = simd-iterator<const basic_vec>;
    
        constexpr iterator begin() noexcept { return iterator({*this, 0}); }
        constexpr const_iterator begin() const noexcept { return const_iterator({*this, 0}); }
        constexpr const_iterator cbegin() const noexcept { return const_iterator({*this, 0}); }
        constexpr default_sentinel_t end() const noexcept { return {}; }
        constexpr default_sentinel_t cend() const noexcept { return {}; }
        
        […]
      };
    }
    
  3. Modify [simd.mask.overview] as indicated:

    namespace std::simd {
      template<size_t Bytes, class Abi> class basic_mask {
      public:
        using value_type = bool;
        using abi_type = Abi;
        using iterator = simd-iterator<basic_mask>;
        using const_iterator = simd-iterator<const basic_mask>;
    
        constexpr iterator begin() noexcept { return iterator({*this, 0}); }
        constexpr const_iterator begin() const noexcept { return const_iterator({*this, 0}); }
        constexpr const_iterator cbegin() const noexcept { return const_iterator({*this, 0}); }
        constexpr default_sentinel_t end() const noexcept { return {}; }
        constexpr default_sentinel_t cend() const noexcept { return {}; }
        
        […]
      };
    }
    
Date: 2025-10-02.00:00:00

[simd.mask.overview] has

namespace std::simd {
 template<class V>
 class simd-iterator { // exposition only
  V* data_ = nullptr; // exposition only
  simd-size-type offset_ = 0; // exposition only
  constexpr simd-iterator(V& d, simd-size-type off) noexcept; // exposition only
  […]
 };
[…]
 template<size_t Bytes, class Abi>
  class basic_mask {
  public:
   using value_type = bool;
   using abi_type = Abi;
   using iterator = simd-iterator<basic_mask>;
   using const_iterator = simd-iterator<const basic_mask>;
   constexpr iterator begin() noexcept { return {*this, 0}; }
   constexpr const_iterator begin() const noexcept { return {*this, 0}; }
   constexpr const_iterator cbegin() const noexcept { return {*this, 0}; }
   constexpr default_sentinel_t end() const noexcept { return {}; }
   constexpr default_sentinel_t cend() const noexcept { return {}; }
   […]

It's unclear whether the "exposition-only" constructor is required to be present. If it is present, as written, without `explicit`, then `{someBasicMask, 0}` becomes a valid initializer for an iterator. Evidence in favor of its intentionality: the use of `return {*this, 0}` in `basic_mask::begin()`. (The constructor is `private`, but it still participates in overload resolution and will ambiguate other possible conversions.) But this makes many expressions ambiguous that could be unambiguous to a human.

using Mask = std::simd::mask<int>;

void overloaded(std::string, std::pair<Mask, int> kv);
void overloaded(std::string, Mask::iterator it);

int main() {
  Mask m;
  overloaded("the pair is", {m, 0});  // ambiguous?
}

At the very least, we should say that this list-initialization is intentional, and add wording to class simd-iterator and/or remove the "exposition only" from simd-iterator's constructor. That makes it clear that the above program is indeed intended to be ambiguous. But IMO we should instead simply make the above program valid.

History
Date User Action Args
2025-10-04 14:14:10adminsetmessages: + msg15122
2025-10-02 00:00:00admincreate